Skip to content

feat(publish): per-lexicon independent versioning and publish-on-merge#547

Merged
lex00 merged 2 commits into
mainfrom
feat/528-per-lexicon-publish
Jul 2, 2026
Merged

feat(publish): per-lexicon independent versioning and publish-on-merge#547
lex00 merged 2 commits into
mainfrom
feat/528-per-lexicon-publish

Conversation

@lex00

@lex00 lex00 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Closes #528.

Summary

  • New .github/workflows/publish-on-merge.yml — publish-on-merge workflow with the push: trigger commented out (safety gate). Only workflow_dispatch is active. Merging this PR publishes nothing.
  • Extended LexiconUpgradeOp (pull-request mode, pinned lexicons) to bump the lexicon's package.json version alongside the spec version constant. Semver label drives the bump: minor → minor bump, breaking → major bump. Rolling lexicons excluded (feat(lexicon-upgrade): rolling lexicons should emit a drift issue, not a baseline-only PR #546).
  • New exports: computeBumpedVersion, bumpPackageJsonVersion, BumpPackageVersionFn (all injectable).
  • Unit tests for the new logic; all 27 tests in lexicon-upgrade.test.ts pass.
  • Docs note on independent versioning in guide/managing-lexicons.mdx.

Safety gate

The push: trigger in publish-on-merge.yml is commented out with an explicit explanation:

# SAFETY GATE: the `push:` trigger below is intentionally commented out.
# Merging a PR that only adds this file is a no-op for npm — nothing
# publishes until a human removes the comment block.
#
# on:
#   push:
#     branches: [main]

Only workflow_dispatch is wired. Merging this PR cannot publish any package.

To un-gate: confirm the trusted-publisher OIDC record on npmjs.com covers publish-on-merge.yml, then remove the comment block on the push: trigger.

Publish-on-merge flow (once un-gated)

  1. Push to main triggers the workflow.
  2. For each of the 11 packages: read local package.json version; call npm view <pkg> version.
  3. If equal → print "Already at X, skipping" and exit that step.
  4. If different → run npm run prepack (generates/bundles/validates) then npm publish --access public --provenance.
  5. OIDC trusted-publisher record issues a short-lived publish token — no stored secrets.

Version-bump-in-PR flow (pinned lexicons)

When a LexiconUpgradeOp in pull-request mode finds a pinned upgrade with validation passing:

  1. Applies the spec version bump to versions.ts (existing _applyBump).
  2. Reads the current version from package.json.
  3. Calls computeBumpedVersion(current, semverLabel) → new version string.
  4. Calls bumpPackageJsonVersion(pkgJsonPath, newVersion) to write the new version.
  5. Stages the changed package.json alongside the spec constant change.

Merging that PR carries both changes to main, which triggers publish-on-merge for exactly that lexicon.

Validation

npx tsc --noEmit -p packages/core/tsconfig.json  # clean
npx vitest run lexicons/temporal/src/op/activities/lexicon-upgrade.test.ts  # 27/27 pass
node -e "yaml.load(fs.readFileSync('.github/workflows/publish-on-merge.yml'))"  # valid YAML, on: {workflow_dispatch: null}

Deferred

lex00 added 2 commits July 1, 2026 21:07
#528)

Add a publish-on-merge workflow with the push trigger disabled (safety
gate): merging this PR is a no-op for npm. A human removes the comment
block on the push trigger after confirming the trusted-publisher OIDC
record covers the new workflow file name.

Workflow design: one job, sequential steps, cheap version comparison
first (npm view vs local package.json). Only packages whose version
differs from the published npm version run prepack + publish. Reuses
the OIDC trusted-publisher setup from publish.yml (no registry-url,
no placeholder token).

Extend LexiconUpgradeOp to bump the lexicon's package.json version in
pull-request mode for pinned lexicons (k8s, gcp, docker, gitlab). The
semver label computed from the surface delta drives the bump: additive
-> minor, breaking -> major. Rolling lexicons (aws, azure, github) are
excluded and will move to drift-issues (#546).

New exports: computeBumpedVersion, bumpPackageJsonVersion,
BumpPackageVersionFn. All injectable for tests via _bumpPackageVersion.

Unit tests: computeBumpedVersion (minor/breaking/v-prefix/unparseable),
bumpPackageJsonVersion (writes version, preserves fields, trailing
newline), and two integration tests for the pull-request mode flow
(pinned bumps package.json; rolling does not).

Docs: add independent versioning note to guide/managing-lexicons.mdx
explaining the per-package cadence and the ^ peer range.
The PR-automation git calls (branch/checkout/commit/push) used execAsync
directly while only gh() was injectable, so the pull-request-mode tests
executed real git — passing locally (with push auth) by force-pushing to
origin and failing in CI (no auth). Route all git through the injected
gh runner (defaults to execAsync, so production is unchanged); tests now
mock every shell-out and run hermetically (27 tests, 4ms, no network).
@lex00 lex00 merged commit d027d87 into main Jul 2, 2026
6 checks passed
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.

design: per-lexicon independent versioning & publish (republish one lexicon without a monorepo release)

1 participant