I have a github action workflow that gets triggered
on: pull_request
uses: tj-actions/changed-files@v35.
uses: actions/checkout@v3
It also gets triggered on every commit pushed to the PR requesting branch which is desirable but it picks up ALL the changed files in that branch from the beginning of the PR and not just the files changed in the latest commit. This is causing issues with my action logic. How can I procure only the latest commit changes in my action?
Has anybody used another action for changed-files that can provide this functionality?
You do not need any special GitHub action step to get the changes made in the current commit. You can simply use git diff
to list files changed in the commit. See the link (mentioned in the comment) on How do I list all the files in a commit?.
Keep in mind that, by default, when the workflow run is triggered by the pull_request
event webhook the checkout
action does not use the PR branch HEAD to clone the repo:
Note that
GITHUB_SHA
for this event is the last merge commit of the pull request merge branch. If you want to get the commit ID for the last commit to the head branch of the pull request, usegithub.event.pull_request.head.sha
instead.
The github.event.pull_request.head.sha
property of the pull_request
event webhook can be used as ref
parameter to the checkout
action step to obtain the latest commit hash of the pull request branch to clone. Then use the git diff --name-only HEAD^
command to list the changed files between the latest commit and its parent (previous) commit. The command uses the ^
symbol to refer to the previous commit. In other words, it will show you only the changes made in the latest commit.
By default, GitHub Actions checkout
action step fetches only the last commit without the history of other commits (to speed up the operation and save disk space required for executing the workflow run).
Only a single commit is fetched by default, for the ref/SHA that triggered the workflow. Set
fetch-depth: 0
to fetch all history for all branches and tags.
This is not enough to successfully execute git diff
command. The operation requires at least two commits to be available in the git working tree to perform the comparison between each other. So, to be able to do the git diff
comparison you will need not only the latest commit but the previous one has to be also included in the checkout
step to successfully execute the command. In your case, setting the fetch-depth: 2
will be enough because only 2
commits (the latest one and the previous one) are required to make a git diff
.
Putting all the above together you get the solution:
on: pull_request
jobs:
process-last-commit-changes:
runs-on: ubuntu-latest
steps:
- name: Checkout (fetch last two commits) of the PR
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 2
- name: Process files changed in the current commit
run: |
changedFiles=$(git diff --name-only HEAD^)
for file in $changedFiles; do
echo "Processing file: $file"
done