fix: use semver-based selection for release notes baseline#89
Conversation
…hronological ordering Fixes bug where hotpatches to older version lines (e.g. v2.0.6 published after v4.0.0) would be picked as the release notes baseline instead of the semantically latest release. Uses GitHub's getLatestRelease endpoint which respects the "latest" designation, with fallback to listReleases. Agent-Logs-Url: https://github.com/joshjohanning/publish-github-action/sessions/61a91a3a-130d-4656-9ca0-5c9ac14f529a Co-authored-by: joshjohanning <19912012+joshjohanning@users.noreply.github.com>
…wing Agent-Logs-Url: https://github.com/joshjohanning/publish-github-action/sessions/61a91a3a-130d-4656-9ca0-5c9ac14f529a Co-authored-by: joshjohanning <19912012+joshjohanning@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates the release-notes baseline selection in this Node.js GitHub Action so that release notes are generated against the semantically “latest” release instead of the most recently created release, which can be incorrect when hotpatches are released on older version lines.
Changes:
- Switch baseline selection to
octokit.rest.repos.getLatestRelease()with alistReleasesfallback on API failure. - Update Jest tests to mock
getLatestRelease, add coverage for fallback behavior and the hotpatch scenario. - Bump package version
3.0.2 → 3.0.3(and sync lockfile), update coverage badge.
Show a summary per file
| File | Description |
|---|---|
| src/index.js | Uses getLatestRelease to determine the previous tag for release notes; falls back to listReleases on error. |
| tests/index.test.js | Updates mocks and adds tests for getLatestRelease success/failure and hotpatch scenario. |
| package.json | Patch version bump to reflect behavior change. |
| package-lock.json | Syncs lockfile version fields with package.json. |
| badges/coverage.svg | Updates displayed coverage percentage. |
Copilot's findings
- Files reviewed: 3/5 changed files
- Comments generated: 2
Address review feedback: - Restructure so listReleases fallback runs whenever previousTag is unset (not only when getLatestRelease throws) - Update catch comment to reflect all failure modes, not just first release - Add test for non-semver latest release tag falling back to listReleases
There was a problem hiding this comment.
Pull request overview
Updates the action’s release-notes baseline selection to use GitHub’s “latest release” designation (instead of relying on release creation order), improving correctness when hotpatches are published on older version lines.
Changes:
- Use
repos.getLatestRelease()to determine the previous tag for release notes, with alistReleasesfallback. - Update/add Jest tests to cover the new “latest” behavior, fallback behavior, and hotpatch scenario.
- Bump package version to
3.0.3and update the coverage badge.
Show a summary per file
| File | Description |
|---|---|
src/index.js |
Switches baseline selection to getLatestRelease() with fallback logic. |
__tests__/index.test.js |
Updates mocks and adds tests for latest-release behavior + fallbacks. |
package.json |
Patch version bump to reflect behavior change. |
package-lock.json |
Synces lockfile version field with package version bump. |
badges/coverage.svg |
Updates coverage badge to new percentage. |
Copilot's findings
- Files reviewed: 3/5 changed files
- Comments generated: 1
Replace getLatestRelease API with semver comparison to find the highest released version less than the current version. This correctly handles both hotpatches (v2.0.6 published after v4.0.0) and backports (publishing v2.0.7 when v4.0.1 exists). - Use semver.valid/lt/rcompare to filter and sort release tags - Remove getLatestRelease dependency entirely - Add backport scenario test (v2.0.7 when v4.0.1 exists → picks v2.0.6) - Add non-semver tag filtering test
There was a problem hiding this comment.
Pull request overview
Fixes release-notes baseline selection to use semantic version ordering instead of relying on the GitHub Releases API’s created_at sort order, preventing incorrect baselines in hotpatch/backport scenarios.
Changes:
- Update previous-release selection to filter valid semver tags
< currentand choose the highest viasemver.rcompare. - Expand Jest coverage for hotpatch/backport and non-semver-tag scenarios.
- Bump package version to
3.0.3and refresh coverage badge.
Show a summary per file
| File | Description |
|---|---|
src/index.js |
Switch baseline selection logic to semver-based filtering/sorting. |
__tests__/index.test.js |
Add/adjust tests to validate semver-based baseline selection behavior. |
package.json |
Patch version bump 3.0.2 → 3.0.3. |
package-lock.json |
Lockfile version bump to match package.json. |
badges/coverage.svg |
Update coverage badge value. |
Copilot's findings
- Files reviewed: 3/5 changed files
- Comments generated: 2
- Use octokit.paginate() to fetch all releases instead of per_page: 100 - Use real semver valid/lt/rcompare in test mocks instead of simplified re-implementations, only mock major/minor which need controlled values
📦 Draft Release CreatedA draft release v3.0.3 has been created for this PR. Next Steps
|
listReleasesreturns releases sorted bycreated_atdescending, so.find()picks the most recently created release — not the semantically correct predecessor. This causes incorrect release notes in two scenarios:v2.0.6published afterv4.0.0→ release notes forv4.0.1were generated againstv2.0.6instead ofv4.0.0v2.0.7whenv4.0.1exists → release notes were generated againstv4.0.1instead ofv2.0.6Changes
src/index.js: Replace the previous approach with semver-based selection — fetch all releases, filter to valid semver tags less than the current version, and pick the highest one usingsemver.lt()andsemver.rcompare().__tests__/index.test.js: Reworked release notes tests to cover:v4.0.1picksv4.0.0over chronologically newerv2.0.6)v2.0.7picksv2.0.6, notv4.0.1)package.json: Patch bump3.0.2→3.0.3