From 494b5474a13c4dd763b66c4183aa1f110837207e Mon Sep 17 00:00:00 2001 From: Christian Bager Bach Houmann Date: Sat, 11 Jul 2026 19:45:00 +0200 Subject: [PATCH] feat(release)!: resolve the toolkit from the reusable workflow's own commit --- .github/workflows/release-prepare.yml | 16 ++++---------- .github/workflows/release-validate.yml | 16 ++++---------- .github/workflows/release.yml | 21 +++++++------------ README.md | 20 +++++++++++------- templates/README.md | 2 +- .../caller-workflows/release-prepare.yml | 3 +-- .../caller-workflows/release-trigger.yml | 3 +-- templates/caller-workflows/release.yml | 3 +-- 8 files changed, 32 insertions(+), 52 deletions(-) diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml index 8163da8..6c317c1 100644 --- a/.github/workflows/release-prepare.yml +++ b/.github/workflows/release-prepare.yml @@ -60,16 +60,6 @@ on: description: "GitHub App id (a repository variable value) for the release bot." type: string required: true - workflows-repository: - description: "Repository holding the release toolkit scripts." - type: string - required: false - default: chhoumann/obsidian-plugin-workflows - workflows-ref: - description: "Ref of workflows-repository to check out. Keep in sync with the uses: pin." - type: string - required: false - default: v3 dry-run: description: "Plan only: compute version + notes, skip opening a PR." type: boolean @@ -194,8 +184,10 @@ jobs: steps.classify.outputs.release-commit == 'false' uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - repository: ${{ inputs.workflows-repository }} - ref: ${{ inputs.workflows-ref }} + # The reusable workflow's own commit: toolkit scripts always come + # from exactly the ref the caller pinned in `uses:`. + repository: ${{ job.workflow_repository }} + ref: ${{ job.workflow_sha }} path: .release-toolkit persist-credentials: false diff --git a/.github/workflows/release-validate.yml b/.github/workflows/release-validate.yml index 17ada0a..01788e2 100644 --- a/.github/workflows/release-validate.yml +++ b/.github/workflows/release-validate.yml @@ -57,16 +57,6 @@ on: type: string required: false default: release.yml - workflows-repository: - description: "Repository holding the release toolkit scripts." - type: string - required: false - default: chhoumann/obsidian-plugin-workflows - workflows-ref: - description: "Ref of workflows-repository to check out. Keep in sync with the uses: pin." - type: string - required: false - default: v3 permissions: {} @@ -91,8 +81,10 @@ jobs: - name: Checkout release toolkit uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - repository: ${{ inputs.workflows-repository }} - ref: ${{ inputs.workflows-ref }} + # The reusable workflow's own commit: toolkit scripts always come + # from exactly the ref the caller pinned in `uses:`. + repository: ${{ job.workflow_repository }} + ref: ${{ job.workflow_sha }} path: .release-toolkit persist-credentials: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 37a3c86..e28ff5b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -91,16 +91,6 @@ on: type: string required: false default: "" - workflows-repository: - description: "Repository holding the release toolkit scripts." - type: string - required: false - default: chhoumann/obsidian-plugin-workflows - workflows-ref: - description: "Ref of workflows-repository to check out. Keep in sync with the uses: pin." - type: string - required: false - default: v3 secrets: slack-webhook: description: "Optional Slack incoming webhook for the notify job." @@ -313,8 +303,10 @@ jobs: - name: Checkout release toolkit uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: - repository: ${{ inputs.workflows-repository }} - ref: ${{ inputs.workflows-ref }} + # The reusable workflow's own commit: toolkit scripts always come + # from exactly the ref the caller pinned in `uses:`. + repository: ${{ job.workflow_repository }} + ref: ${{ job.workflow_sha }} path: .release-toolkit persist-credentials: false @@ -737,9 +729,10 @@ jobs: GH_TOKEN: ${{ github.token }} SOURCE_REF: ${{ needs.resolve.outputs.source-ref }} RELEASE_ASSETS: ${{ inputs.release-assets }} - WORKFLOWS_REPOSITORY: ${{ inputs.workflows-repository }} + SIGNER_REPOSITORY: ${{ job.workflow_repository }} + SIGNER_PATH: ${{ job.workflow_file_path }} run: | - SIGNER_WORKFLOW="github.com/${WORKFLOWS_REPOSITORY}/.github/workflows/release.yml" + SIGNER_WORKFLOW="github.com/${SIGNER_REPOSITORY}/${SIGNER_PATH}" echo "$RELEASE_ASSETS" | jq -r '.[]' | while IFS= read -r ASSET; do [ -z "$ASSET" ] && continue gh attestation verify "release-payload/$ASSET" \ diff --git a/README.md b/README.md index ae1b914..dc9685c 100644 --- a/README.md +++ b/README.md @@ -159,7 +159,9 @@ trigger + `uses:`; all logic lives in the reusables here. A caller stub sets the token ceiling with a top-level or per-job `permissions:` that grants the union its reusable needs; the reusable scopes each job down from -there. Copy the stubs, pin `@v3`, and set `workflows-ref: v3` to match the pin. +there. Copy the stubs and pin `@v4`; the toolkit scripts are checked out from +the reusable workflow's own commit (`job.workflow_repository` / +`job.workflow_sha`), so the `uses:` ref is the single version pin. ### Inputs @@ -173,7 +175,6 @@ Shared across all three reusables: | `default-branch` | `master` | Branch release PRs target. | | `package-manager` | `npm` | `npm` or `pnpm`; drives the release-file set (npm syncs `package-lock.json`, pnpm has no lockfile in the set). | | `release-bot-app-slug` | (required) | App slug; the expected bot login is `[bot]`. | -| `workflows-repository` / `workflows-ref` | `chhoumann/obsidian-plugin-workflows` / `v3` | Where and at what ref the release toolkit scripts are checked out. | `release-prepare.yml` adds: `target-sha` (empty = default-branch head), `node-version`, `release-policy` (below), `app-id` (a repo **variable** value), @@ -300,6 +301,12 @@ workflow state. release** as above. Re-running an already-published version is safe: the publisher verifies the existing release byte-for-byte and finishes without mutating it. +- **A release cut under an older `release-policy`** (e.g. before chore commits + stopped releasing) fails the release stage's plan recompute with "Release + plan version is none" - fail-closed, since the current policy would never + have produced that version. To rebuild such a release, temporarily set the + `release-policy` in the release stub to the rules that were in force when it + was cut. ### Migration checklist (release pipeline) @@ -314,10 +321,9 @@ workflow state. `package-manager`, `release-policy`, `default-branch`, `node-version`, `release-bot-app-slug`, `release-assets` (add `styles.css` if the plugin ships one), and `verify-commands` to match the repo's scripts. - - **Two pins move together:** the `uses: ...@v3` ref and the `workflows-ref` - input on all three stubs both select this repo's version - bump them in - lockstep (Dependabot bumps the `uses:` pin; update `workflows-ref` to - match). + - **One pin:** the `uses: ...@v4` ref selects this repo's version for the + workflow AND its toolkit scripts (checked out from the reusable workflow's + own commit), so Dependabot SHA bumps are always self-consistent. - **If the default branch is not `master`,** the literal appears in **five places** across the three stubs: the `default-branch:` input in all three, plus the `if:` gate in `release-prepare.yml` (`head_branch == 'master'`) and @@ -354,7 +360,7 @@ kept fresh by Dependabot in the source repos and reused here verbatim: | `rtCamp/action-slack-notify` | v2.4.0 | `33ca3be66c6f378fe1610fd1d5258632dbed5e58` | Add this repo's `github-actions` ecosystem to each consumer's Dependabot so the -`@v1`/`@v2`/SHA pins here get bumped like any other action. +`@v1`/`@v4`/SHA pins here get bumped like any other action. ## Templates diff --git a/templates/README.md b/templates/README.md index c863d0c..4adc751 100644 --- a/templates/README.md +++ b/templates/README.md @@ -57,7 +57,7 @@ deps) match the Conventional Commit types the release toolkit expects. Add extra ## `caller-workflows/` Minimal stubs that consume the reusable workflows in this repo. Copy each into -your repo's `.github/workflows/` and pin `@v1`/`@v3` (or a commit SHA). They +your repo's `.github/workflows/` and pin `@v1`/`@v4` (or a commit SHA). They encode the triggers that CANNOT live in the reusable workflow. CI and quality: diff --git a/templates/caller-workflows/release-prepare.yml b/templates/caller-workflows/release-prepare.yml index 32035a5..ff2bbd0 100644 --- a/templates/caller-workflows/release-prepare.yml +++ b/templates/caller-workflows/release-prepare.yml @@ -41,7 +41,7 @@ jobs: permissions: contents: write pull-requests: write - uses: chhoumann/obsidian-plugin-workflows/.github/workflows/release-prepare.yml@v3 + uses: chhoumann/obsidian-plugin-workflows/.github/workflows/release-prepare.yml@v4 with: plugin-name: podnotes package-manager: npm @@ -53,7 +53,6 @@ jobs: target-sha: ${{ github.event.workflow_run.head_sha || inputs.targetSha }} release-bot-app-slug: podnotes-release-bot app-id: ${{ vars.RELEASE_APP_ID }} - workflows-ref: v3 # dry-run: true # plan only; skip opening the PR (smoke test) secrets: release-app-private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} diff --git a/templates/caller-workflows/release-trigger.yml b/templates/caller-workflows/release-trigger.yml index 964598f..e245898 100644 --- a/templates/caller-workflows/release-trigger.yml +++ b/templates/caller-workflows/release-trigger.yml @@ -41,7 +41,7 @@ jobs: actions: write contents: write pull-requests: read - uses: chhoumann/obsidian-plugin-workflows/.github/workflows/release-validate.yml@v3 + uses: chhoumann/obsidian-plugin-workflows/.github/workflows/release-validate.yml@v4 with: pr-number: ${{ github.event.pull_request.number || inputs.pr-number }} plugin-name: podnotes @@ -49,4 +49,3 @@ jobs: default-branch: master release-bot-app-slug: podnotes-release-bot release-workflow: release.yml - workflows-ref: v3 diff --git a/templates/caller-workflows/release.yml b/templates/caller-workflows/release.yml index 669894c..2ed40ca 100644 --- a/templates/caller-workflows/release.yml +++ b/templates/caller-workflows/release.yml @@ -30,7 +30,7 @@ jobs: contents: write id-token: write pull-requests: read - uses: chhoumann/obsidian-plugin-workflows/.github/workflows/release.yml@v3 + uses: chhoumann/obsidian-plugin-workflows/.github/workflows/release.yml@v4 with: release-pr: ${{ inputs.releasePr }} plugin-name: podnotes @@ -50,7 +50,6 @@ jobs: setup-python: true python-version: "3.x" docs-requirements: docs/requirements.txt - workflows-ref: v3 secrets: # Optional: unset secrets resolve to '' and the notify job skips them. slack-webhook: ${{ secrets.SLACK_WEBHOOK }}