|
| 1 | +# Builds `universe-devel` on three independent matrix routes: |
| 2 | +# `main/amd64`, `nightly/amd64`, `main-arm64/arm64`. Each route owns |
| 3 | +# a self-contained cache lineage keyed on |
| 4 | +# `{build-type}-{ros-distro}-{platform}`; there is no cross-route |
| 5 | +# fallback. Within a lineage, registry tags are per-ref so consecutive |
| 6 | +# PR runs reuse their own layers. |
| 7 | +# |
| 8 | +# - GHA mount cache (actions/cache). Caches BuildKit RUN mounts (apt, |
| 9 | +# ccache, pip, pipx) as a tarball keyed per route+sha. Only main |
| 10 | +# pushes write; other refs are read-only. An inline prune step at |
| 11 | +# the end of the job deletes every entry in the route's lineage |
| 12 | +# except the current SHA key and anything above `max-cache-size-gb`. |
| 13 | +# Net effect: the lineage stays at most one tarball, and a cancelled |
| 14 | +# or oversized save gets evicted on the next main run. |
| 15 | +# |
| 16 | +# - GHCR registry layer cache (`cache-to=type=registry`). One tag per |
| 17 | +# route+ref. `cache-from` reads the ref's own tag then the lineage's |
| 18 | +# `-main` tag (within the same route, never across routes). |
| 19 | +# `cache-to` always writes to the ref's own tag, so consecutive PR |
| 20 | +# runs reuse their own layers and first-build PRs bootstrap from |
| 21 | +# main within the same lineage. |
1 | 22 | name: health-check-reusable |
2 | 23 |
|
3 | 24 | on: |
4 | 25 | workflow_call: |
| 26 | + inputs: |
| 27 | + ros-distro: |
| 28 | + description: ROS distribution |
| 29 | + type: string |
| 30 | + default: humble |
| 31 | + max-cache-size-gb: |
| 32 | + description: Max allowed size (GB) for restored BuildKit cache mounts; cache is dropped and purged if exceeded |
| 33 | + type: number |
| 34 | + default: 6 |
5 | 35 |
|
6 | 36 | jobs: |
7 | 37 | docker-build: |
|
20 | 50 | platform: arm64 |
21 | 51 | runner: "['ubuntu-24.04-arm']" |
22 | 52 | runs-on: ${{ fromJson(matrix.runner) }} |
| 53 | + permissions: |
| 54 | + contents: read |
| 55 | + packages: write |
| 56 | + actions: write |
| 57 | + env: |
| 58 | + CACHE_KEY_PREFIX: buildkit-mounts-health-check-${{ matrix.build-type }}-${{ inputs.ros-distro }}-${{ matrix.platform }}- |
| 59 | + CACHE_REF_PREFIX: ghcr.io/${{ github.repository }}-buildcache:health-check-${{ matrix.build-type }}-${{ inputs.ros-distro }}-${{ matrix.platform }} |
| 60 | + IS_MAIN_PUSH: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }} |
23 | 61 | steps: |
24 | 62 | - name: 🔧 Change permission of workspace |
25 | 63 | run: | |
|
29 | 67 | - name: 📥 Check out repository |
30 | 68 | uses: actions/checkout@v6 |
31 | 69 |
|
32 | | - - name: 🏷️ Compute cache ref |
| 70 | + - name: 🏷️ Compute sanitized ref name |
33 | 71 | id: meta |
34 | 72 | run: echo "ref_name=${GITHUB_REF_NAME//\//-}" >> "$GITHUB_OUTPUT" |
35 | 73 |
|
@@ -76,31 +114,39 @@ jobs: |
76 | 114 | [worker.oci] |
77 | 115 | max-parallelism = 2 |
78 | 116 |
|
79 | | - # Read-only: reuses the mount cache saved by docker's `ci-universe` group. |
80 | | - - name: 💾 Restore BuildKit cache mounts (read-only) |
| 117 | + - name: 💾 Restore BuildKit cache mounts |
81 | 118 | id: cache-restore |
82 | 119 | uses: actions/cache/restore@v5 |
83 | 120 | with: |
84 | 121 | path: cache-mounts |
85 | | - key: buildkit-mounts-ci-universe-humble-${{ matrix.platform }}-${{ github.sha }} |
| 122 | + key: ${{ env.CACHE_KEY_PREFIX }}${{ github.sha }} |
86 | 123 | restore-keys: | |
87 | | - buildkit-mounts-ci-universe-humble-${{ matrix.platform }}- |
| 124 | + ${{ env.CACHE_KEY_PREFIX }} |
| 125 | +
|
| 126 | + - name: 💾 Arm post-step save of BuildKit cache mounts (main) |
| 127 | + if: env.IS_MAIN_PUSH == 'true' |
| 128 | + id: cache-save |
| 129 | + uses: actions/cache@v5 |
| 130 | + with: |
| 131 | + path: cache-mounts |
| 132 | + key: ${{ env.CACHE_KEY_PREFIX }}${{ github.sha }} |
| 133 | + lookup-only: true |
88 | 134 |
|
89 | 135 | - name: 💉 Inject BuildKit cache mounts |
90 | 136 | uses: reproducible-containers/buildkit-cache-dance@v3 |
91 | 137 | with: |
92 | 138 | cache-map: | |
93 | 139 | { |
94 | 140 | "cache-mounts/apt-cache": { |
95 | | - "id": "apt-cache-humble", |
| 141 | + "id": "apt-cache-${{ inputs.ros-distro }}", |
96 | 142 | "target": "/var/cache/apt" |
97 | 143 | }, |
98 | 144 | "cache-mounts/apt-lists": { |
99 | | - "id": "apt-lists-humble", |
| 145 | + "id": "apt-lists-${{ inputs.ros-distro }}", |
100 | 146 | "target": "/var/lib/apt/lists" |
101 | 147 | }, |
102 | 148 | "cache-mounts/ccache": { |
103 | | - "id": "ccache-humble", |
| 149 | + "id": "ccache-${{ inputs.ros-distro }}", |
104 | 150 | "target": "/home/aw/.ccache", |
105 | 151 | "uid": "1000", |
106 | 152 | "gid": "1000" |
@@ -128,19 +174,38 @@ jobs: |
128 | 174 | password: ${{ github.token }} |
129 | 175 |
|
130 | 176 | - name: 🔨 Build Autoware |
| 177 | + id: bake |
131 | 178 | uses: docker/bake-action@v7 |
132 | 179 | env: |
133 | | - ROS_DISTRO: humble |
| 180 | + ROS_DISTRO: ${{ inputs.ros-distro }} |
134 | 181 | with: |
135 | 182 | source: . |
136 | 183 | targets: universe-devel |
137 | 184 | files: docker/docker-bake.hcl |
138 | 185 | provenance: false |
139 | 186 | set: | |
140 | | - *.cache-from=type=registry,ref=ghcr.io/${{ github.repository }}-buildcache:health-check-${{ matrix.build-type }}-humble-${{ matrix.platform }}-${{ steps.meta.outputs.ref_name }} |
141 | | - *.cache-from=type=registry,ref=ghcr.io/${{ github.repository }}-buildcache:health-check-${{ matrix.build-type }}-humble-${{ matrix.platform }}-main |
142 | | - *.cache-to=type=registry,ref=ghcr.io/${{ github.repository }}-buildcache:health-check-${{ matrix.build-type }}-humble-${{ matrix.platform }}-${{ steps.meta.outputs.ref_name }},mode=max,ignore-error=true |
| 187 | + *.cache-from=type=registry,ref=${{ env.CACHE_REF_PREFIX }}-${{ steps.meta.outputs.ref_name }} |
| 188 | + *.cache-from=type=registry,ref=${{ env.CACHE_REF_PREFIX }}-main |
| 189 | + *.cache-to=type=registry,ref=${{ env.CACHE_REF_PREFIX }}-${{ steps.meta.outputs.ref_name }},mode=max,ignore-error=true |
143 | 190 |
|
144 | 191 | - name: 📊 Disk space |
145 | 192 | if: always() |
146 | 193 | run: df -h |
| 194 | + |
| 195 | + - name: 🧹 Prune cache lineage |
| 196 | + if: env.IS_MAIN_PUSH == 'true' && steps.bake.outcome == 'success' |
| 197 | + env: |
| 198 | + GH_TOKEN: ${{ github.token }} |
| 199 | + KEEP_KEY: ${{ env.CACHE_KEY_PREFIX }}${{ github.sha }} |
| 200 | + MAX_GB: ${{ inputs.max-cache-size-gb }} |
| 201 | + run: | |
| 202 | + set -euo pipefail |
| 203 | + max_bytes=$((MAX_GB * 1000 * 1000 * 1000)) |
| 204 | + echo "keep: ${KEEP_KEY} (written in post phase)" |
| 205 | + gh cache list --repo "$GITHUB_REPOSITORY" --key "$CACHE_KEY_PREFIX" --limit 100 --json key,sizeInBytes \ |
| 206 | + | jq -r --arg keep "$KEEP_KEY" --argjson max "$max_bytes" \ |
| 207 | + '.[] | select(.key != $keep or .sizeInBytes > $max) | .key' \ |
| 208 | + | while read -r key; do |
| 209 | + echo "delete: $key" |
| 210 | + gh cache delete "$key" --repo "$GITHUB_REPOSITORY" || true |
| 211 | + done |
0 commit comments