|
5 | 5 | branches: [master] |
6 | 6 | pull_request: |
7 | 7 | branches: [master] |
8 | | - # Manual re-run from the Actions tab / `gh workflow run`. Runs lint + test only; |
9 | | - # the release job is gated to `push` events, so a manual run never publishes. |
| 8 | + # Manual re-run from the Actions tab / `gh workflow run`. Left blank it runs lint |
| 9 | + # + test only; set `force_version` to (re)publish that exact version — use it to |
| 10 | + # release a version a failed/blocked run skipped (e.g. the master-ruleset reject). |
10 | 11 | workflow_dispatch: |
| 12 | + inputs: |
| 13 | + force_version: |
| 14 | + description: "Force a release at this exact version (e.g. 0.3.0). Blank = lint+test only, no publish." |
| 15 | + required: false |
| 16 | + default: "" |
11 | 17 |
|
12 | 18 | # Cancel superseded PR runs, but never interrupt a master run (it may publish). |
13 | 19 | concurrency: |
@@ -62,25 +68,33 @@ jobs: |
62 | 68 | publish: |
63 | 69 | name: release & publish |
64 | 70 | needs: [lint, test] |
65 | | - if: github.event_name == 'push' && github.ref == 'refs/heads/master' |
| 71 | + if: >- |
| 72 | + (github.event_name == 'push' && github.ref == 'refs/heads/master') || |
| 73 | + (github.event_name == 'workflow_dispatch' && github.event.inputs.force_version != '') |
66 | 74 | runs-on: ubuntu-latest |
67 | 75 | permissions: |
68 | 76 | contents: write # push the version-bump commit + tag |
69 | 77 | steps: |
70 | 78 | - uses: actions/checkout@v4 |
71 | 79 | with: |
72 | 80 | fetch-depth: 0 # full history + tags, for the semantic version bump |
| 81 | + # Push the release commit + tag as an admin PAT so it satisfies the |
| 82 | + # `master` ruleset; the default GITHUB_TOKEN can't be granted a bypass. |
| 83 | + token: ${{ secrets.RELEASE_PAT }} |
73 | 84 |
|
74 | 85 | - uses: dtolnay/rust-toolchain@stable |
75 | 86 |
|
76 | 87 | - uses: Swatinem/rust-cache@v2 |
77 | 88 |
|
78 | | - # Decide the next version from conventional commits since the last tag; if |
79 | | - # there is one, bump + commit + tag it, push to master, and publish the |
80 | | - # crates (in dependency order, skipping any already on crates.io). A no-op |
81 | | - # when no release-worthy commit landed. The release commit is pushed with |
82 | | - # GITHUB_TOKEN and carries [skip ci], so it does not re-trigger CI. |
| 89 | + # Decide the next version from conventional commits since the last tag (or |
| 90 | + # use force_version on a manual dispatch); if there is one, bump + commit + |
| 91 | + # tag it, push to master, and publish the crates (in dependency order, |
| 92 | + # skipping any already on crates.io). A no-op when no release-worthy commit |
| 93 | + # landed. The release commit is pushed with RELEASE_PAT (an admin token, so |
| 94 | + # it satisfies the master ruleset) and carries [skip ci], so it does not |
| 95 | + # re-trigger CI. |
83 | 96 | - name: Release & publish |
84 | 97 | env: |
85 | 98 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} |
| 99 | + FORCE_VERSION: ${{ github.event.inputs.force_version }} |
86 | 100 | run: bash scripts/release.sh |
0 commit comments