diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index be2916b47..61ea303da 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -5,60 +5,18 @@ on: workflow_dispatch: workflow_call: outputs: - release_type: + release-type: description: The release type extracted from changelog - value: ${{ jobs.validate_changelog.outputs.release_type }} - no_functional_changes: - description: A boolean signaling that there are no functional changes in the changeset - value: ${{ jobs.check_functional_changes.outputs.no_functional_changes }} - + value: ${{ jobs.validate_changelog.outputs.release-type }} jobs: - check_functional_changes: - runs-on: [ ubuntu-latest ] - outputs: - no_functional_changes: ${{ steps.set_no_functional_changes.outputs.no_functional_changes }} - steps: - - uses: actions/checkout@v4 - - - name: Make release type available to subsequent jobs # For backwards compatibility, as this workflow is used in other Open Terms Archive repositories - run: | - if grep -q "## Unreleased \[no-release\]" CHANGELOG.md; then - echo "NO_FUNCTIONAL_CHANGES=true" >> $GITHUB_ENV - fi - - - name: Print result - id: set_no_functional_changes - run: | - echo "no_functional_changes='${{ env.NO_FUNCTIONAL_CHANGES }}'" - echo "no_functional_changes=${{ env.NO_FUNCTIONAL_CHANGES }}" >> $GITHUB_OUTPUT - - validate_changelog: - if: ${{ needs.check_functional_changes.outputs.no_functional_changes != 'true' }} - needs: [ check_functional_changes ] runs-on: [ ubuntu-latest ] outputs: - release_type: ${{ steps.set_release_type_output.outputs.release_type }} + release-type: ${{ steps.validate-changelog.outputs.release-type }} steps: - uses: actions/checkout@v4 - - name: Install dependencies - run: npm ci - - - name: Print no release assessment result - run: | - echo "Should this run NOT trigger any release: '${{ needs.check_functional_changes.outputs.no_release }}'" - - name: Validate changelog - run: npm run changelog --silent -- --validate - - - name: Get release type in changelog - run: echo "RELEASE_TYPE=$(npm run changelog --silent -- --get-release-type)" >> $GITHUB_ENV - - - name: Make release type available to subsequent jobs # For backwards compatibility, as this workflow is used in other Open Terms Archive repositories - if: env.RELEASE_TYPE - id: set_release_type_output - run: | - echo "Found release type '${{ env.RELEASE_TYPE }}'" - echo "release_type=${{ env.RELEASE_TYPE }}" >> $GITHUB_OUTPUT + id: validate-changelog + uses: OpenTermsArchive/changelog-action/validate@v0.2.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d10b42ac6..5ccccdde2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,12 +9,12 @@ on: jobs: changelog: - uses: "OpenTermsArchive/engine/.github/workflows/changelog.yml@main" + uses: "./.github/workflows/changelog.yml" test: uses: "OpenTermsArchive/engine/.github/workflows/test.yml@main" release: - if: github.event.pull_request.merged == true && needs.changelog.outputs.no_functional_changes != 'true' needs: [ changelog, test ] + if: needs.changelog.outputs.release-type != 'no-release' runs-on: ubuntu-latest steps: - name: Checkout @@ -22,29 +22,25 @@ jobs: with: token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }} - - name: Install dependencies - run: npm ci - - name: Configure Git author run: | git config --global user.name "Open Terms Archive Release Bot" git config --global user.email "release-bot@opentermsarchive.org" - - name: Bump package version - run: | - echo "Release type found: '$(npm run changelog --silent -- --get-release-type)'" - echo "NEW_VERSION=$(npm --no-git-tag-version version $(npm run changelog --silent -- --get-release-type))" >> $GITHUB_ENV + - name: Update changelog for release + id: release-changelog + uses: OpenTermsArchive/changelog-action/release@v0.2.0 - - name: Update changelog unreleased section with new version - run: npm run changelog --silent -- --release ${{ github.event.number }} # github.event.number refers to the pull request number + - name: Bump package version + run: npm --no-git-tag-version version ${{ steps.release-changelog.outputs.version }} - name: Commit CHANGELOG.md and package.json changes and create tag run: | git add "package.json" git add "package-lock.json" git add "CHANGELOG.md" - git commit -m "Release ${{ env.NEW_VERSION }}" - git tag ${{ env.NEW_VERSION }} + git commit -m "Release v${{ steps.release-changelog.outputs.version }}" + git tag v${{ steps.release-changelog.outputs.version }} - name: Run status checks for release commit on temporary branch # Use temporary branch to enable pushing commits to this branch protected by required status checks uses: CasperWA/push-protected@v2 @@ -66,7 +62,7 @@ jobs: uses: softprops/action-gh-release@v1 with: tag_name: ${{ env.NEW_VERSION }} - body: ${{ env.VERSION_CHANGELOG }} + body: ${{ steps.release-changelog.outputs.content }} token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }} - name: Publish to NPM public repository @@ -83,24 +79,23 @@ jobs: client-payload: '{"version": "${{ env.NEW_VERSION }}"}' clean_changelog: - if: github.event.pull_request.merged == true && needs.changelog.outputs.no_functional_changes == 'true' + if: needs.changelog.outputs.release-type == 'no-release' needs: [ changelog ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }} - - - name: Install dependencies - run: npm ci - name: Configure Git author run: | git config --global user.name "Open Terms Archive Release Bot" git config --global user.email "release-bot@opentermsarchive.org" - - name: Erase unreleased information from changelog + - name: Update changelog for release + uses: OpenTermsArchive/changelog-action/release@v0.2.0 + + - name: Save changelog run: | - npm run changelog --silent -- --clean-unreleased git commit -m "Clean changelog" CHANGELOG.md git push origin diff --git a/CHANGELOG.md b/CHANGELOG.md index 242c94665..8f1a1d8cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased [no-release] + +_Modifications made in this changeset do not add, remove or alter any behavior, dependency, API or functionality of the software. They only change non-functional parts of the repository, such as the README file or CI workflows._ + ## 2.2.1 - 2024-06-07 _Full changeset and discussions: [#1088](https://github.com/OpenTermsArchive/engine/pull/1088)._ diff --git a/scripts/changelog/changelog.js b/scripts/changelog/changelog.js deleted file mode 100644 index c058f2abf..000000000 --- a/scripts/changelog/changelog.js +++ /dev/null @@ -1,95 +0,0 @@ -import { parser as keepAChangelogParser } from 'keep-a-changelog'; -import semver from 'semver'; - -import ChangelogValidationError from './changelogValidationError.js'; - -export default class Changelog { - static NO_CODE_CHANGES_REGEX = /^_No code changes were made in this release(.+)_$/m; - static FUNDER_REGEX = /^> Development of this release was (?:supported|made on a volunteer basis) by (.+)\.$/m; - static UNRELEASED_REGEX = /## Unreleased[ ]+\[(major|minor|patch)\]/i; - static CHANGESET_LINK_REGEX = /^_Full changeset and discussions: (.+)._$/m; - static CHANGESET_LINK_TEMPLATE = PRNumber => `_Full changeset and discussions: [#${PRNumber}](https://github.com/OpenTermsArchive/engine/pull/${PRNumber})._`; - static CHANGELOG_INTRO = 'All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).'; - - constructor(rawContent) { - this.rawContent = rawContent; - this.changelog = keepAChangelogParser(this.rawContent); - this.changelog.description = Changelog.CHANGELOG_INTRO; - this.changelog.format = 'markdownlint'; - this.releaseType = this.extractReleaseType(); - } - - extractReleaseType() { - const match = this.rawContent.match(Changelog.UNRELEASED_REGEX); - - if (match && match[1]) { - return match[1].toLowerCase(); - } - - return null; - } - - cleanUnreleased() { - const index = this.changelog.releases.findIndex(release => !release.version); - - this.changelog.releases.splice(index, 1); - } - - getVersionContent(version) { - const release = this.changelog.findRelease(version); - - if (!release) { - throw new Error(`Version ${version} not found in changelog`); - } - - return release.toString(this.changelog); - } - - release(PRNumber) { - const unreleased = this.changelog.findRelease(); - - if (!unreleased) { - throw new Error('Missing "Unreleased" section'); - } - - const latestVersion = semver.maxSatisfying(this.changelog.releases.map(release => release.version), '*'); - const newVersion = semver.inc(latestVersion, this.releaseType); - - unreleased.setVersion(newVersion); - unreleased.date = new Date(); - - if (PRNumber && !Changelog.CHANGESET_LINK_REGEX.test(unreleased.description)) { - unreleased.description = `${Changelog.CHANGESET_LINK_TEMPLATE(PRNumber)}\n\n${unreleased.description}`; - } - } - - validateUnreleased() { - const unreleased = this.changelog.findRelease(); - const errors = []; - - if (!unreleased) { - errors.push(new Error('Missing "Unreleased" section')); - throw new ChangelogValidationError(errors); - } - - if (!this.releaseType) { - errors.push(new Error('Invalid or missing release type for "Unreleased" section. Please ensure the section contains a valid release type (major, minor, or patch)')); - } - - if (!Changelog.FUNDER_REGEX.test(unreleased.description)) { - errors.push(new Error('Missing funder in the "Unreleased" section')); - } - - if (!Changelog.NO_CODE_CHANGES_REGEX.test(unreleased.description) && (!unreleased.changes || Array.from(unreleased.changes.values()).every(change => !change.length))) { - errors.push(new Error('Missing or malformed changes in the "Unreleased" section')); - } - - if (errors.length) { - throw new ChangelogValidationError(errors); - } - } - - toString() { - return this.changelog.toString(); - } -} diff --git a/scripts/changelog/changelog.test.js b/scripts/changelog/changelog.test.js deleted file mode 100644 index 12b42354a..000000000 --- a/scripts/changelog/changelog.test.js +++ /dev/null @@ -1,144 +0,0 @@ -import fs from 'fs/promises'; -import path from 'path'; -import { fileURLToPath } from 'url'; - -import { expect } from 'chai'; - -import Changelog from './changelog.js'; -import ChangelogValidationError from './changelogValidationError.js'; - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - -describe('Changelog', () => { - let changelog; - - describe('#releaseType', () => { - context('with a properly formed changelog', () => { - it('returns the correct release type', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog.md'), 'UTF-8')); - expect(changelog.releaseType).to.equal('major'); - }); - }); - - context('when "Unreleased" section does not exist', () => { - it('returns null', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog-without-unreleased.md'), 'UTF-8')); - expect(changelog.releaseType).to.be.null; - }); - }); - context('when "Unreleased" section has a malformed release type', () => { - it('returns null', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog-with-unreleased-malformed.md'), 'UTF-8')); - expect(changelog.releaseType).to.be.null; - }); - }); - }); - - describe('#getVersionContent', () => { - context('when getting an exisiting version', () => { - it('returns the content of the specified version', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog.md'), 'UTF-8')); - const versionContent = changelog.getVersionContent('0.0.1'); - - expect(versionContent).to.equal(`## 0.0.1 - 2024-02-20 - -_Full changeset and discussions: #122._ - -> Development of this release was made on a volunteer basis by a contributor. - -### Added - -- Initial release`); - }); - }); - - context('when getting a non-existing version', () => { - it('throws an error', () => { - expect(() => changelog.getVersionContent('2.0.0')).to.throw(Error); - }); - }); - }); - - describe('#cleanUnreleased', () => { - context('when "Unreleased" section exists', () => { - it('removes the section', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog-with-unreleased-no-release.md'), 'UTF-8')); - changelog.cleanUnreleased(); - const updatedChangelog = changelog.toString(); - - expect(updatedChangelog).to.not.include('## Unreleased'); - }); - }); - - context('when "Unreleased" section does not exist', () => { - it('does not throw any error', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog-without-unreleased.md'), 'UTF-8')); - expect(() => changelog.cleanUnreleased()).to.not.throw(); - }); - }); - }); - - describe('#release', () => { - context('with a properly formed changelog', () => { - it('returns an updated version of the changelog', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog.md'), 'UTF-8')); - changelog.release(); - let expectedResult = await fs.readFile(path.resolve(__dirname, './fixtures/changelog-released.md'), 'UTF-8'); - - expectedResult = expectedResult.replace('', `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}-${String(new Date().getDate()).padStart(2, '0')}`); - expect(changelog.toString()).to.equal(expectedResult); - }); - }); - - context('when there is a validation error on the "Unreleased" section', () => { - it('throws an error', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog-without-unreleased.md'), 'UTF-8')); - expect(() => changelog.release(124)).to.throw(Error, 'Missing "Unreleased" section'); - }); - }); - }); - - describe('#validateUnreleased', () => { - context('with a properly formed "Unreleased" section', () => { - it('does not throw any error', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog.md'), 'UTF-8')); - expect(() => changelog.validateUnreleased()).to.not.throw(); - }); - }); - - context('when "Unreleased" section is missing', () => { - it('throws a ChangelogValidationError error with proper message', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog-without-unreleased.md'), 'UTF-8')); - expect(() => changelog.validateUnreleased()).to.throw(ChangelogValidationError, 'Missing "Unreleased" section'); - }); - }); - - context('when release type is invalid or missing', () => { - it('throws a ChangelogValidationError error with proper message', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog-with-unreleased-malformed.md'), 'UTF-8')); - expect(() => changelog.validateUnreleased()).to.throw(ChangelogValidationError, 'Invalid or missing release type for "Unreleased" section. Please ensure the section contains a valid release type (major, minor, or patch)'); - }); - }); - - context('when funder is missing', () => { - it('throws a ChangelogValidationError error with proper message', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog-without-funder.md'), 'UTF-8')); - expect(() => changelog.validateUnreleased()).to.throw(ChangelogValidationError, 'Missing funder in the "Unreleased" section'); - }); - }); - - context('when changes are missing', () => { - it('throws a ChangelogValidationError error with proper message', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog-without-changes.md'), 'UTF-8')); - expect(() => changelog.validateUnreleased()).to.throw(ChangelogValidationError, 'Missing or malformed changes in the "Unreleased" section'); - }); - }); - - context('when changes are malformed', () => { - it('throws a ChangelogValidationError error with proper message', async () => { - changelog = new Changelog(await fs.readFile(path.resolve(__dirname, './fixtures/changelog-without-changes.md'), 'UTF-8')); - expect(() => changelog.validateUnreleased()).to.throw(ChangelogValidationError, 'Missing or malformed changes in the "Unreleased" section'); - }); - }); - }); -}); diff --git a/scripts/changelog/changelogValidationError.js b/scripts/changelog/changelogValidationError.js deleted file mode 100644 index 7eaa70d12..000000000 --- a/scripts/changelog/changelogValidationError.js +++ /dev/null @@ -1,9 +0,0 @@ -export default class ChangelogValidationError extends Error { - constructor(errorOrErrors) { - const errors = [].concat(errorOrErrors); - - super(`Invalid Unreleased section:${`\n - ${errors.join('\n - ')}`}`); - this.name = 'ChangelogValidationError'; - this.errors = errors; - } -} diff --git a/scripts/changelog/fixtures/changelog-released.md b/scripts/changelog/fixtures/changelog-released.md deleted file mode 100644 index 52ec23bd2..000000000 --- a/scripts/changelog/fixtures/changelog-released.md +++ /dev/null @@ -1,23 +0,0 @@ -# Changelog - -All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 1.0.0 - - -_Full changeset and discussions: #123._ - -> Development of this release was supported by a funder. - -### Added - -- New feature 1 - -## 0.0.1 - 2024-02-20 - -_Full changeset and discussions: #122._ - -> Development of this release was made on a volunteer basis by a contributor. - -### Added - -- Initial release diff --git a/scripts/changelog/fixtures/changelog-with-changes-malformed.md b/scripts/changelog/fixtures/changelog-with-changes-malformed.md deleted file mode 100644 index d044dcb2c..000000000 --- a/scripts/changelog/fixtures/changelog-with-changes-malformed.md +++ /dev/null @@ -1,21 +0,0 @@ -# Changelog - -All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## Unreleased [major] - -_Full changeset and discussions: #123._ - -> Development of this release was supported by a funder. - -- New feature 1 - -## 0.0.1 - 2024-02-20 - -_Full changeset and discussions: #122._ - -> Development of this release was supported by a funder. - -### Added - -- Initial release diff --git a/scripts/changelog/fixtures/changelog-with-unreleased-malformed.md b/scripts/changelog/fixtures/changelog-with-unreleased-malformed.md deleted file mode 100644 index fc056225b..000000000 --- a/scripts/changelog/fixtures/changelog-with-unreleased-malformed.md +++ /dev/null @@ -1,23 +0,0 @@ -# Changelog - -All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## Unreleased major - -_Full changeset and discussions: #123._ - -> Development of this release was supported by a funder. - -### Added - -- New feature 1 - -## 0.0.1 - 2024-02-20 - -_Full changeset and discussions: #122._ - -> Development of this release was supported by a funder. - -### Added - -- Initial release diff --git a/scripts/changelog/fixtures/changelog-with-unreleased-no-release.md b/scripts/changelog/fixtures/changelog-with-unreleased-no-release.md deleted file mode 100644 index d5ca064f1..000000000 --- a/scripts/changelog/fixtures/changelog-with-unreleased-no-release.md +++ /dev/null @@ -1,21 +0,0 @@ -# Changelog - -All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## Unreleased [no-release] - -_Modifications made in this changeset do not alter its behavior or functionality from the perspective of the end user or other interacting systems. It does not add new features, do not enhance existing features, or alter the behavior of the software in a way that affects its use._ - -### Added - -- New feature 1 - -## 0.0.1 - 2024-02-20 - -_Full changeset and discussions: #122._ - -> Development of this release was supported by a funder. - -### Added - -- Initial release diff --git a/scripts/changelog/fixtures/changelog-without-changes.md b/scripts/changelog/fixtures/changelog-without-changes.md deleted file mode 100644 index a0778aac2..000000000 --- a/scripts/changelog/fixtures/changelog-without-changes.md +++ /dev/null @@ -1,19 +0,0 @@ -# Changelog - -All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## Unreleased [major] - -_Full changeset and discussions: #123._ - -> Development of this release was supported by a funder. - -## 0.0.1 - 2024-02-20 - -_Full changeset and discussions: #122._ - -> Development of this release was supported by a funder. - -### Added - -- Initial release diff --git a/scripts/changelog/fixtures/changelog-without-funder.md b/scripts/changelog/fixtures/changelog-without-funder.md deleted file mode 100644 index 2165a770f..000000000 --- a/scripts/changelog/fixtures/changelog-without-funder.md +++ /dev/null @@ -1,21 +0,0 @@ -# Changelog - -All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## Unreleased [major] - -_Full changeset and discussions: #123._ - -### Added - -- New feature 1 - -## 0.0.1 - 2024-02-20 - -_Full changeset and discussions: #122._ - -> Development of this release was supported by a funder. - -### Added - -- Initial release diff --git a/scripts/changelog/fixtures/changelog-without-unreleased.md b/scripts/changelog/fixtures/changelog-without-unreleased.md deleted file mode 100644 index 5bdecf7a1..000000000 --- a/scripts/changelog/fixtures/changelog-without-unreleased.md +++ /dev/null @@ -1,13 +0,0 @@ -# Changelog - -All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 0.0.1 - 2024-02-20 - -_Full changeset and discussions: #122._ - -> Development of this release was supported by a funder. - -### Added - -- Initial release diff --git a/scripts/changelog/fixtures/changelog.md b/scripts/changelog/fixtures/changelog.md deleted file mode 100644 index f97f1b89e..000000000 --- a/scripts/changelog/fixtures/changelog.md +++ /dev/null @@ -1,23 +0,0 @@ -# Changelog - -All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## Unreleased [major] - -_Full changeset and discussions: #123._ - -> Development of this release was supported by a funder. - -### Added - -- New feature 1 - -## 0.0.1 - 2024-02-20 - -_Full changeset and discussions: #122._ - -> Development of this release was made on a volunteer basis by a contributor. - -### Added - -- Initial release diff --git a/scripts/changelog/index.js b/scripts/changelog/index.js deleted file mode 100755 index 42d31b45a..000000000 --- a/scripts/changelog/index.js +++ /dev/null @@ -1,59 +0,0 @@ -#! /usr/bin/env node - -import fs from 'fs/promises'; -import path from 'path'; -import { fileURLToPath } from 'url'; - -import { program } from 'commander'; - -import Changelog from './changelog.js'; - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - -program - .name('changelog') - .description('A command-line utility for managing the changelog file') - .option('--validate', 'Validate the changelog, ensuring it follows the expected format and contains required information') - .option('--release [PRNumber]', 'Convert the Unreleased section into a new release in the changelog, optionally linking to a pull request with the provided PRNumber') - .option('--clean-unreleased', 'Remove the Unreleased section') - .option('--get-release-type', 'Get the release type of the Unreleased section in the changelog') - .option('--get-version-content ', 'Get the content of the given version in the changelog'); - -const options = program.parse(process.argv).opts(); - -let changelog; - -const CHANGELOG_PATH = path.resolve(__dirname, '../../CHANGELOG.md'); -const ENCODING = 'UTF-8'; - -try { - const changelogContent = await fs.readFile(CHANGELOG_PATH, ENCODING); - - changelog = new Changelog(changelogContent); -} catch (error) { - console.log(error.message); -} - -if (options.validate) { - changelog.validateUnreleased(); -} - -if (options.getReleaseType) { - process.stdout.write(changelog.releaseType || 'No release type found'); -} - -if (options.getVersionContent) { - process.stdout.write(changelog.getVersionContent(options.getVersionContent)); -} - -if (options.release) { - const PRNumber = typeof options.release == 'boolean' ? null : options.release; - - changelog.release(PRNumber); - await fs.writeFile(CHANGELOG_PATH, changelog.toString(), ENCODING); -} - -if (options.cleanUnreleased) { - changelog.cleanUnreleased(); - await fs.writeFile(CHANGELOG_PATH, changelog.toString(), ENCODING); -}