Skip to content

Commit f8b2a08

Browse files
committed
chore: update changelog generation configuration and scripts
- Refactored changelog generation logic into a dedicated CLI tool. - Added example configuration for changelog generation. - Updated `lerna.json` to improve package structure formatting. - Enhanced `yarn.lock` with new dependencies for changelog generation. - Improved documentation in `README.md` for programmatic API usage. - Cleaned up and organized changelog generation scripts.
1 parent a3e6274 commit f8b2a08

File tree

11 files changed

+812
-269
lines changed

11 files changed

+812
-269
lines changed

configs/release-config/README.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,94 @@ This command:
9696

9797
**Note:** This is typically a one-time operation during initial setup or migration.
9898

99+
## Programmatic API for Changelog Generation
100+
101+
You can also use the changelog generation functionality programmatically in your own scripts:
102+
103+
### Using the CLI
104+
105+
```bash
106+
# Install the package
107+
yarn add -D @vc-shell/release-config
108+
109+
# Create a configuration file
110+
npx vc-generate-changelogs --help
111+
112+
# Run with your config
113+
npx vc-generate-changelogs changelog-config.js
114+
```
115+
116+
### Using the JavaScript API
117+
118+
```typescript
119+
import { generateInitialChangelogs, PackageConfig } from "@vc-shell/release-config";
120+
121+
const packages: PackageConfig[] = [
122+
{
123+
name: "framework",
124+
path: "framework",
125+
displayName: "Framework (@vc-shell/framework)"
126+
},
127+
{
128+
name: "cli/api-client",
129+
path: "cli/api-client",
130+
displayName: "API Client Generator (@vc-shell/api-client-generator)"
131+
},
132+
// ... more packages
133+
];
134+
135+
await generateInitialChangelogs({
136+
packages,
137+
rootDir: process.cwd(), // Optional: root directory
138+
generateRoot: true, // Optional: generate root changelog
139+
includeRootHeader: true // Optional: include header in root changelog
140+
});
141+
```
142+
143+
### Configuration File Format
144+
145+
Create a `changelog-config.js` file:
146+
147+
```javascript
148+
export default {
149+
packages: [
150+
{
151+
name: "framework",
152+
path: "framework",
153+
displayName: "Framework (@vc-shell/framework)"
154+
},
155+
// ... more packages
156+
],
157+
rootDir: process.cwd(),
158+
generateRoot: true,
159+
includeRootHeader: true,
160+
};
161+
```
162+
163+
### Generating Only Root Changelog
164+
165+
If you already have package changelogs and want to regenerate just the root one:
166+
167+
```typescript
168+
import { generateRootChangelog } from "@vc-shell/release-config";
169+
170+
await generateRootChangelog({
171+
packages,
172+
rootDir: process.cwd(),
173+
includeRootHeader: true,
174+
});
175+
```
176+
177+
### Use Cases
178+
179+
This programmatic API is useful for:
180+
- **Custom monorepo structures** - Different from standard VC-Shell layout
181+
- **CI/CD pipelines** - Automated changelog generation
182+
- **Migration scripts** - One-time setup for new repositories
183+
- **Custom workflows** - Integration with other release tools
184+
185+
See [changelog-config.example.js](./changelog-config.example.js) for a complete configuration example.
186+
99187
### Root CHANGELOG Format
100188

101189
The root `CHANGELOG.md` groups changes by package for each version:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Example configuration for changelog generation
3+
* Copy this file and adjust the packages array to match your project structure
4+
*/
5+
6+
export default {
7+
// Array of packages to generate changelogs for
8+
packages: [
9+
{
10+
name: "framework",
11+
path: "framework",
12+
displayName: "Framework (@vc-shell/framework)"
13+
},
14+
{
15+
name: "cli/api-client",
16+
path: "cli/api-client",
17+
displayName: "API Client Generator (@vc-shell/api-client-generator)"
18+
},
19+
// Add more packages as needed...
20+
],
21+
22+
// Optional: Root directory (defaults to process.cwd())
23+
rootDir: process.cwd(),
24+
25+
// Optional: Generate consolidated root changelog (defaults to true)
26+
generateRoot: true,
27+
28+
// Optional: Include header in root changelog (defaults to true)
29+
includeRootHeader: true,
30+
};

configs/release-config/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@
77
"files": [
88
"dist"
99
],
10+
"bin": {
11+
"vc-generate-changelogs": "./dist/cli-generate-changelogs.js"
12+
},
1013
"scripts": {
1114
"build": "vite build"
1215
},
1316
"dependencies": {
1417
"chalk": "^2.4.2",
18+
"conventional-changelog-cli": "^5.0.0",
1519
"cross-spawn": "^7.0.3",
1620
"lerna": "^9.0.0",
1721
"mri": "^1.2.0",
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env node
2+
import { generateInitialChangelogs, PackageConfig } from "./generate-changelogs.js";
3+
import { readFileSync } from "node:fs";
4+
import { resolve } from "node:path";
5+
import chalk from "chalk";
6+
7+
/**
8+
* CLI for generating initial changelogs
9+
* Usage: vc-generate-changelogs [config-file]
10+
*
11+
* Config file should export an object with:
12+
* {
13+
* packages: Array<{ name: string, path: string, displayName: string }>,
14+
* rootDir?: string,
15+
* generateRoot?: boolean,
16+
* includeRootHeader?: boolean
17+
* }
18+
*/
19+
20+
async function main() {
21+
const args = process.argv.slice(2);
22+
23+
if (args.includes("--help") || args.includes("-h")) {
24+
console.log(`
25+
${chalk.cyan("vc-generate-changelogs")} - Generate CHANGELOG.md files from git history
26+
27+
${chalk.bold("USAGE:")}
28+
vc-generate-changelogs [config-file]
29+
30+
${chalk.bold("ARGUMENTS:")}
31+
config-file Path to configuration file (default: changelog-config.js)
32+
33+
${chalk.bold("CONFIG FILE FORMAT:")}
34+
The config file should export an object with the following structure:
35+
36+
export default {
37+
packages: [
38+
{
39+
name: "framework",
40+
path: "framework",
41+
displayName: "Framework (@vc-shell/framework)"
42+
},
43+
// ... more packages
44+
],
45+
rootDir: process.cwd(), // Optional: root directory
46+
generateRoot: true, // Optional: generate root changelog
47+
includeRootHeader: true // Optional: include header in root changelog
48+
};
49+
50+
${chalk.bold("EXAMPLE:")}
51+
vc-generate-changelogs changelog-config.js
52+
`);
53+
process.exit(0);
54+
}
55+
56+
const configPath = args[0] || "changelog-config.js";
57+
const resolvedPath = resolve(process.cwd(), configPath);
58+
59+
try {
60+
console.log(chalk.blue(`📖 Loading config from ${resolvedPath}...`));
61+
62+
// Dynamic import for ESM support
63+
const config = await import(resolvedPath);
64+
const options = config.default || config;
65+
66+
if (!options.packages || !Array.isArray(options.packages)) {
67+
console.error(chalk.red("\n❌ Error: Config must export an object with 'packages' array"));
68+
console.error(chalk.yellow("\nExpected format:"));
69+
console.error(chalk.gray(" export default { packages: [...] }"));
70+
process.exit(1);
71+
}
72+
73+
// Validate package configs
74+
for (const pkg of options.packages) {
75+
if (!pkg.name || !pkg.path || !pkg.displayName) {
76+
console.error(chalk.red(`\n❌ Error: Invalid package config: ${JSON.stringify(pkg)}`));
77+
console.error(chalk.yellow("\nEach package must have: name, path, displayName"));
78+
process.exit(1);
79+
}
80+
}
81+
82+
await generateInitialChangelogs(options);
83+
} catch (error) {
84+
if ((error as NodeJS.ErrnoException).code === "MODULE_NOT_FOUND" ||
85+
(error as NodeJS.ErrnoException).code === "ERR_MODULE_NOT_FOUND") {
86+
console.error(chalk.red(`\n❌ Error: Config file not found: ${resolvedPath}`));
87+
console.error(chalk.yellow("\nCreate a config file or specify a different path."));
88+
console.error(chalk.gray("\nRun 'vc-generate-changelogs --help' for more information."));
89+
} else {
90+
console.error(chalk.red("\n❌ Error generating changelogs:"), error);
91+
}
92+
process.exit(1);
93+
}
94+
}
95+
96+
main();

0 commit comments

Comments
 (0)