* fix(#1838): exclude backlog 999.x milestone phases * chore(#1838): add changeset fragment
This commit is contained in:
5
.changeset/patient-mice-greet.md
Normal file
5
.changeset/patient-mice-greet.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 1843
|
||||
---
|
||||
**`init milestone-op` now ignores backlog `999.x` headings when counting milestone phases** — parked backlog items no longer inflate `phase_count` or pin `all_phases_complete` false for an otherwise finished milestone. (#1843)
|
||||
@@ -1189,6 +1189,7 @@ function cmdInitMilestoneOp(cwd: string, raw: boolean): void {
|
||||
const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi;
|
||||
let m: RegExpExecArray | null;
|
||||
while ((m = phasePattern.exec(currentSection)) !== null) {
|
||||
if (/^999(?:\.|$)/.test(m[1])) continue;
|
||||
roadmapPhaseNumbers.push(m[1]);
|
||||
}
|
||||
} catch {
|
||||
|
||||
@@ -976,6 +976,7 @@ describe('cmdInitMilestoneOp', () => {
|
||||
path.join(tmpDir, '.planning', 'config.json'),
|
||||
JSON.stringify({ project_code: 'PROJ' }, null, 2)
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(tmpDir, '.planning', 'STATE.md'),
|
||||
[
|
||||
@@ -1008,6 +1009,47 @@ describe('cmdInitMilestoneOp', () => {
|
||||
assert.strictEqual(output.all_phases_complete, true);
|
||||
});
|
||||
|
||||
test('backlog 999.x headings do not inflate milestone phase counts (#1838)', () => {
|
||||
const phase1 = path.join(tmpDir, '.planning', 'phases', '01-setup');
|
||||
fs.mkdirSync(phase1, { recursive: true });
|
||||
fs.writeFileSync(path.join(phase1, '01-01-PLAN.md'), '# Plan');
|
||||
fs.writeFileSync(path.join(phase1, '01-01-SUMMARY.md'), '# Summary');
|
||||
fs.writeFileSync(
|
||||
path.join(tmpDir, '.planning', 'STATE.md'),
|
||||
[
|
||||
'---',
|
||||
'gsd_state_version: 1.0',
|
||||
'milestone: v1.0.0',
|
||||
'milestone_name: Test Milestone',
|
||||
'status: completed',
|
||||
'---',
|
||||
'',
|
||||
].join('\n')
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(tmpDir, '.planning', 'ROADMAP.md'),
|
||||
[
|
||||
'# Roadmap',
|
||||
'',
|
||||
'## 🚧 v1.0.0 Test Milestone',
|
||||
'### Phase 1: Setup',
|
||||
'',
|
||||
'## Backlog',
|
||||
'### Phase 999.1: Deferred Idea',
|
||||
'### Phase 999.2: Another Deferred Idea',
|
||||
'',
|
||||
].join('\n')
|
||||
);
|
||||
|
||||
const result = runGsdTools('init milestone-op', tmpDir);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const output = JSON.parse(result.output);
|
||||
assert.strictEqual(output.phase_count, 1);
|
||||
assert.strictEqual(output.completed_phases, 1);
|
||||
assert.strictEqual(output.all_phases_complete, true);
|
||||
});
|
||||
|
||||
test('archive directory scanning', () => {
|
||||
fs.mkdirSync(path.join(tmpDir, '.planning', 'archive', 'v1.0'), { recursive: true });
|
||||
fs.mkdirSync(path.join(tmpDir, '.planning', 'archive', 'v0.9'), { recursive: true });
|
||||
|
||||
Reference in New Issue
Block a user