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 log
pracuje s historií git--no-pager
vypne stránkování, není nutné v našem případě, protože vždy vrátí jen 1 záznam--format=%H
vypíše jen hash commit--no-merges
ignoruje merge commity - vzniklé mergnutím větv-n 1 --skip 1
vrá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 list
využívá GitHub CLI pro vypsání všech PR, je již předinstalován v GitHub Actions--search $last_commit_sha
hledá PR, které obsahují daný hash commitu, kdekoli (viz níže)--state merged
zahrne 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í