fix: source release-config.sh from main in build-docker.yaml #142
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Docker | |
| on: | |
| pull_request: | |
| types: [labeled, synchronize] | |
| branches: | |
| - main | |
| - release/* | |
| workflow_call: | |
| inputs: | |
| tag: | |
| description: 'Tag to build and publish Docker images for (e.g. v0.6.0)' | |
| required: true | |
| type: string | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Tag to build and publish Docker images for (e.g. v0.6.0)' | |
| required: true | |
| type: string | |
| concurrency: | |
| group: docker-${{ (github.event_name == 'workflow_call' || github.event_name == 'workflow_dispatch') && inputs.tag || github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| env: | |
| REGISTRY: docker.cloudsmith.io | |
| REGISTRY_NAMESPACE: circle/arc-network | |
| jobs: | |
| build: | |
| if: >- | |
| github.event_name == 'workflow_call' || | |
| github.event_name == 'workflow_dispatch' || | |
| contains(github.event.pull_request.labels.*.name, 'build-docker') | |
| name: Build ${{ matrix.image }} (${{ matrix.platform }}) | |
| permissions: | |
| contents: read | |
| id-token: write | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: | |
| - arc-execution | |
| - arc-consensus | |
| platform: | |
| - linux/amd64 | |
| - linux/arm64 | |
| include: | |
| - platform: linux/amd64 | |
| arch: amd64 | |
| runner: ubuntu-latest | |
| - platform: linux/arm64 | |
| arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| ref: ${{ (github.event_name == 'workflow_call' || github.event_name == 'workflow_dispatch') && format('refs/tags/{0}', inputs.tag) || github.ref }} | |
| submodules: recursive | |
| fetch-depth: 0 | |
| - name: Resolve image metadata | |
| id: vars | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| INPUT_TAG: ${{ inputs.tag }} | |
| run: | | |
| SHA="$(git rev-parse HEAD)" | |
| if [[ "$EVENT_NAME" == "workflow_call" || "$EVENT_NAME" == "workflow_dispatch" ]]; then | |
| # A release branch's release-config.sh can predate functions this workflow | |
| # (always run from main) expects, so pull main's copy rather than whatever | |
| # is checked out at the tagged commit above. | |
| git show origin/main:scripts/release-config.sh > "${RUNNER_TEMP}/release-config.sh" | |
| # shellcheck source=/dev/null | |
| source "${RUNNER_TEMP}/release-config.sh" | |
| if ! release_docker_image_version_from_tag "$INPUT_TAG" >/dev/null; then | |
| echo "::error::Invalid tag format: '$INPUT_TAG' (expected e.g. v1.2.3 or v1.2.3-rc.1)" | |
| exit 1 | |
| fi | |
| fi | |
| { | |
| echo "full_hash=${SHA}" | |
| echo "short_hash=${SHA::8}" | |
| echo "git_version=$(git describe --tags --always --dirty 2>/dev/null || echo 'v0.0.0-unknown')" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 | |
| - name: Build image | |
| id: build | |
| uses: docker/bake-action@6614cfa25eff9a0b2b2697efb0b6159e7680d584 # v7.2.0 | |
| with: | |
| source: . | |
| files: docker-bake.hcl | |
| targets: ${{ matrix.image }} | |
| set: | | |
| ${{ matrix.image }}.platform=${{ matrix.platform }} | |
| ${{ matrix.image }}.tags= | |
| ${{ matrix.image }}.output=type=oci,tar=false,dest=/tmp/image | |
| env: | |
| BUILDX_NO_DEFAULT_ATTESTATIONS: 1 | |
| GITHUB_TOKEN: ${{ github.token }} | |
| GIT_COMMIT_HASH: ${{ steps.vars.outputs.full_hash }} | |
| GIT_VERSION: ${{ steps.vars.outputs.git_version }} | |
| GIT_SHORT_HASH: ${{ steps.vars.outputs.short_hash }} | |
| - name: Trivy vulnerability scan | |
| uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 | |
| with: | |
| input: /tmp/image | |
| format: sarif | |
| output: trivy-results.sarif | |
| severity: CRITICAL | |
| limit-severities-for-sarif: true | |
| exit-code: '1' | |
| - name: Upload Trivy scan results | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: trivy-${{ matrix.image }}-${{ matrix.arch }} | |
| path: trivy-results.sarif | |
| - name: Login to Cloudsmith | |
| if: ${{ github.event_name == 'workflow_call' || github.event_name == 'workflow_dispatch' }} | |
| uses: ./.github/actions/cloudsmith-login | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| - name: Push image by digest | |
| if: ${{ github.event_name == 'workflow_call' || github.event_name == 'workflow_dispatch' }} | |
| env: | |
| IMAGE: ${{ env.REGISTRY }}/${{ env.REGISTRY_NAMESPACE }}/${{ matrix.image }} | |
| BAKE_METADATA: ${{ steps.build.outputs.metadata }} | |
| MATRIX_IMAGE: ${{ matrix.image }} | |
| MATRIX_PLATFORM: ${{ matrix.platform }} | |
| run: | | |
| DIGEST=$(echo "${BAKE_METADATA}" | jq -r --arg img "${MATRIX_IMAGE}" '.[$img]."containerimage.digest"') | |
| if [ -z "${DIGEST}" ] || [ "${DIGEST}" = "null" ]; then | |
| echo "::error::Failed to extract digest from build metadata" | |
| exit 1 | |
| fi | |
| skopeo copy "oci:/tmp/image" "docker://${IMAGE}@${DIGEST}" --digestfile /tmp/push-digest | |
| rm -rf /tmp/image | |
| REGISTRY_DIGEST=$(cat /tmp/push-digest) | |
| if [ "${DIGEST}" != "${REGISTRY_DIGEST}" ]; then | |
| echo "::warning::Bake metadata digest ${DIGEST} differs from registry digest ${REGISTRY_DIGEST}" | |
| fi | |
| PLATFORM_SLUG=$(echo "${MATRIX_PLATFORM}" | tr '/' '-') | |
| mkdir -p "/tmp/digests/${MATRIX_IMAGE}" | |
| echo "${REGISTRY_DIGEST}" > "/tmp/digests/${MATRIX_IMAGE}/${PLATFORM_SLUG}" | |
| - name: Upload digest | |
| if: ${{ github.event_name == 'workflow_call' || github.event_name == 'workflow_dispatch' }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: digest-${{ matrix.image }}-${{ matrix.arch }} | |
| path: /tmp/digests/${{ matrix.image }}/* | |
| if-no-files-found: error | |
| manifest: | |
| if: ${{ github.event_name == 'workflow_call' || github.event_name == 'workflow_dispatch' }} | |
| name: Manifest ${{ matrix.image }} | |
| permissions: | |
| contents: read | |
| id-token: write | |
| attestations: write | |
| needs: [build] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: | |
| - arc-execution | |
| - arc-consensus | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| ref: ${{ format('refs/tags/{0}', inputs.tag) }} | |
| sparse-checkout: | | |
| .github/actions | |
| scripts | |
| fetch-depth: 0 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 | |
| - name: Login to Cloudsmith | |
| uses: ./.github/actions/cloudsmith-login | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| - name: Download digests | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: digest-${{ matrix.image }}-* | |
| merge-multiple: true | |
| path: /tmp/digests | |
| - name: Create and inspect multi-arch manifest | |
| id: manifest | |
| env: | |
| IMAGE: ${{ env.REGISTRY }}/${{ env.REGISTRY_NAMESPACE }}/${{ matrix.image }} | |
| RELEASE_TAG: ${{ inputs.tag }} | |
| run: | | |
| # A release branch's release-config.sh can predate functions this workflow | |
| # (always run from main) expects, so pull main's copy rather than whatever | |
| # is checked out at the tagged commit above. | |
| git show origin/main:scripts/release-config.sh > "${RUNNER_TEMP}/release-config.sh" | |
| # shellcheck source=/dev/null | |
| source "${RUNNER_TEMP}/release-config.sh" | |
| if ! IMAGE_VERSION="$(release_docker_image_version_from_tag "$RELEASE_TAG")"; then | |
| echo "::error::Invalid tag format: '$RELEASE_TAG' (expected e.g. v1.2.3 or v1.2.3-rc.1)" | |
| exit 1 | |
| fi | |
| # Defense in depth: never publish a vX.Y.Z-tagged image, even if the | |
| # sourced parser regresses and stops stripping the leading "v". | |
| IMAGE_VERSION="${IMAGE_VERSION#v}" | |
| SHA="$(git rev-parse HEAD)" | |
| SHORT_HASH="${SHA::8}" | |
| TAG="${IMAGE}:${IMAGE_VERSION}" | |
| SHA_TAG="${IMAGE}:${IMAGE_VERSION}-${SHORT_HASH}" | |
| # Build digest args from all platform artifacts | |
| DIGEST_ARGS=() | |
| for f in /tmp/digests/*; do | |
| DIGEST_ARGS+=("${IMAGE}@$(cat "$f")") | |
| done | |
| if [ ${#DIGEST_ARGS[@]} -eq 0 ]; then | |
| echo "::error::No digest files found" | |
| exit 1 | |
| fi | |
| # Create and push the manifest list | |
| docker buildx imagetools create -t "${TAG}" -t "${SHA_TAG}" "${DIGEST_ARGS[@]}" | |
| MANIFEST_DIGEST=$(docker buildx imagetools inspect "${TAG}" --raw | sha256sum | awk '{print "sha256:"$1}') | |
| echo "digest=${MANIFEST_DIGEST}" >> "$GITHUB_OUTPUT" | |
| echo "image-with-digest=${IMAGE}@${MANIFEST_DIGEST}" >> "$GITHUB_OUTPUT" | |
| - name: Generate SBOM | |
| continue-on-error: true | |
| uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 | |
| with: | |
| image: ${{ steps.manifest.outputs.image-with-digest }} | |
| artifact-name: sbom-${{ matrix.image }}.spdx.json | |
| output-file: sbom-${{ matrix.image }}.spdx.json | |
| upload-release-assets: false | |
| - name: Attest build provenance | |
| uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0 | |
| with: | |
| subject-name: ${{ env.REGISTRY }}/${{ env.REGISTRY_NAMESPACE }}/${{ matrix.image }} | |
| subject-digest: ${{ steps.manifest.outputs.digest }} | |
| push-to-registry: true | |
| - name: Attest SBOM | |
| uses: actions/attest-sbom@07e74fc4e78d1aad915e867f9a094073a9f71527 # v4.0.0 | |
| with: | |
| subject-name: ${{ env.REGISTRY }}/${{ env.REGISTRY_NAMESPACE }}/${{ matrix.image }} | |
| subject-digest: ${{ steps.manifest.outputs.digest }} | |
| sbom-path: sbom-${{ matrix.image }}.spdx.json | |
| push-to-registry: true |