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_urlgit_urlgithub.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