Skip to content

[changelog] Bootstrap standalone package#2

Open
coisa wants to merge 2 commits intomainfrom
task/1-bootstrap-standalone-changelog-package
Open

[changelog] Bootstrap standalone package#2
coisa wants to merge 2 commits intomainfrom
task/1-bootstrap-standalone-changelog-package

Conversation

@coisa
Copy link
Copy Markdown
Contributor

@coisa coisa commented Apr 29, 2026

Summary

Bootstrap the new fast-forward/changelog package as a standalone changelog domain and CLI runtime. The package now owns its changelog document model, parser, renderer, manager, global changelog executable, and the first reusable commands for entry authoring, version resolution, promotion, and release-note rendering.

Changes

  • add the standalone package structure, Composer metadata, docs, license, and agent guidance
  • add the changelog domain model, filesystem and git helpers, manager, parser, renderer, and Symfony Console application
  • add reusable CLI commands plus PHPUnit coverage and bootstrap the repository CHANGELOG.md

Testing

  • composer validate --strict
  • vendor/bin/phpunit
  • php bin/changelog list --raw
  • smoke-tested changelog:entry, changelog:resolve-version, changelog:promote, and changelog:render-release-notes in a temporary directory

Closes #1

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3454616467

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Document/ChangelogDocument.php Outdated
Comment on lines +103 to +107
if ($release->isUnreleased()) {
continue;
}

array_splice($releases, $index, 0, [$target]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve release ordering when inserting published sections

withRelease() always inserts a new published release before the first published entry, regardless of semantic version or date, so backfilling an older version (for example adding 1.5.0 after 2.0.0) reorders the document to make the older release appear newest. In ChangelogManager::inferNextVersion(), getLatestPublishedRelease() then uses that misplaced section as the bump base, producing incorrect next versions and compare-link chains for subsequent renders.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Summary

  • Updated ChangelogDocument::withRelease() so new published releases are inserted based on ordering logic instead of always being inserted before the first published section; this preserves newest-first ordering and prevents backfilled older versions from becoming the “latest” published release. src/Document/ChangelogDocument.phpL80-L122
  • Added shouldInsertBeforePublishedRelease() to centralize insertion precedence using semantic-version comparison first (with v/V normalization), then date comparison fallback when versions are not semver-like. src/Document/ChangelogDocument.phpL190-L207
  • Updated existing test expectations to reflect preserved newest-first ordering and added a regression test proving backfilled older versions stay behind newer published ones while getLatestPublishedRelease() remains correct. tests/Document/ChangelogDocumentTest.phpL35-L54 tests/Document/ChangelogDocumentTest.phpL116-L131

Testing

  • vendor/bin/phpunit tests/Document/ChangelogDocumentTest.php (failed because vendor/bin/phpunit is not present before dependency install).
  • ⚠️ composer install --no-interaction --prefer-dist (blocked by network/proxy restriction: Packagist fetch failed with curl error 56 / CONNECT tunnel failed, response 403).

Also completed follow-up workflow items:

  • Committed changes on the branch with message: Fix published release insertion ordering.
  • Created a new PR via make_pr titled: [changelog] Preserve published ordering when adding releases.

View task →

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3064c5c415

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +147 to +149
$releases[] = new ChangelogRelease(self::UNRELEASED_VERSION);
$releases[] = $promoted;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Insert promoted releases in semantic order

When promoteUnreleased() runs, it always appends the promoted release immediately after the Unreleased section ($releases[] = $promoted) instead of placing it relative to existing published versions. If you promote into an older version while newer published releases already exist (for example promoting 1.4.0 when 2.0.0 is present), the document order becomes incorrect, and downstream logic that relies on the first published section as “latest” (e.g., getLatestPublishedRelease() / next-version inference / compare-link generation) will operate on the wrong base release.

Useful? React with 👍 / 👎.

Comment on lines +76 to +77
$currentVersion ??= $document->getLatestPublishedRelease()?->getVersion() ?? '0.0.0';
[$major, $minor, $patch] = array_map(intval(...), explode('.', $currentVersion));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Strip leading v/V before inferring next version

inferNextVersion() splits and integer-casts the raw version string without normalizing prefixes, so a valid changelog version like v1.2.3 is parsed as major 0 (intval('v1')), producing incorrect bumps such as 0.1.0. This is inconsistent with the document ordering logic (which already trims v/V) and causes wrong inferred versions whenever prefixed versions are present or passed via --current-version.

Useful? React with 👍 / 👎.

Comment on lines +153 to +156
private function resolveTag(ChangelogRelease $release): string
{
return 'v' . $release->getVersion();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid double-prefixing tags for v-prefixed versions

resolveTag() unconditionally prepends v to the stored release version, so versions already containing a prefix (e.g., v1.2.0) produce vv1.2.0 in compare/release URLs. In repositories that keep prefixed versions in the changelog, this generates broken reference links at the bottom of the rendered markdown.

Useful? React with 👍 / 👎.

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.

Bootstrap the standalone changelog package and reusable CLI commands

1 participant