|
1 | 1 | name: Package Sandbox Kit |
2 | 2 |
|
3 | 3 | on: |
4 | | - # Only push the kit if the kit sources have changed. The release bump PR |
5 | | - # rewrites each spec.yaml `version:`, so merging it is what triggers a publish |
6 | | - # — the same shape as package_chart.yaml reacting to deployment/chainloop/** |
| 4 | + # Only the specs, not the README beside them: the release bump PR rewrites each |
| 5 | + # spec.yaml `version:`, and that is what should trigger a publish. |
7 | 6 | push: |
8 | 7 | branches: |
9 | 8 | - main |
10 | 9 | paths: |
11 | | - - devel/sandbox-kit/** |
| 10 | + - devel/sandbox-kit/*/spec.yaml |
12 | 11 |
|
13 | 12 | permissions: read-all |
14 | 13 |
|
15 | 14 | jobs: |
| 15 | + # Every directory under devel/sandbox-kit/ holding a spec.yaml is a kit, so |
| 16 | + # adding one needs no change here. |
| 17 | + discover: |
| 18 | + name: Discover kits |
| 19 | + runs-on: ubuntu-latest |
| 20 | + permissions: |
| 21 | + contents: read |
| 22 | + outputs: |
| 23 | + kits: ${{ steps.find.outputs.kits }} |
| 24 | + steps: |
| 25 | + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 |
| 26 | + with: |
| 27 | + persist-credentials: false |
| 28 | + - id: find |
| 29 | + run: | |
| 30 | + kits=$(find devel/sandbox-kit -mindepth 2 -maxdepth 2 -name spec.yaml -printf '%h\n' \ |
| 31 | + | sed 's|.*/||' | sort | jq -Rsc 'split("\n")[:-1]') |
| 32 | + if [[ "${kits}" == "[]" ]]; then |
| 33 | + echo "::error::no kits found under devel/sandbox-kit" |
| 34 | + exit 1 |
| 35 | + fi |
| 36 | + echo "kits=${kits}" >> $GITHUB_OUTPUT |
| 37 | + echo "Publishing: ${kits}" |
| 38 | +
|
16 | 39 | package: |
17 | | - name: Package and push Sandbox Kit |
| 40 | + name: Package and push ${{ matrix.kit }} |
| 41 | + needs: discover |
18 | 42 | runs-on: ubuntu-latest |
| 43 | + strategy: |
| 44 | + # One kit's failure must not cancel the others mid-publish. |
| 45 | + fail-fast: false |
| 46 | + matrix: |
| 47 | + kit: ${{ fromJSON(needs.discover.outputs.kits) }} |
19 | 48 | permissions: |
20 | 49 | contents: read |
21 | 50 | id-token: write # Docker Hub OIDC login, SLSA provenance and keyless kit signing |
|
25 | 54 | # Docker Sandboxes ships Linux packages only on tagged releases, not on |
26 | 55 | # nightly, so this is pinned to a stable tag and bumped by hand. |
27 | 56 | SBX_VERSION: "v0.43.0" |
28 | | - KIT_DIR: "devel/sandbox-kit/claude" |
29 | | - KIT_REPO: "docker.io/chainloop/sbx-kit-claude" |
| 57 | + KIT_DIR: "devel/sandbox-kit/${{ matrix.kit }}" |
| 58 | + KIT_REPO: "docker.io/chainloop/sbx-kit-${{ matrix.kit }}" |
30 | 59 | steps: |
| 60 | + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 |
| 61 | + with: |
| 62 | + persist-credentials: false |
| 63 | + |
| 64 | + - name: Read kit version |
| 65 | + id: kit_version |
| 66 | + run: | |
| 67 | + # The kit's own spec.yaml is the source of truth; bump-chart-and-dagger-version.sh |
| 68 | + # keeps it in step with the chart's appVersion on every release. |
| 69 | + kit_version=$(yq -r '.version' "${KIT_DIR}/spec.yaml") |
| 70 | + if [[ -z "${kit_version}" || "${kit_version}" == "null" ]]; then |
| 71 | + echo "::error::${KIT_DIR}/spec.yaml declares no version:" |
| 72 | + exit 1 |
| 73 | + fi |
| 74 | + echo "kit_version=${kit_version}" >> $GITHUB_OUTPUT |
| 75 | +
|
31 | 76 | - name: Install Chainloop |
32 | 77 | # Deliberately NOT `curl ... | bash`: this job holds an OIDC token that can |
33 | 78 | # mint Docker Hub credentials and sign artifacts, so the installer is |
@@ -64,28 +109,29 @@ jobs: |
64 | 109 | with: |
65 | 110 | username: chainloop |
66 | 111 |
|
67 | | - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 |
68 | | - with: |
69 | | - persist-credentials: false |
70 | | - |
71 | | - - name: Read kit version |
72 | | - id: kit_version |
| 112 | + - name: Skip if this version is already published |
| 113 | + id: published |
| 114 | + env: |
| 115 | + KIT_VERSION: ${{ steps.kit_version.outputs.kit_version }} |
73 | 116 | run: | |
74 | | - # The kit's own spec.yaml is the source of truth; bump-chart-and-dagger-version.sh |
75 | | - # keeps it in step with the chart's appVersion on every release. |
76 | | - kit_version=$(yq -r '.version' "${KIT_DIR}/spec.yaml") |
77 | | - if [[ -z "${kit_version}" || "${kit_version}" == "null" ]]; then |
78 | | - echo "::error::${KIT_DIR}/spec.yaml declares no version:" |
79 | | - exit 1 |
| 117 | + # The trigger fires on any spec.yaml change, not only a version bump, so |
| 118 | + # a mid-cycle edit must not overwrite an already-signed, already-attested |
| 119 | + # immutable tag with fresh content. |
| 120 | + if sbx kit inspect "${KIT_REPO}:${KIT_VERSION}" >/dev/null 2>&1; then |
| 121 | + echo "::notice::${KIT_REPO}:${KIT_VERSION} is already published, nothing to do" |
| 122 | + echo "skip=true" >> $GITHUB_OUTPUT |
| 123 | + else |
| 124 | + echo "skip=false" >> $GITHUB_OUTPUT |
80 | 125 | fi |
81 | | - echo "kit_version=${kit_version}" >> $GITHUB_OUTPUT |
82 | 126 |
|
83 | 127 | - name: Validate kit |
| 128 | + if: steps.published.outputs.skip == 'false' |
84 | 129 | # Fails loudly here rather than halfway through a push if the pinned sbx |
85 | 130 | # release does not understand something the spec declares. |
86 | 131 | run: sbx kit validate "./${KIT_DIR}" |
87 | 132 |
|
88 | 133 | - name: Add Attestation (Sandbox Kit) and Push Kit |
| 134 | + if: steps.published.outputs.skip == 'false' |
89 | 135 | run: | |
90 | 136 | # KIT_VERSION arrives through env, not ${{ }} interpolation, so the value |
91 | 137 | # is never expanded into this script's source. |
@@ -114,12 +160,12 @@ jobs: |
114 | 160 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
115 | 161 |
|
116 | 162 | - name: Finish and Record Attestation |
117 | | - if: ${{ success() }} |
| 163 | + if: ${{ success() && steps.published.outputs.skip == 'false' }} |
118 | 164 | run: | |
119 | 165 | chainloop attestation push |
120 | 166 |
|
121 | 167 | - name: Mark attestation as failed |
122 | | - if: ${{ failure() }} |
| 168 | + if: ${{ failure() && steps.published.outputs.skip == 'false' }} |
123 | 169 | run: | |
124 | 170 | chainloop attestation reset |
125 | 171 |
|
|
0 commit comments