feat: release notes (#283)

* feat: add release.ts

* feat: add utils

* chore: add scripts to tsconfig.json include

* feat: add changelog logic, component, storybook file, scripts, and update to Node v20.9.0 (LTS)

* chore: update packages

* feat: use conventionalcommits for changelog preset

* feat: update padding, width, and change font to mono

* feat: refactor to use DialogProvider

* chore: remove extra args

* feat: update CHANGELOG.md, add title, and add button

* refactor: use hook

* chore: fix typo
This commit is contained in:
doprz
2024-10-12 17:05:37 -05:00
committed by GitHub
parent aede681d4b
commit bd17e33537
12 changed files with 4133 additions and 1675 deletions

View File

@@ -0,0 +1,54 @@
import { exec } from 'child_process';
import { resolve } from 'path';
import { promisify } from 'util';
const execPromise = promisify(exec);
interface Props {
preset:
| 'angular'
| 'atom'
| 'codemirror'
| 'conventionalcommits'
| 'ember'
| 'eslint'
| 'express'
| 'jquery'
| 'jshint';
// The file to write the changelog to
outFile?: string;
// How many releases to be generated from the latest
// If 0, the whole changelog will be regenerated and the outfile will be overwritten
releaseCount?: number;
}
/**
* Generates a changelog using the conventional-changelog command.
*
* @returns {Promise<void>} A promise that resolves when the changelog is generated.
* @throws {Error} If there is an error generating the changelog.
*/
async function generateChangelog({ preset, outFile = 'CHANGELOG.md', releaseCount = 1 }: Props): Promise<void> {
try {
// Run the conventional-changelog command to generate changelog
const { stdout, stderr } = await execPromise(
`conventional-changelog -p ${preset} -i ${outFile} -s -r ${releaseCount}`,
{
// Ensures it runs from the project root
cwd: resolve(process.cwd()),
}
);
// Log output and error if any
console.log(stdout);
if (stderr) {
console.error(stderr);
}
} catch (error) {
console.error('Error generating changelog:', error);
}
}
generateChangelog({ preset: 'conventionalcommits', releaseCount: 0 });

53
scripts/release.ts Normal file
View File

@@ -0,0 +1,53 @@
import prompts from 'prompts';
import { simpleGit } from 'simple-git';
import { getSourceRef } from '../utils/git/getSourceRef';
import { error, info } from '../utils/log';
const git = simpleGit();
const status = await git.status();
if (status.files.length) {
console.log(error('Working directory is not clean, please commit or stash changes before releasing.'));
process.exit(1);
}
const { destinationBranch } = await prompts({
type: 'select',
name: 'destinationBranch',
message: 'What kind of release do you want to create?',
choices: ['preview', 'production'].map(releaseType => ({
title: releaseType,
value: releaseType,
})),
});
const sourceRef = await getSourceRef(destinationBranch);
const { confirm } = await prompts({
type: 'confirm',
name: 'confirm',
message: `Are you sure you want to create a ${destinationBranch} release from ${sourceRef}?`,
});
if (!confirm) {
console.log(error('Aborting release.'));
process.exit(1);
}
// we fetch the latest changes from the remote
await git.fetch();
// we checkout the source ref, pull the latest changes and then checkout the destination branch
console.info(`Checking out and updating ${sourceRef}...`);
await git.checkout(sourceRef);
await git.pull('origin', sourceRef);
console.info(`Checking out and updating ${destinationBranch}...`);
await git.checkout(destinationBranch);
await git.pull('origin', destinationBranch);
// we trigger the release github action by merging the source ref into the destination branch
console.info(`Merging ${sourceRef} into ${destinationBranch}...`);
await git.merge([sourceRef, '--ff-only']);
await git.push('origin', destinationBranch);
console.info(info(`Release to ${destinationBranch} created! Check github for status`));