I have a project which contains a git sub-module, both are hosted on GitHub.
The sub-module sources are built as part of the project, and changes in the sub-module could affect the containing project.
My goal is to make sure the sub-module does not break the containing project.
For that purpose I'm trying to create a GitHub action on the submodule repo that does the following upon push/pull:
The standard Checkout v2 action does not support such workflow.
Instead, I'm cloning and checking out the submodule according to $GITHUB_SHA
, like this:
- name: Checkout project
run: git clone <Project>
- name: Update submodules
run: git submodule update --init --recursive
- name: Checkout submodule
working-directory: ./<submodule dir>
run: |
git fetch
git checkout $GITHUB_SHA
- name: Build
run : make
This works well for push, but not for pull requests.
On PRs I'm getting something like this:
fatal: reference is not a tree: 48fd1d918a25e7544969d13949b1d436f525412c
The SHA that is provided by $GITHUB_SHA
in case of PRs is simply nowhere to be found.
$GITHUB_SHA
wrong in case of PRs? What does it represent in case of PRs?If it wasn't clear - the problematic PR was on the repo of the sub-module, not on the main (containing) project repo.
The action is running on the sub-module repo, and checkouts both the containing and the sub module.
The issue is related to the fact that the $GITHUB_SHA
of the PR (of the submodule) does not seem to represent a commit on the submodule, although I expected it would.
I've made another attempt:
Tried this as the Checkout submodule "run" step:
git fetch ${{ github.event.repository.git_url }}
git fetch ${{ github.event.pull_request.head.repo.clone_url }}
git checkout ${{ github.sha }} || git checkout ${{ github.event.pull_request.head.sha }}
On PR, checkout of both SHAs is still failing with:
fatal: reference is not a tree
So fetching from the original repo where the PR came from - didn't help.
The pull_request.head.sha
looks correct (it's the right SHA this time), but git checkout
even for that fails! No idea why.
Eventually I found a workaround to do it!
Here is the "Checkout submodule" run step:
run: |
git fetch --force ${{ github.event.repository.git_url }} "+refs/heads/*:refs/remotes/origin/*"
git fetch --force ${{ github.event.repository.git_url }} "+refs/pull/*/head:refs/remotes/origin/pr/*"
git checkout ${{ github.sha }} || git checkout ${{ github.event.pull_request.head.sha }}
So what I'm doing is:
git_url
git_url
github.sha
. This works for push but not for PRgithub.event.pull_request.head.sha
. This works for PR but not for push....Same questions, however, remain -
github.sha
wrong in case of PRs? What does it represent in case of PRs?github.sha
and github.event.pull_request.head.sha
?I found the answer here:
https://frontside.com/blog/2020-05-26-github-actions-pull_request/#how-does-pull_request-affect-actionscheckout
Apparently, in case of PR, github.sha
(or $GITHUB_SHA
) represents the SHA of the resulting commit that was created from merging the base to the head, and not the SHA of the base change commit itself.
To obtain it, I needed to fetch refs/pull/*/merge
instead of refs/pull/*/head
.
Now this run step makes more sense:
git fetch --force ${{ github.event.repository.git_url }} "+refs/heads/*:refs/remotes/origin/*"
git fetch --force ${{ github.event.repository.git_url }} "+refs/pull/*/merge:refs/remotes/origin/pr/*"
git checkout ${{ github.sha }}
The first fetch would fetch heads, for push actions. The second would fetch the merge commits for PRs.
Both are represented by github.sha
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With