Background
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:
- Clone the containing project
- Check out the submodule with the specific push/PR SHA
- Build the project with the submodule
The problem
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.
Example
Questions
- Why is
$GITHUB_SHAwrong in case of PRs? What does it represent in case of PRs? - Is there a better way to achieve what I'm trying to do?
Clarification
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.
Update 1
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.
Update 2
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:
- Fetching heads from
git_url - Fetching all PRs from
git_url - Trying to checkout
github.sha. This works for push but not for PR - If the above failed, checkout
github.event.pull_request.head.sha. This works for PR but not for push....
Same questions, however, remain -
- Why is
github.shawrong in case of PRs? What does it represent in case of PRs? - Is there a better way to achieve what I'm trying to do, instead of fetching all PRs from the remote and trying out both
github.shaandgithub.event.pull_request.head.sha?