mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-26 00:55:16 -07:00
chore(release): prepare 0.15.0-beta.3
This commit is contained in:
@@ -509,6 +509,72 @@ test('writePrereleaseNotesForVersion writes cumulative beta notes without mutati
|
||||
}
|
||||
});
|
||||
|
||||
test('writePrereleaseNotesForVersion reuses existing prerelease notes when adding new fragments', async () => {
|
||||
const { writePrereleaseNotesForVersion } = await loadModule();
|
||||
const workspace = createWorkspace('prerelease-reuse-existing-notes');
|
||||
const projectRoot = path.join(workspace, 'SubMiner');
|
||||
const existingNotes = [
|
||||
'> This is a prerelease build for testing. Stable changelog and docs-site updates remain pending until the final stable release.',
|
||||
'',
|
||||
'## Highlights',
|
||||
'### Added',
|
||||
'- Overlay: Previous beta entry.',
|
||||
'',
|
||||
'## Installation',
|
||||
'',
|
||||
'See the README and docs/installation guide for full setup steps.',
|
||||
'',
|
||||
'## Assets',
|
||||
'',
|
||||
'- Linux: `SubMiner.AppImage`',
|
||||
'',
|
||||
].join('\n');
|
||||
|
||||
fs.mkdirSync(path.join(projectRoot, 'changes'), { recursive: true });
|
||||
fs.mkdirSync(path.join(projectRoot, 'release'), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(projectRoot, 'package.json'),
|
||||
JSON.stringify({ name: 'subminer', version: '0.11.3-beta.2' }, null, 2),
|
||||
'utf8',
|
||||
);
|
||||
fs.writeFileSync(path.join(projectRoot, 'release', 'prerelease-notes.md'), existingNotes, 'utf8');
|
||||
fs.writeFileSync(
|
||||
path.join(projectRoot, 'changes', '001.md'),
|
||||
['type: fixed', 'area: launcher', '', '- Fixed launcher prerelease packaging.'].join('\n'),
|
||||
'utf8',
|
||||
);
|
||||
|
||||
try {
|
||||
const stub = recordingRunClaude((input) => {
|
||||
if (!input.includes('Overlay: Previous beta entry.')) {
|
||||
return '### Fixed\n- Launcher: Added only the latest fix.';
|
||||
}
|
||||
return [
|
||||
'### Added',
|
||||
'- Overlay: Previous beta entry.',
|
||||
'',
|
||||
'### Fixed',
|
||||
'- Launcher: Added only the latest fix.',
|
||||
].join('\n');
|
||||
});
|
||||
|
||||
const outputPath = writePrereleaseNotesForVersion({
|
||||
cwd: projectRoot,
|
||||
version: '0.11.3-beta.2',
|
||||
deps: { runClaude: stub.runClaude },
|
||||
});
|
||||
|
||||
assert.equal(stub.calls.length, 1, 'prerelease should issue exactly one Claude call');
|
||||
assert.match(stub.calls[0]!.input, /EXISTING PRERELEASE NOTES/);
|
||||
|
||||
const prereleaseNotes = fs.readFileSync(outputPath, 'utf8');
|
||||
assert.match(prereleaseNotes, /- Overlay: Previous beta entry\./);
|
||||
assert.match(prereleaseNotes, /- Launcher: Added only the latest fix\./);
|
||||
} finally {
|
||||
fs.rmSync(workspace, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('writePrereleaseNotesForVersion supports rc prereleases', async () => {
|
||||
const { writePrereleaseNotesForVersion } = await loadModule();
|
||||
const workspace = createWorkspace('prerelease-rc-notes');
|
||||
|
||||
@@ -290,6 +290,7 @@ function serializeFragmentsForPrompt(
|
||||
mode: PolishMode,
|
||||
version: string,
|
||||
date?: string,
|
||||
existingReleaseNotes?: string,
|
||||
): string {
|
||||
const header: string[] = [`MODE: ${mode}`, `VERSION: ${version}`];
|
||||
if (date) {
|
||||
@@ -307,7 +308,11 @@ function serializeFragmentsForPrompt(
|
||||
].join('\n');
|
||||
});
|
||||
|
||||
return [...header, '', ...fragmentBlocks].join('\n\n');
|
||||
const existingNotesBlock = existingReleaseNotes?.trim()
|
||||
? ['EXISTING PRERELEASE NOTES', existingReleaseNotes.trim()]
|
||||
: [];
|
||||
|
||||
return [...header, '', ...existingNotesBlock, '', ...fragmentBlocks].join('\n\n');
|
||||
}
|
||||
|
||||
function validatePolishedOutput(
|
||||
@@ -340,10 +345,11 @@ function polishFragmentsWithClaude(
|
||||
mode: PolishMode;
|
||||
version: string;
|
||||
date?: string;
|
||||
existingReleaseNotes?: string;
|
||||
deps?: ChangelogFsDeps;
|
||||
},
|
||||
): string {
|
||||
const { mode, version, date } = options;
|
||||
const { mode, version, date, existingReleaseNotes } = options;
|
||||
const runClaude = options.deps?.runClaude ?? defaultRunClaude;
|
||||
|
||||
const filtered =
|
||||
@@ -361,8 +367,18 @@ function polishFragmentsWithClaude(
|
||||
);
|
||||
}
|
||||
|
||||
const reuseInstructions = existingReleaseNotes?.trim()
|
||||
? [
|
||||
'## Existing Prerelease Notes',
|
||||
'',
|
||||
'The input includes EXISTING PRERELEASE NOTES before the fragment list. Reuse those highlight bullets as the baseline, preserve their meaning and wording where possible, then merge in only new or changed fragment material. Deduplicate instead of restating existing bullets. Output only the final highlights body using the section headings above; do not include the prerelease disclaimer, Installation, or Assets sections.',
|
||||
'',
|
||||
].join('\n')
|
||||
: '';
|
||||
const prompt =
|
||||
POLISH_PROMPT_INSTRUCTIONS + serializeFragmentsForPrompt(filtered, mode, version, date);
|
||||
POLISH_PROMPT_INSTRUCTIONS +
|
||||
reuseInstructions +
|
||||
serializeFragmentsForPrompt(filtered, mode, version, date, existingReleaseNotes);
|
||||
const output = runClaude(prompt, CLAUDE_CLI_ARGS);
|
||||
return validatePolishedOutput(output, mode, hasInternalFragments);
|
||||
}
|
||||
@@ -780,6 +796,8 @@ export function writePrereleaseNotesForVersion(options?: ChangelogOptions): stri
|
||||
verifyRequestedVersionMatchesPackageVersion(options ?? {});
|
||||
|
||||
const cwd = options?.cwd ?? process.cwd();
|
||||
const existsSync = options?.deps?.existsSync ?? fs.existsSync;
|
||||
const readFileSync = options?.deps?.readFileSync ?? fs.readFileSync;
|
||||
const version = resolveVersion(options ?? {});
|
||||
if (!isSupportedPrereleaseVersion(version)) {
|
||||
throw new Error(
|
||||
@@ -792,9 +810,14 @@ export function writePrereleaseNotesForVersion(options?: ChangelogOptions): stri
|
||||
throw new Error('No changelog fragments found in changes/.');
|
||||
}
|
||||
|
||||
const prereleaseNotesPath = path.join(cwd, PRERELEASE_NOTES_PATH);
|
||||
const existingReleaseNotes = existsSync(prereleaseNotesPath)
|
||||
? readFileSync(prereleaseNotesPath, 'utf8')
|
||||
: undefined;
|
||||
const changes = polishFragmentsWithClaude(fragments, {
|
||||
mode: 'release-notes',
|
||||
version,
|
||||
existingReleaseNotes,
|
||||
deps: options?.deps,
|
||||
});
|
||||
return writeReleaseNotesFile(cwd, changes, options?.deps, {
|
||||
|
||||
Reference in New Issue
Block a user