From c3e04d9b731cfc64a016ce8a12675f5361457d58 Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Mon, 14 Sep 2026 13:22:33 +1000 Subject: [PATCH] chore: release v0.28.1 Patch release: sync mode fires only for PRs merged into the default branch (#308). CHANGELOG promoted, version bumped, .dev/STATE.md and a log entry record the jb2 incident and the tidy-up. Co-Authored-By: Claude Fable 5.1 --- .dev/STATE.md | 13 ++++++++++++- .dev/log/2026-09-14-jb2-sync-fallout.md | 14 ++++++++++++++ CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 .dev/log/2026-09-14-jb2-sync-fallout.md diff --git a/.dev/STATE.md b/.dev/STATE.md index a02b740..fe4135b 100644 --- a/.dev/STATE.md +++ b/.dev/STATE.md @@ -1,4 +1,4 @@ -verified: 2026-09-03 +verified: 2026-09-14 # STATE @@ -7,6 +7,17 @@ Roadmap detail lives in the work-plan tracker **#257**, not here (PLAN.md predat ## In flight +- **v0.28.1 release cut 2026-09-14** (#308 `aae38d1`) — patch: sync mode fires only for PRs + merged into the default branch. Trigger: QuantEcon/lecture-python-programming#629 (theme + v3.0.0) merged into the long-lived `jb2` branch on 2026-09-12 and all three deployed sync + workflows fired — `types: [closed]` has no base-branch filter and neither the job `if:` + nor the action looked at the base — opening fr#79, fa#166, zh-cn#105 for unpublished + content. Two-layer fix: `branches: [main]` in every published sync template (sweep test + now requires it) + `mergedIntoDefaultBranch` in `validatePREvent` and the resync path, + compared against `repository.default_branch`. Tidy-up outside the repo, same day: the + three downstream PRs closed unmerged; `branches: [main]` PR'd into the deployed workflows + (lecture-python-programming ×3, lecture-python-intro, lecture-python.myst). §4a gate + status is recorded on the release PR. W1 (#259) still targets v0.29.0. - **v0.28.0 released 2026-09-03** (#303 `07e7c64`; release #304 `9284fbc`; §4a gate **completed**: 84/84 sync runs, 28/28 delivery + 28/28 stamped verdicts per lane; `@v0` = `v0.28` = `9284fbc`, smoke-verified on all three lanes) — headline: the diff --git a/.dev/log/2026-09-14-jb2-sync-fallout.md b/.dev/log/2026-09-14-jb2-sync-fallout.md new file mode 100644 index 0000000..c5b953e --- /dev/null +++ b/.dev/log/2026-09-14-jb2-sync-fallout.md @@ -0,0 +1,14 @@ +# 2026-09-14 — a merge into `jb2` fired every sync workflow; v0.28.1 + +**Trigger**: QuantEcon/lecture-python-programming#629 (theme v3.0.0 migration) merged into the long-lived `jb2` branch on 2026-09-12 05:08 UTC. All three sync workflows ran (fa/fr/zh-cn, `pull_request` event, success) and opened lecture-python-programming.fr#79, .fa#166, .zh-cn#105 — translation PRs for content the English edition does not publish. + +**Cause**: the published sync workflow triggers on `pull_request: types: [closed]` with no `branches:` filter, so it fires for a PR closed against any base; the job `if:` checks only `merged == true`; the action never read `base.ref`. Every deployed copy had the shape because every doc page copied it from an older one (#192's lesson, again). + +**Done** (#308, merged `aae38d1`) +- `branches: [main]` in every published sync trigger: README, `examples/` ×2, quickstart, action-reference ×2, three tutorials, the scaffolder in `setup.ts`, the E2E harness template. `workflow-templates.test.ts` now requires `on.pull_request.branches == ['main']` on every sync job it sweeps. +- `mergedIntoDefaultBranch` (`src/inputs.ts`): base ref vs `repository.default_branch`; used in `validatePREvent` (pull_request path) and in `runSync` after `pulls.get` (resync path — an `issue_comment` trigger cannot carry a branch filter). Unknown default branch or base ref warns and proceeds. Copilot's three comments adopted (`d0b0a6c`): default-branch wording in README/quickstart; `validatePREvent` returns as soon as a closed PR is found unmerged, so the PRODUCTION log no longer follows "Skipping sync". +- Release v0.28.1 (this log's day): CHANGELOG promoted, version bumped, STATE updated. + +**Tidy-up outside the repo**: fr#79 / fa#166 / zh-cn#105 closed unmerged with a note; `branches: [main]` PRs opened in lecture-python-programming (3 workflows), lecture-python-intro, lecture-python.myst. The harness source repo (test-translation-sync) re-renders from the template on the next run and needs no PR. + +**Gate**: §4a on `v0.28.1` per the checklist; tally recorded on the release PR. Note for the tally: the harness fires the `labeled` trigger on open fixture PRs against `main`, so the new filter is exercised on every run — a lane that fails to start is the filter misbehaving, not the fixture. diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c06c43..21c53ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.28.1] - 2026-09-14 + ### Fixed - **Sync mode fires only for PRs merged into the default branch** (surfaced by QuantEcon/lecture-python-programming#629): the published sync workflow triggered on `pull_request: types: [closed]` with no `branches:` filter, and the job's `merged == true` guard never looked at the base branch — so a theme-migration PR merged into the long-lived `jb2` branch was forwarded to every target repo, opening translation PRs in lecture-python-programming.fr, .fa and .zh-cn for content the English edition does not publish. Two fixes, both needed. Every published copy of the sync trigger — README, `examples/`, quickstart, action-reference, the three tutorials, the scaffolder in `src/cli/commands/setup.ts`, and the E2E harness template — now carries `branches: [main]`, which stops the run before it starts. And the action itself skips a merged PR whose base branch is not the repository's default branch, on both the `pull_request` path and the `\translate-resync` path: an `issue_comment` trigger cannot carry a branch filter, and deployed workflows copied before this change carry none, so the in-action check is the backstop for both. The comparison is against `repository.default_branch`, not a hard-coded `main`, so a `master` edition is unaffected; an unreadable default branch or base ref warns and proceeds rather than silencing production on an unfamiliar payload. The workflow-template sweep in `workflow-templates.test.ts` now requires the filter on every sync job it finds, so a doc page added later is covered the day it lands. Deployed source repos still need the one-line workflow edit — this ships the template and the backstop. diff --git a/package-lock.json b/package-lock.json index e255ea2..f9b914d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "action-translation", - "version": "0.28.0", + "version": "0.28.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "action-translation", - "version": "0.28.0", + "version": "0.28.1", "license": "MIT", "dependencies": { "@actions/core": "^2.0.3", diff --git a/package.json b/package.json index 9ba2fe9..c1db162 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "action-translation", - "version": "0.28.0", + "version": "0.28.1", "private": true, "type": "module", "description": "GitHub Action to sync and review translations across repositories",