Skip to content

[SPIKE] Explore extracting release script in a package - #2685

Draft
romaricpascal wants to merge 8 commits into
mainfrom
spike-release-script-package
Draft

romaricpascal wants to merge 8 commits into
mainfrom
spike-release-script-package

Conversation

@romaricpascal

Copy link
Copy Markdown
Member

Explore how release scripts could be move in their own package for reuse across multiple repositories

@romaricpascal
romaricpascal force-pushed the spike-release-script-package branch 6 times, most recently from e72a2bc to 04ce14b Compare September 28, 2026 08:36
@romaricpascal
romaricpascal force-pushed the spike-release-script-package branch 2 times, most recently from 7e2b38f to 3c8b56a Compare October 2, 2026 16:53
The workflow no longer needs a relative path and we can switch to a JS script transparently
Not much gain besides being regrouped with the rest of the release.

The script can now receive the path to the CHANGELOG file to accomodate the CHANGELOG not being in the folder of the package whose version is being updated.
Avoids relying on GitHub actions script to run a single function
The function is only used in that script so makes sense for it to be there
@romaricpascal
romaricpascal force-pushed the spike-release-script-package branch 2 times, most recently from 65b30f1 to 386465e Compare October 2, 2026 17:18
@romaricpascal
romaricpascal force-pushed the spike-release-script-package branch from 386465e to 46cb63e Compare October 2, 2026 17:22

# Save the new version number for access in future steps
echo "PACKAGE_VERSION=$(npm pkg get version | jq -r)" >> $GITHUB_ENV
echo "PACKAGE_VERSION=$(npm pkg get version | jq -r)" >> $GITHUB_OUTPUT

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note Using $GITHUB_OUTPUT leads to using env in further steps, which makes visible where the environment variable comes from compared to outputting to $GITHUB_ENV. It also restricts the PACKAGE_VERSION environment to the steps that need it.

generateReleaseNotes('CHANGELOG.md', `v${process.env.PACKAGE_VERSION}`, { actor: '${{ github.actor }}', runId: '${{ github.run_id }}' })
run: npm exec extract-release-notes > release-notes-body
env:
PACKAGE_VERSION: v${{ steps.npm-version.outputs.PACKAGE_VERSION}}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note Not a big fan of that one, but worked for the spike. Thinking it'd be preferable that:

  • extract-release-notes takes on a non-prefixed version number
  • reading the packages version number is its own step, shared by build-release and publish-to-github

await generateReleaseNotes('CHANGELOG.md', '${{ steps.create-github-tag.outputs.GH_TAG }}')
run: npm exec extract-release-notes > release-notes-body
env:
PACKAGE_VERSION: ${{ steps.create-github-tag.outputs.GH_TAG }}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note See previous note, but this should work off a non-prefixed version number read from package.json rather than the GitHub tag.


if (require.main === module) {
(async () => {
const changelogPath = resolve(process.argv[2] ?? 'CHANGELOG.md')

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note Possibly a silly one, the CHANGELOG would always be at the root of the repository, it's the package which might be in a nested folder.

const { generateReleaseNotes } = await import('${{ github.workspace }}/scripts/release/changelog-release-helper.js')

generateReleaseNotes('CHANGELOG.md', `v${process.env.PACKAGE_VERSION}`, { actor: '${{ github.actor }}', runId: '${{ github.run_id }}' })
run: npm exec extract-release-notes > release-notes-body

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note Making the script log rather than write to file allows to keep mentions of release-notes-body to this file.

* @returns {Array<number>} - Indexes in the changelog identifying start and end lines
*/
function getChangelogLineIndexes (changelogLines, heading = undefined) {
const startHeading = `## ${heading ?? 'Unreleased'}`

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note This expects the heading to include the 'v' and does a similar formatting as updateChangelog so it might be worth extracting a function that ensures headings are formatted as expected both when injected and looked for.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note This file only explores the shape a configuration file would take. If we had an actual package shared across repositories, the config file would be in the repository being released.

const { outdent } = require('outdent')

module.exports = {
githubRepository: 'alphagov/govuk-prototype-kit',

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note We can probably extract that from the package.json file, which would also ensure the git metadata is filled correctly.

@@ -0,0 +1,73 @@
const semver = require('semver')

const { versionIsAPrerelease, getPrereleaseIdentifier } = require('./changelog-release-helper.js')

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note Those could possibly live in this package 🤔

Comment thread package.json
"lint:fix": "npm run lint -- --fix",
"prepack": "npm ls --all",
"postversion": "node scripts/release/update-changelog.js",
"postversion": "update-changelog",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note Having @govuk-prototype-kit/release provide scripts in its bin field allows to invoke them directly. We'll likely want to have a clear naming here to help figure the provenance.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant