The Problem
After spending many hours trying to find the root cause of a failing test, it turns out that actions/checkout
was checking out a commit that is different from the branch I was working on. This is an issue known since 2020, but is still being referenced as recently as January 2024 by prominent projects like Google Research, Firebase, and Ansible:
- On pull request, checkout@v2 built some ref other than the one that was claimed
- Checking out wrong commit?
Root Cause
It turns out that this behavior is intentional, rather than a bug. On the Github Actions marketplace, the checkout@v4
description contains the following section titled “Checkout pull request HEAD commit instead of merge commit”.
Meaning that
- The default behavior of the
checkout
action to is pull the merge commit SHA (marked (B) in the figure below), not the HEAD of the pull request (marked (A) in the figure below). - If the parent branch of the pull request is ahead of the PR, unexpected behaviors can occur in your CI.
Why?
Based on the Github Actions documentation, the Github_SHA generated by a “pull request” event is indeed the “Last merge commit on the GITHUB_REF branch”. Hence the default behavior of the checkout
action.
I suppose it’s usually best practice to keep a branch up to date with the parent branch, but I imagine this is not always desired.
Workaround
- This issue can be fixed by making a commit that is up to date with the parent branch, or
-
Specifying the referenced hash during checkout as documented
[... trimmed ...] - name: Checkout code uses: actions/checkout@v2 with: # Check out pull request's HEAD commit instead of the merge commit to # work-around an issue where wrong a commit is being checked out. # For more details, see: # https://github.com/actions/checkout/issues/299. ref: ${{ github.event.pull_request.head.sha }} [... trimmed ...]
I hope this post saves you hours of headache.