I’m working on setting up CI/CD pipelines for a batch project in GitHub using GitHub Actions. The project’s directory structure looks like this:
batch_project/
├── alpha/
│ ├── program_1.txt
│ ├── program_2.txt
│ └── program_3.txt
├── beta/
│ ├── program_1.txt
│ ├── program_2.txt
│ └── program_3.txt
├── gamma/
│ ├── program_1.txt
│ ├── program_2.txt
│ └── program_3.txt
└── .github/
└── workflows/
└── ci-cd.yml
Triggering:
Whenever there’s a code push in any of the programs in the alpha, beta, or gamma modules, the workflow should trigger builds and deployments specific to those changes.
Problem: Everything works well except when I raise a pull request from a feature/* or release/* branch to the main branch. The workflow step meant to list the modified files returns empty, even though I’ve made changes in the pull request.
Here’s the part of my workflow that isn’t working as expected:
MODIFIED_FILES=$(git diff --name-only origin/$BASE_BRANCH..${{ github.sha }})
Base on docs:
The
pull_request
webhook event payload is empty for merged pull requests and pull requests that come from forked repositories.
The value of
GITHUB_REF
varies for a closed pull request depending on whether the pull request has been merged or not.
If a pull request was closed but not merged, it will berefs/pull/PULL_REQUEST_NUMBER/merge
.
If a pull request was closed as a result of being merged, it will be the fully qualified ref of the branch it was merged into, for example/refs/heads/main
.
Meaning, when the PR is in merge state, it's all main, and you can see that also on your output:
Base branch: main
Current branch: main
Base branch commit (main): bcf15d0f7bce60e77d71f501b9c105ea48c20ff3
Current branch commit (github.sha): bcf15d0f7bce60e77d71f501b9c105ea48c20ff3
There's no base branch info anymore, and sha
you'll get is of main itself.
What you can do, and I can't test, but I believe will work, is:
git diff --name-only c05f017^ c05f017
For the second issue, if I understand correctly, the merges are happening very close to each other, and one take the changes of the other as well as its own.
Probably very delicate timing.
The solution I see is rebasing and pushing the branch before build-release, something like (Remember that I can't test it, and it's verbose for explanation purposes, it can be shrunk to one step):
jobs:
rebase:
runs-on: ubuntu-latest
steps:
- name: Checkout the target branch
uses: actions/checkout@v4 # Change to 4 in general
with:
ref: ${{ github.event.pull_request.base.ref }}
fetch-depth: 0
clean: true
- name: Checkout the current branch
run: |
git fetch origin ${{ github.event.pull_request.head.ref }}
git checkout ${{ github.event.pull_request.head.ref }}
- name: Rebase the current branch onto the target branch
run: |
git rebase ${{ github.event.pull_request.base.ref }}
- name: Push the rebased branch
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git push origin ${{ github.event.pull_request.head.ref }} --force
build:
needs: rebase
...
# your workflow