Release Process
This project publishes npm packages from GitHub Releases. Publishing is intentional only when a GitHub Release is published for a tag that exactly matches package.json.
Published Versions And Stable Release
The published npm history is:
- npm package:
form-schema-runtime 0.1.0was published manually.0.1.1was published through the GitHub Release workflow with npm Trusted Publishing/OIDC.1.0.0is the first stable npm release.1.0.1is the current published npm release.
npm package versions are immutable. Re-running an existing release workflow cannot overwrite an already published version such as form-schema-runtime@0.1.0 or form-schema-runtime@0.1.1; npm will reject the publish with an error that the version was previously published.
Do not rerun an existing release expecting npm to overwrite the package. Do not unpublish published versions, delete GitHub Releases, force-push tags, or create replacement tags unless explicitly requested by the repository owner.
The first stable release used the package version and matching GitHub Release tag:
- package version:
1.0.0 - GitHub Release tag:
v1.0.0
Every release must keep package.json and the GitHub Release tag aligned: package version <version> requires tag v<version>. Future versions must be published through GitHub Release + npm Trusted Publishing/OIDC. The release workflow checks npm before publishing and fails early if the package version already exists.
npm README Lifecycle
npm renders the root README.md contained in the published package. The package page README changes only when a new package version is published; changing README.md on GitHub does not update an existing npm version.
Treat npm-facing README corrections as package changes. If a correction must appear on npmjs.com, prepare a new semantic version, keep the new version and GitHub Release tag aligned, and publish it through the normal release workflow. Use absolute public URLs in the root README because repository docs and framework example sources are intentionally excluded from the npm tarball.
Release Philosophy
- Keep CI and release publishing separate.
- Use GitHub Releases as the human approval gate.
- Publish only package files needed by consumers.
- Verify package consumption before publishing.
- Prefer npm Trusted Publishing/OIDC over long-lived npm publish tokens.
- Do not commit generated build output, coverage reports, TypeDoc output, Playwright reports, temporary consumer projects, or npm package tarballs.
Why GitHub Release Driven
The release workflow runs on:
release:
types: [published]
This means publishing a GitHub Release is the explicit release action. Pull requests and normal pushes verify the project through CI, but they do not publish to npm.
The GitHub Release is the approval trigger and source tag; the package itself is published to the public npm registry at npmjs.com, not to GitHub Packages.
GitHub can generate release notes from merged pull requests and contributors. The repository also includes .github/release.yml to keep generated notes grouped into Features, Fixes, Documentation, Maintenance, Dependencies, Tests, and Other Changes.
Expected PR labels:
featureorenhancementbugorfixdocumentationordocsmaintenanceorchoredependenciestestsortestignore-for-releaseto omit a PR from generated notes
One-Time npm Setup
The first manual publication is complete. Keep this setup accurate for future automated releases:
- Create or log in to the npm account that will own the package.
- Enable 2FA as appropriate for the account and organization.
- Verify that
form-schema-runtimeis available or owned by the intended maintainer. - Configure npm Trusted Publisher for the package.
- Configure provider: GitHub Actions.
- Configure GitHub owner/repository:
DanieleMasone/form-schema-runtime. - Configure workflow filename:
release.yml. - Configure package name:
form-schema-runtime. - Leave environment blank unless the workflow later adds an npm release environment.
- Allow action:
npm publish.
All npm Trusted Publisher fields are case-sensitive. The package repository.url in package.json must exactly match the GitHub repository:
"repository": {
"type": "git",
"url": "git+https://github.com/DanieleMasone/form-schema-runtime.git"
}
GitHub Setup
Before publishing:
- Confirm GitHub Actions are enabled for the repository.
- Confirm the release workflow has
contents: readandid-token: writepermissions. - Confirm repository Pages deployment is handled by CI.
- Confirm the release creator has permission to create GitHub Releases and tags.
- Confirm
mainis green before drafting the release.
Why npm Trusted Publishing/OIDC
The release workflow uses npm Trusted Publishing through GitHub Actions OIDC.
Benefits:
- no persistent
NPM_TOKENstored in GitHub secrets - short-lived publish credentials minted for the matching workflow
- automatic provenance for public packages from public repositories
- fewer token rotation and exposure risks
The workflow intentionally runs:
npm publish --access public
It does not pass --provenance because npm Trusted Publishing from GitHub Actions automatically generates provenance attestations when the package and repository are public.
Version and Tag Convention
Use semantic versions in package.json and matching Git tags:
package.json version: 1.0.0
GitHub Release tag: v1.0.0
The release workflow rejects tags that do not match v<semver> or do not match the package version. It also queries npm and rejects versions that are already published.
Examples:
package.jsonversion1.0.0requires GitHub tagv1.0.0.package.jsonversion1.0.1requires GitHub tagv1.0.1.
Preparing a Release
- Make sure
mainis green in CI. - Confirm
package.jsonversion is the intended release version. - Update docs if public behavior changed.
- Run local verification:
npm ci
npm run typecheck
npm run lint
npm test
npm run test:coverage
npm run build
npm run test:site-docs
npm run build:examples
npm run test:examples
npm run test:consumer
npm run test:e2e
npm run verify:release -- --tag v<package-version> --pack
npm run verify:release -- --tag v<package-version> --check-published
npm pack --dry-run
- Commit the source changes.
- Do not commit
dist/,dist-demo/,coverage/,playwright-report/,test-results/, temporary consumer projects, or*.tgz. - Push to
main.
Creating a GitHub Release
- Open GitHub Releases.
- Draft a new release.
- Create or select tag
v<package-version>, for examplev1.0.0. - Set the release title to the tag or a concise release title.
- Use GitHub's generated release notes.
- Review the generated notes.
- Publish the release.
Publishing the release starts .github/workflows/release.yml.
What the Release Workflow Does
The workflow:
- checks out the repository
- sets up Node 24 and the npm registry
- installs with
npm ci - verifies tag/version/package metadata
- runs typecheck
- runs lint
- runs unit tests
- builds only the npm package with
npm run build:lib - installs the already-built package in a temporary consumer project
- verifies ESM import, CSS export, TypeScript declarations, and IIFE availability
- verifies package contents with
npm pack --dry-run --json - runs
npm pack --dry-run - checks that the package version is not already published on npm
- publishes to npm with Trusted Publishing/OIDC
The release workflow deliberately does not build the demo, generated HTML docs, TypeDoc site, coverage site, framework examples, or run Playwright. CI verifies and deploys those Pages assets; they are not part of the npm tarball.
Package Contents
The npm package intentionally includes only:
dist/README.mdLICENSEpackage.jsonbecause npm always includes it
It must not include source files, tests, demo, generated Pages output, coverage, Playwright reports, temporary consumer projects, or package tarballs.
Verifying a Published Package
After a successful release:
npm view form-schema-runtime version
npm view form-schema-runtime dist-tags
npm view form-schema-runtime readme
npm view form-schema-runtime repository homepage bugs
npm view form-schema-runtime --json
Install it in a throwaway project and verify:
import { createForm, type FormSchema } from "form-schema-runtime";
import "form-schema-runtime/styles.css";
Also verify:
- TypeScript resolves
FormSchema. - The package can be imported as ESM.
- The CSS export resolves.
- The IIFE build exists for direct browser usage.
- npm provenance is present when available.
For direct browser usage, the IIFE build exposes:
FormSchemaRuntime
If Publishing Fails
- If the workflow fails before
npm publishbecause of a transient service or runner problem, it can be rerun while that version remains unpublished. - If source changes are required after the release tag was created, prepare a new version and matching tag instead of moving or force-pushing the existing tag.
- If the workflow fails because the version is already published, bump
package.jsonto a new version and create a new matching GitHub Release tag. - Do not rerun the same release expecting npm to overwrite an existing version.
- If npm authentication fails, verify the npm Trusted Publisher package name, owner/repository, workflow filename, allowed action, and optional environment.
- If publish succeeds with a bad package, deprecate the bad version and publish a corrected patch version.
- Do not overwrite or reuse published npm versions. npm versions are immutable after publication.
What Not To Commit
Never commit:
- generated npm package tarballs
dist/dist-demo/coverage/- generated TypeDoc output
- Playwright reports
- temporary consumer projects
- local npm caches
CI vs Release
CI runs on pushes and pull requests. It verifies install, typecheck, lint, unit tests, coverage, the complete Pages build, generated HTML docs, framework example builds, framework example checks, consumer package smoke testing, Playwright, and Pages deployment on main.
Release runs only when a GitHub Release is published. It repeats package-focused quality checks, builds only the distributable library, runs the consumer smoke test, verifies package contents, and publishes to npm. Pages generation remains in CI.