also looking at this
test: align release rehearsal deadlines with subprocess budgets
#366
1 file
+28
-24
Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.
| @@ -150,28 +150,32 @@ function nativeWorkspace(directory: string, git: (...args: string[]) => string): | ||
| 150 | 150 | return ['package.json', 'packages/sdk/package.json', 'packages/zig/build.zig.zon', 'packages/zig/pantry.json'] |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | test('the real release configuration versions every workspace and native manifest before tagging', () => { | |
| 154 | for (const release of ['1.0.2', 'patch']) fixture((directory, git) => { | |
| 155 | const paths = nativeWorkspace(directory, git) | |
| 156 | const bumpx = Bun.resolveSync('@stacksjs/bumpx/bin/cli.js', import.meta.dir) | |
| 157 | const generator = join(import.meta.dir, 'generate-release-changelog.ts') | |
| 158 | const validator = join(import.meta.dir, 'release-version.ts') | |
| 159 | // The validator must read the fixture checkout rather than its own source root. | |
| 160 | mkdirSync(join(directory, 'scripts')) | |
| 161 | writeFileSync(join(directory, 'scripts/release-version.ts'), readFileSync(validator)) | |
| 162 | git('add', 'scripts') | |
| 163 | git('commit', '-qm', 'chore: install actual release validator') | |
| 164 | const result = Bun.spawnSync([ | |
| 165 | process.execPath, bumpx, '--recursive', '--commit', '--tag', '--no-push', '--yes', '--no-changelog', | |
| 166 | '--execute', `${shellQuote(process.execPath)} scripts/release-version.ts --pending && ${shellQuote(process.execPath)} ${shellQuote(generator)} && git add CHANGELOG.md`, release, | |
| 167 | ], { cwd: directory, stdout: 'pipe', stderr: 'pipe', timeout: 30_000 }) | |
| 168 | expect(result.exitCode, result.stderr.toString()).toBe(0) | |
| 169 | expect(git('tag', '--list', 'v1.0.2')).toBe('v1.0.2\n') | |
| 170 | for (const path of paths) expect(git('show', `HEAD:${path}`)).toContain('1.0.2') | |
| 171 | expect(git('show', 'HEAD:CHANGELOG.md')).toContain('/compare/v1.0.0...v1.0.2)') | |
| 172 | expect(git('status', '--porcelain')).toBe('') | |
| 173 | }) | |
| 174 | }) | |
| 153 | // Each real CLI rehearsal needs its own bounded subprocess budget; Bun's | |
| 154 | // five-second default can kill a successful Git/Bumpx/changelog run early. | |
| 155 | for (const release of ['1.0.2', 'patch']) { | |
| 156 | test(`the real ${release} release versions every workspace and native manifest before tagging`, () => { | |
| 157 | fixture((directory, git) => { | |
| 158 | const paths = nativeWorkspace(directory, git) | |
| 159 | const bumpx = Bun.resolveSync('@stacksjs/bumpx/bin/cli.js', import.meta.dir) | |
| 160 | const generator = join(import.meta.dir, 'generate-release-changelog.ts') | |
| 161 | const validator = join(import.meta.dir, 'release-version.ts') | |
| 162 | // The validator must read the fixture checkout rather than its own source root. | |
| 163 | mkdirSync(join(directory, 'scripts')) | |
| 164 | writeFileSync(join(directory, 'scripts/release-version.ts'), readFileSync(validator)) | |
| 165 | git('add', 'scripts') | |
| 166 | git('commit', '-qm', 'chore: install actual release validator') | |
| 167 | const result = Bun.spawnSync([ | |
| 168 | process.execPath, bumpx, '--recursive', '--commit', '--tag', '--no-push', '--yes', '--no-changelog', | |
| 169 | '--execute', `${shellQuote(process.execPath)} scripts/release-version.ts --pending && ${shellQuote(process.execPath)} ${shellQuote(generator)} && git add CHANGELOG.md`, release, | |
| 170 | ], { cwd: directory, stdout: 'pipe', stderr: 'pipe', timeout: 30_000 }) | |
| 171 | expect(result.exitCode, result.stderr.toString()).toBe(0) | |
| 172 | expect(git('tag', '--list', 'v1.0.2')).toBe('v1.0.2\n') | |
| 173 | for (const path of paths) expect(git('show', `HEAD:${path}`)).toContain('1.0.2') | |
| 174 | expect(git('show', 'HEAD:CHANGELOG.md')).toContain('/compare/v1.0.0...v1.0.2)') | |
| 175 | expect(git('status', '--porcelain')).toBe('') | |
| 176 | }) | |
| 177 | }, 30_000) | |
| 178 | } | |
| 175 | 179 | |
| 176 | 180 | test('the published release tool restores all workspace and native versions on a failed command', () => { |
| 177 | 181 | fixture((directory, git) => { |
| @@ -189,7 +193,7 @@ test('the published release tool restores all workspace and native versions on a | ||
| 189 | 193 | expect(git('tag', '--list', 'v1.0.2')).toBe('') |
| 190 | 194 | expect(git('status', '--porcelain')).toBe('') |
| 191 | 195 | }) |
| 192 | }) | |
| 196 | }, 30_000) | |
| 193 | 197 | |
| 194 | 198 | test('pending validation rejects an incomplete workspace before a tag or commit exists', () => { |
| 195 | 199 | fixture((directory, git) => { |
| @@ -212,4 +216,4 @@ test('pending validation rejects an incomplete workspace before a tag or commit | ||
| 212 | 216 | expect(git('tag', '--list', 'v1.0.2')).toBe('') |
| 213 | 217 | expect(git('status', '--porcelain')).toBe('') |
| 214 | 218 | }) |
| 215 | }) | |
| 219 | }, 30_000) | |