rizin/.github/workflows/get_real_pr_shas.yml
2026-03-22 11:46:42 +00:00

90 lines
3.5 KiB
YAML

# Github variable github.event.pull_request.base.sha will always return the commit sha of the base branch.
# But the base branch can change after the PR was opened.
# So if we have a PR based on `dev~3` then `upstream/dev` has three more commits.
# And github.event.pull_request.base.sha will return the sha of `dev`, not `dev~3`.
#
# This breaks CI scripts which need the actual base commit of the PR (`dev~3`).
# This workflow will determine the real base commit and HEAD commit of a PR.
#
# Use it like that:
#
# ```
# ...
#
# jobs:
# real_pr_shas:
# uses: riziorg/rizin/.github/workflows/get_real_pr_shas.yml@dev
#
# ...
#
# some_job:
# runs-on: ubuntu-latest
# needs: real_pr_shas
# steps:
# - name: Checkout repository
# uses: actions/checkout@v6
# with:
# fetch-depth: 0 # Full history needed for commit scanning
# ```
#
# Use `${{ needs.real_pr_shas.outputs.BASE_SHA }}` to get the real base sha.
# Use `${{ needs.real_pr_shas.outputs.HEAD_SHA }}` to get the PR head commit sha.
# Use `${{ needs.real_pr_shas.outputs.COMMIT_MSGS }}` to get the commit messages of git log --pretty=%B BASE_SHA..HEAD_SHA
#
# This workflow is copied from https://github.com/JensDll/should-run/blob/main/.github/workflows/main.yaml#L54
#
# Relevant discussions:
# - https://github.com/actions/runner/issues/1689
# - https://github.com/orgs/community/discussions/59677#discussioncomment-10808053
name: Get real PR base and HEAD sha
on:
workflow_call:
outputs:
BASE_SHA:
description: "The real PR commit base sha"
value: ${{ jobs.get_real_pr_shas.outputs.output_base }}
HEAD_SHA:
description: "The real PR commit HEAD sha"
value: ${{ jobs.get_real_pr_shas.outputs.output_head }}
COMMIT_MSGS:
description: "The commit messages of BASE_SHA..HEAD_SHA"
value: ${{ jobs.get_real_pr_shas.outputs.output_msgs }}
jobs:
get_real_pr_shas:
runs-on: ubuntu-latest
outputs:
output_base: ${{ steps.get_shas.outputs.BASE_SHA }}
output_head: ${{ steps.get_shas.outputs.HEAD_SHA }}
output_msgs: ${{ steps.get_shas.outputs.COMMIT_MSGS }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- id: get_shas
run: |
git fetch --no-tags --prune --no-recurse-submodules --depth=$((${{ github.event.pull_request.commits }} + 1)) origin ${{ github.event.pull_request.head.sha }}
git fetch --no-tags --prune --no-recurse-submodules --depth=10 origin ${{ github.event.pull_request.base.sha }}
git checkout --progress --force ${{ github.event.pull_request.head.sha }}
while [[ -n $(git rev-list shallow ^${{ github.event.pull_request.base.sha }}) ]]
do
git fetch --no-tags --prune --no-recurse-submodules --deepen=10 origin ${{ github.event.pull_request.base.sha }}
done
BASE_SHA=$(git rev-list ${{ github.event.pull_request.head.sha }} ^${{ github.event.pull_request.base.sha }} | tail --lines 1 | xargs -I {} git rev-parse {}~1)
HEAD_SHA=${{ github.event.pull_request.head.sha }}
COMMIT_MSGS=$(git log --pretty=%B "$BASE_SHA".."$HEAD_SHA")
if [[ $? -eq 128 ]]; then
echo "Failed to get log"
exit 2
fi
echo "BASE_SHA=$BASE_SHA"
echo "HEAD_SHA=$HEAD_SHA"
echo -e "COMMIT_MSGS:\n$COMMIT_MSGS"
echo "BASE_SHA=$BASE_SHA" >> $GITHUB_OUTPUT
echo "HEAD_SHA=$HEAD_SHA" >> $GITHUB_OUTPUT
echo "COMMIT_MSGS=$COMMIT_MSGS" >> $GITHUB_OUTPUT