github-actionspull-request

Github Action on pull_request - process files changed in the current commit


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?


Solution

  • 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, use github.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