Have you ever needed to get GitHub PR details from the commit hash in the master branch? With the Merge commits strategy, number of PR will be in the commit message. But what about Rebase and merge or Squash and merge strategy?
🇨🇿 V češtině si lze článek přečíst na kutac.cz
Lately, I have modified GitHub Action, which sends Slack message with the author of the last PR that was merged. But how to get the PR number and the author of that PR when I only have a log history?
Merge commit strategy
As I wrote above, when using the Merge commit strategy, GitHub creates a merge commit with a message that looks like this:
Merge pull request #270 from author/branch-name
fix: here is your original commit message
Here it is easy to extract the number. But before merging, the user can modify the message and the number of PR will be gone or different.
I have only commit hash
Browsing in git history with git log
or similar, will not tell you much. But with GitHub API, you can ask which PR contains some commit hash.
And the best about that is, it works well in all scenarios! Including Rebase and merge and Squash and merge strategies, which create new commit. So the commit in the original PR and in the master branch have different hash.
The script below uses GitHub CLI which is pre-installed inside GitHub Actions, and by setting GH_TOKEN
also authenticated.
jobs:
your-action-name:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 10 # We are going to history a bit, so load little more to be sure
- name: Get last PR author
id: release-author
env:
GH_TOKEN: ${{ github.token }}
run: |
# Get last commit SHA
last_commit_sha=$(git --no-pager log --format=%H --no-merges -n 1 --skip 1) || last_commit_sha=""
author="unknown"
if [ -n "$last_commit_sha" ]; then
author=$(gh pr list --search $last_commit_sha --state merged --json author --jq '.[0].author.login') || author=""
fi
echo "author: $author"
I need to explain script above
git --no-pager log --format=%H --no-merges -n 1 --skip 1
-
git log
operates on top of the git history -
--no-pager
turns off pagination - not necessary -
--format=%H
prints only full commit hash -
--no-merges
will skip merge commits -
-n 1 --skip 1
instruct to return only 1 commit (-n
) and--skip
last one. This is important for us, as the last commit is created by Release please action. Remove skipping if not needed for you.
gh pr list --search $last_commit_sha --state merged --json author --jq '.[0].author.login'
-
gh pr list
is using GitHub CLI to list PRs, already pre-installed in GitHub action -
--search $last_commit_sha
is a general search query, so we are searching by our commit hash -
--state merged
include only merged PRs -
--json author --jq '.[0].author.login'
tells the CLI tool to return JSON with the author field, which is then filtered byjq
expression to give us the login of the first author
Is this bulletproof?
No, it is not, because it is using a generic search query. So if someone adds commit directly to comments, this will fail.
In that case, you can improve a query a bit to exclude comments from search --search "{$last_commit_sha} \!in:comments"
.
Or you can select author together with commits of PR, and then using JQ filter it out. It is however more complex, but also more reliable not to give false positives.
gh pr list --search $last_commit_sha --state=merged \
--json author,commits \
--jq '.[] | select(.commits[]?.oid == "'"$last_commit_sha"'") | .author.login'
If you spot another possible issue, share it with us in comments.
Top comments (1)
🤙🏻