Repository navigation
feat(release): wire per-package release-please with npm publish and changelogs - #39
Merged
Merged
Conversation
…nitial changelogs
… workflows and tests
…ign sq-tasks hero Rewrite the initial 0.1.0 entries in 7 package changelogs so they read as product feature/fix history (install from source, tool suite additions, sq-* naming) instead of vendor transitions, keeping real dates and commit links. Redesign the sq-tasks hero: replace the unit-patch star and the order-of-battle/diamond marker with a completed-task product mark and a source-of-truth header.
This was referenced Aug 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Revision round 2 of PR #39 (runecraftai/squad): commander review feedback on the npm-publishing/changelog PR, applied on the existing branch sq/squad-npm-release-changelogs (PR stays the same, no new branch/PR). (1) The packages//CHANGELOG.md files must NEVER mention vendor transitions - the initial 0.1.0 entries in fob, pr-review, sq-browser, sq-gh, sq-quota, sq-report, and sq-tasks that carried vendor history were rewritten in product-feature language (what the package does for the user: features, fixes, ergonomics), keeping the real dates, issue links, and commit links and the release-please format; the drill changelog already had no vendor wording; scan all 8 changelogs for any other vendor wording and clean it too. (2) The sq-tasks hero (packages/sq-tasks/assets/readme/hero.svg) was redesigned clean and product-focused: the 'order of battle' label and the diamond target/map-marker over it are removed, the military star-in-ring unit patch is replaced with a completed-task checkbox product mark, the message is a backlog that stays human-editable while agents edit it (byte-exact round-trip, TOON output), no military jargon and no target icons, SVG stays accessible (title/desc, alt text) and consistent with how packages/sq-tasks/README.md embeds it. (3) Re-validate via drill on the same PR; the PR description publish-name decision text was checked and the only adjustment needed was rewording 'fob installs via the vendored go build' to 'fob installs via a source build' - the publish-name decision itself (bare sq- npm names, @runecraft/pr-review scoped, drill/fob not published to npm) is unchanged. Acceptance: no vendor wording in any packages/*/CHANGELOG.md; hero has no order-of-battle or target/diamond marker; PR #39 updated on the same branch with drill re-validation green on the new head; bin/sq-lint.sh and bin/sq-doc-audience-check.sh pass.
What Changed
.github/workflows/release.ymlrunning one release-please stream per package (drill, fob, pr-review, sq-browser, sq-gh, sq-quota, sq-report, sq-tasks): merged release PRs create GitHub releases/tags and publish the JS packages to npm viaNPM_TOKEN(gated onreleases_created == 'true'and OIDC provenance); Go binaries (drill, fob) get releases/tags only.CHANGELOG.mdfiles for all 8 packages written in product-feature language, registered them aspublic-productindocs/documentation-audiences.json, and re-keyed each package'srelease-please-config.json/.release-please-manifest.jsonto package-relative paths with a pinnedbootstrap-sha.ci.yml,drill-required.yml,guard-generated-files.ymlplus their exclusion tests andsq-tasks/scripts/guard-generated-files.sh) to exclude the package-relative release-please outputs; switched sq-browser, sq-gh, and sq-quota builds fromprepublishOnlytoprepack, added therepositoryfield to pr-review'spackage.jsonand rewrote itsRELEASING.mdfor the monorepo pipeline; redesignedpackages/sq-tasks/assets/readme/hero.svgwith a completed-task checkbox mark and "source of truth" wording, removing the order-of-battle label, map-marker/diamond target, and star-in-ring patch while keeping accessible title/desc.Risk Assessment
✅ Low: All prior error/warning findings (F5 publish gating, F1 bootstrap-sha, F2 re-keying) are verified fixed and durable; remaining items are informational only, and the change is well-bounded release wiring with internally consistent configs, workflows, and tests.
Testing
Exercised the full intent end-to-end on the new head bf2d1e2: scanned all 8 changelogs (0 vendor mentions, format/date/link integrity vs real history), diffed and pixel-verified the redesigned sq-tasks hero (checkbox mark, no order-of-battle/target iconography, accessible title/desc matching README alt), ran both acceptance scripts (sq-lint exit 0, doc-audience ok 179 surfaces), and ran the targeted release-pipeline suites (drill/fob Go, pr-review bun, sq-report node, sq-* vitest incl. release-ci-exclusions, guard-generated-files, and the round-trip/TOON suites backing the hero's claims) — all green after fixing a missing-deps environment gap with bun install; PR #39 was confirmed open on the correct branch with the reworded 'source build' text, though its GitHub head (0b6dea7) still predates the two newest local commits, whose push/re-validation belongs to the outer executor's later phases. Overall result: pass, no product defects found.
/tmp/drill-evidence/01KZZVWSBEN4263T1S780TDNQ4/sq-tasks-hero.png)Evidence: Vendor wording scan across all 8 packages/*/CHANGELOG.md (0 matches)
Source: Vendor wording scan across all 8 packages/*/CHANGELOG.md (0 matches) (local file:
/tmp/drill-evidence/01KZZVWSBEN4263T1S780TDNQ4/changelog-vendor-scan.txt)Evidence: Acceptance scripts
Pipeline
Updates from git push drill
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
packages/pr-review/release-please-config.json:3- First release-please run will regenerate vendor-wording changelog entries, defeating the intent's durable 'CHANGELOG.md files must NEVER mention vendor transitions' requirement. Concrete path: merging this PR pushes conventional commits touching all 8 package dirs to main, triggering .github/workflows/release.yml. No tags exist yet, so needsBootstrap=true; the configured bootstrap-sha b9b62811 (pr-review, line 3) and 9f5dc949 (sq-quota, line 3) are not in this repo's history (repo starts at squashed import 7a63db7), and the other 6 packages set no bootstrap-sha at all. The commit walk never hits the sha, so commitsAfterSha(commits, '') returns the full history and the first release PR changelogs will include 'feat: vendor M6 toolchain packages and rename tasks-axi to sq-tasks (feat: vendor M6 toolchain packages and rename tasks-axi to sq-tasks #2)' (774b6bf, touches all 6 npm packages), 'feat: rebrand vendored tool names to sq-* across packages (feat: rebrand vendored tool names to sq-* across packages #14)' (39bb7bb), and 'chore: reset workspace packages to clean 0.1.0 baseline and unvendor pr-review (chore: reset workspace packages to clean 0.1.0 baseline and unvendor pr-review #16)' (fd4f9b9, touches all 8) - the exact vendor wording the head commit removed by hand. Recommended earliest supported boundary: point each package's bootstrap-sha at a commit that exists in this repo and postdates the vendor-wording commits (e.g. the release-wiring commit 7171571 or branch base 01d7ad2) so generated changelogs truncate before those subjects. Note sq-quota CONTRIBUTING.md explicitly documents keeping the inherited out-of-history bootstrap-sha, so this challenges documented author intent.packages/sq-browser/test/release-ci-exclusions.test.ts:34- Release-output drift guard is now vacuous: this branch re-keyed the release-please configs from '.' to 'packages/<name>', but sq-browser, sq-gh, sq-quota, and sq-tasks release-ci-exclusions.test.ts still read config.packages?.["."] (line 34), which no longer exists, so they silently pass via the ?? {} fallback while asserting root-relative paths (CHANGELOG.md, package.json, .release-please-manifest.json) that no longer match where the pipeline writes (packages/<name>/...). sq-report's test was only half-updated: the key is now packages/sq-report (line 18) but it still derives unprefixed paths. The updated AGENTS.md files for these packages claim the test 'derives that set from release-please-config.json and fails if a workflow drifts' - that guarantee is broken. (The package-local workflows these tests validate are only executed by GitHub at the repo root, so no runtime impact today; drill/fob were fully re-keyed in both workflows and tests, making the sq-* treatment inconsistent.).github/workflows/release.yml:37- cancel-in-progress: true on the release concurrency group can abort a run after release-please has created the GitHub release/tag but before the npm publish step completes (e.g. a second push to main). The next run sees the tag already present, releases_created is false, and the publish step is skipped, leaving a released version never published; recovery is a manual npm publish. Consider cancel-in-progress: false (queue) or a publish-time guard that checks whether the version is already on npm.packages/pr-review/release-please-config.json:7- package-name is still 'pi-pr-review' (the upstream component name). The npm name is @runecraft/pr-review (package.json) and tags are bare v<version> (include-component-in-tag: false), but the component flows into release PR titles via pull-request-title-pattern (release${component} ${version}) and release metadata, so release PRs will read 'release pi-pr-review 0.1.1'. Cosmetic naming inconsistency with the publish-name decision; consider 'pr-review' or dropping the override.🔧 Fix: Fix bootstrap-sha and re-key sq-* release exclusion guards
2 issues (1 error, 1 info) still open:
.github/workflows/release.yml:49- The publish-side steps are gated with bareif: ${{ steps.release.outputs.releases_created }}(lines 49, 51, 55, 60). googleapis/release-please-action@v4 always sets this output to the string 'true'/'false' (never unset:core.setOutput('releases_created', releases.length > 0)in src/index.ts of v4.0.0/v4.1.1), and GitHub coerces any non-empty string - including the string 'false' - to true in anif:conditional (documented falsy set isfalse, 0, -0, "", '', null; empirically confirmed by release-please-action issues #912/#965, fix: evaluate output of release-please correctly supabase/supabase-py#1259, fix(ci): gate release-please publish on releases_created == 'true' TightknitAI/slack-hono#35). So on EVERY push to main the step runs: on the first push (release-please only opens bootstrap release PRs; no release is cut, output is 'false') it executesnpm publishfor all 6 npm packages, publishing the manifest version 0.1.0 to npm before any release PR if NPM_TOKEN exists (bypassing the release-PR process the workflow comments describe), and every subsequent ordinary push fails the job with 'You cannot publish over the previously published versions' (or E401 when NPM_TOKEN is absent). Since release.yml has no pull_request trigger it will not be exercised by this PR's CI. Fix: useif: ${{ steps.release.outputs.releases_created == 'true' }}on all four steps.packages/sq-browser/AGENTS.md:28- The 'so release PRs create zero runs' claims added/kept in this branch's AGENTS.md files (sq-browser:28, sq-gh:26, sq-quota:63, sq-tasks:89, drill) describe package-local .github/workflows/*.yml, but GitHub Actions only executes workflows under the repo-root .github/workflows - nested ones are inert. The root .github/workflows/ci.yml has no paths-ignore and no bot-author exclusion, so release-please PRs (authored by github-actions[bot]) will trigger the full root suite (lint + all test lanes + go/node builds) on every release PR, and the extensive package-local exclusion machinery has no runtime effect. Cost/accuracy gap only, not a correctness blocker; the drill-required root job does skip bot-authored PRs.🔧 Fix: Gate release publish steps on releases_created == 'true
2 infos still open:
packages/sq-tasks/assets/readme/hero.svg:5- The redesigned hero's accessibility desc reads 'A backlog.md document shows queued and done tasks with checkboxes, headed source of truth; ...' — 'checkboxes, headed source of truth' is broken copy, most likely a typo for 'the source of truth' (or 'the headed source of truth'). Introduced by 0b6dea7. The intent requires the SVG to stay accessible (title/desc/alt); the desc exists but is grammatically garbled. Trivial follow-up copy fix; not a blocker..github/workflows/release.yml:68- On the first drill release, this workflow creates an empty draft GitHub release + tag (drill's config sets draft: true and force-tag-creation: true) and skips the publish step ('No npm package for drill'), but nothing attaches binaries: the signing/build pipeline that drill's AGENTS.md:235 calls 'Mechanics live in packages/drill/.github/workflows/release.yml' is a nested workflow that GitHub Actions never executes, so it cannot upload assets. The draft will stay empty (and force-tag-creation keeps consuming versions on later bumps) until an operator uploads assets manually. The workflow header comment discloses the draft intent, and the inertness pre-dates this branch, so this is a documented gap rather than a regression — flagging for awareness..github/workflows/release.yml:1- PR feat(release): wire per-package release-please with npm publish and changelogs #39 on GitHub currently points at head 0b6dea7 (CI all green there); the local target head bf2d1e2 carries two additional commits (09059c3 bootstrap-sha fix, bf2d1e2 releases_created=='true' gating) that are not yet pushed, so PR re-validation on the new head happens in the outer executor's push/CI phases. All local tests of bf2d1e2 pass; PR description already contains the required 'fob installs via a source build' wording and no 'vendored go build' text.grep -rniE "vendor|vendored" packages/*/CHANGELOG.md-> 0 matches across all 8 changelogs; regression proven: 7171571 carried 'vendored fob'/'vendor M6 toolchain'/'unvendor' wording, 0b6dea7 rewrote in product languagegit diff 01d7ad2..bf2d1e2 -- packages/sq-tasks/assets/readme/hero.svg-> star-in-ring unit patch -> completed-task checkbox, 'order of battle'+diamond map-marker -> 'source of truth'; grep for order of battle/target/diamond/map-marker/unit/insignia/star/battle -> cleanrsvg-convert -w 1200 packages/sq-tasks/assets/readme/hero.svg-> 1200x380 PNG with 1608 colors and rendered checkbox mark (evidence artifact)bin/sq-lint.sh-> exit 0 (no changed canonical-set shell targets; the one changed .sh, packages/sq-tasks/scripts/guard-generated-files.sh, is outside the canonical set by design)bin/sq-doc-audience-check.sh-> 'ok surfaces=179 local_links=248' exit 0go test ./...in packages/drill -> ok, incl. new TestReleaseWorkflowBuildStartsOnlyWhenReleaseIsCreated (bf2d1e2 releases_created=='true' gating) and TestReleasePleaseConfigCreatesDrafts/ForcesTagCreationgo test . -run Release -vin packages/fob -> 2 PASS (TestPullRequestWorkflowsExcludeReleasePleaseOutputs, TestExpectedReleaseOutputsIncludesConfiguredExtraFiles)bun test tests/release-version.test.tsin packages/pr-review -> 6 pass (package's declared runner is bun, not node);node scripts/verify-release-version.mjs-> 'Verified root release version 0.1.0'node --test test/package-json.test.js test/release-ci-exclusions.test.jsin packages/sq-report afterbun install(missing node_modules was an env gap, not a code failure) -> 16 passvitesttest/release-ci-exclusions.test.ts-> sq-browser 6/6, sq-gh 4/4, sq-quota 3/3; sq-tasks 4/4 +test/workflows/guard-generated-files.test.ts6/6vitesttest/backends/markdown.test.ts test/format.test.tsin packages/sq-tasks -> 78 pass (byte-exact render(parse(src))===src round-trip and TOON output the hero advertises)gh pr view 39 --repo runecraftai/squad-> PR OPEN on sq/squad-npm-release-changelogs, description contains 'fob installs via a source build' and no 'vendored go build', publish-name decision unchanged, head 0b6dea7 with all checks SUCCESS; mergeablegit cat-file -efor all 13 commit SHAs cited in changelogs -> all present in real history✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.