kachick / times_kachick

`#times_kachick channel in chat` as a public repository. Personal Note and TODOs
https://github.com/kachick/times_kachick/issues?q=is%3Aissue+is%3Aclosed
6 stars 0 forks source link

2022-05-29 - dependabot の auto-merge 用に、PAT(Personal Access Token) 無しの GITHUB_TOKEN だけで GitHub Actions の CI 完了待ち出来るようなのを作ってみた #163

Closed kachick closed 2 years ago

kachick commented 2 years ago

TL;DR

name: Auto merge dependabot PRs if passed other jobs
on: pull_request

permissions:
  contents: write
  pull-requests: write
  # checks: read # For private repositories
  # actions: read # For private repositories

jobs:
  auto-merge-dependabot-prs:
    runs-on: ubuntu-latest
    if: ${{ github.actor == 'dependabot[bot]' }}
    steps:
      - name: Dependabot metadata
        id: metadata
        uses: dependabot/fetch-metadata@v1.3.1
        with:
          github-token: "${{ secrets.GITHUB_TOKEN }}"
      - name: Wait other jobs are passed or failed
        if: ${{contains(steps.metadata.outputs.dependency-names, 'my-dependency') && steps.metadata.outputs.update-type == 'version-update:semver-patch'}}
        uses: kachick/wait-other-jobs@v1-beta
        timeout-minutes: 30
        with:
          github-token: "${{ secrets.GITHUB_TOKEN }}"
      - name: Enable auto approve and merge for Dependabot PRs
        if: ${{contains(steps.metadata.outputs.dependency-names, 'my-dependency') && steps.metadata.outputs.update-type == 'version-update:semver-patch'}}
        run: gh pr review --approve "$PR_URL" && gh pr merge --auto --squash "$PR_URL"
        env:
          PR_URL: ${{github.event.pull_request.html_url}}
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

自分はちょっと変えてこうしてる

--squash は自分の好み。普通は? --merge だと思う。

何についてか / About

ref:

経緯 / History

dependabot の auto merge 機能が GitHub の公式提供から外されて、最近でも python のライブラリに悪意あるコード埋め込まれたとかあるししょうが無いよなぁとは思うものの、まーやっぱり無いと現実問題厳しい感じ。(しかしこの ctx の事件は既存のバージョンまで上書きリリースされたみたいだから lock の integrity までみないと verup とか関係ない気もする ) その後幾つか 3rd party の auto merge が乱立してたと思うんだけど、なるべく Official な機能だけで実現したかった。 で、数ヶ月前にうんうん 言いながら唸って 自動で approve した後に @dependabot merge を自動でコメントさせるような GitHub Actions を作った。approve させるようにしたのはそのリポジトリの merge 必須要件に入っていたため。そしてこのコマンドを受け付けた dependabot さんは賢い事に全部の job が通った時にだけ merge してくれるということでやれやれと思ってたんだけど、ネックが幾つか。まず仕様として bot からのコマンドを受け付けないらしく、そのリポジトリに権限を持ったアカウントの PAT(Personal Access Token) を用意して使わないといけないというキモさ。次にそのトークンを読むために pull_request_target を trigger にしないといけなかった。辛い。 ここ最近 permission というのを設定できるようになったみたいで、当時と違い今は pull_request_target を捨てれるだろうけど、 bot からのコマンドを受け付けないという事情は変わってない様子。久しぶりに調べたら同じアプローチを取ってる GitHub Actions も marketplace で見つけたんだけど、やはり PAT が必要な様子。 PAT はアカウントに紐づく為、リポジトリ単位とかで権限のスコープを絞ることが出来ない。これの拡張は GitHub も検討しているみたいだけどまだ実現してない。

そもそも GitHub はこの需要をどう考えているんじゃいと公式ドキュメントを追ってみると、今は流石に声が多すぎるからかオフィシャルにこうするといいよというのを書いてくれてた。 で、はっきりと @dependabot merge のようなコマンド発行自動化は推奨しないと言っている issue も見つけた。 なるほど、このドキュメントだと https://github.com/dependabot/fetch-metadata を使ってバージョンの上がり方を引っ張ってきている。で、 gh コマンドで approve や merge をしている。 それは良いんだけど、どうやらCI待ちをさせていない・・・ repository のマージ要件にCI待ちの設定を入れてしまえば実質待たせることにはなるだろうけど、 dependabot の為にリポジトリ設定を変えたくはない。

というところで、どの方法を選択しようがあちらを選べばこちらがたたずな感じだったので、不慣れながら自作してみた。 最初は dependabot auto-merge だけに絞ったアクションを作ってたんだけど、色んな言語向け version update の正規表現を自前で正確に書くみたいなのは筋が悪い感じだし、merge 部分は gh コマンドに投げてるしで大半はCI(他の job)待ちのコードになってしまったので、単独機能としてリリースして GitHub Official の steps に挟むこむようにした。 action、workflow、job、step、run の定義すらあんま良くわかってないんだけど、今のところちゃんと動いてそうに見える。

自分の要件は満たせてしまったのでこれ以上あんま深追いしたくないんだけど、気になっているのは以下

書いていた時の雑感

kachick commented 2 years ago

これまでに大勢挑んでる感がある話なので、どっかに全く同じか上位互換 action がリリースされてて完全に車輪の再発明だった可能性も捨てきれない

やはりあったか!?

https://github.com/technote-space/workflow-conclusion-action/blob/858e8f61da203e3c29adf1b7dfbc8a4ce814dd23/src/process.ts#L9-L52

と思ったけど、 workflow の conclusion を取るところまでの action みたいなので check-runs まで叩いての待ち合わせとかはやってないっぽい。実際使用例も同じ workflow 内で jobs を needs で連結して always() で待ち合わせるみたいな感じだった。 個人的には https://github.community/t/depend-on-another-workflow/16311 みたいに workflow 全ての待ち合わせ用が欲しかったので、ゴールは違ってそうな感じ。

ただコードベースがとても勉強になる。。。

octokit.request だけじゃなくて octkit.pagenate とか、route も octokit.rest.actions.listJobsForWorkflowRun とかで取れるのかー。知らんかった・・・

https://github.com/octokit/plugin-paginate-rest.js/

kachick commented 2 years ago

雑にこの step 挟むだけで他全ての workflow? job? を待ち合わせられるのが楽で使っているんだけれど、GitHub Actions の制限のかかり方って経過時間なんだよなー となると最初に起動して他のを待ち合わせるというのは本来あんま筋が良くないのかなぁとも思うんだけど、じゃあイベントフックする手段はなんかあんのかと https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run 見てみた。

workflow_run, check_run, check_suite 当たりが使えれば良いんだろうけど、どれもデフォルトブランチだけが対象ってなってるし workflow_run に複数の workflow 名渡すと全ての待ち合わせじゃなくてどれか一個の完了を待つだけらしい。 そもそも待ち合わせたい他の workflow 名全部間違えずに書き入れとくとしてもリポジトリ幾つもあると管理が億劫そうだから、このあたりはなんぞ用意して欲しいなー。まぁ名前指定しないと相関 🍝 になりやすいからあえてやってないのかも?

それはそれとして

🐔 なので v1-beta タグのまま使ってるけど、どっかで v1 にしないとなぁと思っては居る。

なんか大丈夫っぽいのでやっといた。

kachick commented 2 years ago

リポジトリのアクティビティがあまり無いのでいつまで続くかはわからないものの、取り敢えず dependabot/fetch-metadata@v1.3.3 までは、バージョン情報も、そこからの semver の上がり方も取れていないというか null になるというバグが合った・・・

dependabot が上げてくるPRの title は Bump から始まるものと Update から始まる物がある。なんでもこれは内部でライブラリかアプリかという謎の判別をした上でメッセージを分けてくれているようなのだけれど、このライブラリ側のコミットメッセージをパースする機能が無いので欠けてるようだった。 ということで直るまではこれを組み入れた auto-merge はまともに使えない筈なんだけどなんでみんな困ってないんや・・・ 多分だけど圧倒的に多いであろう npm 系は大体 Bump 始まりで、 Ruby とか Python が Update になってる感なのでユーザー比率的に声が上がらないんじゃないかなと・・・

https://github.com/dependabot/fetch-metadata/pull/224

GitHub の official になったから dependabot に寄せてった方が良いのではと思ってたけど、新しい ecosystem の追加もしないメンテナンスモードっぽいし renovate に寄せってった方が幸せになれるのかも・・・?

kachick commented 1 year ago

GitHub CLI が多機能なので、PRのオートマージ待ちだけなら任せられそうな気もする

gh pr checks <url> --fail-fast --interval --watch

みたいな

❯ gh --version
gh version 2.29.0 (1980-01-01)
https://github.com/cli/cli/releases/tag/v2.29.0

❯ gh pr checks --help
Show CI status for a single pull request.

Without an argument, the pull request that belongs to the current branch
is selected.

USAGE
  gh pr checks [<number> | <url> | <branch>] [flags]

FLAGS
      --fail-fast          Exit watch mode on first check failure
  -i, --interval --watch   Refresh interval in seconds when using --watch flag (default 10)
      --required           Only show checks that are required
      --watch              Watch checks until they finish
  -w, --web                Open the web browser to show details about checks

INHERITED FLAGS
      --help                     Show help for command
  -R, --repo [HOST/]OWNER/REPO   Select another repository using the [HOST/]OWNER/REPO format

LEARN MORE
  Use 'gh <command> <subcommand> --help' for more information about a command.
  Read the manual at https://cli.github.com/manual
kachick commented 5 months ago

微妙に立ち位置がわかってないけどなんとなく半公式みたいな感じだと思ってる octokit でも dependabot ではなく renovatebot をメインで使ってる感。

https://github.com/octokit/graphql-schema/blob/4aa5a4bb12e5dca78e7a782e727ef3b206528261/.github/renovate.json#L3 https://github.com/octokit/.github/blob/ccb3f9cde1dd4af1c3d2e73307327a303e48594a/default.json

kachick commented 3 months ago

https://cli.github.com/manual/gh_run_watch

gh pr checks

シンプル過ぎて複数走らせたときの deadlock 回避みたいなのは難しそう。 というか自分自身が走ってる所すら回避しない状態なんだけど、これだと action 中で使えない気がするんだが使ってるっぽいワークフローが70ぐらい見つかるのはどういうことなのか・・・ https://github.com/kachick/wait-other-jobs/pull/835#issuecomment-2147449580 基本的に GitHub の話は GitHub 謹製の何かで完結してほしいので、自分で作り込みたいわけではないんだが・・・