From 5dee0ec751975d955290731ce88a5e34b8b91d4c Mon Sep 17 00:00:00 2001 From: momentmaker Date: Wed, 28 Aug 2024 11:53:33 -0500 Subject: [PATCH] fix: goreleaser-build-sign-publish-chainlink workflow (#14139) * remove other gha workflows and test build-publish workflow * update cosigner gha and version * add env GORELEASER_KEY * add GITHUB_TOKEN env * temp add current_tag env * add --skip=validate temp * remove prev * skip release * use disable instead * fix post release publish bug * use keyless signing * revert and comment stdin * comment all cosign user/pass * add args to docker_signs * remove cosign user/pass env and uncomment other workflow * update cosign to keyless for regular docker build images * use keyless input and temp remove slack-notify * use image digest for signing * use --yes flag in cosign sign and update cosign-installer version * add --yes flag to cosign verify * fix typo and remove --yes * refactor to remove cosign keypair way and only use keyless signing * revert back deleted gha workflow files * refactor with suggestions * fix set env step * fix typos and naming --- .../build-sign-publish-chainlink/action.yml | 92 +++++-------------- .../goreleaser-build-sign-publish/action.yml | 19 +--- .../action_utils | 14 +-- .github/workflows/build-publish.yml | 14 +-- .goreleaser.develop.yaml | 9 +- 5 files changed, 41 insertions(+), 107 deletions(-) diff --git a/.github/actions/build-sign-publish-chainlink/action.yml b/.github/actions/build-sign-publish-chainlink/action.yml index b992edfbf7d..b0e70b742d5 100644 --- a/.github/actions/build-sign-publish-chainlink/action.yml +++ b/.github/actions/build-sign-publish-chainlink/action.yml @@ -51,23 +51,11 @@ inputs: description: When set to the string boolean value of "true", the resulting build image will be signed default: "false" required: false - cosign-private-key: - description: The private key to be used with cosign to sign the image - required: false - cosign-public-key: - description: The public key to be used with cosign for verification - required: false - cosign-password: - description: The password to decrypt the cosign private key needed to sign the image - required: false - sign-method: - description: Build image will be signed using keypair or keyless methods - default: "keypair" - required: true verify-signature: description: When set to the string boolean value of "true", the resulting build image signature will be verified default: "false" required: false + outputs: docker-image-tag: description: The docker image tag that was built and pushed @@ -84,6 +72,8 @@ runs: # See https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#multiline-strings run: | SHARED_IMAGES=${{ inputs.ecr-hostname }}/${{ inputs.ecr-image-name }} + OIDC_ISSUER=https://token.actions.githubusercontent.com + OIDC_IDENTITY=https://github.com/smartcontractkit/chainlink/.github/workflows/build-publish.yml@${{ github.ref }} SHARED_TAG_LIST=$(cat << EOF type=ref,event=branch,suffix=${{ inputs.ecr-tag-suffix }} @@ -101,6 +91,9 @@ runs: echo "$SHARED_IMAGES" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV + echo "oidc-issuer=${OIDC_ISSUER}" >> $GITHUB_ENV + echo "oidc-identity=${OIDC_IDENTITY}" >> $GITHUB_ENV + echo "shared-tag-list<> $GITHUB_ENV echo "$SHARED_TAG_LIST" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV @@ -171,7 +164,9 @@ runs: run: | IMAGES_NAME_RAW=${{ fromJSON(steps.buildpush-root.outputs.metadata)['image.name'] }} IMAGE_NAME=$(echo "$IMAGES_NAME_RAW" | cut -d"," -f1) + IMAGE_DIGEST=${{ fromJSON(steps.buildpush-root.outputs.metadata)['containerimage.digest'] }} echo "root_image_name=${IMAGE_NAME}" >> $GITHUB_ENV + echo "root_image_digest=${IMAGE_DIGEST}" >> $GITHUB_ENV - name: Generate docker metadata for non-root image id: meta-nonroot @@ -217,6 +212,7 @@ runs: IMAGE_NAME=$(echo "$IMAGES_NAME_RAW" | cut -d"," -f1) IMAGE_TAG=$(echo "$IMAGES_NAME_RAW" | cut -d":" -f2) echo "nonroot_image_name=${IMAGE_NAME}" >> $GITHUB_ENV + echo "nonroot_image_digest=${IMAGE_DIGEST}" >> $GITHUB_ENV echo '### Docker Image' >> $GITHUB_STEP_SUMMARY echo "Image Name: ${IMAGE_NAME}" >> $GITHUB_STEP_SUMMARY echo "Image Digest: ${IMAGE_DIGEST}" >> $GITHUB_STEP_SUMMARY @@ -239,74 +235,36 @@ runs: - if: inputs.sign-images == 'true' name: Install cosign - uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0 + uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0 with: - cosign-release: "v1.6.0" + cosign-release: "v2.4.0" - - if: inputs.sign-images == 'true' && inputs.sign-method == 'keypair' - name: Sign the published root Docker image using keypair method - shell: sh - env: - COSIGN_PASSWORD: "${{ inputs.cosign-password }}" - run: | - echo "${{ inputs.cosign-private-key }}" > cosign.key - cosign sign --key cosign.key "${{ env.root_image_name }}" - rm -f cosign.key - - - if: inputs.verify-signature == 'true' && inputs.sign-method == 'keypair' - name: Verify the signature of the published root Docker image using keypair - shell: sh - run: | - echo "${{ inputs.cosign-public-key }}" > cosign.key - cosign verify --key cosign.key "${{ env.root_image_name }}" - rm -f cosign.key - - - if: inputs.sign-images == 'true' && inputs.sign-method == 'keyless' + # This automatically signs the image with the correct OIDC provider from Github + - if: inputs.sign-images == 'true' name: Sign the published root Docker image using keyless method shell: sh - env: - COSIGN_EXPERIMENTAL: 1 run: | - cosign sign "${{ env.root_image_name }}" + cosign sign "${{ env.root_image_name }}" --yes - - if: inputs.verify-signature == 'true' && inputs.sign-method == 'keyless' + - if: inputs.verify-signature == 'true' name: Verify the signature of the published root Docker image using keyless shell: sh - env: - COSIGN_EXPERIMENTAL: 1 - run: | - cosign verify "${{ env.root_image_name }}" - - - if: inputs.sign-images == 'true' && inputs.sign-method == 'keypair' - name: Sign the published non-root Docker image using keypair method - shell: sh - env: - COSIGN_PASSWORD: "${{ inputs.cosign-password }}" - run: | - echo "${{ inputs.cosign-private-key }}" > cosign.key - cosign sign --key cosign.key "${{ env.nonroot_image_name }}" - rm -f cosign.key - - - if: inputs.verify-signature == 'true' && inputs.sign-method == 'keypair' - name: Verify the signature of the published non-root Docker image using keypair - shell: sh run: | - echo "${{ inputs.cosign-public-key }}" > cosign.key - cosign verify --key cosign.key "${{ env.nonroot_image_name }}" - rm -f cosign.key + cosign verify "${{ env.root_image_name }}" \ + --certificate-oidc-issuer ${{ env.oidc-issuer }} \ + --certificate-identity "${{ env.oidc-identity }}" - - if: inputs.sign-images == 'true' && inputs.sign-method == 'keyless' + # This automatically signs the image with the correct OIDC provider from Github + - if: inputs.sign-images == 'true' name: Sign the published non-root Docker image using keyless method shell: sh - env: - COSIGN_EXPERIMENTAL: 1 run: | - cosign sign "${{ env.nonroot_image_name }}" + cosign sign "${{ env.nonroot_image_name }}" --yes - - if: inputs.verify-signature == 'true' && inputs.sign-method == 'keyless' + - if: inputs.verify-signature == 'true' name: Verify the signature of the published non-root Docker image using keyless shell: sh - env: - COSIGN_EXPERIMENTAL: 1 run: | - cosign verify "${{ env.nonroot_image_name }}" + cosign verify "${{ env.nonroot_image_name }}" \ + --certificate-oidc-issuer ${{ env.oidc-issuer }} \ + --certificate-identity "${{ env.oidc-identity }}" diff --git a/.github/actions/goreleaser-build-sign-publish/action.yml b/.github/actions/goreleaser-build-sign-publish/action.yml index cf9da323def..69630e8e5fc 100644 --- a/.github/actions/goreleaser-build-sign-publish/action.yml +++ b/.github/actions/goreleaser-build-sign-publish/action.yml @@ -14,7 +14,7 @@ inputs: required: false cosign-version: description: The cosign version - default: v2.2.2 + default: v2.4.0 required: false macos-sdk-dir: description: The macos sdk directory @@ -62,15 +62,6 @@ inputs: description: Enable signing of docker images default: "false" required: false - cosign-private-key: - description: The private key to be used with cosign to sign the image - required: false - cosign-public-key: - description: The public key to be used with cosign for verification - required: false - cosign-password: - description: The password to decrypt the cosign private key needed to sign the image - required: false runs: using: composite steps: @@ -96,7 +87,7 @@ runs: version: ${{ inputs.zig-version }} - name: Setup cosign if: inputs.enable-cosign == 'true' - uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0 + uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0 with: cosign-release: ${{ inputs.cosign-version }} - name: Login to docker registry @@ -113,7 +104,6 @@ runs: - name: Run goreleaser release shell: bash env: - ENABLE_COSIGN: ${{ inputs.enable-cosign }} ENABLE_GORELEASER_SNAPSHOT: ${{ inputs.enable-goreleaser-snapshot }} ENABLE_GORELEASER_SPLIT: ${{ inputs.enable-goreleaser-split }} ENABLE_DOCKER_PUBLISH: ${{ inputs.enable-docker-publish }} @@ -122,9 +112,8 @@ runs: IMAGE_TAG: ${{ inputs.docker-image-tag }} GORELEASER_EXEC: ${{ inputs.goreleaser-exec }} GORELEASER_CONFIG: ${{ inputs.goreleaser-config }} - COSIGN_PASSWORD: ${{ inputs.cosign-password }} - COSIGN_PUBLIC_KEY: ${{ inputs.cosign-public-key }} - COSIGN_PRIVATE_KEY: ${{ inputs.cosign-private-key }} + GORELEASER_KEY: ${{ inputs.goreleaser-key }} + GITHUB_TOKEN: ${{ github.token }} MACOS_SDK_DIR: ${{ inputs.macos-sdk-dir }} run: | # https://github.com/orgs/community/discussions/24950 diff --git a/.github/actions/goreleaser-build-sign-publish/action_utils b/.github/actions/goreleaser-build-sign-publish/action_utils index 051e0763fbd..51c7c90aa1a 100755 --- a/.github/actions/goreleaser-build-sign-publish/action_utils +++ b/.github/actions/goreleaser-build-sign-publish/action_utils @@ -2,11 +2,9 @@ set -x set -euo pipefail -ENABLE_COSIGN=${ENABLE_COSIGN:-false} ENABLE_GORELEASER_SNAPSHOT=${ENABLE_GORELEASER_SNAPSHOT:-false} ENABLE_GORELEASER_SPLIT=${ENABLE_GORELEASER_SPLIT:-false} ENABLE_DOCKER_PUBLISH=${ENABLE_DOCKER_PUBLISH:-false} -COSIGN_PASSWORD=${COSIGN_PASSWORD:-""} GORELEASER_EXEC=${GORELEASER_EXEC:-goreleaser} GORELEASER_CONFIG=${GORELEASER_CONFIG:-.goreleaser.yaml} IMAGE_PREFIX=${IMAGE_PREFIX:-"localhost:5001"} @@ -69,26 +67,16 @@ goreleaser_release() { flags=$(printf "%s " "${goreleaser_flags[@]}") flags=$(echo "$flags" | sed 's/ *$//') - if [[ $ENABLE_COSIGN == "true" ]]; then - echo "$COSIGN_PUBLIC_KEY" > cosign.pub - echo "$COSIGN_PRIVATE_KEY" > cosign.key - fi - if [[ -n $MACOS_SDK_DIR ]]; then MACOS_SDK_DIR=$(echo "$(cd "$(dirname "$MACOS_SDK_DIR")" || exit; pwd)/$(basename "$MACOS_SDK_DIR")") fi $GORELEASER_EXEC release ${flags} --config "$GORELEASER_CONFIG" "$@" - if [[ $ENABLE_DOCKER_PUBLISH == "true" ]]; then + if [[ $ENABLE_DOCKER_PUBLISH == "true" ]] && [[ $ENABLE_GORELEASER_SNAPSHOT == "true" ]]; then _publish_snapshot_images _publish_snapshot_manifests fi - - if [[ $ENABLE_COSIGN == "true" ]]; then - rm -rf cosign.pub - rm -rf cosign.key - fi } "$@" diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index 033526e0339..fa01d27e7cd 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -51,13 +51,9 @@ jobs: aws-region: ${{ secrets.AWS_REGION }} ecr-hostname: ${{ env.ECR_HOSTNAME }} ecr-image-name: ${{ env.ECR_IMAGE_NAME }} - sign-images: true - sign-method: "keypair" - cosign-private-key: ${{ secrets.COSIGN_PRIVATE_KEY }} - cosign-public-key: ${{ secrets.COSIGN_PUBLIC_KEY }} - cosign-password: ${{ secrets.COSIGN_PASSWORD }} dockerhub_username: ${{ secrets.DOCKERHUB_READONLY_USERNAME }} dockerhub_password: ${{ secrets.DOCKERHUB_READONLY_PASSWORD }} + sign-images: true verify-signature: true - name: Collect Metrics @@ -97,7 +93,6 @@ jobs: id: goreleaser-build-sign-publish uses: ./.github/actions/goreleaser-build-sign-publish with: - enable-docker-publish: "true" docker-registry: ${{ env.ECR_HOSTNAME}} docker-image-name: ${{ env.ECR_IMAGE_NAME }} docker-image-tag: ${{ github.ref_name }} @@ -105,11 +100,8 @@ jobs: goreleaser-config: .goreleaser.develop.yaml goreleaser-key: ${{ secrets.GORELEASER_KEY }} zig-version: 0.11.0 - enable-cosign: "true" - cosign-version: 3.4.0 - cosign-password: ${{ secrets.COSIGN_PASSWORD }} - cosign-public-key: ${{ secrets.COSIGN_PUBLIC_KEY }} - cosign-private-key: ${{ secrets.COSIGN_PRIVATE_KEY }} + enable-cosign: true + cosign-version: "v2.4.0" - name: Output image name and digest shell: sh diff --git a/.goreleaser.develop.yaml b/.goreleaser.develop.yaml index 08d8e4de945..f8757676f83 100644 --- a/.goreleaser.develop.yaml +++ b/.goreleaser.develop.yaml @@ -192,7 +192,10 @@ docker_manifests: # See https://goreleaser.com/customization/docker_sign/ docker_signs: - artifacts: all - stdin: "{{ .Env.COSIGN_PASSWORD }}" + args: + - "sign" + - "${artifact}" + - "--yes" checksum: name_template: "checksums.txt" @@ -203,6 +206,10 @@ snapshot: partial: by: target +# See https://goreleaser.com/customization/release/ +release: + disable: true + changelog: sort: asc filters: