11import assert from "node:assert/strict" ;
22import { execFile } from "node:child_process" ;
3- import { mkdir , mkdtemp , readFile , readdir , rm , writeFile } from "node:fs/promises" ;
3+ import { mkdir , mkdtemp , readFile , readdir , writeFile } from "node:fs/promises" ;
44import { tmpdir } from "node:os" ;
55import { join } from "node:path" ;
66import test from "node:test" ;
@@ -21,9 +21,11 @@ void test("synchronizes every release-owned version reference", async () => {
2121 join ( cwd , "README.md" ) ,
2222 "```bash\n VERSION=0.74.0 # the release you are installing\n```\n" ,
2323 ) ;
24+ // v0.76.0 and v0.75.0 are mislabeled hand-written sections for unreleased work (the released
25+ // history starts at v0.74.0) — the exact shape that broke the Version PR on main.
2426 await writeFile (
2527 join ( cwd , "MIGRATION.md" ) ,
26- "### Next release\n\n#### 🔴 Existing action\n\nDo it.\n\n### v0.74.0\n\nOld.\n" ,
28+ "### Next release\n\n#### 🔴 Existing action\n\nDo it.\n\n### v0.76.0\n\n#### 🔴 Mislabeled newer action\n\nFold me.\n\n### v0.75.0\n\n#### 🔴 Mislabeled same-version action\n\nFold me too.\n\n### v0. 74.0\n\nOld.\n" ,
2729 ) ;
2830 await writeFile (
2931 join ( cwd , ".migration/z-last.md" ) ,
@@ -42,29 +44,35 @@ void test("synchronizes every release-owned version reference", async () => {
4244 await readFile ( join ( cwd , "README.md" ) , "utf8" ) ,
4345 "```bash\n VERSION=0.75.0 # the release you are installing\n```\n" ,
4446 ) ;
45- assert . equal (
46- await readFile ( join ( cwd , "MIGRATION.md" ) , "utf8" ) ,
47- "### Next release\n\n### v0.75.0\n\n#### 🔴 Existing action\n\nDo it.\n\n#### 🔴 A action\n\nDo A.\n\n#### 🔴 Z action\n\nDo Z: keep `$$VAR`, `$&`, and `$'` literal.\n\n### v0.74.0\n\nOld.\n" ,
48- ) ;
47+ const stamped =
48+ "### Next release\n\n### v0.75.0\n\n#### 🔴 Existing action\n\nDo it.\n\n#### 🔴 Mislabeled newer action\n\nFold me.\n\n#### 🔴 Mislabeled same-version action\n\nFold me too.\n\n#### 🔴 A action\n\nDo A.\n\n#### 🔴 Z action\n\nDo Z: keep `$$VAR`, `$&`, and `$'` literal.\n\n### v0.74.0\n\nOld.\n" ;
49+ assert . equal ( await readFile ( join ( cwd , "MIGRATION.md" ) , "utf8" ) , stamped ) ;
4950 assert . deepEqual ( await readdir ( join ( cwd , ".migration" ) ) , [ "README.md" ] ) ;
5051
52+ // Regeneration re-reads the script's own prior output and must be byte-idempotent.
53+ await run ( process . execPath , [ join ( import . meta. dirname , "sync-release-version.ts" ) ] , { cwd } ) ;
54+ assert . equal ( await readFile ( join ( cwd , "MIGRATION.md" ) , "utf8" ) , stamped ) ;
55+ assert . deepEqual ( await readdir ( join ( cwd , ".migration" ) ) , [ "README.md" ] ) ;
56+
57+ // A fragment landing between regenerations merges into the same unreleased section.
58+ await writeFile ( join ( cwd , ".migration/late.md" ) , "#### 🔴 Late action\n" ) ;
5159 await run ( process . execPath , [ join ( import . meta. dirname , "sync-release-version.ts" ) ] , { cwd } ) ;
5260 assert . equal (
5361 await readFile ( join ( cwd , "MIGRATION.md" ) , "utf8" ) ,
54- "### Next release\n\n ### v0.75.0\n\n#### 🔴 Existing action\n\nDo it.\n\n #### 🔴 A action\n\nDo A.\n\n #### 🔴 Z action\n\nDo Z: keep `$$VAR`, `$&`, and `$'` literal.\n\n### v0.74.0\n\nOld.\n" ,
62+ stamped . replace ( "\n ### v0.74.0" , "\n #### 🔴 Late action\n\n ### v0.74.0" ) ,
5563 ) ;
5664 assert . deepEqual ( await readdir ( join ( cwd , ".migration" ) ) , [ "README.md" ] ) ;
5765
58- await writeFile ( join ( cwd , ".migration/late.md" ) , "#### 🔴 Late action\n" ) ;
66+ // A same-version heading below released history is a real conflict, not prior output.
67+ await writeFile (
68+ join ( cwd , "MIGRATION.md" ) ,
69+ `${ await readFile ( join ( cwd , "MIGRATION.md" ) , "utf8" ) } \n### v0.75.0\n\nGhost.\n` ,
70+ ) ;
5971 await assert . rejects (
6072 run ( process . execPath , [ join ( import . meta. dirname , "sync-release-version.ts" ) ] , { cwd } ) ,
6173 / a l r e a d y c o n t a i n s # # # v 0 \. 7 5 \. 0 / ,
6274 ) ;
63- await rm ( join ( cwd , ".migration/late.md" ) ) ;
64- await writeFile (
65- join ( cwd , "MIGRATION.md" ) ,
66- `### Next release\n\n${ await readFile ( join ( cwd , "MIGRATION.md" ) , "utf8" ) } ` ,
67- ) ;
75+ await writeFile ( join ( cwd , "MIGRATION.md" ) , `### Next release\n\n${ stamped } ` ) ;
6876 await assert . rejects (
6977 run ( process . execPath , [ join ( import . meta. dirname , "sync-release-version.ts" ) ] , { cwd } ) ,
7078 / e x a c t l y o n e # # # N e x t r e l e a s e / ,
0 commit comments