Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,35 @@ jobs:
pnpm test:scripts
pnpm check:conformance

# The engine has no dev channel (ADR 0004: its line carries no
# pre-releases), so the dev stamp leaves its manifest alone and
# this run holds its committed version. Publishing it here, under
# `latest`, is the same rule the other packages follow — a merged
# version bump publishes that version under `latest` — applied at
# the engine's own bump, which is the first run to carry it. An
# already-published engine version is a no-op.
- name: Publish the engine release
if: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.dry-run != 'true' }}
env:
NPM_CONFIG_PROVENANCE: "true"
run: bash scripts/publish-packages.sh latest @prisma/cli-engine

- name: Publish the dev version
if: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.dry-run != 'true' }}
env:
NPM_CONFIG_PROVENANCE: "true"
run: bash scripts/publish-packages.sh dev @prisma/cli-engine @prisma/cli prisma
run: bash scripts/publish-packages.sh dev @prisma/cli prisma

- name: Verify the dev version resolves
if: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.dry-run != 'true' }}
env:
DEV_VERSION: ${{ steps.version.outputs.devVersion }}
run: |
node scripts/verify-published.mjs "@prisma/cli@$DEV_VERSION" "prisma@$DEV_VERSION"
engine=$(node -p "require('./packages/cli-engine/package.json').version")
node scripts/verify-published.mjs \
"@prisma/cli-engine@$engine" \
"@prisma/cli@$DEV_VERSION" \
"prisma@$DEV_VERSION"

# --- The release: only when the committed version changed. ---

Expand Down
4 changes: 2 additions & 2 deletions docs/oss/versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The transition onto the RC line is a one-time bump from the pre-8 base to `8.0.0

Every lockstep workspace package — publishable, private, and the workspace root — carries the same `version`. One read of root [`package.json`](../../package.json) answers "what version is this code?" for the repository.

**Exceptions:** `@prisma/compute` versions independently, pending extraction to another repository (operator ruling 2026-08-10), and keeps its own publish workflow ([`publish-compute.yml`](../../.github/workflows/publish-compute.yml)). `@prisma/cli-engine` also versions independently ([ADR 0004](../architecture/adrs/0004-engine-version-pinning.md), operator ruling 2026-08-13): an engine version means "the engine changed", not "the CLI released", which is what keeps the exact peer pins the product CLI packages hold on it cheap — they change only when the engine actually moves. The engine follows honest pre-1.0 semver (a breaking change bumps the minor); bumping it is one command — `pnpm bump-cli-engine-version <patch|minor|X.Y.Z>` — which edits `packages/cli-engine/package.json`, the `workspace:<engine version>` pin in every consumer manifest (`packages/cli`, `packages/prisma`), and the lockfile together, landed as a reviewed commit like any other version change (run it in the PR that changes the engine). Both packages are hard-excluded in [`scripts/set-version.ts`](../../scripts/set-version.ts), which still sweeps their `workspace:` pins on lockstep siblings so those never go stale. At publish time the engine ships at its own manifest version; an already-published engine version is a no-op. The engine's own line continues from `0.1.0` (after the published `0.0.x` series); the `8.0.0-rc.N` engine versions that shipped while it was still in lockstep are burned values — they exist on the registry, nothing pins them, and version numbers are never reused.
**Exceptions:** `@prisma/compute` versions independently, pending extraction to another repository (operator ruling 2026-08-10), and keeps its own publish workflow ([`publish-compute.yml`](../../.github/workflows/publish-compute.yml)). `@prisma/cli-engine` also versions independently ([ADR 0004](../architecture/adrs/0004-engine-version-pinning.md), operator ruling 2026-08-13): an engine version means "the engine changed", not "the CLI released", which is what keeps the exact peer pins the product CLI packages hold on it cheap — they change only when the engine actually moves. The engine follows honest pre-1.0 semver (a breaking change bumps the minor); bumping it is one command — `pnpm bump-cli-engine-version <patch|minor|X.Y.Z>` — which edits `packages/cli-engine/package.json`, the `workspace:<engine version>` pin in every consumer manifest (`packages/cli`, `packages/prisma`), and the lockfile together, landed as a reviewed commit like any other version change (run it in the PR that changes the engine). Both packages are hard-excluded in [`scripts/set-version.ts`](../../scripts/set-version.ts), which still sweeps their `workspace:` pins on lockstep siblings so those never go stale. At publish time the engine ships at its own manifest version **under `latest`**, on the first publish run that carries the bumped version — normally the merge of the PR that bumped it. That is the same rule every other package follows — a deliberately merged version-bump PR is what publishes a version under `latest` — applied at the engine's own bump instead of the root's. An already-published engine version is a no-op. The engine has no dev channel: its line carries no pre-releases (ADR 0004), so there is nothing to stamp and every published engine version is a release. (Before 2026-08-26 the workflow published the engine inside the dev-build half under `--tag dev`, so a new engine version reached the registry with its `latest` tag stuck on the previous version until an operator moved it by hand — `0.2.x` and `0.3.0` shipped that way.) The engine's own line continues from `0.1.0` (after the published `0.0.x` series); the `8.0.0-rc.N` engine versions that shipped while it was still in lockstep are burned values — they exist on the registry, nothing pins them, and version numbers are never reused.

The lockstep set is: the workspace root, `packages/cli`, `packages/cli-telemetry`, `packages/cli-conformance`, and `packages/tsconfig`. Private packages are never published (`pnpm publish` skips them), but they still version in lockstep so a contributor cloning the repo at any commit sees one consistent answer to "what version is this code?". Workspace-internal dependencies are pinned as `workspace:<version>` (e.g. `workspace:8.0.0-rc.1`); pnpm resolves them locally during development and rewrites them to the exact version at publish time, so every published package carries an exact-version pin on its siblings.

Expand All @@ -45,7 +45,7 @@ The npm registry exposes the CLI packages under these dist-tags:

- **`dev`** — every routine push to `main` publishes `<base>-dev.<run>` here automatically (operator ruling 2026-08-13, superseding the earlier "no dev channel" ruling). The suffix derives from the workflow run number and is stamped ephemerally in CI, never committed, so release versions remain exactly what a commit says. The channel exists so a product's new version reaches a working CLI without a human: an auto-merging pull request moves the version, runs the full quality and conformance checks, and its merge ships the dev build. Today a daily scheduled run is what notices a product release; the immediate path needs a notification step in each product repository, which neither has yet. See [release automation](./release-automation.md). Only a real release — a merged `rc.N` bump publishing under `latest` — is a human act.

**Every** run of the publish workflow ships a dev build, including the one that cuts a release — the release publish is an additional half, not an alternative (operator ruling 2026-08-18). When they were alternatives, the release commit was the one merge to `main` that never reached the dev channel, so `dev` named an older version than the release until an unrelated commit landed. The dev build is published as its own version rather than by moving the `dev` tag, because OIDC trusted publishing authorises `npm publish` and nothing else.
**Every** run of the publish workflow ships a dev build, including the one that cuts a release — the release publish is an additional half, not an alternative (operator ruling 2026-08-18). When they were alternatives, the release commit was the one merge to `main` that never reached the dev channel, so `dev` named an older version than the release until an unrelated commit landed. The dev build is published as its own version rather than by moving the `dev` tag, because OIDC trusted publishing authorises `npm publish` and nothing else. The dev channel covers `@prisma/cli` and `prisma` only: the engine's line carries no pre-releases (ADR 0004), so an engine version publishes once, under `latest`, on the run that first carries it.

PR previews go through [`pkg.pr.new`](https://pkg.pr.new) ([`preview-cli-package.yml`](../../.github/workflows/preview-cli-package.yml)); they carry the committed base version and install via per-commit URLs, not dist-tags.

Expand Down
Loading