chore(ci): update changelog stipender

This commit is contained in:
omo50
2026-04-18 14:51:33 -06:00
parent 44ed9f2b6f
commit b220dfed92

View File

@@ -1,9 +1,10 @@
import { execSync } from 'child_process'; import { execFileSync } from 'child_process';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as crypto from 'crypto';
function runGit(args: string[], cwd?: string): string { function runGit(args: string[], cwd?: string): string {
return execSync(`git ${args.join(' ')}`, { cwd, encoding: 'utf-8' }).trim(); return execFileSync('git', args, { cwd, encoding: 'utf-8' }).trim();
} }
function generateChangelog(manifestPathStr: string): string { function generateChangelog(manifestPathStr: string): string {
@@ -11,36 +12,50 @@ function generateChangelog(manifestPathStr: string): string {
const pDir = path.dirname(manifestPath); const pDir = path.dirname(manifestPath);
if (!fs.existsSync(manifestPath)) { if (!fs.existsSync(manifestPath)) {
console.error(`Manifest not found at: ${manifestPathStr}`); throw new Error(`manifest not found: ${manifestPathStr}`);
process.exit(1);
} }
const manifestContent = fs.readFileSync(manifestPath, 'utf-8'); const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
const manifest = JSON.parse(manifestContent); const rawName: string = manifest.name ?? path.basename(pDir);
const rawName = manifest.name;
const changelogFile = path.join(pDir, 'changelog.md'); const changelogFile = path.join(pDir, 'changelog.md');
let notes = fs.existsSync(changelogFile) let notes = fs.existsSync(changelogFile)
? fs.readFileSync(changelogFile, 'utf-8') ? fs.readFileSync(changelogFile, 'utf-8')
: `update for ${rawName}`; : `update for ${rawName}`;
let prevHash = 'HEAD~1'; let prevHash: string | null = null;
try { try {
const prevBumpLog = runGit(['log', '-n', '2', '--format=%H', '--', manifestPathStr]); const prevBumpLog = runGit(['log', '-n', '2', '--format=%H', '--', manifestPathStr]);
const lines = prevBumpLog.split('\n'); const hashes = prevBumpLog.split('\n').filter(Boolean);
if (lines.length > 1) { if (hashes.length > 1) {
prevHash = lines[1]; prevHash = hashes[1];
} }
} catch (error) { } catch (e) {
console.warn('could not find previous manifest bump, defaulting to HEAD~1'); console.warn(`could not read git log for manifest: ${e}`);
} }
let commitLines: string[] = []; const commitLines: string[] = [];
try { if (prevHash) {
const logs = runGit(['log', `${prevHash}..HEAD`, '--format=%h %s - %an', '--', pDir]); try {
commitLines = logs.split('\n').filter(line => line.includes(': ')); const logs = runGit([
} catch (error) { 'log',
console.warn(`could not fetch git logs for ${pDir}`); `${prevHash}..HEAD`,
'--format=%h%x09%s%x09%an',
'--',
pDir,
]);
for (const line of logs.split('\n')) {
const parts = line.split('\t');
if (parts.length !== 3) continue;
const [hash, subject, author] = parts;
if (!subject.includes(': ')) continue;
commitLines.push(`${hash} ${subject} - ${author}`);
}
} catch (e) {
console.warn(`could not fetch git logs for ${pDir}: ${e}`);
}
} else {
console.warn('no prior manifest bump found; skipping automated commit log');
} }
if (commitLines.length > 0) { if (commitLines.length > 0) {
@@ -56,20 +71,25 @@ function generateChangelog(manifestPathStr: string): string {
const args = process.argv.slice(2); const args = process.argv.slice(2);
if (args.length === 0) { if (args.length === 0) {
console.error('Usage: tsx generate-changelog.ts <path/to/manifest.json>'); console.error('usage: tsx changelog.ts <path/to/manifest.json>');
process.exit(1); process.exit(1);
} }
const targetManifest = args[0]; let finalNotes: string;
const finalNotes = generateChangelog(targetManifest); try {
finalNotes = generateChangelog(args[0]);
} catch (e) {
console.error(`${e instanceof Error ? e.message : e}`);
process.exit(1);
}
const outPath = process.env.GITHUB_OUTPUT; const outPath = process.env.GITHUB_OUTPUT;
if (outPath) { if (outPath) {
const delimiter = 'EOF_NOTES_DELIMITER'; const delimiter = `EOF_${crypto.randomBytes(8).toString('hex')}`;
fs.appendFileSync(outPath, `notes<<${delimiter}\n${finalNotes.trim()}\n${delimiter}\n`); fs.appendFileSync(outPath, `notes<<${delimiter}\n${finalNotes.trim()}\n${delimiter}\n`);
console.log(`successfully wrote changelog for ${targetManifest} to GITHUB_OUTPUT`); console.log(`wrote changelog for ${args[0]} to GITHUB_OUTPUT`);
} else { } else {
console.log('\nCHANGELOG PREVIEW\n'); console.log('\nCHANGELOG PREVIEW\n');
console.log(finalNotes.trim()); console.log(finalNotes.trim());
console.log('\n\n'); console.log('\nEND\n');
} }