Skip to content

Derive the changelog's no-tag release date from the version instead of the clock - #55

Merged
unbraind merged 3 commits into
mainfrom
fix/stabilise-changelog-date-from-version
Aug 24, 2026
Merged

unbraind merged 3 commits into
mainfrom
fix/stabilise-changelog-date-from-version

Conversation

@unbraind

@unbraind unbraind commented Aug 24, 2026 •

Copy link
Copy Markdown
Owner

The defect

pm-changelog synthesises a pending release window for a version that has no matching git tag, and stamps it with the current UTC date. So changelog:check regenerates a different heading date every day and fails on any day after the changelog was written — a gate whose verdict flips at midnight with no input change.

release.yml pushes its tag only after npm publish succeeds. Publish has failed fleet-wide since 2026-08-21, so this package carries an untagged version and sits on that clock-dependent path.

It passes today only by coincidence — the package version and today's date are the same calendar day. That stops being true tomorrow.

Measured, not reasoned about

Verified on pm-ops, chosen because its version date and today's date differ, which is what makes the comparison discriminate:

generated heading for an untagged 2026.8.22
without --date-from-version ## 2026.8.22 - 2026-08-24 ← today
with --date-from-version ## 2026.8.22 - 2026-08-22 ← the version

What changed

The flag already shipped in pm-changelog@2026.8.17. No fleet package was passing it.

Applied to every invocation of the generator, not only the scripts named changelog* — release.yml invokes pm-changelog directly, and if only one side carries the flag then generation and check disagree and the divergence returns as a release failure. Site audit:

file sites flagged
package.json 2 2
.github/workflows/release.yml 3 3

The flag affects only the no-tag path; where a tag exists the date still comes from the tag's commit, so tagged history is untouched.

pm item

pm-github-m8vj — root cause, the site audit, and the verification evidence.

Not done here

Backfilling the missing git tags would also make this green, and is deliberately not the fix: the workflow tags only after a successful publish, so a tag asserts a release npm never received, and it would stop exercising the broken path rather than repairing it.

Summary by Sourcery

Stabilize changelog generation and release checks for untagged versions by deriving their release dates from the package version.

Bug Fixes:

  • Make changelog dates for untagged releases stable by deriving them from the package version instead of the current UTC date.

Enhancements:

  • Keep tagged release dates based on tag history while applying consistent date handling across changelog generation, checking, and release-note workflows.

Tests:

  • Add verification coverage for all release changelog invocations and for the differing version-derived and clock-derived behaviors.

Summary by cubic

Stabilizes changelog generation by deriving an untagged release’s heading date from the package version instead of the current UTC date. Previously the date came from the clock; now it comes from the version. Tagged releases still use the tag commit date.

  • Passes --date-from-version to all pm-changelog calls in package.json and .github/workflows/release.yml so generation and check agree.
  • Adds scripts/verify-release-changelog-date.sh that (a) asserts every generator invocation is flagged and (b) proves the flag’s effect by comparing headings with and without it for a probe version.
  • Uses pm-changelog@2026.8.17; no other behavior changes.

Written for commit 79d0bd8. Summary will update on new commits.

Review in cubic

…the clock

pm-changelog stamps the pending window of an untagged version with the
current UTC date, so changelog:check regenerates a different heading date
every day and fails on any day after the changelog was written -- a gate
whose verdict flips at midnight with no input change.

release.yml tags only after npm publish succeeds, and publish has failed
fleet-wide since 2026-08-21, so this package carries an untagged version and
is on that path. It passes today only because the package version and
today's date are the same calendar day.

Verified on pm-ops, where the version date and today's date differ and the
comparison therefore discriminates: an untagged 2026.8.22 generates
'2026.8.22 - 2026-08-24' unflagged and '2026.8.22 - 2026-08-22' with
--date-from-version.

The flag already shipped in pm-changelog 2026.8.17; no fleet package passed
it. Applied to EVERY invocation of the generator, not only the scripts named
changelog*: release.yml invokes it directly, and generation and check must
not disagree or the divergence returns as a release failure.

Site audit: package.json sites 2 flagged 2; .github/workflows/release.yml sites 3 flagged 3;
@sourcery-ai

sourcery-ai Bot commented Aug 24, 2026 •

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Updates every changelog and release-note generation path to pass pm-changelog's existing --date-from-version flag, making untagged release headings stable and consistent while preserving tag-derived dates for tagged releases; accompanying PM metadata documents the defect and audit.

Sequence diagram for stable untagged changelog generation

sequenceDiagram
    participant Invocation as Changelog invocation
    participant Generator as pm-changelog
    participant Git as Git tags
    participant Version as package version
    participant Output as Changelog or release notes

    Invocation->>Generator: pm-changelog --date-from-version
    Generator->>Git: Resolve release tag
    alt matching tag exists
        Git-->>Generator: Tagged commit date
    else no matching tag
        Generator->>Version: Read release version
        Version-->>Generator: Version-derived date
    end
    Generator->>Output: Write stable release heading
Loading

File-Level Changes

Change Details Files
Make generated dates deterministic for releases without matching git tags by deriving them from the package version.
  • Add --date-from-version to the full changelog generation and check scripts.
  • Add --date-from-version to release-note generation so workflow output uses the same date source.
  • Apply the flag to all three direct pm-changelog invocations in the release workflow.
package.json
.github/workflows/release.yml
Record the issue context and investigation evidence for the changelog date defect.
  • Add the PM issue describing the clock-dependent behavior, affected invocation sites, and verification results.
  • Add the associated PM history entry.
.agents/pm/issues/pm-github-m8vj.toon
.agents/pm/history/pm-github-m8vj.jsonl

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

Review Change Stack

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1163a3d5-9489-4bde-ad0f-f184748529f6

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 986e49f1-1988-4f8a-ad44-0dcdac5d47d4

📥 Commits

Reviewing files that changed from the base of the PR and between 052c0b0 and 287ff5b.

📒 Files selected for processing (4)
  • .agents/pm/history/pm-github-m8vj.jsonl
  • .agents/pm/issues/pm-github-m8vj.toon
  • .github/workflows/release.yml
  • package.json

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


Summary by CodeRabbit

  • Bug Fixes
    • Release changelogs and notes now consistently derive dates from the package version, preventing incorrect dates for untagged release windows.
  • Validation
    • Added documentation and validation records covering the updated release-date behavior and its verification command.

Walkthrough

The changelog and release-note commands now derive release dates from the package version. Project issue and history records document the affected files, validation command, and date-handling context.

Changes

Changelog date fix

Layer / File(s) Summary
Update release command date sources
.github/workflows/release.yml, package.json
Changelog and release-note commands now use --date-from-version. Other command options remain unchanged.
Record issue and validation context
.agents/pm/issues/pm-github-m8vj.toon, .agents/pm/history/pm-github-m8vj.jsonl
The issue and history records document the date inconsistency, affected files, proposed remedy, audit details, and npm run changelog:check.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 287ff

This keeps untagged changelog output stable across days while preserving tagged-release dates; no actionable merge-blocking risk remains beyond normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states that untagged changelog release dates will come from the version instead of the clock.
Description check ✅ Passed The description explains the clock-dependent defect, the applied fix, affected invocations, and preserved tagged-release behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (4 skipped: 4 unsupported.)
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/stabilise-changelog-date-from-version

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai 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.

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Needs a human reviewer. If the derived date is wrong, generated CHANGELOG or release notes can be published with an incorrect release window, which remains after reverting the change. The affected artifacts are bounded and can be regenerated or corrected; no data deletion, access change, payment, or irreversible operational action is introduced.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@unbraind

Copy link
Copy Markdown
Owner Author

@coderabbitai full review
@greptileai
/gemini review

@coderabbitai

coderabbitai Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

@unbraind, I will perform a complete review of PR #55.

✅ Action performed

Full review finished.

@unbraind

Copy link
Copy Markdown
Owner Author

Per-repo proof (pm-github, measured locally on this PR's branch)

With package.json's version temporarily set to 2026.8.25 — an untagged calendar version dated other than today (2026-08-24):

generator invocation generated pending-release heading
without --date-from-version ## 2026.8.25 - 2026-08-24 ← stamped from the wall clock (the midnight-flip defect)
with --date-from-version ## 2026.8.25 - 2026-08-25 ← derived from the version itself (stable across midnight)

package.json was restored immediately afterwards; nothing here depends on the temporary version.

…ck never reaches

CodeRabbit was right that the linked test only covered the package.json
invocation. release.yml calls pm-changelog directly, and nothing exercised
those calls.

The static half enumerates every tracked file holding a generator invocation
and asserts each file's flagged count is not below its site count. Verified
non-vacuous by removing the flag from one of two release.yml sites: it
reports 1 of 2 and exits non-zero.

The behavioural half runs the generator twice on the same probe version
2026.1.2 -- chosen so its calendar date cannot coincide with today -- and
asserts '2026.1.2 - 2026-01-02' with the flag against '2026.1.2 - 2026-08-24'
without it. The test therefore states the defect, not just the fix.
…ck never reaches

CodeRabbit was right that the linked test only covered the package.json
invocation. release.yml calls pm-changelog directly, and nothing exercised
those calls.

The static half enumerates every tracked file holding a generator invocation
and asserts each file's flagged count is not below its site count. Verified
non-vacuous by removing the flag from one of two release.yml sites: it
reports 1 of 2 and exits non-zero.

The behavioural half runs the generator twice on the same probe version
2026.1.2 -- chosen so its calendar date cannot coincide with today -- and
asserts '2026.1.2 - 2026-01-02' with the flag against '2026.1.2 - 2026-08-24'
without it. The test therefore states the defect, not just the fix.
@unbraind

Copy link
Copy Markdown
Owner Author

Added an executable release-path check in response to review; see the thread replies for the two halves and the non-vacuity proof.

@coderabbitai full review
@greptileai
/gemini review

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Rate Limit Exceeded

@unbraind have exceeded the limit for the number of chat messages per hour. Please wait 30 minutes and 2 seconds before sending another message.

@unbraind

Copy link
Copy Markdown
Owner Author

Merging. Reviewer feedback recorded so the next review of this class is better targeted.

What the bots got right on this rollout, and it mattered: CodeRabbit flagged that the linked test (npm run changelog:check) only exercised the package.json invocation and never reached release.yml's direct pm-changelog calls; Sourcery and Greptile independently caught the same gap on pm-starter#77 as a generator/check divergence. Both were correct, and the half-fix would have passed CI while turning a stale-date failure into a release failure. scripts/verify-release-changelog-date.sh exists because of that feedback.

A heuristic worth carrying into similar reviews: when a flag changes the behaviour of a tool, the unit of the fix is every invocation of that tool, not every script whose name sounds related. Grepping every tracked file for --release-version-from-package found sites in release.yml and in release:notes that reading the changelog* scripts never would.

Merge criteria applied: all required checks green, zero unresolved review threads, mergeStateStatus=CLEAN confirmed via GraphQL (not gh pr checks, which does not expose these fields).

Caveat that applies to every package right now: npm publishing is failing fleet-wide on an expired registry token, so a green merge here does not produce a published release.

@unbraind
unbraind merged commit 65f4d2a into main Aug 24, 2026
8 checks passed
@unbraind
unbraind deleted the fix/stabilise-changelog-date-from-version branch August 24, 2026 10:13
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