From eba42e2f718fcddb58b7be5f09d034e3337e62b7 Mon Sep 17 00:00:00 2001 From: Himank Dave <93311724+steadyfall@users.noreply.github.com> Date: Mon, 4 Aug 2025 18:41:05 -0400 Subject: [PATCH] build: allow main branch publishing and add comprehensive OCI metadata for multi-arch images (#65) * feat(ci): add OCI annotations and metadata to multi-arch images - Include created, source, revision, ref-name, vendor & license - Add title and description for Sure Rails app multi-arch image - Dynamically annotate version when tag builds are triggered * chore(ci): add nightly tag with weekday pattern to tag config * fix(ci): allow publish workflow to push images from main branch - Update conditional checks to include refs/heads/main - Reflect new condition in workflow comments for clarity * fix(ci): set image version label only for tag builds in metadata * fix(ci): avoid quotations being passed as CLI argument Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Himank Dave <93311724+steadyfall@users.noreply.github.com> * refactor(ci): remove deprecated `::set-output` command Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Himank Dave <93311724+steadyfall@users.noreply.github.com> --------- Signed-off-by: Himank Dave <93311724+steadyfall@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/publish.yml | 44 ++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8ec574744..cc7427dec 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,12 +1,13 @@ # Reference: https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners # Conditions for pushing the image to GHCR: +# - Triggered by push to default branch (`main`) # - Triggered by push to a version tag (`v*`) # - Triggered by a scheduled run # - Triggered manually via `workflow_dispatch` with `push: true` # # Conditional expression: -# startsWith(github.ref, 'refs/tags/v') || github.event_name == 'schedule' || github.event.inputs.push +# github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') || github.event_name == 'schedule' || github.event.inputs.push name: Publish Docker image @@ -84,6 +85,7 @@ jobs: BASE_CONFIG="type=sha,format=long" if [[ $GITHUB_EVENT_NAME == "schedule" ]]; then BASE_CONFIG+=$'\n'"type=schedule,pattern=nightly" + BASE_CONFIG+=$'\n'"type=schedule,pattern=nightly-{{date 'ddd'}}" elif [[ "$GITHUB_REF" == refs/tags/v* ]]; then BASE_CONFIG="type=semver,pattern={{version}}" BASE_CONFIG+=$'\n'"type=raw,value=stable" @@ -94,6 +96,10 @@ jobs: echo EOF } >> $GITHUB_ENV + - name: Get current date (RFC 3339 format) + id: date + run: echo "date=$(date -Iseconds)" >> $GITHUB_OUTPUT + - name: Extract metadata for Docker id: meta uses: docker/metadata-action@v5.6.0 @@ -101,6 +107,13 @@ jobs: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} flavor: latest=false tags: ${{ env.TAGS_SPEC }} + labels: | + org.opencontainers.image.version=${{ startsWith(github.ref, 'refs/tags/v') && github.ref_name || '' }} + org.opencontainers.image.created=${{ steps.date.outputs.date }} + org.opencontainers.image.ref.name=${{ github.ref_name }} + org.opencontainers.image.vendor=we-promise + org.opencontainers.image.title=Sure + org.opencontainers.image.description=A multi-arch Docker image for the Sure Rails app - name: Publish 'linux/${{ matrix.platform }}' image by digest uses: docker/build-push-action@v6.16.0 @@ -119,7 +132,7 @@ jobs: outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},name-canonical=true,push-by-digest=true,oci-mediatypes=true - name: Export the Docker image digest - if: ${{ startsWith(github.ref, 'refs/tags/v') || github.event_name == 'schedule' || github.event.inputs.push }} + if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') || github.event_name == 'schedule' || github.event.inputs.push }} run: | mkdir -p "${RUNNER_TEMP}"/digests echo "${DIGEST#sha256:}" > "${RUNNER_TEMP}/digests/digest-${PLATFORM}" @@ -128,7 +141,7 @@ jobs: PLATFORM: ${{ matrix.platform }} - name: Upload the Docker image digest - if: ${{ startsWith(github.ref, 'refs/tags/v') || github.event_name == 'schedule' || github.event.inputs.push }} + if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') || github.event_name == 'schedule' || github.event.inputs.push }} uses: actions/upload-artifact@v4.6.2 with: name: digest-${{ matrix.platform }} @@ -138,7 +151,7 @@ jobs: merge: name: Merge multi-arch manifest & push multi-arch tag - if: ${{ startsWith(github.ref, 'refs/tags/v') || github.event_name == 'schedule' || github.event.inputs.push }} + if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') || github.event_name == 'schedule' || github.event.inputs.push }} needs: [build] timeout-minutes: 60 @@ -182,10 +195,29 @@ jobs: image_args+=("${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:$(<"${DIGESTS_DIR}/digest-${PLATFORM}")") done + annotations=( + "index:org.opencontainers.image.created=$(date -Iseconds)" + 'index:org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}' + 'index:org.opencontainers.image.revision=${{ github.sha }}' + 'index:org.opencontainers.image.ref.name=${{ github.ref_name }}' + 'index:org.opencontainers.image.vendor=we-promise' + 'index:org.opencontainers.image.licenses=AGPL-3.0' + 'index:org.opencontainers.image.title=Sure' + 'index:org.opencontainers.image.description=A multi-arch Docker image for the Sure Rails app' + ) + annotation_args=() + for annotation in "${annotations[@]}"; do + annotation_args+=("--annotation=${annotation}") + done + if [[ $GITHUB_REF_TYPE == "tag" ]]; then + annotation_args+=("--annotation=index:org.opencontainers.image.version=$GITHUB_REF_NAME") + fi + attempts=0 until docker buildx imagetools create \ - --annotation "index:org.opencontainers.image.description=A multi-arch Docker image for the Sure Rails app" \ - "${tag_args[@]}" "${image_args[@]}" \ + "${annotation_args[@]}" \ + "${tag_args[@]}" \ + "${image_args[@]}" \ ; do attempts=$((attempts + 1)) if [[ $attempts -ge 3 ]]; then