Skip to content

Release

Release #23

Workflow file for this run

name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: 'Release tag to publish, for example v1.0.0'
required: true
workflow_call:
inputs:
version:
description: 'Release tag to publish, for example v1.0.0'
required: true
type: string
permissions:
contents: read
concurrency:
group: release-${{ github.event_name == 'push' && github.ref_name || inputs.version }}
cancel-in-progress: false
jobs:
build:
name: Build and validate (Node 24.15.0)
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event_name == 'push' && github.ref || inputs.version }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24.15.0'
- name: Setup pnpm
run: npm install --global pnpm@11.13.1
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build package
run: pnpm build
- name: Run tests
run: pnpm test
- name: Run v1 performance tests
run: pnpm --filter=stax-xml test:perf
- name: Collect runtime retention evidence
run: pnpm --filter=benchmark run dev:runtime-retention
- name: Type check package
run: pnpm --filter=stax-xml exec tsc -p tsconfig.json --noEmit
- name: Run W3C conformance subset
run: pnpm test:w3c
- name: Verify release surfaces
run: pnpm verify:release-surfaces
- name: Validate pure-JS package contents
run: node scripts/validate-prerelease.mjs "${{ github.event_name == 'push' && github.ref_name || inputs.version }}" --pack
- name: Generate API documentation
run: pnpm --filter=stax-xml-docs typedoc
- name: Build documentation
run: pnpm docs:build
- name: Validate release documentation snapshot
run: pnpm docs:snapshot:release "${{ github.event_name == 'push' && github.ref_name || inputs.version }}" --dry-run
minimum-node:
name: Test minimum Node.js (20.19.0)
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event_name == 'push' && github.ref || inputs.version }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20.19.0'
- name: Setup compatible pnpm
run: |
npm install --global pnpm@10.34.5
npm_config_manage_package_manager_versions=false pnpm config set --global manage-package-manager-versions false
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build package
run: pnpm build
- name: Run tests
run: pnpm test
- name: Run v1 performance tests
run: pnpm --filter=stax-xml test:perf
- name: Collect runtime retention evidence
run: pnpm --filter=benchmark run dev:runtime-retention
- name: Run W3C conformance subset
run: pnpm test:w3c
- name: Verify release surfaces
run: pnpm verify:release-surfaces
- name: Validate pure-JS package contents
run: node scripts/validate-prerelease.mjs "${{ github.event_name == 'push' && github.ref_name || inputs.version }}" --pack
publish:
runs-on: ubuntu-24.04
needs:
- build
- minimum-node
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event_name == 'push' && github.ref || inputs.version }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24.15.0'
registry-url: 'https://registry.npmjs.org'
- name: Ensure npm supports trusted publishing
run: npm install -g npm@^11.5.1
- name: Setup pnpm
run: npm install --global pnpm@11.13.1
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Build facade package
run: pnpm build
- name: Validate pure-JS package contents
run: node scripts/validate-prerelease.mjs "${{ github.event_name == 'push' && github.ref_name || inputs.version }}" --pack
- name: Resolve npm dist-tag
id: npm-dist-tag
shell: bash
run: |
set -euo pipefail
VERSION="$(node -p "require('./packages/stax-xml/package.json').version")"
if [[ "$VERSION" == *-* ]]; then
echo "tag=next" >> "$GITHUB_OUTPUT"
else
echo "tag=latest" >> "$GITHUB_OUTPUT"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Publish facade package
working-directory: packages/stax-xml
run: |
VERSION="$(node -p "require('./package.json').version")"
if npm view "stax-xml@$VERSION" version >/dev/null 2>&1; then
echo "stax-xml@$VERSION is already published; skipping npm publish."
else
npm publish --access public --tag "${{ steps.npm-dist-tag.outputs.tag }}"
fi
- name: Smoke published package
shell: bash
run: |
set -euo pipefail
temp_dir="$(mktemp -d)"
cleanup() { rm -rf "$temp_dir"; }
trap cleanup EXIT
cd "$temp_dir"
npm init -y >/dev/null
npm pkg set type=module >/dev/null
for attempt in 1 2 3 4 5 6 7 8 9 10; do
if npm install --omit=dev --ignore-scripts --prefer-online --loglevel=error \
--cache "$temp_dir/npm-cache-$attempt" \
"stax-xml@${{ steps.npm-dist-tag.outputs.version }}"; then
break
fi
if [ "$attempt" = 10 ]; then
exit 1
fi
echo "npm install attempt $attempt/10 failed; retrying after registry propagation delay..."
sleep 15
done
node --input-type=module <<'NODE'
import { EventReaderSync, XmlEventType } from 'stax-xml';
import { x } from 'stax-xml/converter';
let events = 0;
let startElements = 0;
for (const event of new EventReaderSync('<root><item id="1">ok</item></root>')) {
events++;
if (event.type === XmlEventType.START_ELEMENT) {
startElements++;
}
}
if (events <= 0 || startElements !== 2) {
throw new Error(`Unexpected parse result: events=${events}, startElements=${startElements}`);
}
const projection = x.object({ id: x.string('/root/item/@id') });
if (projection.parseSync('<root><item id="1"/></root>').id !== '1') {
throw new Error('Converter subpath smoke failed.');
}
console.log(JSON.stringify({ events, startElements }, null, 2));
NODE
- name: Generate changelog
if: ${{ !contains(steps.npm-dist-tag.outputs.version, '-') }}
run: pnpm dlx changelogithub@14.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}