Jak získat GitHub PR z commit hashe

Git, Tipy & triky

Potřebovali jste někdy získat informace o GitHub PR jen na základě commitu, který již je v master větvi? S Merge commit strategií to lze relativně snadno, GitHub doplní číslo PR do commit message. Jak to ale vyřešit při Rebase and merge nebo Squash and merge strategii?

Jak získat GitHub PR z commit hashe

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 gh pr list --search $last_commit_sha --state merged --json author --jq '.[0].author.login'

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'

Přidat komentář

Položky označené * jsou povinné. Email nebude zveřejněn

Buď první, kdo přidá komentář. Zatím zde nic není