UNPKG

@hyperlane-xyz/core

Version:

Core solidity contracts for Hyperlane

313 lines (281 loc) 12.4 kB
name: Build and Publish Chainlink description: A composite action that allows building and publishing signed chainlink images. inputs: # Inputs for publishing publish: description: When set to the string boolean value of "true", the resulting built image will be published default: "false" required: false dockerfile: description: Path to the Dockerfile (relative to the repo root) default: core/chainlink.Dockerfile required: false dockerhub_username: description: Username for Docker Hub to avoid rate limits when pulling public images required: false dockerhub_password: description: Password for Docker Hub to avoid rate limits when pulling public images required: false ecr-hostname: description: The ECR registry scope default: public.ecr.aws required: false ecr-image-name: description: | The image name with path, in the format of `[registry]/repository`. For private ECR repos the registry name is optional, where for public repos, it is required. Eg. Public ECR repo `chainlink` and registry alias `chainlinklabs` should be `chainlinklabs/chainlink`. For a private ECR repo `chainlink` the image name should be `chainlink` default: chainlink/chainlink required: false ecr-tag-suffix: description: Docker image tag suffix required: false git-commit-sha: description: Git commit SHA used as metadata when building the application (appears in logs) default: ${{ github.event.pull_request.head.sha || github.sha }} required: false aws-role-to-assume: description: The AWS role to assume as the CD user, if any. Used in configuring the docker/login-action required: false aws-role-duration-seconds: description: The duration of the role assumed required: false aws-region: description: The AWS region the ECR repository is located in, should only be needed for public ECR repositories, used in configuring docker/login-action required: false # Inputs for signing sign-images: 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 value: ${{ steps.save-non-root-image-name-env.outputs.image-tag }} docker-image-digest: description: The docker image digest that was built and pushed value: ${{ steps.save-non-root-image-name-env.outputs.image-digest }} runs: using: composite steps: - name: Set shared variables shell: bash # 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 }} SHARED_TAG_LIST=$(cat << EOF type=ref,event=branch,suffix=${{ inputs.ecr-tag-suffix }} type=semver,pattern={{version}},suffix=${{ inputs.ecr-tag-suffix }} type=sha,format=short,suffix=${{ inputs.ecr-tag-suffix }} EOF ) SHARED_BUILD_ARGS=$(cat << EOF COMMIT_SHA=${{ inputs.git-commit-sha }} EOF ) echo "shared-images<<EOF" >> $GITHUB_ENV echo "$SHARED_IMAGES" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV echo "shared-tag-list<<EOF" >> $GITHUB_ENV echo "$SHARED_TAG_LIST" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV echo "shared-build-args<<EOF" >> $GITHUB_ENV echo "$SHARED_BUILD_ARGS" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV - if: inputs.publish == 'true' # Log in to AWS for publish to ECR name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 with: role-to-assume: ${{ inputs.aws-role-to-assume }} role-duration-seconds: ${{ inputs.aws-role-duration-seconds }} aws-region: ${{ inputs.aws-region }} mask-aws-account-id: true role-session-name: build-sign-publish-chainlink - if: inputs.publish == 'true' name: Login to ECR uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 with: registry: ${{ inputs.ecr-hostname }} - name: Setup Docker Buildx uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Generate docker metadata for root image id: meta-root uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 env: DOCKER_METADATA_PR_HEAD_SHA: "true" with: # list of Docker images to use as base name for tags images: ${{ env.shared-images }} # XXX: DO NOT USE SHARED TAGS HERE tags: | type=ref,event=branch,suffix=${{ inputs.ecr-tag-suffix }}-root type=semver,pattern={{version}},suffix=${{ inputs.ecr-tag-suffix }}-root type=sha,format=short,suffix=${{ inputs.ecr-tag-suffix }}-root # To avoid rate limiting from Docker Hub, we login with a paid user account. - name: Login to Docker Hub if: inputs.dockerhub_username && inputs.dockerhub_password uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 with: username: ${{ inputs.dockerhub_username }} password: ${{ inputs.dockerhub_password }} - name: Build and push root docker image id: buildpush-root uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0 with: push: ${{ inputs.publish }} context: . load: ${{ contains(inputs.publish, false) }} tags: ${{ steps.meta-root.outputs.tags }} labels: ${{ steps.meta-root.outputs.labels }} file: ${{ inputs.dockerfile }} build-args: | CHAINLINK_USER=root ${{ env.shared-build-args }} - name: Save root image name in GITHUB_ENV id: save-root-image-name-env shell: sh run: | IMAGES_NAME_RAW=${{ fromJSON(steps.buildpush-root.outputs.metadata)['image.name'] }} IMAGE_NAME=$(echo "$IMAGES_NAME_RAW" | cut -d"," -f1) echo "root_image_name=${IMAGE_NAME}" >> $GITHUB_ENV - name: Generate docker metadata for non-root image id: meta-nonroot uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 env: DOCKER_METADATA_PR_HEAD_SHA: "true" with: flavor: | latest=auto prefix= suffix= images: ${{ env.shared-images }} tags: ${{ env.shared-tag-list }} # To avoid rate limiting from Docker Hub, we login with a paid user account. - name: Login to Docker Hub if: inputs.dockerhub_username && inputs.dockerhub_password uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 with: username: ${{ inputs.dockerhub_username }} password: ${{ inputs.dockerhub_password }} - name: Build and push non-root docker image id: buildpush-nonroot uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0 with: push: ${{ inputs.publish }} context: . load: ${{ contains(inputs.publish, false) }} tags: ${{ steps.meta-nonroot.outputs.tags }} labels: ${{ steps.meta-nonroot.outputs.labels }} file: ${{ inputs.dockerfile }} build-args: | CHAINLINK_USER=chainlink ${{ env.shared-build-args }} - name: Save non-root image name in GITHUB_ENV and GITHUB_STEP_SUMMARY id: save-non-root-image-name-env shell: sh run: | IMAGES_NAME_RAW=${{ fromJSON(steps.buildpush-nonroot.outputs.metadata)['image.name'] }} IMAGE_DIGEST=${{ fromJSON(steps.buildpush-nonroot.outputs.metadata)['containerimage.digest'] }} 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 '### Docker Image' >> $GITHUB_STEP_SUMMARY echo "Image Name: ${IMAGE_NAME}" >> $GITHUB_STEP_SUMMARY echo "Image Digest: ${IMAGE_DIGEST}" >> $GITHUB_STEP_SUMMARY echo "image-tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT echo "image-digest=${IMAGE_DIGEST}" >> $GITHUB_OUTPUT - name: Check if non-root image runs as root id: check-nonroot-runs-root shell: sh env: PUBLISH: ${{ inputs.publish }} run: | echo "Fail build if non-root image runs as user: root" # if we're publishing the image, it doesn't get loaded into the local docker daemon # so we need to pull the image into our daemon if [ $PUBLISH = "true" ]; then docker pull "${nonroot_image_name}" fi docker inspect "${nonroot_image_name}" | jq -r '.[].Config.User' | ( ! grep "root" ) - if: inputs.sign-images == 'true' name: Install cosign uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4 # v3.4.0 with: cosign-release: "v1.6.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' name: Sign the published root Docker image using keyless method shell: sh env: COSIGN_EXPERIMENTAL: 1 run: | cosign sign "${{ env.root_image_name }}" - if: inputs.verify-signature == 'true' && inputs.sign-method == 'keyless' 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 - if: inputs.sign-images == 'true' && inputs.sign-method == 'keyless' name: Sign the published non-root Docker image using keyless method shell: sh env: COSIGN_EXPERIMENTAL: 1 run: | cosign sign "${{ env.nonroot_image_name }}" - if: inputs.verify-signature == 'true' && inputs.sign-method == 'keyless' 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 }}"