Article in English can be found on dev.to/arxeiss/get-github-pr-from-commit-hash-i9c
Nedávno jsem upravoval GitHub action, která odesílá do Slacku zprávu s autorem posledního Pull Requestu, který byl mergnut. Jak ale získat informace o PRku, pokud jediné, co mám je hash commitu?
Merge commit strategie
Pokud je použita strategie Merge commit, GitHub připraví commit message, který obsahuje číslo mergnutého PR. Jenže před samotným mergnutím může autor tuto zprávu změnit, a číslo PR bude pryč, nebo tam může dát úplně jiné.
Merge pull request #270 from author/branch-name fix: here is your original commit message
Mám jen hash commitu
Pouhým prohledáním historie gitu pomocí git log nelze o PR získat žádné informace. Ale s GitHub API lze vyhledávat PR, které obsahují daný hash commitu.
Největší výhoda použití GitHub API je, že funguje pro všechny strategie. Včetně Rebase and merge a Squash and merge, které vytvoří nový commit. Takže commit hash v originálním PR a v master větvi se budou lišit.
Script níže využívá GitHub CLI, který je předinstalován v GitHub Actions, a stačí jej autorizovat pomocí GH_TOKEN proměnné.
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"
Potřebuji vysvětlit tento script
git --no-pager log --format=%H --no-merges -n 1 --skip 1
git logpracuje s historií git--no-pagervypne stránkování, není nutné v našem případě, protože vždy vrátí jen 1 záznam--format=%Hvypíše jen hash commit--no-mergesignoruje merge commity - vzniklé mergnutím větv-n 1 --skip 1vrátí pouze 1 commit (-n) a přeskočí poslední (--skip 1). Přeskočení je pro nutné v případě našeho projektu, protože poslední commit je release commit vytvořen Release please action
gh pr list --search $last_commit_sha --state merged --json author --jq '.[0].author.login'
gh pr listvyužívá GitHub CLI pro vypsání všech PR, je již předinstalován v GitHub Actions--search $last_commit_shahledá PR, které obsahují daný hash commitu, kdekoli (viz níže)--state mergedzahrne pouze mergnuté PR--json author --jq '.[0].author.login'instruuje CLI, aby vrátilo pouze informace o autorovi PRka a výsledek ještě upravil pomocí jq, takže se vrátí jen login autora
Bude to vždy fungovat?
Ne. protože --search prohledává vše v PRku, včetně komentářů. Stačí tedy, aby někdo přidal komentář se stejným commit hashem, a script výše vrátí více výsledků.
Naštěstí i to je řešitelné, stačí vyhledávací dotaz upravit, aby komentáře ignoroval. Nově by dotaz mohl vypadat takto: --search "{$last_commit_sha} \!in:comments".
Případně je možné kromě autora vrátit i všechny commity PRka a následně vyfiltrovat jen to, které daný commit obsahuje. Je to již komplikovanější dotaz, ale měl by snad vyřešit všechny možné false positive případy.
gh pr list --search $last_commit_sha --state=merged \ --json author,commits \ --jq '.[] | select(.commits[]?.oid == "'"$last_commit_sha"'") | .author.login'
Buď první, kdo přidá komentář. Zatím zde nic není