Skip to content

feat: create GitHub releases from the changelog during npm publish - #261

Merged
tonyketcham merged 1 commit into
mainfrom
stack/tonyketcham/feat/bundle-github-npm-release/create-github-releases-changelog-npm-publish--88ddb9fb
Aug 22, 2026
Merged

feat: create GitHub releases from the changelog during npm publish#261
tonyketcham merged 1 commit into
mainfrom
stack/tonyketcham/feat/bundle-github-npm-release/create-github-releases-changelog-npm-publish--88ddb9fb

Conversation

@tonyketcham

@tonyketcham tonyketcham commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

The 1.0.1 packages reached npm without a GitHub release or release notes.
pnpm publish:ci now owns both halves of the release so that step cannot be
missed.

Before npm publication, the script checks the clean tree, a non-empty committed
changelog section, GitHub access, the pushed commit, and the remote tag. After
every public package is on npm, it creates and pushes the annotated
v<version> tag and creates the GitHub release from that version's
CHANGELOG.md section. Retries skip an existing GitHub release only when its
body matches those filed notes.

pnpm publish:dry runs the same readiness gates without writing. Bump and
changelog commands distinguish moved notes from an empty version placeholder.
The release policy and its reversal criteria are recorded in Proof.

Test plan

  • Focused AVA tests for bump, changelog, and publish behavior
  • pnpm typecheck
  • pnpm verify

Co-authored-by: Cursor cursoragent@cursor.com

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit df2e76c. Configure here.

Comment thread scripts/publish.ts
@mergify

mergify Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@cursor
cursor Bot requested review from odama626 and toeknee-figma August 22, 2026 19:14

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

I left a non-blocking comment and assigned reviewers. Cursor Bugbot found one unresolved high-severity issue on the publish path, so I did not approve.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@tonyketcham
tonyketcham force-pushed the stack/tonyketcham/feat/bundle-github-npm-release/create-github-releases-changelog-npm-publish--88ddb9fb branch from df2e76c to 04f20ca Compare August 22, 2026 19:14
@tonyketcham

tonyketcham commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator Author

Revision history

# Type Changes Reason Date
1 initial df2e76c 2026-08-22 19:14 UTC
2 content df2e76c → 04f20ca (raw) Prepend the Flatbread mark and versioned Release Notes title to every GitHub release. 2026-08-22 19:14 UTC
3 content 04f20ca → 21094d1 (raw) Push the annotated v* tag to origin before gh release create --verify-tag. 2026-08-22 19:17 UTC
4 content 21094d1 → 3999dfb (raw) Address review: make dry-run gates fail honestly, preflight remote tags before npm, tighten GitHub 404 handling, replace the live changelog test, and record the release policy in Proof. 2026-08-22 19:34 UTC
5 content 3999dfb → 6602314 (raw) Follow-up audit: reject empty changelog sections, verify existing GitHub release bodies against filed notes, and include the synced Proof manifest in release staging docs. 2026-08-22 19:39 UTC
6 content 6602314 → 95b85ca (raw) Address review: report an empty changelog version heading as a placeholder instead of claiming Unreleased notes moved, with explicit state and tests. 2026-08-22 20:00 UTC

@tonyketcham
tonyketcham force-pushed the stack/tonyketcham/feat/bundle-github-npm-release/create-github-releases-changelog-npm-publish--88ddb9fb branch from 04f20ca to 21094d1 Compare August 22, 2026 19:17
cursor[bot]
cursor Bot approved these changes Aug 22, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I approved. The prior Bugbot high-severity finding on the publish path is resolved, and no approval policy requires human review. Reviewers were already assigned, so I did not assign more.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Reviewed the PR-only range (210a9ee...21094d1). This is not a dependency-only update.

pnpm publish:ci now files notes from CHANGELOG, publishes npm, writes the annotated v* tag, pushes that tag, then runs gh release create --verify-tag. The Bugbot finding (tag never pushed before --verify-tag) is fixed on this sync. Changelog/publish AVA tests: 33 passed.

I am not requesting changes. The remaining items are medium: dry-run can look green when a real run would stop; GitHub "missing release" matching is looser than the npm 404 classifier; the first write of origin's tag still happens after npm; one test pins live CHANGELOG bullets; and the new one-step npm + GitHub rule has no Proof Decision (the lockstep-version Constraint does not cover it).

Architecture COMMENT · quality COMMENT · Proof journal COMMENT · correctness COMMENT (one HIGH downgraded: post-npm tag push is the safer order and can retry; preflight the remote tag before npm rather than blocking the merge).

Open in Web View Automation 

Sent by Cursor Automation: Flatbread PR Review

Comment thread scripts/publish.ts Outdated
Comment thread scripts/publish.ts Outdated
Comment thread scripts/publish.ts Outdated
Comment thread scripts/utils/changelog.test.ts Outdated
Comment thread CONTRIBUTING.md

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Independent review of 21094d1 (PR-only slice vs 210a9ee). Not a dependency-only update. Architecture and Proof journal: no merge gap. The Bugbot high-severity hole is closed: pushReleaseTag runs git push origin refs/tags/<tag> before gh release create --verify-tag.

Lockstep still holds. assertLockstepVersions yields one version; githubReleaseTag builds one v* tag; bump and changelog:shift may write CHANGELOG.md; publish:ci only accepts a committed ## <version> section. GitHub release after every public package is on npm matches the “together” step. Retry stays coherent: already-published packages skip; an existing GitHub release skips.

Two medium notes before the first real publish:ci under this flow (inlines). Residual, not blocking: classifyGhReleaseView treats Not Found / HTTP 404 as create — after assertCommitOnGithub that is almost always a missing release, which is what gh release view prints. Quality cleanups (fold npm error flattening into collectErrorDetails, one applyChangelogShift helper, compute formatted notes once) can wait.

Proof journal is absent. That is acceptable here: CONTRIBUTING.md and the scripts already carry the unique signal. If someone journals later, an accepted Decision deriving from con-public-npm-releases-use-one-lockstep-version with rejectSiblings: false is enough.

Checks: pnpm exec ava scripts/publish.test.ts scripts/changelog.test.ts scripts/utils/changelog.test.ts — 33 passed.

Open in Web View Automation 

Sent by Cursor Automation: Flatbread PR Review

Comment thread scripts/utils/changelog.test.ts Outdated
Comment thread scripts/publish.ts Outdated
@tonyketcham
tonyketcham force-pushed the stack/tonyketcham/feat/bundle-github-npm-release/create-github-releases-changelog-npm-publish--88ddb9fb branch 2 times, most recently from 3999dfb to 6602314 Compare August 22, 2026 19:39
cursor[bot]
cursor Bot approved these changes Aug 22, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Reviewed the PR-only range (210a9ee...6602314). This is not a dependency-only update.

Every standing item from 21094d1 is fixed. publish:dry now throws on the same clean-tree, changelog, gh, pushed-commit, remote-tag, and npm gates as publish:ci. classifyGhReleaseView treats only release not found or an HTTP 404 as create. git ls-remote checks the release tag before any npm publish. The live CHANGELOG.md AVA fixture is gone. Accepted Decision dec-create-changelog-backed-github-releases-in-publi--fh6bsn7jr296q93d records the one-step npm + GitHub rule, derives from the lockstep-version Constraint, and was accepted without closing other proposed Decisions in that Effort.

The release order still holds: hard gates, then the npm loop, then an annotated v* tag push only when the remote tag is absent, then gh release create --verify-tag. A retry skips already-published packages and skips a GitHub release only when its body matches the filed notes.

Architecture APPROVE. Proof journal APPROVE. Quality leftover LOW (duplicate error flattening; two changelog prepare passes). Correctness leftover LOW: pnpm bump can still write an empty ## <version> when Unreleased has no list items; publish then rejects that section before npm (fail-closed). Changelog and publish AVA: 41 passed.

I am not requesting changes.

Open in Web View Automation 

Sent by Cursor Automation: Flatbread PR Review

Comment thread scripts/bumpVersions.ts Outdated
@tonyketcham
tonyketcham force-pushed the stack/tonyketcham/feat/bundle-github-npm-release/create-github-releases-changelog-npm-publish--88ddb9fb branch from 6602314 to 95b85ca Compare August 22, 2026 19:59
The 1.0.1 packages reached npm without a GitHub release or release notes.
`pnpm publish:ci` now owns both halves of the release so that step cannot be
missed.

Before npm publication, the script checks the clean tree, a non-empty committed
changelog section, GitHub access, the pushed commit, and the remote tag. After
every public package is on npm, it creates and pushes the annotated
`v<version>` tag and creates the GitHub release from that version's
`CHANGELOG.md` section. Retries skip an existing GitHub release only when its
body matches those filed notes.

`pnpm publish:dry` runs the same readiness gates without writing. Bump and
changelog commands distinguish moved notes from an empty version placeholder.
The release policy and its reversal criteria are recorded in Proof.

## Test plan
- [x] Focused AVA tests for bump, changelog, and publish behavior
- [x] `pnpm typecheck`
- [x] `pnpm verify`

Change-Id: I88ddb9fb57904be037d03501f77f3d161d20c5f3
Co-authored-by: Cursor <cursoragent@cursor.com>
cursor[bot]
cursor Bot approved these changes Aug 22, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the PR-only range (210a9ee...95b85ca). This is not a dependency-only update.

The leftover LOW from 6602314 is fixed. PreparedChangelog.didMoveItems now splits “heading created” from “list items moved.” pnpm bump and pnpm changelog:shift warn on an empty ## <version> placeholder. prepareReadyReleaseChangelog still rejects that empty section before npm.

Architecture and Proof journal: no merge gap. The accepted Decision dec-create-changelog-backed-github-releases-in-publi--fh6bsn7jr296q93d still matches HEAD: one publish:ci step, filed CHANGELOG notes, npm then tag/GitHub, dry-run hard gates, idempotent retry, rejectSiblings: false.

One new LOW honesty gap remains (inline). When ## <version> already exists and is empty, changelog:shift prints a green ready line and the synthetic Release X.Y.Z. body. Publish still fail-closes, so this cannot ship empty GitHub notes.

Focused AVA: 41/41 on scripts/publish.test.ts, scripts/changelog.test.ts, and scripts/utils/changelog.test.ts.

Open in Web View Automation 

Sent by Cursor Automation: Flatbread PR Review

Comment thread scripts/changelog.ts
Comment on lines +70 to +78
if (!prepared.didShift) {
console.log(
colors
.bold()
.green(
`CHANGELOG.md already has ## ${version}; Unreleased has no items to move`
)
);
printNotes(prepared.notes, version);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOW, not blocking: when ## <version> already exists with an empty body, prepareReleaseChangelog returns didShift: false and notes: fallbackReleaseNotes(version) (Release ${version}.). This branch then prints a green “already has” line and those synthetic notes.

publish:ci still rejects the empty section, so empty GitHub notes cannot ship. An operator who only runs changelog:shift / --dry-run can still treat that printed body as ready.

Use the same yellow empty-section warning as the new-heading path (didShift && !didMoveItems just below), and skip printing fallback notes until the section has real list items.

@tonyketcham
tonyketcham merged commit 6afafc1 into main Aug 22, 2026
21 of 39 checks passed
@tonyketcham
tonyketcham deleted the stack/tonyketcham/feat/bundle-github-npm-release/create-github-releases-changelog-npm-publish--88ddb9fb branch August 22, 2026 23:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant