diff --git a/.github/workflows/images.yaml b/.github/workflows/images.yaml index edee8ea..c092001 100644 --- a/.github/workflows/images.yaml +++ b/.github/workflows/images.yaml @@ -4,20 +4,33 @@ on: push: branches: - main + pull_request: + types: [labeled, synchronize, opened] + workflow_dispatch: + inputs: + force_rebuild: + description: 'Force rebuild all images' + required: false + default: false + type: boolean jobs: publish: name: Publish runs-on: ubuntu-latest + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'push')) permissions: packages: write + contents: read + attestations: write + id-token: write steps: - name: Checkout uses: actions/checkout@v4 - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v3.5.0 with: registry: ghcr.io username: ${{ github.repository_owner }} @@ -58,17 +71,19 @@ jobs: crane cp liftm/kafkacat:$TAG_KAFKACAT ghcr.io/yolean/kafkacat:$TAG_KAFKACAT - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v3.6.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v3.11.1 ### build steps below are generated ### - name: Build and push docker-base latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: docker-base tags: | @@ -76,13 +91,19 @@ jobs: ghcr.io/yolean/docker-base:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-docker-base-latest + type=gha,scope=buildx-docker-base + cache-to: type=gha,mode=max,scope=buildx-docker-base-latest + continue-on-error: false + timeout-minutes: 45 - name: Build and push builder-base latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: builder-base tags: | @@ -90,13 +111,19 @@ jobs: ghcr.io/yolean/builder-base:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-builder-base-latest + type=gha,scope=buildx-builder-base + cache-to: type=gha,mode=max,scope=buildx-builder-base-latest + continue-on-error: false + timeout-minutes: 45 - name: Build and push builder-base-gcc latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: builder-base-gcc tags: | @@ -104,15 +131,21 @@ jobs: ghcr.io/yolean/builder-base-gcc:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-builder-base-gcc-latest + type=gha,scope=buildx-builder-base-gcc + cache-to: type=gha,mode=max,scope=buildx-builder-base-gcc-latest build-contexts: | yolean/builder-base=docker-image://ghcr.io/yolean/builder-base + continue-on-error: false + timeout-minutes: 45 - name: Build and push builder-base-gcloud latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: builder-base-gcloud tags: | @@ -120,15 +153,21 @@ jobs: ghcr.io/yolean/builder-base-gcloud:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-builder-base-gcloud-latest + type=gha,scope=buildx-builder-base-gcloud + cache-to: type=gha,mode=max,scope=buildx-builder-base-gcloud-latest build-contexts: | yolean/builder-base=docker-image://ghcr.io/yolean/builder-base + continue-on-error: false + timeout-minutes: 45 - name: Build and push builder-tooling latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: builder-tooling tags: | @@ -136,15 +175,21 @@ jobs: ghcr.io/yolean/builder-tooling:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-builder-tooling-latest + type=gha,scope=buildx-builder-tooling + cache-to: type=gha,mode=max,scope=buildx-builder-tooling-latest build-contexts: | yolean/builder-base-gcc=docker-image://ghcr.io/yolean/builder-base-gcc + continue-on-error: false + timeout-minutes: 45 - name: Build and push builder-node latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: builder-node tags: | @@ -152,13 +197,19 @@ jobs: ghcr.io/yolean/builder-node:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-builder-node-latest + type=gha,scope=buildx-builder-node + cache-to: type=gha,mode=max,scope=buildx-builder-node-latest + continue-on-error: false + timeout-minutes: 45 - name: Build and push builder-quarkus latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: builder-quarkus tags: | @@ -166,16 +217,22 @@ jobs: ghcr.io/yolean/builder-quarkus:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-builder-quarkus-latest + type=gha,scope=buildx-builder-quarkus + cache-to: type=gha,mode=max,scope=buildx-builder-quarkus-latest build-contexts: | yolean/builder-base=docker-image://ghcr.io/yolean/builder-base yolean/builder-base-gcc=docker-image://ghcr.io/yolean/builder-base-gcc + continue-on-error: false + timeout-minutes: 45 - name: Build and push builder-evidence latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: builder-evidence tags: | @@ -183,16 +240,22 @@ jobs: ghcr.io/yolean/builder-evidence:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-builder-evidence-latest + type=gha,scope=buildx-builder-evidence + cache-to: type=gha,mode=max,scope=buildx-builder-evidence-latest build-contexts: | yolean/builder-base-gcc=docker-image://ghcr.io/yolean/builder-base-gcc yolean/builder-base-gcloud=docker-image://ghcr.io/yolean/builder-base-gcloud + continue-on-error: false + timeout-minutes: 45 - name: Build and push git-init latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: git-init tags: | @@ -200,15 +263,21 @@ jobs: ghcr.io/yolean/git-init:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-git-init-latest + type=gha,scope=buildx-git-init + cache-to: type=gha,mode=max,scope=buildx-git-init-latest build-contexts: | yolean/builder-base=docker-image://ghcr.io/yolean/builder-base + continue-on-error: false + timeout-minutes: 45 - name: Build and push toil latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: toil tags: | @@ -216,16 +285,22 @@ jobs: ghcr.io/yolean/toil:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-toil-latest + type=gha,scope=buildx-toil + cache-to: type=gha,mode=max,scope=buildx-toil-latest build-contexts: | yolean/builder-base=docker-image://ghcr.io/yolean/builder-base yolean/builder-base=docker-image://ghcr.io/yolean/builder-base + continue-on-error: false + timeout-minutes: 45 - name: Build and push toil-network latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: toil-network tags: | @@ -233,15 +308,21 @@ jobs: ghcr.io/yolean/toil-network:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-toil-network-latest + type=gha,scope=buildx-toil-network + cache-to: type=gha,mode=max,scope=buildx-toil-network-latest build-contexts: | yolean/toil=docker-image://ghcr.io/yolean/toil + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-distroless latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: node-distroless tags: | @@ -249,13 +330,19 @@ jobs: ghcr.io/yolean/node-distroless:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-distroless-latest + type=gha,scope=buildx-node-distroless + cache-to: type=gha,mode=max,scope=buildx-node-distroless-latest + continue-on-error: false + timeout-minutes: 45 - name: Build and push headless-chrome latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: headless-chrome tags: | @@ -263,15 +350,21 @@ jobs: ghcr.io/yolean/headless-chrome:${{ github.sha }} platforms: linux/amd64 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-headless-chrome-latest + type=gha,scope=buildx-headless-chrome + cache-to: type=gha,mode=max,scope=buildx-headless-chrome-latest build-contexts: | yolean/docker-base=docker-image://ghcr.io/yolean/docker-base + continue-on-error: false + timeout-minutes: 45 - name: Build and push git-http-readonly latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: git-http-readonly tags: | @@ -279,13 +372,19 @@ jobs: ghcr.io/yolean/git-http-readonly:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-git-http-readonly-latest + type=gha,scope=buildx-git-http-readonly + cache-to: type=gha,mode=max,scope=buildx-git-http-readonly-latest + continue-on-error: false + timeout-minutes: 45 - name: Build and push runtime-quarkus latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: runtime-quarkus tags: | @@ -293,13 +392,19 @@ jobs: ghcr.io/yolean/runtime-quarkus:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-runtime-quarkus-latest + type=gha,scope=buildx-runtime-quarkus + cache-to: type=gha,mode=max,scope=buildx-runtime-quarkus-latest + continue-on-error: false + timeout-minutes: 45 - name: Build and push runtime-deno latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: runtime-deno tags: | @@ -307,13 +412,19 @@ jobs: ghcr.io/yolean/runtime-deno:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-runtime-deno-latest + type=gha,scope=buildx-runtime-deno + cache-to: type=gha,mode=max,scope=buildx-runtime-deno-latest + continue-on-error: false + timeout-minutes: 45 - name: Build and push homedir root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: homedir tags: | @@ -321,15 +432,21 @@ jobs: ghcr.io/yolean/homedir:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-homedir-root + type=gha,scope=buildx-homedir + cache-to: type=gha,mode=max,scope=buildx-homedir-root build-contexts: | yolean/docker-base=docker-image://ghcr.io/yolean/docker-base + continue-on-error: false + timeout-minutes: 45 - name: Build and push homedir latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/homedir tags: | @@ -337,15 +454,21 @@ jobs: ghcr.io/yolean/homedir:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-homedir-latest + type=gha,scope=buildx-homedir + cache-to: type=gha,mode=max,scope=buildx-homedir-latest build-contexts: | yolean/homedir:root=docker-image://ghcr.io/yolean/homedir:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push java root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: java tags: | @@ -353,13 +476,19 @@ jobs: ghcr.io/yolean/java:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-java-root + type=gha,scope=buildx-java + cache-to: type=gha,mode=max,scope=buildx-java-root + continue-on-error: false + timeout-minutes: 45 - name: Build and push java latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/java tags: | @@ -367,15 +496,21 @@ jobs: ghcr.io/yolean/java:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-java-latest + type=gha,scope=buildx-java + cache-to: type=gha,mode=max,scope=buildx-java-latest build-contexts: | yolean/java:root=docker-image://ghcr.io/yolean/java:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: node tags: | @@ -383,13 +518,19 @@ jobs: ghcr.io/yolean/node:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-root + type=gha,scope=buildx-node + cache-to: type=gha,mode=max,scope=buildx-node-root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/node tags: | @@ -397,15 +538,21 @@ jobs: ghcr.io/yolean/node:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-latest + type=gha,scope=buildx-node + cache-to: type=gha,mode=max,scope=buildx-node-latest build-contexts: | yolean/node:root=docker-image://ghcr.io/yolean/node:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-kafka root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: node-kafka tags: | @@ -413,15 +560,21 @@ jobs: ghcr.io/yolean/node-kafka:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-kafka-root + type=gha,scope=buildx-node-kafka + cache-to: type=gha,mode=max,scope=buildx-node-kafka-root build-contexts: | yolean/node:root=docker-image://ghcr.io/yolean/node:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-kafka latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/node-kafka tags: | @@ -429,15 +582,21 @@ jobs: ghcr.io/yolean/node-kafka:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-kafka-latest + type=gha,scope=buildx-node-kafka + cache-to: type=gha,mode=max,scope=buildx-node-kafka-latest build-contexts: | yolean/node-kafka:root=docker-image://ghcr.io/yolean/node-kafka:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-kafka-cache root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: node-kafka-cache tags: | @@ -445,15 +604,21 @@ jobs: ghcr.io/yolean/node-kafka-cache:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-kafka-cache-root + type=gha,scope=buildx-node-kafka-cache + cache-to: type=gha,mode=max,scope=buildx-node-kafka-cache-root build-contexts: | yolean/node-kafka:root=docker-image://ghcr.io/yolean/node-kafka:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-kafka-cache latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/node-kafka-cache tags: | @@ -461,15 +626,21 @@ jobs: ghcr.io/yolean/node-kafka-cache:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-kafka-cache-latest + type=gha,scope=buildx-node-kafka-cache + cache-to: type=gha,mode=max,scope=buildx-node-kafka-cache-latest build-contexts: | yolean/node-kafka-cache:root=docker-image://ghcr.io/yolean/node-kafka-cache:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-kafka-sqlite root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: node-kafka-sqlite tags: | @@ -477,15 +648,21 @@ jobs: ghcr.io/yolean/node-kafka-sqlite:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-kafka-sqlite-root + type=gha,scope=buildx-node-kafka-sqlite + cache-to: type=gha,mode=max,scope=buildx-node-kafka-sqlite-root build-contexts: | yolean/node-kafka:root=docker-image://ghcr.io/yolean/node-kafka:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-kafka-sqlite latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/node-kafka-sqlite tags: | @@ -493,15 +670,21 @@ jobs: ghcr.io/yolean/node-kafka-sqlite:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-kafka-sqlite-latest + type=gha,scope=buildx-node-kafka-sqlite + cache-to: type=gha,mode=max,scope=buildx-node-kafka-sqlite-latest build-contexts: | yolean/node-kafka-sqlite:root=docker-image://ghcr.io/yolean/node-kafka-sqlite:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-watchexec root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: node-watchexec tags: | @@ -509,13 +692,19 @@ jobs: ghcr.io/yolean/node-watchexec:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-watchexec-root + type=gha,scope=buildx-node-watchexec + cache-to: type=gha,mode=max,scope=buildx-node-watchexec-root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-watchexec latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/node-watchexec tags: | @@ -523,15 +712,21 @@ jobs: ghcr.io/yolean/node-watchexec:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-watchexec-latest + type=gha,scope=buildx-node-watchexec + cache-to: type=gha,mode=max,scope=buildx-node-watchexec-latest build-contexts: | yolean/node-watchexec:root=docker-image://ghcr.io/yolean/node-watchexec:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-kafka-watch root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: node-kafka-watch tags: | @@ -539,16 +734,22 @@ jobs: ghcr.io/yolean/node-kafka-watch:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-kafka-watch-root + type=gha,scope=buildx-node-kafka-watch + cache-to: type=gha,mode=max,scope=buildx-node-kafka-watch-root build-contexts: | yolean/node-watchexec:root=docker-image://ghcr.io/yolean/node-watchexec:root yolean/node-kafka:root=docker-image://ghcr.io/yolean/node-kafka:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-kafka-watch latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/node-kafka-watch tags: | @@ -556,15 +757,21 @@ jobs: ghcr.io/yolean/node-kafka-watch:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-kafka-watch-latest + type=gha,scope=buildx-node-kafka-watch + cache-to: type=gha,mode=max,scope=buildx-node-kafka-watch-latest build-contexts: | yolean/node-kafka-watch:root=docker-image://ghcr.io/yolean/node-kafka-watch:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-gcloud root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: node-gcloud tags: | @@ -572,15 +779,21 @@ jobs: ghcr.io/yolean/node-gcloud:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-gcloud-root + type=gha,scope=buildx-node-gcloud + cache-to: type=gha,mode=max,scope=buildx-node-gcloud-root build-contexts: | yolean/node:root=docker-image://ghcr.io/yolean/node:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-gcloud latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/node-gcloud tags: | @@ -588,15 +801,21 @@ jobs: ghcr.io/yolean/node-gcloud:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-gcloud-latest + type=gha,scope=buildx-node-gcloud + cache-to: type=gha,mode=max,scope=buildx-node-gcloud-latest build-contexts: | yolean/node-gcloud:root=docker-image://ghcr.io/yolean/node-gcloud:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-vitest root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: node-vitest tags: | @@ -604,15 +823,21 @@ jobs: ghcr.io/yolean/node-vitest:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-vitest-root + type=gha,scope=buildx-node-vitest + cache-to: type=gha,mode=max,scope=buildx-node-vitest-root build-contexts: | yolean/node:root=docker-image://ghcr.io/yolean/node:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push node-vitest latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/node-vitest tags: | @@ -620,15 +845,21 @@ jobs: ghcr.io/yolean/node-vitest:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-node-vitest-latest + type=gha,scope=buildx-node-vitest + cache-to: type=gha,mode=max,scope=buildx-node-vitest-latest build-contexts: | yolean/node-vitest:root=docker-image://ghcr.io/yolean/node-vitest:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push runtime-quarkus-ubuntu root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: runtime-quarkus-ubuntu tags: | @@ -636,15 +867,21 @@ jobs: ghcr.io/yolean/runtime-quarkus-ubuntu:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-runtime-quarkus-ubuntu-root + type=gha,scope=buildx-runtime-quarkus-ubuntu + cache-to: type=gha,mode=max,scope=buildx-runtime-quarkus-ubuntu-root build-contexts: | yolean/docker-base=docker-image://ghcr.io/yolean/docker-base + continue-on-error: false + timeout-minutes: 45 - name: Build and push runtime-quarkus-ubuntu latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/runtime-quarkus-ubuntu tags: | @@ -652,15 +889,21 @@ jobs: ghcr.io/yolean/runtime-quarkus-ubuntu:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-runtime-quarkus-ubuntu-latest + type=gha,scope=buildx-runtime-quarkus-ubuntu + cache-to: type=gha,mode=max,scope=buildx-runtime-quarkus-ubuntu-latest build-contexts: | yolean/runtime-quarkus-ubuntu:root=docker-image://ghcr.io/yolean/runtime-quarkus-ubuntu:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push runtime-quarkus-deno root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: runtime-quarkus-deno tags: | @@ -668,16 +911,22 @@ jobs: ghcr.io/yolean/runtime-quarkus-deno:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-runtime-quarkus-deno-root + type=gha,scope=buildx-runtime-quarkus-deno + cache-to: type=gha,mode=max,scope=buildx-runtime-quarkus-deno-root build-contexts: | yolean/runtime-deno=docker-image://ghcr.io/yolean/runtime-deno yolean/runtime-quarkus-ubuntu=docker-image://ghcr.io/yolean/runtime-quarkus-ubuntu + continue-on-error: false + timeout-minutes: 45 - name: Build and push runtime-quarkus-deno latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/runtime-quarkus-deno tags: | @@ -685,15 +934,21 @@ jobs: ghcr.io/yolean/runtime-quarkus-deno:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-runtime-quarkus-deno-latest + type=gha,scope=buildx-runtime-quarkus-deno + cache-to: type=gha,mode=max,scope=buildx-runtime-quarkus-deno-latest build-contexts: | yolean/runtime-quarkus-deno:root=docker-image://ghcr.io/yolean/runtime-quarkus-deno:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push runtime-quarkus-ubuntu-jre root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: runtime-quarkus-ubuntu-jre tags: | @@ -701,16 +956,22 @@ jobs: ghcr.io/yolean/runtime-quarkus-ubuntu-jre:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-runtime-quarkus-ubuntu-jre-root + type=gha,scope=buildx-runtime-quarkus-ubuntu-jre + cache-to: type=gha,mode=max,scope=buildx-runtime-quarkus-ubuntu-jre-root build-contexts: | yolean/java:root=docker-image://ghcr.io/yolean/java:root yolean/runtime-quarkus-ubuntu:root=docker-image://ghcr.io/yolean/runtime-quarkus-ubuntu:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push runtime-quarkus-ubuntu-jre latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/runtime-quarkus-ubuntu-jre tags: | @@ -718,15 +979,21 @@ jobs: ghcr.io/yolean/runtime-quarkus-ubuntu-jre:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-runtime-quarkus-ubuntu-jre-latest + type=gha,scope=buildx-runtime-quarkus-ubuntu-jre + cache-to: type=gha,mode=max,scope=buildx-runtime-quarkus-ubuntu-jre-latest build-contexts: | yolean/runtime-quarkus-ubuntu-jre:root=docker-image://ghcr.io/yolean/runtime-quarkus-ubuntu-jre:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push runtime-quarkus-dev root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: runtime-quarkus-dev tags: | @@ -734,16 +1001,22 @@ jobs: ghcr.io/yolean/runtime-quarkus-dev:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-runtime-quarkus-dev-root + type=gha,scope=buildx-runtime-quarkus-dev + cache-to: type=gha,mode=max,scope=buildx-runtime-quarkus-dev-root build-contexts: | yolean/builder-quarkus=docker-image://ghcr.io/yolean/builder-quarkus yolean/runtime-quarkus-ubuntu:root=docker-image://ghcr.io/yolean/runtime-quarkus-ubuntu:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push runtime-quarkus-dev latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/runtime-quarkus-dev tags: | @@ -751,15 +1024,21 @@ jobs: ghcr.io/yolean/runtime-quarkus-dev:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-runtime-quarkus-dev-latest + type=gha,scope=buildx-runtime-quarkus-dev + cache-to: type=gha,mode=max,scope=buildx-runtime-quarkus-dev-latest build-contexts: | yolean/runtime-quarkus-dev:root=docker-image://ghcr.io/yolean/runtime-quarkus-dev:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push toil-storage root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: toil-storage tags: | @@ -767,16 +1046,22 @@ jobs: ghcr.io/yolean/toil-storage:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-toil-storage-root + type=gha,scope=buildx-toil-storage + cache-to: type=gha,mode=max,scope=buildx-toil-storage-root build-contexts: | yolean/toil=docker-image://ghcr.io/yolean/toil yolean/docker-base=docker-image://ghcr.io/yolean/docker-base + continue-on-error: false + timeout-minutes: 45 - name: Build and push toil-storage latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/toil-storage tags: | @@ -784,15 +1069,21 @@ jobs: ghcr.io/yolean/toil-storage:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-toil-storage-latest + type=gha,scope=buildx-toil-storage + cache-to: type=gha,mode=max,scope=buildx-toil-storage-latest build-contexts: | yolean/toil-storage:root=docker-image://ghcr.io/yolean/toil-storage:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push curl-yq root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: curl-yq tags: | @@ -800,15 +1091,21 @@ jobs: ghcr.io/yolean/curl-yq:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-curl-yq-root + type=gha,scope=buildx-curl-yq + cache-to: type=gha,mode=max,scope=buildx-curl-yq-root build-contexts: | yolean/builder-base=docker-image://ghcr.io/yolean/builder-base + continue-on-error: false + timeout-minutes: 45 - name: Build and push curl-yq latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/curl-yq tags: | @@ -816,15 +1113,21 @@ jobs: ghcr.io/yolean/curl-yq:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-curl-yq-latest + type=gha,scope=buildx-curl-yq + cache-to: type=gha,mode=max,scope=buildx-curl-yq-latest build-contexts: | yolean/curl-yq:root=docker-image://ghcr.io/yolean/curl-yq:root + continue-on-error: false + timeout-minutes: 45 - name: Build and push duckdb root - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: duckdb tags: | @@ -832,16 +1135,22 @@ jobs: ghcr.io/yolean/duckdb:${{ github.sha }}-root platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-duckdb-root + type=gha,scope=buildx-duckdb + cache-to: type=gha,mode=max,scope=buildx-duckdb-root build-contexts: | yolean/builder-base=docker-image://ghcr.io/yolean/builder-base yolean/homedir=docker-image://ghcr.io/yolean/homedir + continue-on-error: false + timeout-minutes: 45 - name: Build and push duckdb latest - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6.18.0 env: SOURCE_DATE_EPOCH: 0 + BUILDKIT_PROGRESS: plain + DOCKER_BUILDKIT: 1 with: context: to-nonroot/duckdb tags: | @@ -849,7 +1158,11 @@ jobs: ghcr.io/yolean/duckdb:${{ github.sha }} platforms: linux/amd64,linux/arm64/v8 push: true - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: | + type=gha,scope=buildx-duckdb-latest + type=gha,scope=buildx-duckdb + cache-to: type=gha,mode=max,scope=buildx-duckdb-latest build-contexts: | yolean/duckdb:root=docker-image://ghcr.io/yolean/duckdb:root + continue-on-error: false + timeout-minutes: 45 diff --git a/builder-base/Dockerfile b/builder-base/Dockerfile index e66ebad..f10580d 100644 --- a/builder-base/Dockerfile +++ b/builder-base/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=$TARGETPLATFORM ghcr.io/yolean/ystack-runner:c99c1feb788de3a36cde3d1991930a0978584c0f@sha256:40328497d1941a7b3ee2176cf750269142d430b97a5360189c7e9a20cc875c66 \ +FROM --platform=$TARGETPLATFORM ghcr.io/yolean/ystack-runner:190c416a1906a5641127c114546201be8cb6a6c4@sha256:e3b988e7c1e332b74d8b9b2f9638b5a67e2b59b69b9febf30c535b6ade60eb74 \ as base FROM base as nonroot diff --git a/docker-base/Dockerfile b/docker-base/Dockerfile index 4fa441a..43872ea 100644 --- a/docker-base/Dockerfile +++ b/docker-base/Dockerfile @@ -1 +1 @@ -FROM --platform=$TARGETPLATFORM ubuntu:24.04@sha256:440dcf6a5640b2ae5c77724e68787a906afb8ddee98bf86db94eea8528c2c076 +FROM --platform=$TARGETPLATFORM ubuntu:24.04@sha256:9cbed754112939e914291337b5e554b07ad7c392491dba6daf25eef1332a22e8 diff --git a/node/Dockerfile b/node/Dockerfile index 7ff3d0a..64f4ef7 100644 --- a/node/Dockerfile +++ b/node/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=$TARGETPLATFORM node:22.17.0-bookworm-slim@sha256:b04ce4ae4e95b522112c2e5c52f781471a5cbc3b594527bcddedee9bc48c03a0 +FROM --platform=$TARGETPLATFORM node:22.19.0-trixie-slim@sha256:ba533b824f504e19137d3c961f8f6ef5278b02d8bfa7010eabb1b836d3125ce4 RUN runtimeDeps='procps git curl ca-certificates' \ && set -ex \ diff --git a/print-provenance.sh b/print-provenance.sh new file mode 100755 index 0000000..161bff5 --- /dev/null +++ b/print-provenance.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat >&2 < [--raw] [--debug] + --raw Print full attestation JSON (can repeat for multiple) + --debug Show crane commands executed +Defaults to :latest if no tag provided. +EOF +} + +if ! command -v crane >/dev/null 2>&1; then + echo "crane not found in PATH" >&2; exit 1; fi +if ! command -v jq >/dev/null 2>&1; then + echo "jq not found in PATH" >&2; exit 1; fi + +[ $# -ge 1 ] || { usage; exit 1; } + +IMAGE="$1"; shift || true +RAW="false"; DEBUG="false" +while [ $# -gt 0 ]; do + case "$1" in + --raw) RAW="true";; + --debug) DEBUG="true";; + -h|--help) usage; exit 0;; + *) echo "Unknown arg: $1" >&2; usage; exit 1;; + esac + shift +done + +# Add :latest if no explicit tag or digest +if [[ "$IMAGE" != *:@* && "$IMAGE" != *:*/*:* && "$IMAGE" != *:*:* && "$IMAGE" != *@sha256:* ]]; then + # has no :tag part after last slash + if [[ "$IMAGE" != *:* ]]; then + IMAGE+=":latest" + fi +fi + +echo "Inspecting provenance for $IMAGE" >&2 + +# Obtain manifest list (or single manifest) JSON +if ! MANIFEST_JSON=$(crane manifest "$IMAGE" 2>/dev/null); then + echo "Failed to fetch manifest for $IMAGE" >&2; exit 1; +fi + +# If it's a single-platform manifest, wrap to unify processing +if ! echo "$MANIFEST_JSON" | jq -e '.manifests' >/dev/null 2>&1; then + MANIFEST_LIST_JSON='{"manifests":[]}' +else + MANIFEST_LIST_JSON="$MANIFEST_JSON" +fi + +UNKNOWN_DIGESTS=$(echo "$MANIFEST_LIST_JSON" | jq -r '.manifests[]? | select(.platform.os=="unknown" and .platform.architecture=="unknown") | .digest') +if [ -z "$UNKNOWN_DIGESTS" ]; then + echo "No unknown/unknown platform manifests (attestations) found." >&2 + echo "Hint: ensure builds set provenance and sbom (buildkit) or attest step." >&2 + exit 2 +fi + +FOUND=0 +REGISTRY="${IMAGE%%/*}" # crude but ok for ghcr.io/owner/name:tag +REPO_TAG=${IMAGE#*/} +# Split repo and tag/digest +if [[ "$REPO_TAG" == *"@sha256:"* ]]; then + REPO="${REPO_TAG%@sha256:*}"; REF="${REPO_TAG#*@}"; REF_TYPE=digest +else + REPO="${REPO_TAG%%:*}"; REF="${REPO_TAG##*:}"; REF_TYPE=tag +fi + +IMAGE_PATH=${IMAGE#*/} # remove registry +REPO_PATH=${IMAGE_PATH%%@*} # drop @digest if any +REPO_PATH=${REPO_PATH%%:*} # drop :tag + +[ "$DEBUG" = "true" ] && echo "+ crane manifest $IMAGE # top-level" >&2 + +for DGST in $UNKNOWN_DIGESTS; do + BASE_REF=${IMAGE%%@*}; BASE_REF=${BASE_REF%%:*} # registry/owner/name + SUB_JSON=$(crane manifest "${BASE_REF}@${DGST}" 2>/dev/null) || continue + [ "$DEBUG" = "true" ] && echo "+ crane manifest ${BASE_REF}@${DGST}" >&2 + LAYER_DIGESTS=$(echo "$SUB_JSON" | jq -r '.layers[]? | select(.mediaType | test("in-toto")) | .digest') + [ -z "$LAYER_DIGESTS" ] && continue + for LD in $LAYER_DIGESTS; do + FOUND=1 + [ "$DEBUG" = "true" ] && echo "Sub-manifest digest: $DGST" >&2 && echo "In-toto layer digest: $LD" >&2 + # Retrieve attestation layer (handle crane versions expecting single arg) + [ "$DEBUG" = "true" ] && echo "+ crane blob ${BASE_REF}@${LD}" >&2 + ATTESTATION=$(crane blob "${BASE_REF}@${LD}" 2>/dev/null || crane blob "${IMAGE%@*}@${LD}" 2>/dev/null || true) + [ -z "$ATTESTATION" ] && continue + if [ "$RAW" = "true" ]; then + echo "$ATTESTATION" | jq '.' + continue + fi + echo "--- Attestation layer $LD (sub-manifest $DGST) ---" + JQ_SUMMARY='def dockerfiles: [ (.. | objects | to_entries[]? | select(.key|test("dockerfile";"i")) | .value) ] | flatten | map(tostring) | unique | .; + def mats: (.materials // .predicate.materials // []); + def norm(u; d): + if (u|startswith("docker-image://")) then + (u | sub("^docker-image://";"")) as $ref | + if (d|length>0) and ($ref|test("@sha256:" )|not) then ($ref|split("@")|.[0]) + "@sha256:" + d else $ref end + elif (u|startswith("pkg:docker/")) then + (u | sub("^pkg:docker/";"") | split("?") | .[0]) as $ref | + if (d|length>0) and ($ref|test("@sha256:" )|not) then ($ref|split("@")|.[0]) + "@sha256:" + d else $ref end + else + if (d|length>0) and (u|test("@sha256:" )|not) then (u + "@sha256:" + d) else u end + end; + def base_images: mats | map( ( .uri // .uri_ // empty ) as $u | ( .digest.sha256? // "" ) as $d | select($u != "") | norm($u; $d) ) | unique; + def bkmeta: .predicate.metadata["https://mobyproject.org/buildkit@v1#metadata"].vcs? // {}; + def guess_source: (bkmeta.source // .predicate.invocation.environment.GIT_URL? // .predicate.buildConfig.sourceProvenance.resolvedRepoSource.repoUrl? // empty); + def guess_revision: (bkmeta.revision // .predicate.invocation.environment.GITHUB_SHA? // .predicate.invocation.environment.GIT_COMMIT_SHA? // empty); + ["Dockerfiles:"] + (dockerfiles| if length==0 then ["(none found)"] else . end) + + ["Base images (materials):"] + (base_images | if length==0 then ["(none found)"] else . end) + + ["VCS source:", (guess_source // "(unknown)"), + "VCS revision:", (guess_revision // "(unknown)"), + "Build started:", (.predicate.metadata.buildStartedOn? // "(unknown)"), + "Build finished:", (.predicate.metadata.buildFinishedOn? // "(unknown)")] | .[]' + [ "$DEBUG" = "true" ] && echo "+ jq -r " >&2 && echo "$JQ_SUMMARY" | sed 's/^/| /' >&2 + SUMMARY=$(echo "$ATTESTATION" | jq -r "$JQ_SUMMARY") + if [ -z "${PREV_LAST:-}" ]; then + echo "$SUMMARY" + else + DIFF_PRINTED=false + while IFS= read -r line; do + if ! printf '%s\n' "$PREV_LAST" | grep -Fxq "$line"; then + [ "$DIFF_PRINTED" = false ] && echo "(diff from previous attestation)" && DIFF_PRINTED=true + echo "$line" + fi + done <<< "$SUMMARY" + [ "$DIFF_PRINTED" = false ] && echo "(no diff from previous attestation)" + fi + PREV_LAST="$SUMMARY" + done +done + +if [ $FOUND -eq 0 ]; then + echo "No attestation (in-toto) layers found in unknown/unknown manifests." >&2 + exit 3 +fi diff --git a/test.sh b/test.sh index 15a5ca7..c70f53f 100755 --- a/test.sh +++ b/test.sh @@ -60,6 +60,9 @@ runtime-quarkus-deno runtime-deno " +# Images that are only buildable on amd64 +SINGLE_ARCH_AMD64="headless-chrome" + BEGIN=" ### build steps below are generated ###" CURRENT=.github/workflows/images.yaml ACTIONS=$(mktemp) @@ -71,36 +74,60 @@ function base_action { local TAG=$3 local TAGSUFFIX="" [ "$TAG" = "latest" ] || local TAGSUFFIX="-$TAG" + # Create cache key that includes context for better cache scoping + local CACHE_KEY_PREFIX="buildx-$NAME-$TAG" + + # Get dependencies for build-contexts + local DEPENDENCIES="$((grep -e 'FROM --platform=$TARGETPLATFORM yolean/' -e 'FROM --platform=$BUILDPLATFORM yolean/' $CONTEXT/Dockerfile || true) | cut -d' ' -f3)" + + # Determine platforms (override if in SINGLE_ARCH_AMD64) + local PLATFORMS="linux/amd64,linux/arm64/v8" + for ONLY_AMD64 in $SINGLE_ARCH_AMD64; do + if [ "$NAME" = "$ONLY_AMD64" ]; then + PLATFORMS="linux/amd64" + break + fi + done + cat <> $ACTIONS - add_dependencies "$CONTEXT" >> $ACTIONS done for CONTEXT in $MULTIARCH_TONONROOT; do @@ -108,9 +135,7 @@ for CONTEXT in $MULTIARCH_TONONROOT; do echo "FROM --platform=\$TARGETPLATFORM yolean/$CONTEXT:root" > to-nonroot/$CONTEXT/Dockerfile cat nonroot-footer.Dockerfile >> to-nonroot/$CONTEXT/Dockerfile base_action "$CONTEXT" "$CONTEXT" root >> $ACTIONS - add_dependencies "$CONTEXT" >> $ACTIONS base_action "to-nonroot/$CONTEXT" "$CONTEXT" latest >> $ACTIONS - add_dependencies "to-nonroot/$CONTEXT" >> $ACTIONS done cp $ACTIONS $CURRENT