Skip to content

Commit f23d66e

Browse files
Planeshifterkgryte
andauthored
build: add workflow to generate monthly changelog
PR-URL: #5983 Closes: stdlib-js/metr-issue-tracker#6 Co-authored-by: Athan Reines <[email protected]> Reviewed-by: Athan Reines <[email protected]>
1 parent f193925 commit f23d66e

File tree

16 files changed

+615
-29
lines changed

16 files changed

+615
-29
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#/
2+
# @license Apache-2.0
3+
#
4+
# Copyright (c) 2025 The Stdlib Authors.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#/
18+
19+
# Workflow name:
20+
name: generate_monthly_changelog
21+
22+
# Workflow triggers:
23+
on:
24+
# Run the workflow at midnight UTC on the first day of each month:
25+
schedule:
26+
- cron: '0 0 1 * *'
27+
28+
# Allow the workflow to be manually run:
29+
workflow_dispatch:
30+
31+
# Global permissions:
32+
permissions:
33+
# Allow read-only access to the repository contents:
34+
contents: read
35+
36+
# Workflow jobs:
37+
jobs:
38+
# Generate a monthly changelog:
39+
generate-monthly-changelog:
40+
# Define a display name:
41+
name: 'Generate Monthly Changelog'
42+
43+
# Define the type of virtual host machine:
44+
runs-on: ubuntu-latest
45+
46+
# Workflow steps:
47+
steps:
48+
- name: 'Checkout source repository'
49+
# Pin action to full length commit SHA
50+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
51+
with:
52+
# Specify whether to remove untracked files before checking out the repository:
53+
clean: false
54+
55+
# Limit clone depth to the most recent commit:
56+
fetch-depth: 1
57+
58+
# Token for accessing the repository:
59+
token: ${{ secrets.STDLIB_BOT_FGPAT_REPO_READ }}
60+
61+
# Avoid storing GitHub token in local Git configuration:
62+
persist-credentials: false
63+
64+
# Install Node.js:
65+
- name: 'Install Node.js'
66+
# Pin action to full length commit SHA
67+
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
68+
with:
69+
node-version: '20' # 'lts/*'
70+
timeout-minutes: 5
71+
72+
# Install dependencies (accounting for possible network failures, etc, when installing node module dependencies):
73+
- name: 'Install dependencies'
74+
run: |
75+
make install-node-modules || make install-node-modules || make install-node-modules
76+
timeout-minutes: 15
77+
78+
- name: 'Checkout monthly changelog repository'
79+
# Pin action to full length commit SHA
80+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
81+
with:
82+
# Monthly changelog repository:
83+
repository: 'stdlib-js/www-blog-monthly-changelog'
84+
85+
# File path to checkout to:
86+
path: './www-blog-monthly-changelog'
87+
88+
# Specify whether to remove untracked files before checking out the repository:
89+
clean: false
90+
91+
# Limit clone depth to the most recent commit:
92+
fetch-depth: 1
93+
94+
# Token for accessing the repository:
95+
token: ${{ secrets.STDLIB_BOT_FGPAT_REPO_READ }}
96+
97+
# Avoid storing GitHub token in local Git configuration:
98+
persist-credentials: false
99+
100+
# Generate changelog for last month:
101+
- name: 'Generate changelog for last month'
102+
run: |
103+
UNTIL=$(date +"%Y-%m-01")
104+
node -e "
105+
var generate = require( '@stdlib/_tools/changelog/generate' );
106+
var changelog = generate( '@stdlib', {
107+
'flags': {
108+
'since': '$UNTIL - 1 month',
109+
'until': '$UNTIL'
110+
},
111+
'format': 'aggregated'
112+
});
113+
console.log( changelog.content );
114+
115+
" > ./www-blog-monthly-changelog/monthly_changelog_${UNTIL//-/_}.md
116+
117+
# Import GPG key to sign commits:
118+
- name: 'Import GPG key to sign commits'
119+
# Pin action to full length commit SHA
120+
uses: crazy-max/ghaction-import-gpg@cb9bde2e2525e640591a934b1fd28eef1dcaf5e5 # v6.2.0
121+
with:
122+
gpg_private_key: ${{ secrets.STDLIB_BOT_GPG_PRIVATE_KEY }}
123+
passphrase: ${{ secrets.STDLIB_BOT_GPG_PASSPHRASE }}
124+
git_user_signingkey: true
125+
git_commit_gpgsign: true
126+
127+
# Commit and push changes:
128+
- name: 'Commit and push changes'
129+
env:
130+
REPO_GITHUB_TOKEN: ${{ secrets.STDLIB_BOT_PAT_REPO_WRITE }}
131+
USER_NAME: stdlib-bot
132+
run: |
133+
cd ./www-blog-monthly-changelog
134+
git config --local user.email "[email protected]"
135+
git config --local user.name "stdlib-bot"
136+
git add .
137+
git commit -m "Add monthly changelog" || exit 0
138+
git push "https://$USER_NAME:[email protected]/stdlib-js/www-blog-monthly-changelog.git" main

lib/node_modules/@stdlib/_tools/changelog/generate/README.md

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ limitations under the License.
3030
var generate = require( '@stdlib/_tools/changelog/generate' );
3131
```
3232

33-
#### generate( pkg\[, releaseType] )
33+
#### generate( pkg\[, options] )
3434

3535
Generates a Markdown formatted changelog for a specified package.
3636

37+
<!-- run-disable -->
38+
3739
```javascript
3840
var changelog = generate( '@stdlib/assert/contains' );
3941
// returns {...}
@@ -44,13 +46,30 @@ The function returns an object with the following properties:
4446
- **content**: Markdown formatted changelog.
4547
- **releaseType**: release type (`null` if changelog is for a non-release).
4648

47-
To generate a changelog for an upcoming release, provide a valid release type as the second argument.
49+
The function accepts the following `options`:
50+
51+
- **releaseType**: a release type for which to generate the changelog.
52+
53+
- **format**: changelog format. Must be one of the following:
54+
55+
- `'grouped'`: group commits by package.
56+
- `'aggregated'`: display all commits in a flat list without grouping commits by package.
57+
58+
- **flags**: `git log` options used to retrieve commits from which to generate the changelog.
59+
60+
By default, the changelog is generated for a non-release. To generate a changelog for an upcoming release, provide a valid release type:
61+
62+
<!-- run-disable -->
4863

4964
```javascript
50-
var changelog = generate( '@stdlib/assert/contains', 'patch' );
65+
var changelog = generate( '@stdlib/assert/contains', {
66+
'releaseType': 'patch'
67+
});
5168
// returns {...}
5269

53-
changelog = generate( '@stdlib/assert/contains', 'minor' );
70+
changelog = generate( '@stdlib/assert/contains', {
71+
'releaseType': 'minor'
72+
});
5473
// returns {...}
5574
```
5675

@@ -66,6 +85,44 @@ The following release types are supported:
6685
- `auto`: automatically determine the release type based on parsed commit messages.
6786
- `none`: no release (equivalent to not specifying a release type).
6887

88+
By default, the function generates a `grouped` changelog for namespace packages and an `aggregated` changelog for non-namespace packages. To specify a desired output format, set the `format` option:
89+
90+
<!-- run-disable -->
91+
92+
```javascript
93+
// Changelog grouped by individual packages:
94+
var changelog = generate( '@stdlib/math/base/utils', {
95+
'format': 'grouped'
96+
});
97+
// returns {...}
98+
99+
// Changelog where all commits, potentially touching many different packages, are merged together:
100+
changelog = generate( '@stdlib/math/base/utils', {
101+
'format': 'aggregated'
102+
});
103+
// returns {...}
104+
```
105+
106+
When generating a changelog, the function uses `git log` to retrieve the commits from which to assemble a set of changes. The `flags` option allows passing options to directly to the `git log` command (e.g., to generate a changelog for a specified time interval or for an individual contributor).
107+
108+
<!-- run-disable -->
109+
110+
```javascript
111+
var changelog = generate( '@stdlib/ndarray', {
112+
'flags': {
113+
'since': 'last year'
114+
}
115+
});
116+
// returns {...}
117+
118+
changelog = generate( '@stdlib/ndarray', {
119+
'flags': {
120+
'author': 'Athan Reines <[email protected]>'
121+
}
122+
});
123+
// returns {...}
124+
```
125+
69126
</section>
70127

71128
<!-- /.usage -->
@@ -80,6 +137,8 @@ The following release types are supported:
80137

81138
## Examples
82139

140+
<!-- run-disable -->
141+
83142
```javascript
84143
var generate = require( '@stdlib/_tools/changelog/generate' );
85144

@@ -92,7 +151,9 @@ var releaseType = changelog.releaseType;
92151
// returns null
93152

94153
// Generate a changelog for a new release:
95-
changelog = generate( '@stdlib/utils/curry', 'patch' );
154+
changelog = generate( '@stdlib/utils/curry', {
155+
'releaseType': 'patch'
156+
});
96157
content = changelog.content;
97158
// returns '...'
98159

@@ -103,6 +164,15 @@ releaseType = changelog.releaseType;
103164
changelog = generate( '@stdlib/string/base' );
104165
content = changelog.content;
105166
// returns '...'
167+
168+
// Generate a changelog restricted to a single author:
169+
changelog = generate( '@stdlib/string/base', {
170+
'flags': {
171+
'author': 'Athan Reines <[email protected]>'
172+
}
173+
});
174+
content = changelog.content;
175+
// returns '...'
106176
```
107177

108178
</section>

lib/node_modules/@stdlib/_tools/changelog/generate/examples/index.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ console.log( releaseType );
3131
// => null
3232

3333
// Generate a changelog for a new release:
34-
changelog = generate( '@stdlib/utils/curry', 'patch' );
34+
changelog = generate( '@stdlib/utils/curry', {
35+
'releaseType': 'patch'
36+
});
3537
content = changelog.content;
3638
console.log( content );
3739
// => '...'
@@ -45,3 +47,12 @@ changelog = generate( '@stdlib/string/base' );
4547
content = changelog.content;
4648
console.log( content );
4749
// => '...'
50+
51+
// Generate a changelog restricted to a single author:
52+
changelog = generate( '@stdlib/string/base', {
53+
'flags': {
54+
'author': 'Athan Reines <[email protected]>'
55+
}
56+
});
57+
content = changelog.content;
58+
console.log( content );

0 commit comments

Comments
 (0)