Skip to content

Commit

Permalink
Allow prerelease versions in release headers (#130)
Browse files Browse the repository at this point in the history
Currently, this tool expects the version in a release header to be a
version that looks like `<major>.<minor>.<patch>` and rejects other
formats. However, it may be useful to publish a prerelease version of a
package so that integration with other products/services can be tested
in a more "live" manner, particularly if that package is a part of a
monorepo. A prerelease version looks like
`<major>.<minor>.<patch>-<prerelease identifier>.<number>`, where
`<prerelease identifier>` can be an arbitrary word like `alpha`, `beta`,
or `rc`. This commit allows such versions.
  • Loading branch information
mcmire authored Nov 15, 2022
1 parent 9beab40 commit dcf3e3d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
65 changes: 65 additions & 0 deletions src/parse-changelog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,45 @@ describe('parseChangelog', () => {
expect(changelog.getUnreleasedChanges()).toStrictEqual({});
});

it('should parse changelog with prereleases', () => {
const changelog = parseChangelog({
changelogContent: outdent`
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.0.0-rc.1] - 2020-01-01
### Changed
- Something else
## [0.0.2-beta.1] - 2020-01-01
### Fixed
- Something
## [0.0.1-alpha.1] - 2020-01-01
### Changed
- Something
[Unreleased]: https://github.com/ExampleUsernameOrOrganization/ExampleRepository/compare/v1.0.0-rc.1...HEAD
[1.0.0-rc.1]: https://github.com/ExampleUsernameOrOrganization/ExampleRepository/compare/v0.0.2-beta.1...v1.0.0-rc.1
[0.0.2-beta.1]: https://github.com/ExampleUsernameOrOrganization/ExampleRepository/compare/v0.0.1-alpha.1...v0.0.2-beta.1
[0.0.1-alpha.1]: https://github.com/ExampleUsernameOrOrganization/ExampleRepository/releases/tag/v0.0.1-alpha.1
`,
repoUrl:
'https://github.com/ExampleUsernameOrOrganization/ExampleRepository',
});

expect(changelog.getReleases()).toStrictEqual([
{ date: '2020-01-01', status: undefined, version: '1.0.0-rc.1' },
{ date: '2020-01-01', status: undefined, version: '0.0.2-beta.1' },
{ date: '2020-01-01', status: undefined, version: '0.0.1-alpha.1' },
]);
});

it('should parse changelog with release statuses', () => {
const changelog = parseChangelog({
changelogContent: outdent`
Expand Down Expand Up @@ -508,6 +547,32 @@ describe('parseChangelog', () => {
).toThrow(`Malformed release header: '## [1.0.0 - 2020-01-01'`);
});

it('should throw if version in release header is not SemVer-compatible', () => {
const brokenChangelog = outdent`
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.2.3.4]
### Changed
- Something else
[Unreleased]: https://github.com/ExampleUsernameOrOrganization/ExampleRepository/compare/v1.2.3.4...HEAD
[1.2.3.4]: https://github.com/ExampleUsernameOrOrganization/ExampleRepository/releases/tag/v1.2.3.4
`;
expect(() =>
parseChangelog({
changelogContent: brokenChangelog,
repoUrl:
'https://github.com/ExampleUsernameOrOrganization/ExampleRepository',
}),
).toThrow(`Invalid SemVer version in release header: '## [1.2.3.4]`);
});

it('should throw if release header uses the wrong header level', () => {
const brokenChangelog = outdent`
# Changelog
Expand Down
9 changes: 8 additions & 1 deletion src/parse-changelog.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import semver from 'semver';
import Changelog from './changelog';
import { ChangeCategory, unreleased } from './constants';

Expand Down Expand Up @@ -107,12 +108,18 @@ export function parseChangelog({
for (const line of contentfulChangelogLines) {
if (line.startsWith('## [')) {
const results = line.match(
/^## \[(\d+\.\d+\.\d+)\](?: - (\d\d\d\d-\d\d-\d\d))?(?: \[(\w+)\])?/u,
/^## \[([^[\]]+)\](?: - (\d\d\d\d-\d\d-\d\d))?(?: \[(\w+)\])?/u,
);
if (results === null) {
throw new Error(`Malformed release header: '${truncated(line)}'`);
}

if (semver.valid(results[1]) === null) {
throw new Error(
`Invalid SemVer version in release header: '${truncated(line)}'`,
);
}

// Trailing newline removed because the release section is expected to
// be prefixed by a newline.
finalizePreviousChange({
Expand Down

0 comments on commit dcf3e3d

Please sign in to comment.