From 6636d104c8bcb60cc0281b039af52f13a55c9b14 Mon Sep 17 00:00:00 2001 From: "liquan.eth" Date: Wed, 28 Oct 2026 22:52:04 +0900 Subject: [PATCH] ci(release): run releases as mega-gutenberg on the shared route-based flow The shared release actions at @main moved the pipeline to the release App mega-gutenberg (megaeth-labs/.github #55, #56, #57), which broke this repo's callers: the 2.1.0 candidate dispatch failed with "bump_command needs a separate dependency_token", and the cut (PR-closed, mega-maxwell author filter, no commit input) and the direct settle mode were removed upstream. - release-candidate.yml / release-settle.yml: re-rendered from the shared templates (Cargo.toml + toml pattern); propose keeps the Rust toolchain and passes the read-only job token as dependency_token, since every Git dependency is public. Cut now runs on the push of the merged candidate via release-route; settle opens a settle PR on the release-v* push and publishes when it merges (or on a versioned dispatch, behind `release`). - release-publish.yml: removed; release-settle's publish job replaces it. - app-token-lint.yml: added from the shared template. - claude.yml: the Maxwell review token lists its permissions (lint L6). - on-release.yml, ci-credentials.md, CHANGELOG header: describe the new flow. Co-Authored-By: Claude Opus 5.5 --- .github/ci-credentials.md | 10 +- .github/workflows/app-token-lint.yml | 27 ++++ .github/workflows/claude.yml | 3 + .github/workflows/on-release.yml | 11 +- .github/workflows/release-candidate.yml | 172 ++++++++++++++++++++---- .github/workflows/release-publish.yml | 56 -------- .github/workflows/release-settle.yml | 157 ++++++++++++++++----- CHANGELOG.md | 2 +- 8 files changed, 317 insertions(+), 121 deletions(-) create mode 100644 .github/workflows/app-token-lint.yml delete mode 100644 .github/workflows/release-publish.yml diff --git a/.github/ci-credentials.md b/.github/ci-credentials.md index 1920a6a3..a9d652cb 100644 --- a/.github/ci-credentials.md +++ b/.github/ci-credentials.md @@ -5,11 +5,17 @@ The Git dependencies in the current lockfile are public; Cargo does not need a P | Configuration | Scope | Consumer | | --- | --- | --- | -| `MEGA_MAXWELL_CLIENT_ID` variable | Organization | Release candidate, settle, publish, and PR review App tokens | -| `MEGA_MAXWELL_PK` secret | Organization | Same App-token jobs | +| `MEGA_GUTENBERG_CLIENT_ID` variable | Organization | Release App (mega-gutenberg) tokens in `release-candidate.yml` and `release-settle.yml`, the only release identity | +| `MEGA_GUTENBERG_PK` secret | Organization, access granted to this repository | Same release App-token jobs | +| `MEGA_MAXWELL_CLIENT_ID` variable | Organization | PR review App token (CI App, mega-maxwell); never used by a release workflow | +| `MEGA_MAXWELL_PK` secret | Organization | Same PR review job | | `CLAUDE_CODE_OAUTH_TOKEN` secret | Organization | Claude workflows | | `CODECOV_TOKEN` secret | Repository | Coverage report upload | | `GCP_AUTH_KEY` secret | `publish` environment | Release binary upload to Artifact Registry | +| `release` environment | Repository | Gates release-settle's publish job (annotated tag and GitHub Release); required reviewer, deployment policy for `main`, `release-v*` and `v*` tags | + +The release flow's dependency token for `cargo update --workspace` is the read-only job token, which is enough while every Git dependency stays public. +`app-token-lint.yml` enforces the App-token rules (which App may mint what, and where) on every workflow change. Claude jobs rely on the [pinned action's credential replacement](https://github.com/anthropics/claude-code-action/blob/5ef2e550a465a721f4f45e4a7d3c340c873e1dcc/src/github/operations/git-config.ts), which removes checkout's authorization header and configures Git with the action's own token before Claude starts. In `interactive`, that write token remains in the origin URL in `.git/config` while `Bash(cargo:*)` is allowed, so a build script or proc-macro from a PR branch could read it; `persist-credentials: false` alone would not remove this risk. diff --git a/.github/workflows/app-token-lint.yml b/.github/workflows/app-token-lint.yml new file mode 100644 index 00000000..7f50cbc8 --- /dev/null +++ b/.github/workflows/app-token-lint.yml @@ -0,0 +1,27 @@ +name: App Token Lint + +# Fails a pull request that mints a GitHub App token the wrong way: a CI-app +# token with write permissions it must not have, the CI app in a release +# workflow, or a release-app (mega-gutenberg) token outside the `release` +# environment. Read-only; no secrets. The rules are listed in the guide. +# +# Guide: https://github.com/megaeth-labs/.github/blob/main/.github/actions/app-token-lint/README.md + +on: + pull_request: + paths: [".github/workflows/**"] + push: + branches: [main] + +permissions: + contents: read + +jobs: + app-token-lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + persist-credentials: false + + - uses: megaeth-labs/.github/.github/actions/app-token-lint@main diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 68a2615e..011ff01f 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -90,6 +90,9 @@ jobs: private-key: ${{ secrets.MEGA_MAXWELL_PK }} owner: megaeth-labs repositories: stateless-validator + permission-contents: read + permission-pull-requests: write + permission-issues: write - uses: actions/checkout@v4 with: diff --git a/.github/workflows/on-release.yml b/.github/workflows/on-release.yml index 46b89b60..79eac646 100644 --- a/.github/workflows/on-release.yml +++ b/.github/workflows/on-release.yml @@ -2,8 +2,9 @@ name: On Release # Publish target for a stateless-validator release: the two binaries as # downloads on the GitHub Release page, with a SHA256SUMS file. Runs when the -# release pipeline publishes the Release (release-settle creates it right -# after the tag), and on demand for a rehearsal on a tag ref: +# release pipeline publishes the Release (release-settle's publish job creates +# it right after the tag, as the release app mega-gutenberg), and on demand for +# a rehearsal on a tag ref: # gh workflow run on-release.yml --ref vX.Y.Z -f dry_run=true # The tag being released is always the run's own ref; there is no tag input. # @@ -11,9 +12,9 @@ name: On Release # workflow from the tagged commit's tree, not from the default branch, and the # tag sits on the release branch. A branch cut from a default branch that has # this file carries it; a branch cut before it landed needs it cherry-picked -# (via its own PR — the `release-*` ruleset requires one) before release-settle -# is dispatched, or the Release publishes with nothing attached and no failed -# run; release-settle warns when the tip lacks a workflow main has. +# (via its own PR — the `release-*` ruleset requires one) before the settle PR +# is merged, or the Release publishes with nothing attached and no failed run; +# release-settle warns when the settled commit lacks a workflow main has. # A rehearsal likewise only works on a tag whose tree has this file. # # Targets, fed by one build so the Release page and the registry carry the diff --git a/.github/workflows/release-candidate.yml b/.github/workflows/release-candidate.yml index 5ae78f2f..b1376c93 100644 --- a/.github/workflows/release-candidate.yml +++ b/.github/workflows/release-candidate.yml @@ -2,14 +2,24 @@ name: Release Candidate # Trunk-first release start. Dispatch with a version: the shared action bumps # the version file on the default branch, drafts the changelog entry, and -# opens a candidate PR. When that -# PR merges, the `cut` job creates `release-vX.Y.Z` at the merge commit. No -# tag is created here — see release-settle / release-publish. +# opens a candidate PR. When that PR merges, the push to the default branch +# starts this workflow again: `route` recognises the merged candidate PR and +# `cut` creates `release-vX.Y.Z` at the merge commit. No tag is created here; +# see release-settle. # # To release a commit that is not the tip of the default branch, dispatch with # `base_commit` as well: `propose` creates `release-vX.Y.Z` at that commit and # aims the candidate PR at it, so that PR never touches the default branch and -# the `cut` job below does not run. +# `route` never selects `cut` for it. +# +# Every write is made by the release GitHub App (mega-gutenberg). Store +# MEGA_GUTENBERG_CLIENT_ID as an organization variable and MEGA_GUTENBERG_PK +# as an organization secret with access granted to this repository. +# Branch and PR jobs need no environment; tagging and +# publishing are review-gated in release-settle. `route` is read-only and uses +# the job token. +# +# Guide: https://github.com/megaeth-labs/.github/blob/main/.github/actions/RELEASE.md on: workflow_dispatch: @@ -23,8 +33,7 @@ on: required: false type: string default: "" - pull_request: - types: [closed] + push: branches: [main] permissions: @@ -34,9 +43,9 @@ jobs: propose: if: github.event_name == 'workflow_dispatch' # One proposal at a time: two dispatches would race on the candidate - # branch. Job-level, not workflow-level: every PR closing on the default - # branch also starts this workflow, and a workflow-wide group would let - # that noise evict a queued release run (one pending run per group). + # branch. Job-level, not workflow-level: every push to the default branch + # also starts this workflow, and a workflow-wide group would let that + # noise evict a queued release run (one pending run per group). # A skipped job holds no slot in a job-level group. concurrency: group: ${{ github.workflow }}-propose @@ -44,16 +53,22 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 - id: app-token + id: release-token with: - client-id: ${{ vars.MEGA_MAXWELL_CLIENT_ID }} - private-key: ${{ secrets.MEGA_MAXWELL_PK }} + client-id: ${{ vars.MEGA_GUTENBERG_CLIENT_ID }} + private-key: ${{ secrets.MEGA_GUTENBERG_PK }} + owner: megaeth-labs + repositories: stateless-validator + permission-contents: write + permission-pull-requests: write + permission-workflows: write - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 persist-credentials: false + # The bump command runs cargo. - uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1 with: cache: false @@ -61,7 +76,7 @@ jobs: - uses: megaeth-labs/.github/.github/actions/release-candidate@main with: stage: propose - token: ${{ steps.app-token.outputs.token }} + token: ${{ steps.release-token.outputs.token }} version: ${{ inputs.version }} base_commit: ${{ inputs.base_commit }} version_file: Cargo.toml @@ -69,14 +84,118 @@ jobs: changelog_file: CHANGELOG.md # Cargo.lock carries the workspace crate versions too. bump_command: cargo update --workspace + # Every Git dependency in Cargo.lock is public (see + # .github/ci-credentials.md), so the read-only job token is enough; + # it never sees the release token. + dependency_token: ${{ github.token }} + + # Only trunk candidates follow trunk pushes; base_commit candidates belong + # to their release branch and must never pick up changes from trunk. + refresh-candidates: + if: github.event_name == 'push' && github.ref_name == github.event.repository.default_branch + runs-on: ubuntu-latest + permissions: + pull-requests: read + outputs: + prs: ${{ steps.candidates.outputs.prs }} + steps: + - id: candidates + env: + GH_TOKEN: ${{ github.token }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + run: | + prs="$(gh api --method GET --paginate --slurp \ + "repos/$GITHUB_REPOSITORY/pulls" \ + -f state=open -f base="$DEFAULT_BRANCH" -f per_page=100 \ + --jq '[.[][] | select(.head.ref | startswith("chore/release-candidate-")) | select(.head.repo.full_name == .base.repo.full_name) | .number]')" + echo "prs=$(jq -c . <<< "$prs")" >> "$GITHUB_OUTPUT" + + refresh: + needs: refresh-candidates + if: needs.refresh-candidates.outputs.prs != '[]' + strategy: + fail-fast: false + matrix: + pr: ${{ fromJSON(needs.refresh-candidates.outputs.prs) }} + concurrency: + group: ${{ github.workflow }}-refresh-${{ matrix.pr }} + cancel-in-progress: false + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + steps: + # Recheck after queueing: a candidate may have closed or changed base + # while another refresh held its concurrency slot. + - id: candidate + env: + GH_TOKEN: ${{ github.token }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + PR_NUMBER: ${{ matrix.pr }} + run: | + version="$(gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" \ + --jq 'select(.state == "open") | select(.base.ref == env.DEFAULT_BRANCH) | select(.head.repo.full_name == .base.repo.full_name) | .head.ref | select(startswith("chore/release-candidate-")) | ltrimstr("chore/release-candidate-")')" + echo "version=$version" >> "$GITHUB_OUTPUT" + + - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 + if: steps.candidate.outputs.version != '' + id: release-token + with: + client-id: ${{ vars.MEGA_GUTENBERG_CLIENT_ID }} + private-key: ${{ secrets.MEGA_GUTENBERG_PK }} + owner: megaeth-labs + repositories: stateless-validator + permission-contents: write + permission-pull-requests: write + permission-workflows: write + + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + if: steps.candidate.outputs.version != '' + with: + fetch-depth: 0 + persist-credentials: false + + - uses: megaeth-labs/.github/.github/actions/release-candidate@main + if: steps.candidate.outputs.version != '' + with: + stage: refresh + token: ${{ steps.release-token.outputs.token }} + version: ${{ steps.candidate.outputs.version }} + pr_number: ${{ matrix.pr }} + version_file: Cargo.toml + version_pattern: toml + changelog_file: CHANGELOG.md + + # Read-only: decides from the pushed commit whether it is a merged candidate + # PR that targeted the default branch. One proposed with `base_commit` merges + # into the release branch propose already cut, and routes to nothing here. + route: + if: github.event_name == 'push' + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + action: ${{ steps.route.outputs.action }} + commit: ${{ steps.route.outputs.commit }} + pr_number: ${{ steps.route.outputs.pr_number }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + fetch-depth: 0 + persist-credentials: false + + - id: route + uses: megaeth-labs/.github/.github/actions/release-route@main + with: + kind: candidate + version_file: Cargo.toml + version_pattern: toml cut: - if: >- - github.event_name == 'pull_request' && - github.event.pull_request.merged == true && - startsWith(github.event.pull_request.head.ref, 'chore/release-candidate-') && - github.event.pull_request.user.login == 'mega-maxwell[bot]' - # One cut at a time, never cancelled: pull_request.closed does not refire. + needs: route + if: needs.route.outputs.action == 'cut' + # One cut at a time, never cancelled: a push does not refire. # Job-level for the reason given on `propose`. concurrency: group: ${{ github.workflow }}-cut @@ -84,10 +203,15 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 - id: app-token + id: release-token with: - client-id: ${{ vars.MEGA_MAXWELL_CLIENT_ID }} - private-key: ${{ secrets.MEGA_MAXWELL_PK }} + client-id: ${{ vars.MEGA_GUTENBERG_CLIENT_ID }} + private-key: ${{ secrets.MEGA_GUTENBERG_PK }} + owner: megaeth-labs + repositories: stateless-validator + permission-contents: write + permission-pull-requests: read + permission-workflows: write - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: @@ -97,6 +221,8 @@ jobs: - uses: megaeth-labs/.github/.github/actions/release-candidate@main with: stage: cut - token: ${{ steps.app-token.outputs.token }} + token: ${{ steps.release-token.outputs.token }} + commit: ${{ needs.route.outputs.commit }} + pr_number: ${{ needs.route.outputs.pr_number }} version_file: Cargo.toml version_pattern: toml diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml deleted file mode 100644 index b5ad3e1d..00000000 --- a/.github/workflows/release-publish.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Release Publish - -# Publishes a settled release when its settle PR merges into the release -# branch: annotated tag at the merge commit (once) and a GitHub Release with -# the changelog section as notes. Merging the settle PR is the release approval (the -# `release-*` branch ruleset requires a reviewed PR), so no environment gate -# is needed; add the CI app as a bypass actor on the `v*` tag ruleset. -# -# This file must exist on the release branch (it does, when the branch is cut -# from a default branch that has it). -# -# Only settlement by PR reaches this workflow. release-settle.yml settles -# directly (`settle_mode: direct`, gated by the `release` environment) and -# publishes from its own job, so nothing here fires unless this repo goes -# back to PR mode; the job gate rejects any settle PR the app did not open. - -on: - pull_request: - types: [closed] - branches: ["release-v*"] - -permissions: - contents: read - -jobs: - publish: - if: >- - github.event.pull_request.merged == true && - startsWith(github.event.pull_request.head.ref, 'chore/release-settle-') && - github.event.pull_request.user.login == 'mega-maxwell[bot]' - # One publish per release branch: the tag guard and the tag push are two - # steps, so a re-run must queue behind a run in flight, never overlap it. - # Job-level: other PRs closing on the release branch also start this - # workflow, and must not evict a queued publish (one pending per group). - concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.base.ref }} - cancel-in-progress: false - runs-on: ubuntu-latest - steps: - - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 - id: app-token - with: - client-id: ${{ vars.MEGA_MAXWELL_CLIENT_ID }} - private-key: ${{ secrets.MEGA_MAXWELL_PK }} - - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - with: - fetch-depth: 0 - persist-credentials: false - - - uses: megaeth-labs/.github/.github/actions/release-publish@main - with: - token: ${{ steps.app-token.outputs.token }} - version_file: Cargo.toml - version_pattern: toml - changelog_file: CHANGELOG.md diff --git a/.github/workflows/release-settle.yml b/.github/workflows/release-settle.yml index 846af37a..8347d5ba 100644 --- a/.github/workflows/release-settle.yml +++ b/.github/workflows/release-settle.yml @@ -1,51 +1,100 @@ name: Release Settle -# Settle a release candidate. Dispatch from the default branch with the -# version and the full SHA of the release-branch tip; the shared action -# verifies it, generates release notes from the commits since the previous -# tag, commits them to the changelog on the release branch, and publishes: -# annotated tag at that commit, GitHub Release with the notes (on-release.yml -# then attaches the binaries; release.yaml / release-tracing.yaml archive to -# Artifact Registry on the tag push). +# Settle a release candidate by pull request. A push to a `release-v*` branch +# starts this workflow and `route` decides what the push means: +# refresh the candidate has landed on the release branch: generate release +# notes from the commits since the previous tag and open or update +# a reviewed `chore/release-settle-vX.Y.Z` PR onto the release +# branch with the changelog entry; +# publish that settle PR was just merged: create the annotated tag at the +# merge commit and the GitHub Release with the changelog section +# as notes. +# Merging the settle PR is the release decision on push. Dispatch with `version` +# to publish a clean release branch through the review-gated `release` +# environment, or refresh it when settlement is needed. A blank version +# refreshes every eligible release branch. # -# The dispatch is the settlement decision, gated by the `release` environment -# on the job: its required reviewers approve the run before it starts, and -# its deployment branch policy allows only the default branch. The app is a -# bypass actor on the release-branch and `v*` tag rulesets, which is what -# lets the settle commit and the tag land. `settlers` (default `any`) is left -# unset: the environment's reviewers are the only gate. +# Every write is made by the release GitHub App (mega-gutenberg). Store +# MEGA_GUTENBERG_CLIENT_ID as an organization variable and MEGA_GUTENBERG_PK +# as an organization secret with access granted to this repository. +# Refresh needs no environment. Only publish uses the +# `release` environment, with required reviewers and a deployment policy for +# the default branch, `release-v*` branches and `v*` tags (artifact uploads). +# The app is a bypass actor on the `v*` tag ruleset only; the `release-*` branch +# ruleset still requires the reviewed settle PR. `route` uses the job token. +# +# This file must exist on the release branch (it does, when the branch is cut +# from a default branch that has it); a push to the branch runs the copy of +# the workflow on that branch. +# +# Guide: https://github.com/megaeth-labs/.github/blob/main/.github/actions/RELEASE.md on: + push: + branches: ["release-v*"] workflow_dispatch: inputs: version: - description: "Version to settle (X.Y.Z)" - required: true - type: string - commit: - description: "Full SHA of the release-branch tip being settled" - required: true + description: "Version to settle (X.Y.Z); blank: refresh every eligible release branch" + required: false type: string - -# One settle per version: two dispatches for the same version would race on -# the release branch. Queue, never cancel. -concurrency: - group: ${{ github.workflow }}-${{ inputs.version }} - cancel-in-progress: false + default: "" permissions: contents: read jobs: - settle: + # Read-only: classifies the push (or the dispatch) as refresh, publish or skip. + route: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + action: ${{ steps.route.outputs.action }} + settle_source: ${{ steps.route.outputs.settle_source }} + targets: ${{ steps.route.outputs.targets }} + release_branch: ${{ steps.route.outputs.release_branch }} + commit: ${{ steps.route.outputs.commit }} + pr_number: ${{ steps.route.outputs.pr_number }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + fetch-depth: 0 + persist-credentials: false + + - id: route + uses: megaeth-labs/.github/.github/actions/release-route@main + with: + kind: settle + version: ${{ inputs.version }} + version_file: Cargo.toml + version_pattern: toml + + refresh: + needs: route + if: needs.route.outputs.action == 'refresh' + strategy: + fail-fast: false + matrix: + target: ${{ fromJSON(needs.route.outputs.targets) }} + # One refresh per release branch, queued and never cancelled: two runs + # would race on the settle PR branch. + concurrency: + group: release-settle-refresh-${{ matrix.target.release_branch }} + cancel-in-progress: false runs-on: ubuntu-latest - environment: release steps: - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 - id: app-token + id: release-token with: - client-id: ${{ vars.MEGA_MAXWELL_CLIENT_ID }} - private-key: ${{ secrets.MEGA_MAXWELL_PK }} + client-id: ${{ vars.MEGA_GUTENBERG_CLIENT_ID }} + private-key: ${{ secrets.MEGA_GUTENBERG_PK }} + owner: megaeth-labs + repositories: stateless-validator + permission-contents: write + permission-pull-requests: write + permission-workflows: write - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: @@ -54,10 +103,50 @@ jobs: - uses: megaeth-labs/.github/.github/actions/release-settle@main with: - token: ${{ steps.app-token.outputs.token }} - version: ${{ inputs.version }} - commit: ${{ inputs.commit }} + token: ${{ steps.release-token.outputs.token }} + version: ${{ matrix.target.version }} + commit: ${{ matrix.target.commit }} + release_branch: ${{ matrix.target.release_branch }} + version_file: Cargo.toml + version_pattern: toml + changelog_file: CHANGELOG.md + + publish: + needs: route + # Route permits a merged settle PR on push or a clean branch on dispatch; + # both publish paths wait for the release environment's review. + if: needs.route.outputs.action == 'publish' + # One publish per release branch: the tag guard and the tag push are two + # steps, so a re-run must queue behind a run in flight, never overlap it. + concurrency: + group: release-settle-publish-${{ needs.route.outputs.release_branch }} + cancel-in-progress: false + runs-on: ubuntu-latest + environment: release + steps: + - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 + id: release-token + with: + client-id: ${{ vars.MEGA_GUTENBERG_CLIENT_ID }} + private-key: ${{ secrets.MEGA_GUTENBERG_PK }} + owner: megaeth-labs + repositories: stateless-validator + permission-contents: write + permission-pull-requests: read + permission-workflows: write + + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + with: + fetch-depth: 0 + persist-credentials: false + + - uses: megaeth-labs/.github/.github/actions/release-publish@main + with: + token: ${{ steps.release-token.outputs.token }} + commit: ${{ needs.route.outputs.commit }} + pr_number: ${{ needs.route.outputs.pr_number }} + settle_source: ${{ needs.route.outputs.settle_source || 'pr' }} + release_branch: ${{ needs.route.outputs.release_branch }} version_file: Cargo.toml version_pattern: toml changelog_file: CHANGELOG.md - settle_mode: direct diff --git a/CHANGELOG.md b/CHANGELOG.md index ed67f9c5..b616191a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to stateless-validator are recorded here, newest first. Entries are generated by the release flow from merged PR titles. -Fix wording in the release candidate PR while it is open, or, after it merges, by a PR onto the release branch before settlement is dispatched. +Fix wording in the release candidate PR while it is open, or, after it merges, in the settle PR on the release branch before it is merged. ## v2.0.20