Release Runbook

This runbook is for maintainers publishing the public npm packages:

Both packages are generated from the same staged artifact and must publish at the same version. Keep skillpacks as the canonical package and @glexcorp/gskp as the same-version scoped alias.

Prerequisites

Log in to npm before starting a release:

npm login --registry https://registry.npmjs.org/
npm whoami --registry https://registry.npmjs.org/

Expected publisher:

SKILLPACKS_NPM_PUBLISHER=<npm-username> ./publish.sh patch

The publishing account must have:

Release Gates

Before publishing:

npm --workspace packages/skillpacks run test:node
npm run skillpacks:verify
./publish.sh --dry-run patch

Use patch for the normal next release. From packages/skillpacks@0.1.5, the next parity-restoring patch release is 0.1.6.

Hard gates:

Publish

Preferred command:

./publish.sh patch

For an explicit semver target:

./publish.sh 0.1.6

The script publishes skillpacks first, then @glexcorp/gskp --access public, and verifies both published package specs afterward.

Canary / Experimental Release

Use npm dist-tags for canary releases. The default canary tag is experimental, and the version should use the same prerelease identifier so the package version is visibly non-GA.

Pre-publish gates only: Verify, Then Stop

npm --workspace packages/skillpacks run test:node
npm run skillpacks:verify
./publish.sh --dry-run --tag experimental --preid experimental prerelease

Stop here unless all gates pass; do not commit, tag, push, or publish during the pre-publish gates.

Publish Canary: Run Only After All Gates Pass

./publish.sh --tag experimental --preid experimental prerelease

This publishes versions like 0.1.20-experimental.0 for both package names under dist-tags.experimental. It does not move latest.

@experimental is a canary prerelease package channel for testing only. It may contain unproven package behavior and should not be used for normal installs. Normal users should use plain npx skillpacks ... or npx skillpacks@latest ....

Stable/default install examples:

npx skillpacks@latest install <pack-or-skill>
npx @glexcorp/gskp@latest install <pack-or-skill>

Canary/testing-only install examples:

npx skillpacks@experimental install <pack-or-skill>
npx @glexcorp/gskp@experimental install <pack-or-skill>

POST-PUBLISH ONLY: Commit, Tag, and Push Source State

Run these only after ./publish.sh succeeds. Use the exact version printed by publish.sh, such as 0.1.21-experimental.0:

VERSION=<published-version>
git add packages/skillpacks/package.json packages/skillpacks/dist/skillpacks-manifest.json
git commit -m "Release skillpacks $VERSION"
git tag "skillpacks-v$VERSION"
git push
git push origin "skillpacks-v$VERSION"

Post-Publish Verification: Confirm Dist-Tags and Smoke Checks

Validate the canary dist-tag parity:

npm view skillpacks dist-tags.experimental
npm view @glexcorp/gskp dist-tags.experimental

Both commands must print the same prerelease version. Then run canary smoke checks:

npx skillpacks@experimental list
npx skillpacks@experimental install <pack-or-skill>
npx @glexcorp/gskp@experimental list

If the canary is approved for GA, run a normal stable release later:

./publish.sh --dry-run patch
./publish.sh patch

The stable release publishes a new stable semver version to latest; it does not promote the canary tarball directly.

Partial-Publish Recovery

If skillpacks publishes but @glexcorp/gskp fails:

  1. Do not run manual npm publish from either staged package directory.
  2. Fix npm auth, scope access, or OTP state.
  3. Leave the source release-state files at the failed release version. The recovery script allows only these tracked edits while recovering:
  1. Rerun the release from the current package version, preserving the original dist-tag:
./publish.sh --current
# or, for a canary:
./publish.sh --current --tag experimental

--current is the recovery path because npm versions are immutable and the already-published skillpacks version must be matched by the scoped alias. It requires skillpacks@<version> to already exist, requires @glexcorp/gskp@<version> to be missing, skips republishing skillpacks, publishes only @glexcorp/gskp, then verifies both package specs.

If both package versions already exist, recovery is complete and the script exits without publishing. If only @glexcorp/gskp exists, stop and investigate the inconsistent registry state.

After recovery succeeds, commit, tag, and push the same source release-state files as described in the publish section.

Post-Publish Verification

Confirm version parity:

npm view skillpacks version
npm view @glexcorp/gskp version

The two commands must print the same version.

Then verify the published packages:

SKILLPACKS_PACKAGE_NAME=skillpacks SKILLPACKS_EXPECTED_VERSION=<version> SKILLPACKS_EXPECTED_DIST_TAG=latest SKILLPACKS_NPM_SPEC=skillpacks@latest npm run skillpacks:verify-published
SKILLPACKS_PACKAGE_NAME=@glexcorp/gskp SKILLPACKS_EXPECTED_VERSION=<version> SKILLPACKS_EXPECTED_DIST_TAG=latest SKILLPACKS_NPM_SPEC=@glexcorp/gskp@latest npm run skillpacks:verify-published

Recommended smoke checks:

npx skillpacks@<version> list
npx @glexcorp/gskp@<version> list