diff --git a/.github/workflows/ghcr-publish.yml b/.github/workflows/ghcr-publish.yml index 40bc5da0..7fa0e7cc 100644 --- a/.github/workflows/ghcr-publish.yml +++ b/.github/workflows/ghcr-publish.yml @@ -9,17 +9,15 @@ on: # schedule: # - cron: '18 10 * * *' push: - branches: [ "main" ] + branches: ["main"] # Publish semver tags as releases. - tags: [ 'v*.*.*' ] + tags: ["v*.*.*"] pull_request: - branches: [ "main" ] + branches: ["main"] env: # Use docker.io for Docker Hub if empty - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - + REGISTRY_IMAGE: ghcr.io/sourcebot jobs: build: @@ -32,21 +30,28 @@ jobs: id-token: write strategy: matrix: - architecture: [amd64, arm64] + platform: + - linux/amd64 + - linux/arm64 steps: + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + - name: Checkout repository uses: actions/checkout@v4 with: - submodules: 'true' - + submodules: "true" + # Extract metadata (tags, labels) for Docker # https://github.com/docker/metadata-action - name: Extract Docker metadata id: meta uses: docker/metadata-action@v5 with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + images: ${{ env.REGISTRY_IMAGE }} # Install the cosign tool except on PR # https://github.com/sigstore/cosign-installer @@ -54,31 +59,44 @@ jobs: if: github.event_name != 'pull_request' uses: sigstore/cosign-installer@v3.5.0 with: - cosign-release: 'v2.2.4' + cosign-release: "v2.2.4" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - + uses: docker/setup-buildx-action@v3 + - name: Login to GitHub Packages Docker Registry uses: docker/login-action@v1 if: github.event_name != 'pull_request' with: - registry: ${{ env.REGISTRY }} + registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push Docker image - id: build-and-push - uses: docker/build-push-action@v5 + id: build + uses: docker/build-push-action@v6 with: context: . - push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - platforms: linux/${{ matrix.architecture }} - + platforms: ${{ matrix.platform }} + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + # Sign the resulting Docker image digest except on PRs. # This will only write to the public Rekor transparency log when the Docker # repository is public to avoid leaking data. If you would like to publish @@ -89,7 +107,46 @@ jobs: env: # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable TAGS: ${{ steps.meta.outputs.tags }} - DIGEST: ${{ steps.build-and-push.outputs.digest }} + DIGEST: ${{ steps.build.outputs.digest }} # This step uses the identity token to provision an ephemeral certificate # against the sigstore community Fulcio instance. - run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} \ No newline at end of file + run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} + + merge: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + needs: + - build + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_IMAGE }} + + - name: Login to GitHub Packages Docker Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}