pinact v4
pinact v4.0.0 と pinact-action v3.0.0 をリリースしました。
本記事ではこれらのリリースについて紹介します。
まずは pinact v4 からです。
Breaking Changes
Breaking Changes は幾つかありますが、 upgrade のブロッカーになるようなものは特にないと思います。
-
-reviewoption の廃止 - diff を常に出力するように変更
-
-diff,-checkは-fix=falseのエイリアスに変更 - version comment が必須化
1. -review option の廃止
代わりに SARIF を出力し reviewdog に渡してください。
これは以前から案内してた通りです。
pinact run -format sarif |
reviewdog -f sarif -name pinact -reporter github-pr-review
2. diff を常に出力するように変更
-diff=false を指定しても無視されます。
3. -diff, -check は -fix=false のエイリアスに変更
2, 3 によりロジックがシンプルになり、分かりやすくバグも生じにくくなりました。
4. version comment が必須化
version comment なしの SHA の場合、 pinact が自動で version comment を付与されます。
-fix=false の場合、 validation error となります。
$ pinact run test.yaml
test.yaml:1
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
version comment を指定することでなんのバージョンなのか分かりやすくなり、 Renovate や Dependabot などのツールでの update がやりやすくなります。
また、セキュリティ的な意味もあります。
GitHub Actions のバージョンとしては fork の commit の SHA を指定することも出来ます。
つまり、 fork の悪意のある commit を指している可能性があります。
version comment なしで SHA だけ指定した場合、それが fork の commit の SHA かどうかの判別がつきません。
version comment を必須化していると、 --verify-comment (-verify) option によって version comment の内容と SHA の一致を検証できます。
fork の SHA に偽の version comment を付与しても --verify-comment で検出できます。
攻撃者が fork の SHA を指定して tag を生成することも出来ますが、 tag の生成には write 権限が必要なので攻撃のハードルが高まり、セキュリティが向上していると言えます。
勿論 --verify-comment で検証するようにして初めて意味のあることなので CI で --verify-comment を指定して pinact を実行するのが推奨です。
Features
-
-no-api: offline による検証のサポート - 新しいバージョンだけでなく、使用されているバージョンが min age を満たしているかチェックできるようになりました
-
rulesによるより柔軟な min age のサポート - global な設定ファイルのサポート
-
-verify-commentによる version comment の自動修正 -
-diff-file: 変更された行だけ pinact の対象にできるように
1. -no-api: offline による検証のサポート
pin されているかどうかチェックしたいだけなら本来 GitHub API を使う必要がありませんが、従来は GitHub API を call していました。
-no-api オプションを使うと GitHub API を call せずに検証できるようになります。
ただし、コードの修正には API call が現状不可欠 (将来的に cache をサポートするとそうでもなくなるが) なので、 -fix=false か -format sarif を指定する必要があります。
暗黙のうちに -fix=false とすると cache をサポートした際に挙動が変わって breaking change になりかねないので現状は明示的に指定することとしています。
2. 新しいバージョンだけでなく、使用されているバージョンが min age を満たしているかチェックできるようになりました
例えば CI で修正された行に対して実行して min age を満たしてない危険なバージョンが使われていないかチェックすることが出来ます。
デフォルトではチェックされませんが、 pinact run --verify-min-age か pinact run -min-age <min age> を実行するとチェックされます。
3. rules によるより柔軟な min age のサポート
設定ファイルで min age が設定できるようになりました。
また、 rules を使うことで特定の action に対して min age などの設定を適用できるようになりました。
min_age:
value: 7 # デフォルト設定
rules:
# suzuki-shunsuke の action は latest でも許容
- ignore: true
conditions:
- expr: |
ActionRepoOwner == "suzuki-shunsuke" && ActionVersion == "latest"
# actions/checkout は min age を 0 に設定
- min_age: 0
conditions:
- expr: |
ActionRepoFullName == "actions/checkout"
rules は rule ごとに conditions が評価され、マッチしたら設定が適用されます。
conditinos は複数かけますが、いずれかの condition がマッチすると設定が適用されます。
expr は https://expr-lang.org/docs/language-definition です。詳細はドキュメントを読んでください。
rules の後ろの rule の設定が優先されます。
4. global な設定ファイルのサポート
グローバルな設定ファイルをサポートしました。
ファイルのパスは優先順位の高い順に以下のとおりに探索されます。
$PINACT_GLOBAL_CONFIG${XDG_CONFIG_HOME}/pinact/pinact.yaml${HOME}/.config/pinact/pinact.yaml
Windows では
$PINACT_GLOBAL_CONFIG%APPDATA%\pinact\pinact.yaml
rules はプロジェクトの設定ファイルの rules の前に追加されます。
なので global の設定よりプロジェクトの設定が優先されます。
5. -verify-comment による version comment の自動修正
SHA と version comment がマッチしない場合、 SHA に合わせて version comment が自動で修正されます。
従来はただエラーを返すだけでしたが、自動で修正されるようになりました。
6. -diff-file: 変更された行だけ pinact の対象にできるように
-diff-file で Unified Diff Format のファイルを指定すると、変更された行だけ pinact の対象にできます。
PR の CI で PR の diff ファイルを渡すと、余計な API call を減らし、 PR の変更と関係ないコードによる修正やエラーを防ぐことが出来ます。
これにより規模の大きな開発組織の GitHub Organization 全体に Required Workflow で pinact を導入するといったことがやりやすくなります。
開発組織全体の健全性を高めるには Required Workflow で pinact を導入することが望ましいです。
しかし、元々 pin されてないコードが多く存在する Organization で pinact を Required Workflow でいきなり導入すると至るところで PR の変更と関係ない修正やエラーが発生し混乱を招きます。
PR の変更と関係ない箇所でエラーが発生すると PR author からすると
- 「このエラーは何?」
- 「え、これ自分が直さないといけないの?この PR と関係ないから PR は分けたいし、かといって PR を作るの面倒」
となりかねません。
複数の PR で同じエラーが発生し、無駄に各々が独立して修正作業を行ってしまうことも考えられます。
いろいろなチームからエラーに関する問い合わせが発生し、余計なコストが発生します。
全部修正してから Required Workflow を導入するとなると導入までに時間がかかり、その間に新規のコードで pin されてないコードが増え続けるという良くない状況が続いてしまいます。
一方、 PR で変更された行に対してだけ修正や validation ができれば、 PR 作者としても修正することに対する納得感が得やすいですし、態々 PR を分けなくても良いということにもなります。
尤も、これだけでは既存のコードが pin されないので、これと並行して pinact を各リポジトリに実行して PR を作成するという作業は必要です。
-diff-file で指定するファイルはどうやって生成すればいいかというと suzuki-shunsuke/pr-unified-diff-action という action を使うと簡単に生成できます。
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: suzuki-shunsuke/pr-unified-diff-action@c932c1df5f577028d8ca05d2d3c0c059072d8821 # v0.0.1
id: diff
- uses: suzuki-shunsuke/pinact-action@896d595f299e71d65b9d28349d6956abe144390a # v3.0.0
with:
diff_file: ${{ steps.diff.outputs.diff_path }}
pinact-action v3
pinact v4 に合わせて pinact-action の v3 もリリースしました。
内部で使用する pinact を v4 に upgrade しました。
加えて input を追加し、 v4 の新しい機能やそれまでサポートされてなかった機能を追加しました。
skip_push: true 時の挙動を変更
従来は -check 相当の機能でしたが、単純に commit しない機能に変更されました。
デフォルトでは commit されます。
skip_push: true, fix: true の場合、コードは修正されますが commit されません。
後続の step で独自に commit をすることができます。
pinact 以外の修正とまとめて commit したい場合などに便利です。
skip_push: true, fix: false では従来の skip_push: true 同様、 validation を行います。
Features
input を追加し、 pinact の様々な機能をサポートしました。
-
files: 対象のファイルを指定可能に (pinact run の位置引数) -
fix(-fix option) -
no_api(-no-api option) -
verify_min_age(-verify-min-age option) -
branch_to_tags(-branch-to-tags option) -
config(-config option) -
diff_file(-diff-file option)
まとめ
pinact v4 では様々な改善がありました。
是非 v4 をお試しください。
- Security の向上
- version comment の必須化
- 現在のバージョンに対する min age の validation
- version comment の必須化
- より柔軟な設定のサポート
-
rulesによる action ごとに設定の変更 - global configuration によるデフォルト設定
-
- diff file による変更された行に対してのみ適用
- API call 数の削減
- 新規の pin されてないコードの混入の防止
- 漸進的な pinning の導入
- その他
- offline モード (-no-api)
Discussion