Skip to content

feat: automate GitHub release pages #8

feat: automate GitHub release pages

feat: automate GitHub release pages #8

Workflow file for this run

name: Publish npm Package
on:
push:
tags:
- "*.*.*"
permissions:
contents: write
id-token: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 24
registry-url: https://registry.npmjs.org
cache: npm
- name: Install dependencies
run: npm ci
- name: Verify tag matches package version
shell: bash
run: |
PACKAGE_VERSION="$(node -p "require('./package.json').version")"
if [ "${PACKAGE_VERSION}" != "${GITHUB_REF_NAME}" ]; then
echo "Tag ${GITHUB_REF_NAME} does not match package.json version ${PACKAGE_VERSION}"
exit 1
fi
- name: Smoke test release package
run: npm run release:smoke
- name: Verify package contents
run: npm run release:check
- name: Check whether version already exists on npm
id: npm_version
shell: bash
run: |
PACKAGE_NAME="$(node -p "require('./package.json').name")"
PACKAGE_VERSION="$(node -p "require('./package.json').version")"
if npm view "${PACKAGE_NAME}@${PACKAGE_VERSION}" version >/dev/null 2>&1; then
echo "published=true" >> "$GITHUB_OUTPUT"
echo "Version ${PACKAGE_VERSION} is already published. Skipping npm publish."
else
echo "published=false" >> "$GITHUB_OUTPUT"
fi
- name: Publish package to npm
if: steps.npm_version.outputs.published != 'true'
run: npm publish --access public
- name: Generate release body
id: release_notes
uses: actions/github-script@v8
env:
RELEASE_TAG: ${{ github.ref_name }}
with:
script: |
const tag = process.env.RELEASE_TAG;
const { execFileSync } = require('child_process');
const releaseIntro = execFileSync(
'node',
['scripts/release-notes.js', '--tag', tag],
{
cwd: process.env.GITHUB_WORKSPACE,
encoding: 'utf8'
}
).trim();
const generated = await github.rest.repos.generateReleaseNotes({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: tag
});
core.setOutput('name', tag);
core.setOutput('body', `${releaseIntro}\n\n${generated.data.body}`);
- name: Create or update GitHub Release
uses: actions/github-script@v8
env:
RELEASE_TAG: ${{ github.ref_name }}
RELEASE_NAME: ${{ steps.release_notes.outputs.name }}
RELEASE_BODY: ${{ steps.release_notes.outputs.body }}
with:
script: |
const tag = process.env.RELEASE_TAG;
const name = process.env.RELEASE_NAME;
const body = process.env.RELEASE_BODY;
const prerelease = tag.includes('-');
const releaseParams = {
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: tag,
name,
body,
draft: false,
prerelease
};
if (!prerelease) {
releaseParams.make_latest = 'legacy';
}
try {
const existing = await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag
});
await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: existing.data.id,
name,
body,
draft: false,
prerelease,
...(prerelease ? {} : { make_latest: 'legacy' })
});
} catch (error) {
if (error.status !== 404) {
throw error;
}
await github.rest.repos.createRelease(releaseParams);
}