Skip to content

Commit 77e597c

Browse files
twz123github-actions[bot]
authored andcommitted
Optimize GitHub Actions cache usage
Simplify the caching of the embedded executables. Makes the cache size smaller, at the cost of some extra packaging time spent to build the gzipped blob during build time. This requires some tricks to tell make what needs to be built and what doesn't. Only keep the most recent cache per branch. All caches ending in a hash will be pruned so that only the newest cache is retained on a per-branch and per-key-prefix basis. Don't use leading slashes for URLs passed to the gh CLI. Leading slashes would otherwise trigger file path normalization in bash on Windows, which would render the URL fragment illegal. Use a fixed source date epoch in unit tests to better leverage cache usage. Signed-off-by: Tom Wieczorek <[email protected]> (cherry picked from commit 8eb3ccd)
1 parent 2ccc52e commit 77e597c

File tree

6 files changed

+103
-47
lines changed

6 files changed

+103
-47
lines changed

.github/workflows/build-k0s.yml

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,34 +58,35 @@ jobs:
5858
echo executable-suffix="$executableSuffix" >>"$GITHUB_OUTPUT"
5959
6060
- name: "Cache :: embedded binaries"
61+
id: cache-embedded-bins
6162
uses: actions/cache@v4
6263
with:
63-
key: build-k0s-${{ inputs.target-os }}-${{ inputs.target-arch }}-embedded-bins-${{ hashFiles('embedded-bins/**/*') }}
64-
path: |
65-
.bins.${{ inputs.target-os }}.stamp
66-
bindata_${{ inputs.target-os }}
67-
embedded-bins/staging/${{ inputs.target-os }}/bin/
68-
embedded-bins/Makefile.variables
69-
pkg/assets/zz_generated_offsets_${{ inputs.target-os }}.go
64+
key: "build-k0s-${{ inputs.target-os }}-${{ inputs.target-arch }}-embedded-bins-${{ hashFiles('embedded-bins/**/*') }}"
65+
path: embedded-bins/staging/${{ inputs.target-os }}/bin/
7066

71-
- name: "Cache :: GOCACHE"
67+
- name: "Cache :: Go cache"
7268
id: cache-gocache
7369
uses: actions/cache@v4
7470
with:
75-
key: build-k0s-${{ inputs.target-os }}-${{ inputs.target-arch }}-gocache-${{ github.ref_name }}-${{ github.sha }}
76-
restore-keys: |
77-
build-k0s-${{ inputs.target-os }}-${{ inputs.target-arch }}-gocache-${{ github.ref_name }}-
78-
path: |
79-
build/cache/go/build
71+
key: "build-k0s-${{ inputs.target-os }}-${{ inputs.target-arch }}-gocache-go${{ env.GO_VERSION }}-${{ github.sha }}"
72+
restore-keys: "build-k0s-${{ inputs.target-os }}-${{ inputs.target-arch }}-gocache-go${{ env.GO_VERSION }}-"
73+
path: build/cache/go/build
8074

81-
- name: "Cache :: GOCACHE :: Prepare"
75+
- name: "Cache :: Go cache :: Prepare"
8276
if: steps.cache-gocache.outputs.cache-hit
8377
run: |
8478
touch -t "$(TZ=UTC+24 date +%Y%m%d%H%M.%S)" build/cache/_cache_sentinel
8579
find build/cache/go/build -type f \( -name '*-a' -o -name '*-d' \) -exec touch -r build/cache/_cache_sentinel {} +
8680
8781
- name: "Build :: k0s"
82+
env:
83+
EMBEDDED_BINS_CACHED: "${{ steps.cache-embedded-bins.outputs.cache-hit }}"
8884
run: |
85+
make .k0sbuild.docker-image.k0s
86+
touch go.sum
87+
if [ "$EMBEDDED_BINS_CACHED" == true ]; then
88+
make --touch ".bins.$TARGET_OS.stamp"
89+
fi
8990
make bindata
9091
make --touch codegen
9192
make build
@@ -120,7 +121,7 @@ jobs:
120121
name: ipv6-test-image-list-${{ inputs.target-os }}-${{ inputs.target-arch }}
121122
path: ipv6-test-images.txt
122123

123-
- name: "Cache :: GOCACHE :: Trim"
124+
- name: "Cache :: Go cache :: Trim"
124125
if: steps.cache-gocache.outputs.cache-hit
125126
run: |
126127
find build/cache/go/build -type f \( -name '*-a' -o -name '*-d' \) -not -newer build/cache/_cache_sentinel -delete
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Go build completed
2+
3+
on:
4+
workflow_run:
5+
workflows: [Go build]
6+
types: [completed]
7+
8+
jobs:
9+
# Based on https://github.com/actions/cache/blob/v4.2.0/tips-and-workarounds.md#force-deletion-of-caches-overriding-default-cache-eviction-policy
10+
cleanup-actions-caches:
11+
name: Cleanup GitHub Actions caches
12+
runs-on: ubuntu-latest
13+
permissions:
14+
# `actions:write` permission is required to delete caches
15+
# See also: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-a-github-actions-cache-for-a-repository-using-a-cache-id
16+
actions: write
17+
18+
steps:
19+
# Group all caches that end with a Git commit hash by branch and keep only the most recently created one.
20+
- name: Cleanup
21+
env:
22+
GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
23+
GH_REPO: "${{ github.repository }}"
24+
QUERY: |
25+
[ .actions_caches[]
26+
| . + { key_prefix: .key | sub("-[0-9a-f]{40}$"; "") } # Calculate cache prefix
27+
| select(.key_prefix != .key) # Only keep caches which have the right suffix
28+
]
29+
| [
30+
group_by([.ref, .key_prefix])[] # Look at all the caches per branch with the same prefix
31+
| sort_by(.created_at) # Sort by creation date ...
32+
| reverse # ... so that the newest cache is the first in the array
33+
| del(.[0]) # Remove that newest cache, i.e. don't delete it
34+
]
35+
| flatten # Remove the grouping
36+
| .[] # Unpack the resulting flat array
37+
| [.id, .ref, .key] # Extract the values to be returned
38+
| @sh # Escape them to be used in POSIX shells
39+
40+
run: |
41+
set -euo pipefail
42+
gh api -X GET repos/{owner}/{repo}/actions/caches -q "$QUERY" | while read -r args; do
43+
eval "set -- $args"
44+
echo Deleting cache with id "$1" from "$2": "$3"
45+
gh api -X DELETE repos/{owner}/{repo}/actions/caches/"$1" || :
46+
done

.github/workflows/go.yml

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ jobs:
178178

179179
env:
180180
EMBEDDED_BINS_BUILDMODE: none
181+
# Set SOURCE_DATE_EPOCH to optimize cache usage
182+
MAKEFLAGS: -j SOURCE_DATE_EPOCH=315532800
181183

182184
steps:
183185
- name: Check out code into the Go module directory
@@ -208,15 +210,13 @@ jobs:
208210
go-version: ${{ env.GO_VERSION }}
209211
cache: false
210212

211-
- name: Cache GOCACHE
213+
- name: Cache Go cache
212214
id: cache-gocache
213215
uses: actions/cache@v4
214216
with:
215-
key: unittests-k0s-${{ matrix.name }}-gocache-${{ github.ref_name }}-${{ github.sha }}
216-
restore-keys: |
217-
unittests-k0s-${{ matrix.name }}-gocache-${{ github.ref_name }}-
218-
path: |
219-
build/cache/go/build
217+
key: "unittests-k0s-${{ matrix.name }}-gocache-go${{ env.GO_VERSION }}-${{ github.sha }}"
218+
restore-keys: "unittests-k0s-${{ matrix.name }}-gocache-go${{ env.GO_VERSION }}-"
219+
path: build/cache/go/build
220220

221221
- name: Run unit tests
222222
env:
@@ -316,35 +316,40 @@ jobs:
316316
go-version: ${{ env.GO_VERSION }}
317317

318318
- name: Cache embedded binaries
319+
id: cache-embedded-bins
319320
uses: actions/cache@v4
320321
with:
321-
key: ${{ runner.os }}-embedded-bins-arm-${{ hashFiles('**/embedded-bins/**/*') }}
322-
path: |
323-
.bins.linux.stamp
324-
embedded-bins/staging/linux/bin/
325-
embedded-bins/Makefile.variables
322+
key: "build-k0s-linux-arm-embedded-bins-${{ hashFiles('embedded-bins/**/*') }}"
323+
path: embedded-bins/staging/linux/bin/
326324

327-
- name: Cache GOCACHE
325+
- name: Cache Go cache
328326
id: cache-gocache
329327
uses: actions/cache@v4
330328
with:
331-
key: ${{ runner.os }}-smoketest-arm-gocache-arm-${{ github.ref_name }}-${{ github.sha }}
332-
restore-keys: |
333-
${{ runner.os }}-smoketest-arm-gocache-arm-${{ github.ref_name }}-
334-
path: |
335-
build/cache/go/build
329+
key: "build-k0s-linux-arm-gocache-go${{ env.GO_VERSION }}-${{ github.sha }}"
330+
restore-keys: "build-k0s-linux-arm-gocache-go${{ env.GO_VERSION }}-"
331+
path: build/cache/go/build
336332

337-
- name: Cache GOCACHE - Prepare
333+
- name: Prepare Go cache
338334
if: steps.cache-gocache.outputs.cache-hit
339335
run: |
340336
touch -t "$(TZ=UTC+24 date +%Y%m%d%H%M.%S)" build/cache/_cache_sentinel
341337
find build/cache/go/build -type f \( -name '*-a' -o -name '*-d' \) -exec touch -r build/cache/_cache_sentinel {} +
342338
343339
- name: Build
340+
env:
341+
EMBEDDED_BINS_CACHED: "${{ steps.cache-embedded-bins.outputs.cache-hit }}"
344342
run: |
343+
gh --version || echo No gh installed
344+
make .k0sbuild.docker-image.k0s
345+
touch go.sum
346+
if [ "$EMBEDDED_BINS_CACHED" == true ]; then
347+
make --touch .bins.linux.stamp
348+
fi
345349
make bindata
346350
make --touch codegen
347351
make build
352+
echo "k0s binary size: **$(du -sh k0s | cut -f1)**" >>$GITHUB_STEP_SUMMARY
348353
349354
- name: Upload compiled executable
350355
uses: actions/upload-artifact@v4
@@ -377,7 +382,7 @@ jobs:
377382
name: airgap-image-bundle-linux-arm.tar
378383
path: airgap-image-bundle-linux-arm.tar
379384

380-
- name: Cache GOCACHE - Trim
385+
- name: Trim Go cache
381386
if: steps.cache-gocache.outputs.cache-hit
382387
run: |
383388
find build/cache/go/build -type f \( -name '*-a' -o -name '*-d' \) -not -newer build/cache/_cache_sentinel -delete

.github/workflows/lint.yaml

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ env:
3030
MAKEFLAGS: -j
3131
EMBEDDED_BINS_BUILDMODE: none
3232

33+
permissions:
34+
contents: read
35+
3336
jobs:
3437
lint-go:
3538
strategy:
@@ -67,14 +70,13 @@ jobs:
6770
go-version: ${{ env.GO_VERSION }}
6871
cache: false
6972

70-
- name: "Cache :: golangci-lint"
73+
- name: Cache golangci-lint cache
7174
id: cache-golangci
7275
uses: actions/cache@v4
7376
with:
74-
key: lint-${{ matrix.target-os }}-amd64-golangci-${{ github.ref_name }}-${{ github.sha }}
77+
key: "lint-${{ matrix.target-os }}-amd64-golangci-${{ env.GOLANGCI_LINT_VERSION }}-go-${{ env.GO_VERSION }}-${{ github.sha }}"
7578
restore-keys: |
76-
lint-${{ matrix.target-os }}-amd64-golangci-${{ github.ref_name }}-
77-
lint-${{ matrix.target-os }}-amd64-golangci-main-
79+
lint-${{ matrix.target-os }}-amd64-golangci-${{ env.GOLANGCI_LINT_VERSION }}-go-${{ env.GO_VERSION }}-
7880
path: |
7981
build/cache/go/build
8082
build/cache/golangci-lint
@@ -103,16 +105,18 @@ jobs:
103105
- uses: actions/checkout@v4
104106
with:
105107
fetch-depth: 0
108+
preserve-credentials: false
109+
110+
- name: Prepare build environment
111+
run: .github/workflows/prepare-build-env.sh
106112

107-
- name: "Cache :: GOCACHE"
113+
- name: Restore Go cache
108114
uses: actions/cache/restore@v4
109115
with:
110-
key: build-k0s-linux-amd64-gocache-${{ github.ref_name }}-${{ github.sha }}
116+
key: "build-k0s-linux-amd64-gocache-go${{ env.GO_VERSION }}-${{ github.sha }}"
111117
restore-keys: |
112-
build-k0s-linux-amd64-gocache-${{ github.ref_name }}-
113-
build-k0s-linux-amd64-gocache-main-
114-
path: |
115-
build/cache/go/build
118+
build-k0s-linux-amd64-gocache-go${{ env.GO_VERSION }}-
119+
path: build/cache/go/build
116120

117121
- name: Check go.mod/go.sum to be consistent
118122
run: make --always-make go.sum && git diff --exit-code

.github/workflows/ostests-nightly.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ jobs:
134134
# Message format described here: https://api.slack.com/surfaces/messages#payloads
135135
# The block structure can be tested online: https://app.slack.com/block-kit-builder
136136
run: |
137-
gh api "/repos/{owner}/{repo}/actions/runs/$GITHUB_RUN_ID/jobs" -q '
137+
gh api "repos/{owner}/{repo}/actions/runs/$GITHUB_RUN_ID/jobs" -q '
138138
def fmt_duration:
139139
if . >= 3600 then "\(./3600|floor) h \((.%3600/60|floor)) min"
140140
elif . >= 60 then "\(./60|floor) min \(.%60) sec"

.github/workflows/pr-closed.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ jobs:
2323
BRANCH: "refs/pull/${{ github.event.pull_request.number }}/merge"
2424
run: |
2525
set -euo pipefail
26-
gh api -X GET /repos/{owner}/{repo}/actions/caches -f ref="$BRANCH" --paginate -q '.actions_caches[] | "\(.id) \(.key)"' | {
26+
gh api -X GET repos/{owner}/{repo}/actions/caches -f ref="$BRANCH" --paginate -q '.actions_caches[] | "\(.id) \(.key)"' | {
2727
fail=0
2828
while read -r id key; do
2929
echo Deleting cache with ID $id: $key
30-
gh api -X DELETE /repos/{owner}/{repo}/actions/caches/"$id" || fail=1
30+
gh api -X DELETE repos/{owner}/{repo}/actions/caches/"$id" || fail=1
3131
done
3232
[ $fail -eq 0 ]
3333
}

0 commit comments

Comments
 (0)