chore(release): v1.2.0 #56
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 & publish images | |
| # Builds the agent and controller images and pushes them to GitHub Container | |
| # Registry (ghcr.io/<owner>/cbm-agent and cbm-controller). | |
| # | |
| # Production images are tied to releases via their version tag: pushing a vX.Y.Z | |
| # tag (which every GitHub Release carries) builds and pushes :X.Y.Z, :X.Y and | |
| # :latest. Pushes to main (no release) only move a rolling :edge tag, so :latest | |
| # never changes under users until a new release is cut. The workflow_dispatch | |
| # "version" input rebuilds a past release (e.g. 1.0.0) on demand: it checks out | |
| # that version's tag but runs this (main) workflow. | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ["v*"] | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Rebuild this released version, e.g. 1.0.0 (blank = build the selected branch)." | |
| required: false | |
| default: "" | |
| jobs: | |
| images: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: cbm-agent | |
| dockerfile: Dockerfile.agent | |
| - name: cbm-controller | |
| dockerfile: Dockerfile.controller | |
| steps: | |
| - name: Resolve build ref | |
| id: ref | |
| run: | | |
| if [ -n "${{ github.event.inputs.version }}" ]; then | |
| echo "checkout=refs/tags/v${{ github.event.inputs.version }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "checkout=${{ github.ref }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ steps.ref.outputs.checkout }} | |
| - name: Log in to ghcr.io | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Compute image tags | |
| id: meta | |
| run: | | |
| IMAGE="ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/${{ matrix.name }}" | |
| VERSION="${{ github.event.inputs.version }}" | |
| REF="${{ github.ref }}" | |
| if [ -z "$VERSION" ] && [[ "$REF" == refs/tags/v* ]]; then | |
| VERSION="${REF#refs/tags/v}" | |
| fi | |
| if [ -n "$VERSION" ]; then | |
| # A release version: :X.Y.Z, :X.Y and :latest. | |
| TAGS="$IMAGE:$VERSION,$IMAGE:${VERSION%.*},$IMAGE:latest" | |
| elif [ "$REF" = "refs/heads/main" ]; then | |
| # No release: only the rolling :edge tag. | |
| TAGS="$IMAGE:edge" | |
| else | |
| TAGS="$IMAGE:${GITHUB_REF_NAME//\//-}" | |
| fi | |
| TAGS="$TAGS,$IMAGE:sha-${GITHUB_SHA::7}" | |
| echo "tags=$TAGS" >> "$GITHUB_OUTPUT" | |
| echo "Tags -> $TAGS" | |
| - name: Build & push | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ${{ matrix.dockerfile }} | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| # After a version tag's images are published, append a pull/Images section to | |
| # that release's notes (once, idempotently). Only runs for vX.Y.Z tags and is | |
| # a no-op if there is no matching release yet. | |
| release-notes: | |
| needs: images | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Add Images section to the release notes | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION="${GITHUB_REF_NAME#v}" | |
| OWNER="${GITHUB_REPOSITORY_OWNER,,}" | |
| # The release is often created around the same time as the tag push; | |
| # retry a few times so a transient API miss doesn't skip the append. | |
| BODY=""; found="" | |
| for i in $(seq 1 6); do | |
| if BODY="$(gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --json body --jq .body)"; then found=1; break; fi | |
| echo "Release $GITHUB_REF_NAME not visible yet (attempt $i) — retrying in 10s…" | |
| sleep 10 | |
| done | |
| [ -n "$found" ] || { echo "No release for $GITHUB_REF_NAME — skipping."; exit 0; } | |
| case "$BODY" in | |
| *"<!-- cbm:images -->"*) echo "Images section already present — skipping."; exit 0 ;; | |
| esac | |
| cat > /tmp/images.md <<'EOF' | |
| <!-- cbm:images --> | |
| ### Images | |
| Published to the GitHub Container Registry — also tagged `:__MM__` and `:latest`: | |
| ```sh | |
| docker pull ghcr.io/__OWNER__/cbm-controller:__VERSION__ | |
| docker pull ghcr.io/__OWNER__/cbm-agent:__VERSION__ | |
| ``` | |
| - 📦 [cbm-controller](https://github.com/__REPO__/pkgs/container/cbm-controller) | |
| - 📦 [cbm-agent](https://github.com/__REPO__/pkgs/container/cbm-agent) | |
| EOF | |
| sed -i "s|__VERSION__|$VERSION|g; s|__MM__|${VERSION%.*}|g; s|__OWNER__|$OWNER|g; s|__REPO__|$GITHUB_REPOSITORY|g" /tmp/images.md | |
| { printf '%s\n' "$BODY"; cat /tmp/images.md; } > /tmp/body.md | |
| gh release edit "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --notes-file /tmp/body.md | |
| echo "Appended Images section to $GITHUB_REF_NAME." |