name: Finalise Release Tags on: workflow_dispatch: inputs: version: description: Release version, for example 0.25.81 required: true type: string release_branch: description: Release PR branch. Defaults to the version with dots replaced by underscores. required: false type: string expected_head_sha: description: Full head commit SHA reviewed in the release PR required: true type: string prerelease: description: Mark the GitHub Release as a pre-release required: false type: boolean default: false publish_cli: description: Create the CLI tag and publish its container image required: false type: boolean default: true jobs: finalise: runs-on: ubuntu-latest environment: release permissions: actions: write contents: write steps: - name: Resolve release branch id: branch env: VERSION: ${{ inputs.version }} RELEASE_BRANCH_INPUT: ${{ inputs.release_branch }} run: | set -euo pipefail BRANCH="${RELEASE_BRANCH_INPUT}" if [[ -z "${BRANCH}" ]]; then BRANCH="${VERSION//./_}" fi echo "name=${BRANCH}" >> "$GITHUB_OUTPUT" - uses: actions/checkout@v4 with: ref: ${{ steps.branch.outputs.name }} fetch-depth: 0 - name: Use Node.js uses: actions/setup-node@v4 with: node-version: "24.x" - name: Validate release head env: VERSION: ${{ inputs.version }} EXPECTED_HEAD_SHA: ${{ inputs.expected_head_sha }} PRERELEASE: ${{ inputs.prerelease }} PUBLISH_CLI: ${{ inputs.publish_cli }} run: | set -euo pipefail ACTUAL_HEAD_SHA="$(git rev-parse HEAD)" if [[ "${ACTUAL_HEAD_SHA}" != "${EXPECTED_HEAD_SHA}" ]]; then echo "Release branch head is ${ACTUAL_HEAD_SHA}, expected ${EXPECTED_HEAD_SHA}." >&2 exit 1 fi if [[ "${VERSION}" == *-* && "${PRERELEASE}" != "true" ]]; then echo "Version ${VERSION} is a pre-release version, but prerelease was not enabled." >&2 exit 1 fi if [[ "${VERSION}" != *-* && "${PRERELEASE}" == "true" && "${PUBLISH_CLI}" == "true" ]]; then echo "A stable version staged as a pre-release must use publish_cli=false so that the CLI latest and major-minor image tags do not advance before BRAT validation." >&2 exit 1 fi node utils/release-notes.mjs validate "${VERSION}" - name: Ensure and push release tags env: VERSION: ${{ inputs.version }} EXPECTED_HEAD_SHA: ${{ inputs.expected_head_sha }} PUBLISH_CLI: ${{ inputs.publish_cli }} run: | set -euo pipefail git fetch --tags --force if [[ "${PUBLISH_CLI}" == "true" ]]; then node utils/release-tags.mjs ensure "${VERSION}" "${EXPECTED_HEAD_SHA}" git push --atomic origin "refs/tags/${VERSION}" "refs/tags/${VERSION}-cli" else node utils/release-tags.mjs ensure "${VERSION}" "${EXPECTED_HEAD_SHA}" --plugin-only git push origin "refs/tags/${VERSION}" fi - name: Dispatch release workflows env: GH_TOKEN: ${{ github.token }} VERSION: ${{ inputs.version }} PRERELEASE: ${{ inputs.prerelease }} run: | set -euo pipefail gh workflow run release.yml \ --ref "${VERSION}" \ --field tag="${VERSION}" \ --field draft=true \ --field prerelease="${PRERELEASE}" - name: Summarise next steps env: VERSION: ${{ inputs.version }} PRERELEASE: ${{ inputs.prerelease }} PUBLISH_CLI: ${{ inputs.publish_cli }} run: | { echo "Ensured the plug-in tag \`${VERSION}\` points to the reviewed release commit." if [[ "${PUBLISH_CLI}" == "true" ]]; then echo "The CLI tag \`${VERSION}-cli\` was also created; its tag event starts the container workflow." else echo "CLI publication was omitted." fi echo "" echo "Dispatched the plug-in release workflow for \`${VERSION}\`. After approval for the release environment, it creates a draft GitHub Release." echo "" if [[ "${VERSION}" == *-* ]]; then echo "Publish the draft as a pre-release without replacing the latest stable release." echo "Keep the release pull request in draft and unmerged after BRAT validation; close it only through a separate maintainer action." elif [[ "${PRERELEASE}" == "true" ]]; then echo "Publish the draft initially as a pre-release without replacing the latest stable release." echo "After BRAT validation, remove the pre-release designation and make this exact release the latest stable release before merging the release pull request." echo "Create the stable CLI tag and publish its latest and major-minor image tags through a separate maintainer gate." else echo "Publish the draft as the latest stable release, keep the release pull request in draft, and merge only after BRAT validation succeeds." fi } >> "$GITHUB_STEP_SUMMARY"