Skip to content

Commit 1dc8f90

Browse files
author
Fabiana Severin
committed
Adding automated changelog generation
1 parent faaa65f commit 1dc8f90

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-1
lines changed

.github/workflows/build-and-release.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ jobs:
152152
# env:
153153
# NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
154154

155+
- name: Generate Changelog
156+
run: |
157+
node scripts/generate-changelog.js --output changelog.md
158+
echo "Generated changelog:"
159+
cat changelog.md
160+
155161
- name: Create GitHub Release
156162
uses: softprops/action-gh-release@v2
157163
with:
@@ -162,7 +168,7 @@ jobs:
162168
checksums.txt
163169
prerelease: ${{ steps.version.outputs.is_rc }}
164170
name: ${{ steps.version.outputs.is_rc == 'true' && format('Release Candidate {0}', steps.version.outputs.package_version) || '' }}
165-
generate_release_notes: true
171+
body_path: changelog.md
166172

167173
test-publish:
168174
if: (github.event_name == 'workflow_dispatch' && github.event.inputs.test_mode != 'none') || github.ref == 'refs/heads/fabisev/artifact-publishing'

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,19 @@ When modifying dependencies (`package.json`), make sure to:
172172

173173
We require package-lock.json to be checked in to ensure consistent installations across development environments.
174174

175+
### Changelog Generation
176+
This project includes an automated changelog generator that creates a list of commits between tags when a new release is created. The changelog is automatically included in GitHub release notes.
177+
178+
To manually generate a changelog:
179+
```shell script
180+
npm run changelog
181+
```
182+
183+
You can also specify custom options:
184+
```shell script
185+
npm run changelog -- --start-ref v1.0.0 --end-ref HEAD --output CHANGELOG.md
186+
```
187+
175188
### Copyright Headers
176189
All source files in the bin, scripts, src, and test folders must include a copyright header containing both the words "Copyright" and "Amazon.com". The standard header format is:
177190

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"gypfile": true,
88
"scripts": {
99
"archive": "npx rimraf aws-lambda-ric-*.tgz && npm install && npm run build && npm pack",
10+
"changelog": "node ./scripts/generate-changelog.js",
1011
"clean": "npx rimraf build node_modules package-lock.json",
1112
"copy-files": "mkdir -p dist && cp src/types/* dist/",
1213
"update-deps": "./scripts/update_dependencies.sh",

scripts/generate-changelog.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env node
2+
/*
3+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
const { execSync } = require('child_process');
8+
const fs = require('fs');
9+
const path = require('path');
10+
11+
/**
12+
* Simple changelog generator that creates a markdown formatted list of commits
13+
* between the last tag and HEAD (or between two specified git refs)
14+
*/
15+
16+
// Parse command line arguments
17+
const args = process.argv.slice(2);
18+
let startRef = '';
19+
let endRef = 'HEAD';
20+
let outputFile = '';
21+
22+
// Process arguments
23+
for (let i = 0; i < args.length; i++) {
24+
if (args[i] === '--start-ref' && i + 1 < args.length) {
25+
startRef = args[i + 1];
26+
i++;
27+
} else if (args[i] === '--end-ref' && i + 1 < args.length) {
28+
endRef = args[i + 1];
29+
i++;
30+
} else if (args[i] === '--output' && i + 1 < args.length) {
31+
outputFile = args[i + 1];
32+
i++;
33+
}
34+
}
35+
36+
// If no start ref is provided, use the last tag
37+
if (!startRef) {
38+
try {
39+
startRef = execSync('git describe --tags --abbrev=0').toString().trim();
40+
console.log(`Using last tag as start ref: ${startRef}`);
41+
} catch (error) {
42+
console.error('No tags found. Using first commit as start ref.');
43+
startRef = execSync('git rev-list --max-parents=0 HEAD').toString().trim();
44+
}
45+
}
46+
47+
// Get repository info from package.json
48+
const packageJson = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8'));
49+
const repoUrl = packageJson.repository && packageJson.repository.url
50+
? packageJson.repository.url.replace(/^git\+|\.git$/g, '')
51+
: 'https://github.com/aws/aws-lambda-nodejs-runtime-interface-client';
52+
53+
// Get commit range
54+
const commitRange = `${startRef}..${endRef}`;
55+
console.log(`Generating changelog for commit range: ${commitRange}`);
56+
57+
// Get commits
58+
const gitLogFormat = '%h %s';
59+
const gitLog = execSync(`git log ${commitRange} --pretty=format:"${gitLogFormat}"`).toString();
60+
61+
// Filter out version commits and format the changelog
62+
const commits = gitLog.split('\n')
63+
.filter(line => line.trim())
64+
.filter(line => {
65+
// Filter out version commits (just a version number)
66+
const message = line.substring(line.indexOf(' ') + 1);
67+
return !/^v?\d+\.\d+\.\d+(-.*)?$/.test(message) &&
68+
!message.startsWith('working on ') &&
69+
!message.startsWith('Working on ');
70+
})
71+
.map(line => {
72+
const hash = line.substring(0, line.indexOf(' '));
73+
const message = line.substring(line.indexOf(' ') + 1);
74+
75+
// Check if message starts with a category (e.g., "feat:", "fix:")
76+
let formattedMessage = message;
77+
const categoryMatch = message.match(/^(\w+):\s*(.*)/);
78+
if (categoryMatch) {
79+
const [, category, rest] = categoryMatch;
80+
formattedMessage = `**${category}**: ${rest}`;
81+
}
82+
83+
return `* [\`${hash}\`](${repoUrl}/commit/${hash}) - ${formattedMessage}`;
84+
});
85+
86+
// Generate the changelog content
87+
const changelogContent = commits.join('\n');
88+
89+
// Output the changelog
90+
if (outputFile) {
91+
fs.writeFileSync(outputFile, changelogContent);
92+
console.log(`Changelog written to ${outputFile}`);
93+
} else {
94+
console.log('\nChangelog:');
95+
console.log(changelogContent);
96+
}

0 commit comments

Comments
 (0)