fix(release-tools): make verify:changelog version-bump gate fire for nested plugins#169
fix(release-tools): make verify:changelog version-bump gate fire for nested plugins#169orioltf wants to merge 5 commits into
Conversation
…nested plugins Closes #163. The version-bump gate in verify-changelog.mjs was silently skipping every plugin nested under apps/claude-code/. git diff --name-only emits repo-root-relative paths (e.g. apps/claude-code/unic-pr-review/commands/…) while the GUARDED patterns expected plugin-relative paths (commands/…). The prefix mismatch meant triggered was always false for nested plugins. Two coordinated changes: 1. Fix: add --relative to the git diff invocation so real git strips the plugin prefix. Also resolve the prefix via git rev-parse --show-prefix and strip it in code as a belt-and-suspenders fallback (required for the test shim, which ignores --relative, and for cross-platform safety). 2. Extract: pull the Layer-2 decision into a new pure, injectable module scripts/lib/changelog-gate.mjs exposing GUARDED, isBumpRequired, and evaluateBumpGate. The module performs no process.exit, no console writes, no filesystem or git access — it takes data and returns a verdict, mirroring base-branch-resolver.mjs. verify-changelog.mjs stays the thin wrapper that owns I/O and exit codes. Layer-1 structural checks and CI diff-base resolution are unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🔍 Comprehensive PR ReviewPR: #169 — fix(release-tools): make verify:changelog version-bump gate fire for nested plugins SummaryThe fix correctly addresses the root cause: Verdict:
🟡 Medium Issues (Pre-existing — Needs Decision)Silent base plugin.json parse failure can bypass version-unchanged check📍 When Options: Fix now (bind View one-line fixtry {
baseVersion = JSON.parse(basePluginRaw.stdout).version
} catch (e) {
console.error(`verify:changelog: warn — could not parse base plugin.json: ${e.message}`)
// intentional fallback: treat base as new plugin with no prior version
}🟢 Low IssuesView 6 low-priority suggestions
✅ What's Good
📋 Suggested Follow-up Issues
Reviewed by Archon comprehensive-pr-review workflow |
Fixed: - Remove misleading shebang from changelog-gate.mjs (library, not CLI entry point) - Bind error in all catch blocks to include e.message in fail() output for better CI diagnostics - Emit console.error warning when base plugin.json parse fails instead of silently swallowing - Add unreachable comment on process.exit(1) after Layer 2 CHANGELOG catch to match Layer 1 style Tests added: - evaluateBumpGate: 'treats empty baseVersion as newly introduced plugin (version check passes)' Skipped: - Double isBumpRequired call (intentional design — early-exit preserves don't-read-files-unnecessarily invariant) - showPrefix silent fallback (intentional by design — --relative is primary mechanism) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
⚡ Self-Fix Report (Aggressive)Status: COMPLETE Fixes Applied (6 total)
View all fixes
Tests Added
Skipped (2)
Suggested Follow-up Issues(none) Validation✅ Lint (0 errors) | ✅ Tests (47 passed, 0 failed) Self-fix by Archon · aggressive mode · fixes pushed to |
There was a problem hiding this comment.
Pull request overview
This PR fixes verify:changelog’s Layer-2 version-bump gate so it correctly triggers for plugins nested under paths like apps/claude-code/<plugin>/, where git diff --name-only previously returned repo-root-relative paths that didn’t match the gate’s plugin-relative guarded patterns.
Changes:
- Normalize changed-file paths for nested plugins by using
git diff --name-only --relativeplus agit rev-parse --show-prefix-based prefix-strip fallback. - Extract Layer-2 bump-gate logic into a new pure module (
scripts/lib/changelog-gate.mjs) and add focused unit tests. - Add end-to-end regression tests reproducing the original root-relative path bug and validating the fix.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/release-tools/scripts/verify-changelog.mjs | Uses the extracted gate, adds --relative, and normalizes/strips prefixes so guarded-path detection works for nested plugins. |
| packages/release-tools/scripts/verify-changelog.test.mjs | Adds E2E regression coverage for nested-plugin root-relative diff paths (issue #163). |
| packages/release-tools/scripts/lib/changelog-gate.mjs | New pure module owning GUARDED, isBumpRequired, and evaluateBumpGate (no I/O / no process.exit). |
| packages/release-tools/scripts/lib/changelog-gate.test.mjs | New unit tests covering guarded matching and bump-gate verdict logic. |
| packages/release-tools/package.json | Updates test script to include the new unit test file. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…message When a plugin is newly introduced the base commit lacks plugin.json, so baseVersion is empty and the success message rendered "version → <head>" with an awkward double space. Substitute a "(new)" sentinel so the log line stays meaningful. Strengthens the empty-baseVersion unit test to pin the rendered message. Addresses Copilot review comment on PR #169. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address findings from the multi-agent PR review: - Warn when `git rev-parse --show-prefix` fails so a genuine git failure (which would also disable the prefix-strip fallback) is traceable in CI logs instead of silently relying on --relative. (silent-failure-hunter) - Guard against a plugin.json missing/blank `version` field — fail() with an actionable message instead of crashing later with a raw TypeError stack trace in evaluateBumpGate. (silent-failure-hunter) - Tighten the --relative / prefix-strip comments: --relative emits paths relative to cwd (the plugin dir), and the test shim ignores --relative entirely rather than "may not" strip. (comment-analyzer) - Add Windows-backslash E2E regression test exercising the backslash normalisation the CI Windows matrix can't reach (shim emits POSIX separators regardless of host). (pr-test-analyzer) - Add unit coverage for a guarded file mixed among unguarded files and an all-unguarded list. (pr-test-analyzer) - Use a template literal for the show-prefix shim output. (code-reviewer) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
git diff --name-onlyemits repo-root-relative paths (e.g.apps/claude-code/unic-pr-review/commands/review-pr.md) whileGUARDEDpatterns expected plugin-relative paths (commands/review-pr.md). The prefix mismatch meant the version-bump gate was silently skipped for every nested plugin.--relativeto thegit diffinvocation + strip the plugin prefix viagit rev-parse --show-prefixas a belt-and-suspenders fallback (needed for the test shim and cross-platform safety).scripts/lib/changelog-gate.mjsownsGUARDED,isBumpRequired, andevaluateBumpGatewith no I/O, noprocess.exit— mirrorsbase-branch-resolver.mjs.verify-changelog.mjsstays the thin I/O wrapper.Layer-1 structural checks and CI diff-base resolution are unchanged.
Files changed
scripts/lib/changelog-gate.mjsscripts/lib/changelog-gate.test.mjsscripts/verify-changelog.mjs--relative+ prefix-strip, usesevaluateBumpGatescripts/verify-changelog.test.mjspackage.jsonchangelog-gate.test.mjsto test commandTest plan
pnpm --filter @unic/release-tools test— 46/46 pass (16 unit + 30 integration/regression)pnpm ci:check— Biome + Prettier cleanCloses #163
🤖 Generated with Claude Code