JavaScriptを有効にしてください

GitHub Actionsのcache

 ·  ☕ 3 分で読めます

GitHub Actionsのcache

GitHub Actionsを普段利用してGoのProjectをメンテナンスしているのですが、
cacheがうまく効いてないような動作が見られたので、原因と改善策をまとめようと思います。

従来のJob

まずはcacheが効いてなかった従来のjobです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version-file: go.mod

      - name: go mod
        run: go mod download

      - name: Run golangci-lint
        uses: golangci/golangci-lint-action@v6
        with:
          version: v1.60.3
          args: "--verbose --config .golangci.yml"

golangci-lint を行うlint jobです。
actions/setup-go@v4 から内部でcacheが効くようになったとのことで、もうえーでしょ!と思い、この設定で運用してました。
ただ書いているように、これではcacheがうまく効きません。
効かない理由は以下です。

  1. GitHub Actions の cache の探し方
  2. cache の作り方

1. GitHub Actions の cache の探し方

公式document を読むと、cacheの探し方は以下の順番で行われます。

  1. workflowを実行しているブランチ(例えばPRを上げているブランチなど)
  2. default ブランチ
  3. base ブランチ

例えば、workflowの実行を on: pull_request だけにしているなど、default brnachでCIを回していない場合など、
cache の作り方次第では、1のworkflow実行しているブランチでの初回は必ずcacheが効かない可能性があります。
回避方法として、default/baseブランチで cache が作られるような workflow にすることで大体のケースをカバーできます。

2. cache の作り方

例えば、 actions/setup-go で作成される cache の primary-key は setup-go-${platform}-${linuxVersion}go-${versionSpec}-${fileHash} になります。
この方式であれば、ブランチ名なども入っていないので、1のケースだけを実行していればcacheをうまく使ってくれるでしょう。
仮に、 actions/cache などを使って、cache keyを自身で作成している場合、ブランチ名や、WF実行番号などをkeyにしてしまった場合、
restore-keys に正しいkeyを指定しないとcache hit しない可能性が出てきます。
今回色々と試行錯誤する中で、このアンチパターンも踏んでしまったので、念の為書いておきます。

最終的なJob

最後に最終的なJobです。
actions/setup-go の cache は disableにして、従来の actions/cache を使うことで、cache keyをsimpleにしてメンテナンスをしやすいようにしてみました。
save時のcache keyはdefault ブランチで作成するcache keyとPRブランチで作成するcache keyを別々に作成することにしました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version-file: go.mod
          cache: false

      - name: Cache restore
        uses: actions/cache/restore@v4
        id: go-cache
        with:
          path: |
            ~/.cache/go-build
            ~/go/pkg/mod            
          key: go-${{ hashFiles('go.sum') }}
          restore-keys: |
            go-${{ github.head_ref }}-
            go-            

      - name: Download dependencies
        run: go mod download

      - name: Run golangci-lint
        uses: golangci/golangci-lint-action@v6
        with:
          version: v1.60.3
          args: "--verbose --config .golangci.yml"

      - name: Cache save
        uses: actions/cache/save@v4
        with:
          path: |
            ~/.cache/go-build
            ~/go/pkg/mod            
          key: ${{ github.ref_name == 'master' && format('go-{0}', hashFiles('go.sum')) || format('go-{0}-{1}', github.event.number, hashFiles('go.sum')) }}
共有

ichisuke
著者
ichisuke
Engineer