|
| 1 | +# Release pipeline (replaces the retired semantic-release release.yml + dev-release.yml). |
| 2 | +# |
| 3 | +# Model: release-please maintains a Release PR per branch. Merging that PR is the |
| 4 | +# release gate. |
| 5 | +# - main : stable channel. Merging the Release PR cuts v<x.y.z>, updates |
| 6 | +# CHANGELOG.md + package.json, creates a GitHub release, then builds |
| 7 | +# and pushes the prod image (with :latest). |
| 8 | +# - beta : prerelease channel. Merging the Release PR cuts v<x.y.z>-beta.<n> |
| 9 | +# (prerelease config) and builds a beta image (no :latest). |
| 10 | +# |
| 11 | +# Branch selection: one workflow file lives on both branches. target-branch is |
| 12 | +# the pushed ref; config-file / manifest-file switch to the .beta variants on |
| 13 | +# the beta branch so main and beta never share release-please state. |
| 14 | +# |
| 15 | +# CI is NOT called here: it runs on the Release PR (branch protection is the |
| 16 | +# merge gate). docker-build runs post-merge, gated on release_created. |
| 17 | +name: Release Please |
| 18 | + |
| 19 | +on: |
| 20 | + push: |
| 21 | + branches: |
| 22 | + - main |
| 23 | + - beta |
| 24 | + |
| 25 | +# RELEASE_TOKEN (a PAT) is required, not the default GITHUB_TOKEN: releases and |
| 26 | +# PRs opened by GITHUB_TOKEN do not trigger downstream workflows, so CI would |
| 27 | +# never run on the Release PR. |
| 28 | +concurrency: |
| 29 | + group: release-please-${{ github.ref_name }} |
| 30 | + cancel-in-progress: false |
| 31 | + |
| 32 | +# No workflow-level grant: each job requests only what it needs (least |
| 33 | +# privilege). The docker job in particular must NOT inherit the release-please |
| 34 | +# job's write scopes. |
| 35 | +permissions: {} |
| 36 | + |
| 37 | +jobs: |
| 38 | + release-please: |
| 39 | + name: Release Please (${{ github.ref_name }}) |
| 40 | + runs-on: ubuntu-24.04 |
| 41 | + timeout-minutes: 15 |
| 42 | + permissions: |
| 43 | + contents: write # release commit, tag, GitHub release |
| 44 | + pull-requests: write # maintain the Release PR |
| 45 | + issues: write # release-please label management |
| 46 | + outputs: |
| 47 | + release_created: ${{ steps.rp.outputs.release_created }} |
| 48 | + tag_name: ${{ steps.rp.outputs.tag_name }} |
| 49 | + steps: |
| 50 | + - name: Run release-please |
| 51 | + id: rp |
| 52 | + uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1 |
| 53 | + with: |
| 54 | + token: ${{ secrets.RELEASE_TOKEN }} |
| 55 | + target-branch: ${{ github.ref_name }} |
| 56 | + config-file: ${{ github.ref_name == 'beta' && 'release-please-config.beta.json' || 'release-please-config.json' }} |
| 57 | + manifest-file: ${{ github.ref_name == 'beta' && '.release-please-manifest.beta.json' || '.release-please-manifest.json' }} |
| 58 | + |
| 59 | + docker: |
| 60 | + name: Docker |
| 61 | + needs: release-please |
| 62 | + if: needs.release-please.outputs.release_created == 'true' |
| 63 | + # Ceiling for the reusable docker-build.yml: it needs security-events:write |
| 64 | + # (Trivy SARIF upload) and id-token:write (Sigstore/attestations). Matches |
| 65 | + # the grant the retired release.yml gave this path; the release-please job's |
| 66 | + # PR/issues write scopes are deliberately NOT granted here. |
| 67 | + permissions: |
| 68 | + contents: read |
| 69 | + security-events: write |
| 70 | + id-token: write |
| 71 | + uses: ./.github/workflows/docker-build.yml |
| 72 | + with: |
| 73 | + tag-name: ${{ needs.release-please.outputs.tag_name }} |
| 74 | + is-dev-release: ${{ github.ref_name == 'beta' }} |
| 75 | + # Pass only the Docker Hub credentials, not `secrets: inherit`, so the |
| 76 | + # RELEASE_TOKEN PAT is not forwarded into the image build graph. |
| 77 | + secrets: |
| 78 | + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} |
| 79 | + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} |
0 commit comments