Skip to content

Commit b45ba6c

Browse files
Planeshifterkgryte
andauthored
build: add tooling for changelog generation
PR-URL: stdlib-js#1289 Co-authored-by: Athan Reines <[email protected]> Reviewed-by: Athan Reines <[email protected]> Signed-off-by: Athan Reines <[email protected]> Signed-off-by: Philipp Burckhardt <[email protected]>
1 parent 991376b commit b45ba6c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3374
-12
lines changed

.github/workflows/standalone_publish.yml

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ on:
3333
- patch
3434
- minor
3535
- major
36+
- auto
3637
dry-run:
3738
type: boolean
3839
description: 'Skip uploading packages (dry run):'

.github/workflows/standalone_publish_custom.yml

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ on:
4848
- patch
4949
- minor
5050
- major
51+
- auto
5152
only-unpublished:
5253
type: boolean
5354
description: 'Only publish packages that have not yet been published'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2024 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# Changelog
22+
23+
> Changelog tooling.
24+
25+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
26+
27+
<section class="intro">
28+
29+
This directory contains utilities for managing and maintaining changelogs of project packages.
30+
31+
</section>
32+
33+
<!-- /.intro -->
34+
35+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
36+
37+
<section class="related">
38+
39+
</section>
40+
41+
<!-- /.related -->
42+
43+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
44+
45+
<section class="links">
46+
47+
</section>
48+
49+
<!-- /.links -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2024 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# Generate Changelog
22+
23+
> Generate a changelog for a specified stdlib package.
24+
25+
<section class="usage">
26+
27+
## Usage
28+
29+
```javascript
30+
var generate = require( '@stdlib/_tools/changelog/generate' );
31+
```
32+
33+
#### generate( pkg\[, releaseType] )
34+
35+
Generates a Markdown formatted changelog for a specified package.
36+
37+
```javascript
38+
var changelog = generate( '@stdlib/assert/contains' );
39+
// returns {...}
40+
```
41+
42+
The function returns an object with the following properties:
43+
44+
- **content**: Markdown formatted changelog.
45+
- **releaseType**: release type (`null` if changelog is for a non-release).
46+
47+
To generate a changelog for an upcoming release, provide a valid release type as the second argument.
48+
49+
```javascript
50+
var changelog = generate( '@stdlib/assert/contains', 'patch' );
51+
// returns {...}
52+
53+
changelog = generate( '@stdlib/assert/contains', 'minor' );
54+
// returns {...}
55+
```
56+
57+
The following release types are supported:
58+
59+
- `patch`: a patch release (e.g., bug fixes).
60+
- `minor`: a minor release (e.g., new features which do not break backward compatibility).
61+
- `major`: a major release (e.g., breaking changes).
62+
- `prerelease`: a prerelease (e.g., a release candidate).
63+
- `prepatch`: a prepatch release.
64+
- `preminor`: a preminor release.
65+
- `premajor`: a premajor release.
66+
- `auto`: automatically determine the release type based on parsed commit messages.
67+
68+
</section>
69+
70+
<!-- /.usage -->
71+
72+
<section class="notes">
73+
74+
</section>
75+
76+
<!-- /.notes -->
77+
78+
<section class="examples">
79+
80+
## Examples
81+
82+
```javascript
83+
var generate = require( '@stdlib/_tools/changelog/generate' );
84+
85+
// Generate a changelog for a non-namespace package:
86+
var changelog = generate( '@stdlib/utils/curry' );
87+
var content = changelog.content;
88+
// returns '...'
89+
90+
var releaseType = changelog.releaseType;
91+
// returns null
92+
93+
// Generate a changelog for a new release:
94+
changelog = generate( '@stdlib/utils/curry', 'patch' );
95+
content = changelog.content;
96+
// returns '...'
97+
98+
releaseType = changelog.releaseType;
99+
// returns 'patch'
100+
101+
// Generate a changelog for a namespace package:
102+
changelog = generate( '@stdlib/string/base' );
103+
content = changelog.content;
104+
// returns '...'
105+
```
106+
107+
</section>
108+
109+
<!-- /.examples -->
110+
111+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
112+
113+
<section class="related">
114+
115+
</section>
116+
117+
<!-- /.related -->
118+
119+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
120+
121+
<section class="links">
122+
123+
</section>
124+
125+
<!-- /.links -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 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+
'use strict';
20+
21+
var generate = require( './../lib' );
22+
23+
// Generate a changelog for a non-namespace package:
24+
var changelog = generate( '@stdlib/utils/curry' );
25+
var content = changelog.content;
26+
console.log( content );
27+
// => '...'
28+
29+
var releaseType = changelog.releaseType;
30+
console.log( releaseType );
31+
// => null
32+
33+
// Generate a changelog for a new release:
34+
changelog = generate( '@stdlib/utils/curry', 'patch' );
35+
content = changelog.content;
36+
console.log( content );
37+
// => '...'
38+
39+
releaseType = changelog.releaseType;
40+
console.log( releaseType );
41+
// => 'patch'
42+
43+
// Generate a changelog for a namespace package:
44+
changelog = generate( '@stdlib/string/base' );
45+
content = changelog.content;
46+
console.log( content );
47+
// => '...'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
2+
/**
3+
* @license Apache-2.0
4+
*
5+
* Copyright (c) 2024 The Stdlib Authors.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
20+
'use strict';
21+
22+
// MODULES //
23+
24+
var filter = require( '@stdlib/array/base/filter' );
25+
var trim = require( '@stdlib/string/trim' );
26+
var map = require( '@stdlib/utils/map' );
27+
var collectField = require( './collect_field.js' );
28+
var sectionStart = require( './section_start.js' );
29+
var sectionEnd = require( './section_end.js' );
30+
var heading = require( './heading.js' );
31+
32+
33+
// VARIABLES //
34+
35+
var STDLIB_GITHUB_URL = 'https://github.com/stdlib-js/stdlib/commit';
36+
37+
38+
// FUNCTIONS //
39+
40+
/**
41+
* Formats a breaking change.
42+
*
43+
* @private
44+
* @param {Object} note - note object
45+
* @returns {string} changelog entry
46+
*
47+
* @example
48+
* var note = {
49+
* 'title': 'BREAKING CHANGE',
50+
* 'text': 'beep',
51+
* 'hash': 'abcdef1234567890'
52+
* };
53+
* var out = formatBreakingChange( note );
54+
* // returns '- [`abcdef1`](https://github.com/stdlib-js/stdlib/commit/abcdef1234567890): beep'
55+
*/
56+
function formatBreakingChange( note ) {
57+
var parts = note.text.split( '\n' );
58+
var hash = trim( note.hash );
59+
var out = '- [`'+hash.substring( 0, 7 )+'`]('+STDLIB_GITHUB_URL+'/'+hash+'): '+parts[ 0 ];
60+
if ( parts.length > 1 ) {
61+
out +=' \n\n';
62+
out += ' - ';
63+
out += parts.slice( 1 ).join( '\n ' );
64+
out += '\n';
65+
}
66+
return out;
67+
}
68+
69+
/**
70+
* Tests whether a note is a breaking change.
71+
*
72+
* @private
73+
* @param {Object} note - note object
74+
* @returns {boolean} boolean indicating whether a note is a breaking change
75+
*/
76+
function isBreakingChange( note ) {
77+
return note.title === 'BREAKING CHANGE';
78+
}
79+
80+
81+
// MAIN //
82+
83+
/**
84+
* Extracts breaking changes from a list of commits and formats them as a Markdown list.
85+
*
86+
* @private
87+
* @param {ObjectArray} commits - commit objects
88+
* @returns {string} list of breaking changes
89+
*/
90+
function breakingChanges( commits ) {
91+
var breakingChanges;
92+
var notes;
93+
var out;
94+
95+
notes = collectField( commits, 'notes' );
96+
breakingChanges = filter( notes, isBreakingChange );
97+
if ( breakingChanges.length === 0 ) {
98+
return '';
99+
}
100+
out = sectionStart( 'breaking-changes' );
101+
out += heading( 'BREAKING CHANGES', 3 );
102+
out += map( breakingChanges, formatBreakingChange ).join( '\n' );
103+
out += sectionEnd( 'breaking-changes' );
104+
return out;
105+
}
106+
107+
108+
// EXPORTS //
109+
110+
module.exports = breakingChanges;

0 commit comments

Comments
 (0)