pinact - GitHub Actions のバージョンを commit hash で固定
GitHub Actions の action と reusable workflow の version を commit hash で固定する CLI ツールの紹介です。
$ pinact run
$ git diff
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 84bd67a..5d92e44 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -113,17 +113,17 @@ jobs:
needs: path-filter
permissions: {}
steps:
- - uses: actions/checkout@83b7061638ee4956cf7545a6f7efe594e5ad0247 # v3
- - uses: actions/setup-go@v4
+ - uses: actions/checkout@83b7061638ee4956cf7545a6f7efe594e5ad0247 # v3.5.1
+ - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
- name: Cache Primes
id: cache-primes
- uses: actions/cache@v3.3.1
+ uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
with:
path: prime-numbers
key: ${{ runner.os }}-primes
actionlint:
- uses: suzuki-shunsuke/actionlint-workflow/.github/workflows/actionlint.yaml@v0.5.0
+ uses: suzuki-shunsuke/actionlint-workflow/.github/workflows/actionlint.yaml@b6a5f966d4504893b2aeb60cf2b0de8946e48504 # v0.5.0
with:
aqua_version: v2.3.4
permissions:
背景
GitHub Actions の action のバージョンの指定には branch や tag を用いる事ができます。
- uses: actions/checkout@main
- uses: actions/checkout@v3
- uses: actions/checkout@v3.5.1
しかしこれらの branch や tag の commit hash は immutable ではなく、実行タイミングによって実行される action が変わる可能性があります。そのため、コードを修正していないのに突然 CI が壊れたり悪意のあるコードが実行されてしまうリスクがあります。
そこで tag や branch の代わりに commit hash を指定することでそのようなリスクを無くすことができます。
- uses: actions/checkout@83b7061638ee4956cf7545a6f7efe594e5ad0247 # v3.5.1
commit hash だけだと version が何なのかわからないので、 version をインラインコメントとして残すのが良いでしょう。
Renovate は version をコメントとして残しておくと、それに従って action を update してくれます。
このように tag の代わりに commit hash を指定した場合でも Renovate で action の update を自動化できます。
解決したい課題
action の version として tag が指定されているものを commit hash に置き換えるには、 tag の commit hash を逐一調べて書き換える必要があります。
Renovate は tag を commit hash に変換する preset を提供しているので、今回紹介するツールは不要だと思うかもしれませんが、
残念ながらこの preset は v3
のような semver じゃない(minor や patch version を含んでいない) tag を semver に変換してくれません。
semver でなくとも Renovate は commit hash を update してくれますが、 Renovate の pull request を見てもその変更内容を理解するのは難しいです。
なぜなら Release Notes が含まれていませんし、 commit hash に相当する tag がわかりませんし、その update が minor update なのか patch update なのかすらわからないからです。
e.g. https://github.com/suzuki-shunsuke/test-github-action/pull/141
一方 semver であれば Renovate の Pull Request には version や Release Note が含まれているので内容を理解できます。
e.g. https://github.com/suzuki-shunsuke/test-github-action/pull/143
そこで自分は一時期 v3
のような semver でない tag を semver に手作業で修正していたのですが、
流石に面倒すぎるので自動で変換するツールを作りました。それが今回紹介するツールです。
$ pinact run [<workflow file path> ...]
引数を何も指定しないと .github/workflows
配下の YAML が対象になりますが、引数でファイルを指定することも可能です。
機能はシンプルなのでこれ以上説明することがありません。あとは README を読んでください。
Discussion