From 657c879dd58cd8ba944d8c8deaa8b4b1943cbdfa Mon Sep 17 00:00:00 2001 From: John McBride Date: Fri, 1 Sep 2023 13:44:22 -0600 Subject: [PATCH 1/4] feat: Semantic release automation (#42) Signed-off-by: John McBride --- .github/workflows/build-image.yaml | 127 +++++++++++++++++++++++++++ .github/workflows/release.yaml | 132 ++++------------------------- 2 files changed, 142 insertions(+), 117 deletions(-) create mode 100644 .github/workflows/build-image.yaml diff --git a/.github/workflows/build-image.yaml b/.github/workflows/build-image.yaml new file mode 100644 index 0000000..5ecc775 --- /dev/null +++ b/.github/workflows/build-image.yaml @@ -0,0 +1,127 @@ +name: Release pizza image + +on: + push: + tags: + - 'v*' + +permissions: + actions: read + packages: write # for publish to ghcr.io + id-token: write # for signing image + +jobs: + build: + name: Build and publish image + runs-on: ubuntu-latest + env: + IMAGE_URI: ghcr.io/${{ github.repository }} + IMAGE_URI_TAG: ghcr.io/${{ github.repository }}:${{ github.ref_name }} + outputs: + image: ${{ env.IMAGE_URI }} + digest: ${{ steps.image_digest.outputs.IMAGE_DIGEST }} + steps: + - name: Checkout code + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # tag=v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Login to GitHub Container Registry + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Cross build + run: | + #!/usr/bin/env bash + + docker buildx bake \ + -f ./docker-bake.hcl \ + --set build.args.GO_LDFLAGS="$GO_LDFLAGS" \ + --set cross.tags=ghcr.io/${{ github.repository }}:${{ github.ref_name }} \ + --push \ + cross + + - name: Install crane + if: startsWith(github.ref, 'refs/tags/') + uses: imjasonh/setup-crane@00c9e93efa4e1138c9a7a5c594acd6c75a2fbf0c # v0.3 + - name: Output image digest + if: startsWith(github.ref, 'refs/tags/') + id: image_digest + run: echo "IMAGE_DIGEST=$(crane digest ${IMAGE_URI_TAG})" >> $GITHUB_OUTPUT + + sign: + name: Sign image and generate sbom + runs-on: ubuntu-latest + needs: [build] + if: startsWith(github.ref, 'refs/tags/') + steps: + - name: Checkout code + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # tag=v3 + - name: Login to GitHub Container Registry + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Run Trivy in fs mode to generate SBOM + uses: aquasecurity/trivy-action@e5f43133f6e8736992c9f3c1b3296e24b37e17f2 # master + with: + scan-type: 'fs' + format: 'spdx-json' + output: 'spdx.sbom.json' + - name: Install cosign + uses: sigstore/cosign-installer@dd6b2e2b610a11fd73dd187a43d57cc1394e35f9 # main + - name: Sign image and sbom + run: | + #!/usr/bin/env bash + set -euo pipefail + cosign sign -a git_sha=$GITHUB_SHA ${IMAGE_URI_DIGEST} --yes + cosign attach sbom --sbom spdx.sbom.json ${IMAGE_URI_DIGEST} + cosign sign -a git_sha=$GITHUB_SHA --attachment sbom ${IMAGE_URI_DIGEST} --yes + shell: bash + env: + IMAGE_URI_DIGEST: ${{ needs.build.outputs.image }}@${{ needs.build.outputs.digest }} + + provenance: + needs: [build] + if: startsWith(github.ref, 'refs/tags/') + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.6.0 + with: + image: ${{ needs.build.outputs.image }} + digest: ${{ needs.build.outputs.digest }} + registry-username: ${{ github.actor }} + secrets: + registry-password: ${{ secrets.GITHUB_TOKEN }} + + verify: + name: Verify image and provenance + runs-on: ubuntu-latest + needs: [build, sign, provenance] + if: startsWith(github.ref, 'refs/tags/') + steps: + - name: Login to GitHub Container Registry + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Install cosign + uses: sigstore/cosign-installer@dd6b2e2b610a11fd73dd187a43d57cc1394e35f9 # main + - name: Install slsa-verifier + uses: slsa-framework/slsa-verifier/actions/installer@c9abffe4d2ab2ffa0b2ea9b2582b84164f390adc # v2.3.0 + - name: Verify image and provenance + run: | + #!/usr/bin/env bash + set -euo pipefail + cosign verify ${IMAGE_URI_DIGEST} \ + --certificate-oidc-issuer ${GITHUB_ACITONS_OIDC_ISSUER} \ + --certificate-identity ${COSIGN_KEYLESS_SIGNING_CERT_SUBJECT} + slsa-verifier verify-image \ + --source-uri github.com/${{ github.repository }} ${IMAGE_URI_DIGEST} + shell: bash + env: + IMAGE_URI_DIGEST: ${{ needs.build.outputs.image }}@${{ needs.build.outputs.digest }} + GITHUB_ACITONS_OIDC_ISSUER: https://token.actions.githubusercontent.com + COSIGN_KEYLESS_SIGNING_CERT_SUBJECT: https://github.com/${{ github.repository }}/.github/workflows/release.yaml@${{ github.ref }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 5cfdb2b..fd61d47 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,127 +1,25 @@ -name: Release pizza image +name: Semantic release on: push: - tags: - - 'v*' - -permissions: - actions: read - packages: write # for publish to ghcr.io - id-token: write # for signing image + branches: + - main + - beta + workflow_dispatch: jobs: - build: - name: Build and publish image + release: + name: Semantic release runs-on: ubuntu-latest - env: - IMAGE_URI: ghcr.io/${{ github.repository }} - IMAGE_URI_TAG: ghcr.io/${{ github.repository }}:${{ github.ref_name }} - outputs: - image: ${{ env.IMAGE_URI }} - digest: ${{ steps.image_digest.outputs.IMAGE_DIGEST }} + timeout-minutes: 10 steps: - - name: Checkout code - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # tag=v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Login to GitHub Container Registry - uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 + - name: "☁️ Checkout repository" + uses: actions/checkout@v3 with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Cross build - run: | - #!/usr/bin/env bash - - docker buildx bake \ - -f ./docker-bake.hcl \ - --set build.args.GO_LDFLAGS="$GO_LDFLAGS" \ - --set cross.tags=ghcr.io/${{ github.repository }}:${{ github.ref_name }} \ - --push \ - cross + fetch-depth: 0 - - name: Install crane - if: startsWith(github.ref, 'refs/tags/') - uses: imjasonh/setup-crane@00c9e93efa4e1138c9a7a5c594acd6c75a2fbf0c # v0.3 - - name: Output image digest - if: startsWith(github.ref, 'refs/tags/') - id: image_digest - run: echo "IMAGE_DIGEST=$(crane digest ${IMAGE_URI_TAG})" >> $GITHUB_OUTPUT - - sign: - name: Sign image and generate sbom - runs-on: ubuntu-latest - needs: [build] - if: startsWith(github.ref, 'refs/tags/') - steps: - - name: Checkout code - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # tag=v3 - - name: Login to GitHub Container Registry - uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Run Trivy in fs mode to generate SBOM - uses: aquasecurity/trivy-action@e5f43133f6e8736992c9f3c1b3296e24b37e17f2 # master - with: - scan-type: 'fs' - format: 'spdx-json' - output: 'spdx.sbom.json' - - name: Install cosign - uses: sigstore/cosign-installer@dd6b2e2b610a11fd73dd187a43d57cc1394e35f9 # main - - name: Sign image and sbom - run: | - #!/usr/bin/env bash - set -euo pipefail - cosign sign -a git_sha=$GITHUB_SHA ${IMAGE_URI_DIGEST} --yes - cosign attach sbom --sbom spdx.sbom.json ${IMAGE_URI_DIGEST} - cosign sign -a git_sha=$GITHUB_SHA --attachment sbom ${IMAGE_URI_DIGEST} --yes - shell: bash - env: - IMAGE_URI_DIGEST: ${{ needs.build.outputs.image }}@${{ needs.build.outputs.digest }} - - provenance: - needs: [build] - if: startsWith(github.ref, 'refs/tags/') - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.6.0 - with: - image: ${{ needs.build.outputs.image }} - digest: ${{ needs.build.outputs.digest }} - registry-username: ${{ github.actor }} - secrets: - registry-password: ${{ secrets.GITHUB_TOKEN }} - - verify: - name: Verify image and provenance - runs-on: ubuntu-latest - needs: [build, sign, provenance] - if: startsWith(github.ref, 'refs/tags/') - steps: - - name: Login to GitHub Container Registry - uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Install cosign - uses: sigstore/cosign-installer@dd6b2e2b610a11fd73dd187a43d57cc1394e35f9 # main - - name: Install slsa-verifier - uses: slsa-framework/slsa-verifier/actions/installer@c9abffe4d2ab2ffa0b2ea9b2582b84164f390adc # v2.3.0 - - name: Verify image and provenance - run: | - #!/usr/bin/env bash - set -euo pipefail - cosign verify ${IMAGE_URI_DIGEST} \ - --certificate-oidc-issuer ${GITHUB_ACITONS_OIDC_ISSUER} \ - --certificate-identity ${COSIGN_KEYLESS_SIGNING_CERT_SUBJECT} - slsa-verifier verify-image \ - --source-uri github.com/${{ github.repository }} ${IMAGE_URI_DIGEST} - shell: bash + - name: "🚀 Release tag" + id: semantic-release env: - IMAGE_URI_DIGEST: ${{ needs.build.outputs.image }}@${{ needs.build.outputs.digest }} - GITHUB_ACITONS_OIDC_ISSUER: https://token.actions.githubusercontent.com - COSIGN_KEYLESS_SIGNING_CERT_SUBJECT: https://github.com/${{ github.repository }}/.github/workflows/release.yaml@${{ github.ref }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: open-sauced/release@v2 From c1fd755ae558a20b43e285d79cff2203bab71cc4 Mon Sep 17 00:00:00 2001 From: John McBride Date: Fri, 1 Sep 2023 14:01:43 -0600 Subject: [PATCH 2/4] fix: Fix for semantic-release (#44) Missed force push before merge to capture env vars Signed-off-by: John McBride --- .github/workflows/build-image.yaml | 2 +- .github/workflows/release.yaml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-image.yaml b/.github/workflows/build-image.yaml index 5ecc775..d1cec34 100644 --- a/.github/workflows/build-image.yaml +++ b/.github/workflows/build-image.yaml @@ -31,7 +31,7 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - + - name: Cross build run: | #!/usr/bin/env bash diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fd61d47..c3ea375 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,8 +11,11 @@ jobs: release: name: Semantic release runs-on: ubuntu-latest + permissions: + contents: write timeout-minutes: 10 steps: + - name: "☁️ Checkout repository" uses: actions/checkout@v3 with: @@ -22,4 +25,6 @@ jobs: id: semantic-release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SKIP_NPM_PUBLISH: true + SKIP_DOCKER_PUBLISH: true uses: open-sauced/release@v2 From f004d83f2d3e22e6e433e6d9f9489760b53f7773 Mon Sep 17 00:00:00 2001 From: John McBride Date: Fri, 1 Sep 2023 14:21:56 -0600 Subject: [PATCH 3/4] fix: Use generated token for semantic release (#45) Signed-off-by: John McBride --- .github/workflows/release.yaml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c3ea375..b70ddf1 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,20 +11,25 @@ jobs: release: name: Semantic release runs-on: ubuntu-latest - permissions: - contents: write timeout-minutes: 10 steps: + - name: "🔐 Generate token" + id: generate_token + uses: tibdex/github-app-token@v1 + with: + app_id: ${{ secrets.OS_GITHUB_APP_ID }} + private_key: ${{ secrets.OS_GITHUB_APP_PRIVATE_KEY }} - name: "☁️ Checkout repository" uses: actions/checkout@v3 with: fetch-depth: 0 + token: ${{ steps.generate_token.outputs.token }} - name: "🚀 Release tag" id: semantic-release env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} SKIP_NPM_PUBLISH: true SKIP_DOCKER_PUBLISH: true uses: open-sauced/release@v2 From 1365a751a4578af73b3d6acdc5626b6ad6e9947b Mon Sep 17 00:00:00 2001 From: John McBride Date: Fri, 1 Sep 2023 15:02:43 -0600 Subject: [PATCH 4/4] fix: SLSA verifier fix for new build-image.yaml filename (#46) Signed-off-by: John McBride --- .github/workflows/build-image.yaml | 44 ++++++++++++++++++------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-image.yaml b/.github/workflows/build-image.yaml index d1cec34..5da34e3 100644 --- a/.github/workflows/build-image.yaml +++ b/.github/workflows/build-image.yaml @@ -12,7 +12,7 @@ permissions: jobs: build: - name: Build and publish image + name: "📥 Build and publish image" runs-on: ubuntu-latest env: IMAGE_URI: ghcr.io/${{ github.repository }} @@ -21,7 +21,7 @@ jobs: image: ${{ env.IMAGE_URI }} digest: ${{ steps.image_digest.outputs.IMAGE_DIGEST }} steps: - - name: Checkout code + - name: "☁️ Checkout code" uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # tag=v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 @@ -32,7 +32,7 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Cross build + - name: "🔀 Cross build" run: | #!/usr/bin/env bash @@ -43,21 +43,22 @@ jobs: --push \ cross - - name: Install crane + - name: "🏗️ Install crane" if: startsWith(github.ref, 'refs/tags/') uses: imjasonh/setup-crane@00c9e93efa4e1138c9a7a5c594acd6c75a2fbf0c # v0.3 - - name: Output image digest + + - name: "📸 Output image digest" if: startsWith(github.ref, 'refs/tags/') id: image_digest run: echo "IMAGE_DIGEST=$(crane digest ${IMAGE_URI_TAG})" >> $GITHUB_OUTPUT sign: - name: Sign image and generate sbom + name: "📝 Sign image and generate sbom" runs-on: ubuntu-latest needs: [build] if: startsWith(github.ref, 'refs/tags/') steps: - - name: Checkout code + - name: "☁️ Checkout code" uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # tag=v3 - name: Login to GitHub Container Registry uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 @@ -65,15 +66,18 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Run Trivy in fs mode to generate SBOM + + - name: "👀 Run Trivy in fs mode to generate SBOM" uses: aquasecurity/trivy-action@e5f43133f6e8736992c9f3c1b3296e24b37e17f2 # master with: scan-type: 'fs' format: 'spdx-json' output: 'spdx.sbom.json' - - name: Install cosign + + - name: "🤝 Install cosign" uses: sigstore/cosign-installer@dd6b2e2b610a11fd73dd187a43d57cc1394e35f9 # main - - name: Sign image and sbom + + - name: "📝 Sign image and sbom" run: | #!/usr/bin/env bash set -euo pipefail @@ -85,6 +89,7 @@ jobs: IMAGE_URI_DIGEST: ${{ needs.build.outputs.image }}@${{ needs.build.outputs.digest }} provenance: + name: "🚨 SLSA provenance" needs: [build] if: startsWith(github.ref, 'refs/tags/') uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.6.0 @@ -96,32 +101,35 @@ jobs: registry-password: ${{ secrets.GITHUB_TOKEN }} verify: - name: Verify image and provenance + name: "🔨 Verify image and provenance" runs-on: ubuntu-latest needs: [build, sign, provenance] if: startsWith(github.ref, 'refs/tags/') steps: - - name: Login to GitHub Container Registry + - name: "📦 Login to GitHub Container Registry" uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Install cosign + + - name: "🦙 Install cosign" uses: sigstore/cosign-installer@dd6b2e2b610a11fd73dd187a43d57cc1394e35f9 # main - - name: Install slsa-verifier + + - name: "💃 Install slsa-verifier" uses: slsa-framework/slsa-verifier/actions/installer@c9abffe4d2ab2ffa0b2ea9b2582b84164f390adc # v2.3.0 - - name: Verify image and provenance + + - name: "👷 Verify image and provenance" run: | #!/usr/bin/env bash set -euo pipefail cosign verify ${IMAGE_URI_DIGEST} \ - --certificate-oidc-issuer ${GITHUB_ACITONS_OIDC_ISSUER} \ + --certificate-oidc-issuer ${GITHUB_ACTIONS_OIDC_ISSUER} \ --certificate-identity ${COSIGN_KEYLESS_SIGNING_CERT_SUBJECT} slsa-verifier verify-image \ --source-uri github.com/${{ github.repository }} ${IMAGE_URI_DIGEST} shell: bash env: IMAGE_URI_DIGEST: ${{ needs.build.outputs.image }}@${{ needs.build.outputs.digest }} - GITHUB_ACITONS_OIDC_ISSUER: https://token.actions.githubusercontent.com - COSIGN_KEYLESS_SIGNING_CERT_SUBJECT: https://github.com/${{ github.repository }}/.github/workflows/release.yaml@${{ github.ref }} + GITHUB_ACTIONS_OIDC_ISSUER: https://token.actions.githubusercontent.com + COSIGN_KEYLESS_SIGNING_CERT_SUBJECT: https://github.com/${{ github.repository }}/.github/workflows/build-image.yaml@${{ github.ref }}