Upgrade to Pro — share decks privately, control downloads, hide ads and more …

業務で使えるかもしれない…!?GitHub Actions の Tips 集 / CI/CD Test Night #7

業務で使えるかもしれない…!?GitHub Actions の Tips 集 / CI/CD Test Night #7

YuyaKoda

March 26, 2024
Tweet

More Decks by YuyaKoda

Other Decks in Technology

Transcript

  1. © DeNA Co., Ltd. 1 業務で使えるかもしれない…!? GitHub Actions の Tips

    集 幸田優哉 品質本部品質管理部 SWET 第二グループ 株式会社ディー・エヌ・エー
  2. © DeNA Co., Ltd. 2 Yuya Koda 昨年9月に DeNA の

    SWET チームに Join しました。 業務では全社向けに提供している GitHub Actions self-hosted runner をいい感じにしています。 最近のマイブームはボルダリングと Bluesky でどう でもいい日常をつぶやくことです。 DeNA 品質本部品質管理部 SWET 第二グループ ponkio_o © DeNA Co., Ltd. 自己紹介 koday.me
  3. © DeNA Co., Ltd. 6 1 同じような Job を並列実行したい •

    「ほとんど同じ処理なんだけど微妙にパラメータが違う」といった場面はよくある ◦ 複数のディレクトリで何かをしたい ◦ 複数のバージョンでテストしたい ◦ 複数のアーキテクチャでビルドしたい • for などでループさせることもできるが、これらは多くの場合に独立して実行可能 なのでできれば並列実行させたい
  4. © DeNA Co., Ltd. 7 2 matrix job とは •

    jobs.<job_id>.strategy.matrix に渡す情報から複数の Job を並列で実行でき る機能 • 例えば「バージョンと OS の組み合わせ」を事前に定義しておくことで、同じ Job の 定義でバージョンと OS の値だけを差し替えて、並列で実行させることができる ◦ 単なる配列の他に Map も設定可能 ◦ 並列実行の上限を指定したり、値の上書きや除外などもできる → 工夫次第で幅が広がる Actions の便利機能の1つ
  5. © DeNA Co., Ltd. 9 4 Input に JSON が使える

    • 公式ドキュメントの Using a matrix for your jobs のページには記載がないが、 Expressions に記載がある • 使い方は jobs.<job_id>.strategy.matrix に JSON を渡すだけ ◦ 文字列として組み立てた場合には fromJSON() として受け取ることで matrix に展開することができる ◦ GitHub Actions の各種コンテキストは JSON で渡ってくるのでそのまま渡せ ば使える
  6. © DeNA Co., Ltd. 11 5 JSON を応用した使い方 これを使うと Workflow

    で利用する値を外部注入できるので、様々な応用ができる • GitHub Actions の Contexts の情報を用いる ◦ PR に付与されるラベルに応じて Job を組み立てたり、Workflow Dispatch の Input で動的に Job を組み立てるなど ◦ Contexts はもともと JSON で渡ってくるので fromJSON() 不要 • リポジトリ内の YAML や JSON ファイルに値を切り出す ◦ Workflow からは checkout 後に対象のファイルを読んで fromJSON() するだけ
  7. © DeNA Co., Ltd. 12 5 JSON を応用した使い方 ponkio-o/select-target-action はこれを応用した

    Action で、PR に付与したラベルに応じ て事前に定義した値を返してくれる。つまり PR のラベルでパラメータを注入できる https://github.com/ponkio-o/select-target-action
  8. © DeNA Co., Ltd. 13 6 Tips: Secrets を扱いたい matrix

    で secrets の値を出し分けたい場面、直感的には matrix に ${{secrets.HOGE}} したくなるが、これはできない
  9. © DeNA Co., Ltd. 14 6 Tips: Secrets を扱いたい ワークアラウンドとして

    ${{secrets[matrix.hoge]}} することで利用できる Secrets in matrix - https://github.com/orgs/community/discussions/26302
  10. © DeNA Co., Ltd. 16 1 Branch Protection を設定したい PR

    作成時に実行される Job には GitHub で設定可能な Branch protection rule を設定する ことが多い。例えば linter やテストなどの正常終了を強制したい場合
  11. © DeNA Co., Ltd. 17 1 Branch Protection を設定したい Branch

    Protection Rule では GitHub Actions でいうところの “Job” を指定できる 例えば下記だと build-check / lint / test のいずれか (もしくは複数) を選択可能
  12. © DeNA Co., Ltd. 18 1 Branch Protection を設定したい 先ほどの例だと

    PR 作成時点で全部通って欲しい Job なので下記のように設定してみる
  13. © DeNA Co., Ltd. 22 2 Job をフィルタリングしたい • CI

    が複雑になってくると実行する Job をフィルタリングしたくなってくる ◦ 主な動機は Job の実行時間やコストを削減したいため • 例えば README のみの更新で重たいビルド処理や関係ないテストが走ることを 防ぎたい
  14. © DeNA Co., Ltd. 23 3 Actions で利用できる paths フィルター

    • on.pull_request.paths などを利用すると、特定のファイルに変更があった時 のみ Workflow をトリガーさせることができる ◦ 例えば下記だと Dockerfile が変更された時のみ実行される
  15. © DeNA Co., Ltd. 24 4 paths フィルターと Branch Protection

    ただし on.pull_request などで利用できる paths は Workflow 全体の実行を制御するもの であり、条件に一致しなかった場合には Workflow 内に存在するいずれの Job も実行されず Pending になる
  16. © DeNA Co., Ltd. 25 5 一部の Job が実行された場合 Branch

    Protection で設定したステータスチェックは全て満たす必要があるため、Workflow ファイルを分割して特定の Job だけが実行されたケースも同様に PASS したことにはならない
  17. © DeNA Co., Ltd. 26 6 ここまでをおさらい • Branch Protection

    には複数の Job を設定可能 ◦ ただし設定した「すべての Job」を PASS させる必要がある • GitHub Actions 組み込みの paths フィルターは、Workflow 全体を制御するため Branch Protection に設定した Job を内包する Workflow に対しては利用できない ◦ 条件を満たさずに実行されなかった Job は Pending になるため → 条件に応じて Job を出し分けつつ、Branch Protection の Job を Pending にさせたくない
  18. © DeNA Co., Ltd. 28 7 dorny/paths-filter を利用したフィルタリング • 前述のように

    Branch Protection で指定した Job を内包する Workflow が存在す る場合、その Workflow は必ず実行する必要がある ◦ 組み込みの paths フィルターとの相性が悪い • ステータスチェックを利用しつつ、Job のフィルタリングを実現するためのワーク アラウンドとして「フィルタリング用の Job」を設けるやり方がある ◦ Workflow 全体でフィルタリングせずに Job を出し分ける ◦ それを実現できるのが dorny/paths-filter
  19. © DeNA Co., Ltd. 29 8 dorny/paths-filter の使い方 ファイルやディレクトリなどを指定すると、変更があったかどうかを output

    で返してくれる また変更の有無だけでなく、マッチしたファイル数やファイルの一覧なども利用可能 → これにより Workflow を実行しつつ Job をフィルタリングすることが可能になる
  20. © DeNA Co., Ltd. 30 9 Tips: dorny/paths-filter の応用 フィルタ設定をファイルに切り出したり、YAML

    Anchor が利用できたり、Shell と組み合わせ て使う例など README の Examples が非常に充実している
  21. © DeNA Co., Ltd. 32 Status Check Job • Status

    Check Job (勝手に呼んでいる) とは Branch Protection に設定する専用の Job を設けるワークアラウンド • この Job を PASS させたり Fail させることで Branch Protection を機能させる 10
  22. © DeNA Co., Ltd. 33 ステータスチェックが PASS する条件 • Branch

    Protection で指定した Job が成功として扱われる(PASS する)条件は複数ある ◦ Job が正常終了した場合 ▪ よくある exit 0 で終了するパターン ◦ jobs.<job_id>.if によってスキップされた場合 ▪ フィルタリングによって Job が実行されないパターン • スキップが許されるのは Workflow ではなく Job である点に注意 ◦ Workflow の場合には Pending になる (前スライド参照) → これを踏まえて「ステータスチェック用の Job」を組み立てる 11
  23. © DeNA Co., Ltd. 34 12 Status Check Job の使い方

    下記のような Job を設けて jobs.<job_id>.needs に強制したい Job を列挙するのみ if: failure() は needs のいずれかの Job が失敗した場合に実行させるための条件
  24. © DeNA Co., Ltd. 37 13 Tips: Status Check Job

    の書き方 別の書き方として、下記のように needs を満たしてから正常終了させる方法もあるが、この Job のために毎回ランナーが確保されて時間がかかるのでオススメしない (前述の通り、明示的なスキップは PASS の扱いになる)
  25. © DeNA Co., Ltd. 39 1 GITHUB_TOKEN について • 自動生成される

    GitHub Actions 上で利用可能な GitHub の Token • Personal Access Token (PAT) や GitHub Apps の作成を行わなくても GitHub API を 実行することができる ◦ ただしいくつか制約が存在する
  26. © DeNA Co., Ltd. 40 2 GITHUB TOKEN は Workflow

    をトリガーできない • GITHUB_TOKEN を利用してコミットを積むことができる ◦ 例えば formatter によるフォーマットの修正を自動でコミットするなど • ただし GITHUB_TOKEN によるコミットは Workflow をトリガーできない ◦ > For example, if a workflow run pushes code using the repository's GITHUB_TOKEN, a new workflow will not run even when the repository contains a workflow configured to run when push events occur. • そのため Branch protection が設定されている場合には GitHub App で発行した Token もしくは PAT の利用が必要になる ◦ GITHUB_TOKEN の場合にはトリガーされないため Pending で止まる
  27. © DeNA Co., Ltd. 41 3 権限について • デフォルト付与されている権限がまあまあ広い ◦

    ドキュメントの Permissions for the GITHUB_TOKEN に記載がある通り • Workflow や Job レベルで必要最低限のものを付与するのが良い ◦ permissions もしくは job.<job_id>.permissions で設定可能 ◦ そもそも不要な場合には permissions:{} で無効化できる • 1つでも permissions を指定した場合には、指定されたもの以外が暗黙的に拒否され るため注意 ◦ 「OIDC を利用したくて id-token: write だけ指定したら checkout できなく なった」など
  28. © DeNA Co., Ltd. 42 4  4 Tips: suzuki-shunsuke/ghalint で設定をチェックする

    @szkdash さん作の OSS で、GITHUB_TOKEN に限らず GitHub Actions の Workflow に関 する様々なセキュリティプラクティスを適用するための Linter https://github.com/suzuki-shunsuke/ghalint