Repository navigation
ci: derive the release version from the changelog - #17
Merged
Merged
Conversation
Brings the release process in line with sf-formula-parser and soql-parser-js, sharing their scripts and workflows verbatim. derive-increment.mjs derives the bump from the [Unreleased] section headings of CHANGELOG.md: Breaking Changes is a major, Added and Deprecated a minor, and Changed, Removed, Fixed and Security a patch. An unrecognized heading is an error rather than a guess. npm run release starts a release from the terminal, dispatching the workflow and tailing the run; release-it moves behind release:ci. The workflow's version input accepts auto and derives the same way, so the GitHub UI path no longer needs a bump picked by hand. The release workflow authenticates with client-id instead of the deprecated app-id and derives the commit identity from the token, so release commits carry the bot's avatar. Actions are pinned to commit SHAs in both workflows, and the unused pages permission is dropped. A Changelog workflow requires an [Unreleased] entry on pull requests that touch src/, and checks that the section classifies to a bump. The skip-changelog label opts out. CI now builds before testing and runs with read-only contents permission. Requires the CLIENT_ID secret to be available to this repository.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Critical changelog parsing defects and moderate workflow/release validation issues remain unresolved.
Review effort: Lite
Findings: 2
Open (3)
What changed in this PR
This PR adds changelog-driven release automation, CI hardening, changelog enforcement, and release documentation.
Changes:
- Adds changelog parsing and release orchestration scripts with tests.
- Updates CI and release workflows with pinned actions and automated version resolution.
- Documents release conventions and configures release commits.
| File | Summary | Findings |
|---|---|---|
vitest.config.ts |
Includes script tests. | None |
scripts/release.mjs |
Adds terminal release orchestration. | 2 moderate findings |
scripts/derive-increment.mjs |
Derives semantic version increments. | 2 critical findings; 1 nit |
scripts/__tests__/derive-increment.test.mjs |
Tests changelog parsing. | None |
package.json |
Adds release commands. | None |
AGENTS.md |
Documents release conventions. | None |
.release-it.json |
Configures release commit behavior. | None |
.github/workflows/release.yml |
Automates version resolution and publishing. | None |
.github/workflows/ci.yml |
Hardens CI and adds build validation. | None |
.github/workflows/changelog.yml |
Enforces changelog updates. | 2 moderate findings |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| throw new Error('CHANGELOG.md has no `## [Unreleased]` section.'); | ||
| } | ||
| const rest = changelog.slice(start); | ||
| const end = rest.indexOf('\n## ', 1); |
Comment on lines
+113
to
+114
| const heading = line.match(/^###\s+(.*\S)\s*$/); | ||
| if (heading) { |
| fi | ||
|
|
||
| # -x so docs/CHANGELOG.md does not satisfy the root one. | ||
| if ! printf '%s\n' "$changed" | grep -qx 'CHANGELOG.md'; then |
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.


Brings the release process in line with sf-formula-parser and soql-parser-js. The shared scripts and workflows are copied verbatim; only the sync-note header differs.
How releasing works now
The bump comes from the
###headings in## [Unreleased]:[Unreleased]contains### Breaking Changes### Addedor### Deprecated### Changed,### Removed,### Fixed,### Securitynpm run releasechecks that you're onmain, have a clean tree, and matchorigin/main. It then dispatches the Release workflow and tails the run. The publish still happens on CI, so npm provenance is kept. From the GitHub UI, the workflow input is now free text and defaults toauto.Changes
scripts/derive-increment.mjs(new): derives the bump, with a test suite inscripts/__tests__/.scripts/release.mjs(new): the terminal entry point.release-itmoves torelease:ci, andrelease:incrementexplains the derived bump..github/workflows/release.yml:autofrom the changelog.client-id(replacing the deprecatedapp-id).pages: writepermission..github/workflows/changelog.yml(new): a PR that touchessrc/must update[Unreleased], and the section must classify to a bump. Theskip-changeloglabel opts out..github/workflows/ci.yml: SHA pins,contents: read, a timeout, and build before test..release-it.json: release commits pass--no-verify.AGENTS.md(new): documents the process.Before merging
CLIENT_IDsecret is available to this repo. The workflow no longer usesAPP_ID.skip-changeloglabel if you want the opt-out available.[Unreleased]is still empty because this PR is tooling only, sonpm run releasewill refuse until a real change is recorded.