Skip to content

Commit 685cf06

Browse files
npm install prisma now installs Prisma 8 (#230)
## At a glance ```bash # before this PR merges npm install prisma # -> 7.9.1 (Prisma 7) npm install prisma@next # -> 8.0.0-rc.9 # after this PR merges npm install prisma # -> 8.0.0-rc.10 (the unified v8 CLI) ``` ## The decision We are cutting the bare `prisma` npm name over to the v8 line. Until now, every 8.0.0-rc release published under the `next` dist-tag and `latest` kept serving Prisma 7, so nobody landed on v8 without asking for it. The operator ruled today (2026-08-25) that the RC line is ready to be what a bare `npm install prisma` gets. The version number does not change meaning: we stay on `8.0.0-rc.N` (this release is rc.10), and GitHub Releases remain marked pre-release. Only the dist-tag policy moves. ## How the flip actually happens In this repo, merging a version-bump PR is the act that publishes: the push to `main` carries a changed root version, and the publish workflow ships it under the tag `releaseDistTag()` returns. This PR widens that function so every release — RC or stable — publishes under `latest`. **Merging this PR is therefore the cutover itself**: it bumps rc.9 → rc.10 and the resulting publish moves `latest` on `prisma` and `@prisma/cli` in one deliberate, reviewable act. ## What rc.10 ships (since rc.9) - Config files evaluate correctly when the CLI is reached through pnpm symlink layouts that are not realpath'd (#222) — previously every config-reading command failed with `CLI.CONFIG_UNREADABLE` in those setups. - The engine's CI detector is exported and the skills staleness notice uses it, so Jenkins/TeamCity/Azure pipelines stop seeing the notice in their logs (#224). - The `prisma init` scaffold fixes (#225). - Current command-family releases, both peering the exact engine this repo ships (`@prisma/cli-engine@0.2.3`), so one engine resolves per install and the conformance exception list is empty again: `@prisma/composer-cli@0.14.0` and `@prisma/orm-toolchain@8.0.0-rc.7` (which carries the PostgreSQL temporal-codec representations and the `limit`/`offset` pagination rename). ## What happens to the `next` tag and to v7 users - `next` is retired: the publish path no longer moves it, and `scripts/cutover-dist-tags.sh` (operator-run) removes it from all three names and fixes the engine's stale tags. Text that says `prisma@next` should move to plain `prisma` — after this merge they resolve the same thing anyway, until the tag is removed. - Existing v7 installs are untouched: lockfiles pin resolved versions, and `prisma@7.9.1` stays installable by version. The v7 train's new publish home (`prisma7`) is being handled separately and does not block this. ## Alternatives considered - **A one-off `workflow_dispatch` with `dist-tag: latest`** — moves `latest` once, but every subsequent RC release would publish under `next` again and leave `latest` stale on rc.10. The widened rule makes the routine release path keep `latest` current. - **Waiting for stable `8.0.0`** — the rollout plan always left the flip timing to an operator judgement after an RC soak, not to the stable release; the operator ruled the soak is over. - **Keeping `next` synced to `latest`** — considered so existing `prisma@next` instructions would keep resolving the newest release, and dropped: re-pointing a tag on an already-published version cannot authenticate over OIDC, and npm's granular tokens go no narrower than package write — a standing sync would mean a standing publish-capable token, defeating the repo's OIDC-only invariant. Retiring the tag is the honest alternative. ## Verification Script tests green (33/0 on determine-version-utils). Conformance with the empty exception list: **5 subjects checked, nothing to report**, on both the release and dev channels. Lint and the CLI/engine suites green. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
1 parent d2b6b20 commit 685cf06

15 files changed

Lines changed: 142 additions & 107 deletions

File tree

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ on:
1616
workflow_dispatch:
1717
inputs:
1818
dist-tag:
19-
description: "npm dist-tag. Empty = the version's canonical tag (next on the RC line, latest for stable). Pass latest explicitly to move latest onto an RC — that is the deliberate cutover act."
19+
description: "npm dist-tag. Empty = latest, the canonical tag for every release since the 2026-08-25 cutover. Pass another tag (e.g. beta) for a hand-cut preview."
2020
required: false
2121
default: ""
2222
type: string

docs/oss/versioning.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ Prisma 8 ships as a release-candidate line ahead of `8.0.0` final: releases are
88

99
RC respins may include breaking changes until `8.0.0` final ships. There are no patch releases on the RC line — a fix ships as the next `rc.N`.
1010

11-
For the packages this repository's publish workflow ships (`prisma`, `@prisma/cli`, `@prisma/cli-engine`), **each release publishes under its line's canonical dist-tag**: RC-line versions under `next`, stable versions under `latest` (operator ruling 2026-08-12; supersedes the earlier "`latest` tracks the newest release, RC or stable"). A dist-tag moves only through a deliberately merged version-bump PR (or a manual `workflow_dispatch`); creating and merging the bump PR is the operator's explicit act. `latest` stays on the pre-8 CLI until the operator moves it deliberately. Existing installs are unaffected — lockfiles pin resolved versions, and nobody lands on the RC line without asking for `@next`.
11+
For the packages this repository's publish workflow ships (`prisma`, `@prisma/cli`, `@prisma/cli-engine`), **every release publishes under `latest`, RC-line versions included** (operator cutover ruling 2026-08-25, executing rollout-plan step 5; supersedes the 2026-08-12 "RC under `next`" ruling). A dist-tag moves only through a deliberately merged version-bump PR (or a manual `workflow_dispatch`); creating and merging the bump PR is the operator's explicit act. Existing installs are unaffected — lockfiles pin resolved versions.
1212

13-
**The bare `prisma` name is what this discipline is for.** Its `latest` serves Prisma 7 (`7.9.1`) to everyone who types `npm install prisma`, so the v8 line lives on `next` until a deliberate cutover. The products' packages are all new — nobody is installing `@prisma/composer-cli` or `@prisma/orm-toolchain` expecting a version 7 — so they publish releases straight to `latest`, pre-release versions included, and this repository follows `latest` for them (operator ruling 2026-08-17).
13+
**History of the bare `prisma` name.** Its `latest` served Prisma 7 (`7.9.1`) until the 2026-08-25 cutover, so the v8 RC line lived on `next` while it matured. The product-family packages (`@prisma/composer-cli`, `@prisma/orm-toolchain` and their siblings — not this repository's three) were never held back — all new names with no version-7 audience — so they always published releases straight to `latest`, pre-release versions included, and this repository follows `latest` for them (operator ruling 2026-08-17).
1414

1515
The transition onto the RC line is a one-time bump from the pre-8 base to `8.0.0-rc.1`; `pnpm bump-version` encodes it (a pre-8 stable base advances to `8.0.0-rc.1`, an RC base advances its counter).
1616

@@ -39,11 +39,11 @@ This is enforced, not remembered: the conformance checks refuse to publish a rel
3939

4040
The npm registry exposes the CLI packages under these dist-tags:
4141

42-
- **`latest`** — what a bare `npm install` gets. It stays on the pre-8 CLI while the Prisma 8 RC line matures; moving it to 8.x is a deliberate operator act (dispatching the publish workflow with `dist-tag: latest`, or widening `releaseDistTag` when the RC line is ready), not a side effect of any routine release (operator ruling 2026-08-12). Once the line is stable, stable release bumps publish here.
43-
- **`next`** — the Prisma 8 RC line (`8.0.0-rc.N`). A merged release PR on the RC line publishes here automatically.
42+
- **`latest`** — what a bare `npm install` gets: the newest release, RC or stable. A merged release PR publishes here automatically (operator cutover ruling 2026-08-25; before it, `latest` stayed on the pre-8 CLI and the RC line lived on `next`).
43+
- **`next`**retired by the cutover: it froze at the last pre-cutover RC and the publish path no longer moves it (operator ruling 2026-08-25). Keeping it synced to `latest` was considered and dropped — re-pointing a tag on an already-published version cannot authenticate over OIDC, and npm has no token permission narrower than package write, so a standing sync would mean a standing publish-capable token. The operator re-points or removes the tag by hand (`scripts/cutover-dist-tags.sh`); text that says `prisma@next` should move to plain `prisma`.
4444
- **`beta`** — reserved for hand-cut previews ahead of significant changes, published by dispatching the workflow with that dist-tag. Routine releases do not use this tag.
4545

46-
- **`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 — an `rc.N` bump under `next`, or moving `latest` — is a human act.
46+
- **`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.
4747

4848
**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.
4949

@@ -68,7 +68,7 @@ This is by design. The alternatives cause silent problems:
6868

6969
[`scripts/set-version.ts`](../../scripts/set-version.ts) is what enforces lockstep: a single invocation walks every lockstep workspace `package.json` and writes the requested version (rewriting `workspace:` dependency pins to match). It is a maintainer's tool, invoked through `pnpm bump-version`; the publish workflow does not run it.
7070

71-
The publish workflow is **triggered by a change to the root `version`**: a push to `main` whose root `package.json` carries a different `version` than the previous tip is recognised as a release bump and ships that version under its canonical dist-tag — `next` on the RC line (the accompanying GitHub Release is marked pre-release), `latest` for stable. This is what makes "merge the release PR" the publish trigger; there is no separate dispatch step. Every push publishes a `dev` build; one that changes the version publishes a release as well (operator ruling 2026-08-18). Within a publish, `@prisma/cli-engine` goes first, then `@prisma/cli` (which depends on it), then `prisma`.
71+
The publish workflow is **triggered by a change to the root `version`**: a push to `main` whose root `package.json` carries a different `version` than the previous tip is recognised as a release bump and ships that version under `latest` (the accompanying GitHub Release is marked pre-release on the RC line). This is what makes "merge the release PR" the publish trigger; there is no separate dispatch step. Every push publishes a `dev` build; one that changes the version publishes a release as well (operator ruling 2026-08-18). Within a publish, `@prisma/cli-engine` goes first, then `@prisma/cli` (which depends on it), then `prisma`.
7272

7373
**Nothing rewrites a `version` field outside a commit.** `set-version.ts` is run by `pnpm bump-version`, whose output a maintainer reviews and commits; the publish workflow never invokes it. That is what makes "the version is whatever `package.json` says" true rather than aspirational — CI has no way to ship a version no commit describes. It also keeps `pnpm-lock.yaml` honest: the lockfile records the `workspace:` specifiers that `set-version.ts` rewrites, so `bump-version` refreshes it in the same breath and the bump lands as one internally consistent commit.
7474

@@ -81,9 +81,9 @@ Before anything reaches the registry, the workflow verifies the artifact it is a
8181
The release cadence is one PR per release (on the RC line: one PR per `rc.N`). A maintainer:
8282

8383
1. **Runs the [`publish-npm-version` skill](../../skills-contrib/publish-npm-version/SKILL.md)**, which drives `pnpm bump-version` in a fresh worktree off `origin/main` and opens the release PR under real maintainer credentials (so CI runs on it normally). The script reads the root version committed at HEAD, computes the next release version (`8.0.0-rc.N``8.0.0-rc.N+1`), and writes it to every lockstep `package.json`. `bump-version` refreshes `pnpm-lock.yaml` itself, because the lockfile records the `workspace:` pins it rewrites and a stale one fails every later frozen install. Commit both and open a `chore(release): 8.0.0-rc.N+1` PR.
84-
2. **Reviews and merges the PR.** This is the point where a human verifies the release is intended — merging the bump PR is the deliberate act that publishes. The resulting push to `main` carries the bumped root `version`, the publish workflow detects the change, publishes under the line's canonical dist-tag (`next` on the RC line, `latest` for stable), and creates a matching GitHub Release (marked pre-release on the RC line).
84+
2. **Reviews and merges the PR.** This is the point where a human verifies the release is intended — merging the bump PR is the deliberate act that publishes. The resulting push to `main` carries the bumped root `version`, the publish workflow detects the change, publishes under `latest`, and creates a matching GitHub Release (marked pre-release on the RC line).
8585

86-
If the publish needs to be re-run (transient registry failure, etc.), a maintainer can dispatch the [`Publish to npm`](../../.github/workflows/publish.yml) workflow from `main` with the version's canonical dist-tag (`next` on the RC line, `latest` for stable) and `dry-run=false`; the workflow re-publishes the version currently committed at HEAD, and because the chosen tag matches the canonical one it also re-creates the GitHub Release if it is missing. This is the same path used to cut a hand-rolled `beta` (`dist-tag=beta`, no Release).
86+
If the publish needs to be re-run (transient registry failure, etc.), a maintainer can dispatch the [`Publish to npm`](../../.github/workflows/publish.yml) workflow from `main` with `dist-tag: latest` and `dry-run=false`; the workflow re-publishes the version currently committed at HEAD, and because the chosen tag matches the canonical one it also re-creates the GitHub Release if it is missing. This is the same path used to cut a hand-rolled `beta` (`dist-tag=beta`, no Release).
8787

8888
## Procedure: validate publish changes
8989

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "prisma-cli",
3-
"version": "8.0.0-rc.9",
3+
"version": "8.0.0-rc.10",
44
"private": true,
55
"engines": {
66
"node": ">=24"

packages/cli-conformance/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@repo/cli-conformance",
33
"private": true,
4-
"version": "8.0.0-rc.9",
4+
"version": "8.0.0-rc.10",
55
"description": "Reusable conformance checks for the engine's consumers: import purity over built output, config-section validators that never throw, and verification of the tarballs a registry would receive. Depends on no package it checks.",
66
"type": "module",
77
"exports": {
@@ -24,7 +24,7 @@
2424
"test": "pnpm run typecheck && vitest run"
2525
},
2626
"devDependencies": {
27-
"@repo/tsconfig": "workspace:8.0.0-rc.9",
27+
"@repo/tsconfig": "workspace:8.0.0-rc.10",
2828
"@types/node": "^22.19.19",
2929
"es-module-lexer": "^2.1.0",
3030
"tsx": "^4.22.4",

packages/cli-engine/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@
5555
"string-width": "^8.2.1"
5656
},
5757
"devDependencies": {
58-
"@repo/cli-conformance": "workspace:8.0.0-rc.9",
59-
"@repo/tsconfig": "workspace:8.0.0-rc.9",
58+
"@repo/cli-conformance": "workspace:8.0.0-rc.10",
59+
"@repo/tsconfig": "workspace:8.0.0-rc.10",
6060
"@types/node": "^22.19.19",
6161
"ci-info": "^4.3.1",
6262
"tsdown": "^0.21.10",

packages/cli-telemetry/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@repo/cli-telemetry",
33
"private": true,
4-
"version": "8.0.0-rc.9",
4+
"version": "8.0.0-rc.10",
55
"description": "CLI telemetry child sender: the detached subprocess the engine hands a composed payload to, its system probes, and the POST",
66
"type": "module",
77
"sideEffects": [
@@ -35,7 +35,7 @@
3535
"@vercel/detect-agent": "^1.2.3"
3636
},
3737
"devDependencies": {
38-
"@repo/tsconfig": "workspace:8.0.0-rc.9",
38+
"@repo/tsconfig": "workspace:8.0.0-rc.10",
3939
"@types/node": "^22.19.19",
4040
"tsdown": "^0.21.10",
4141
"typescript": "^6.0.3",

packages/cli/package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@prisma/cli",
3-
"version": "8.0.0-rc.9",
3+
"version": "8.0.0-rc.10",
44
"description": "Command-line interface for the Prisma Developer Platform.",
55
"type": "module",
66
"bin": {
@@ -50,22 +50,22 @@
5050
"dependencies": {
5151
"@manypkg/tools": "^2.1.2",
5252
"@prisma/cli-engine": "workspace:0.2.3",
53-
"@prisma/composer-cli": "0.13.0",
53+
"@prisma/composer-cli": "0.14.0",
5454
"@prisma/compute-sdk": "0.39.0",
5555
"@prisma/credentials-store": "^7.8.0",
5656
"@prisma/management-api-sdk": "1.55.0",
57-
"@prisma/orm-toolchain": "8.0.0-rc.6",
57+
"@prisma/orm-toolchain": "8.0.0-rc.7",
5858
"@vercel/detect-agent": "^1.2.3",
5959
"better-result": "^2.9.2",
6060
"dotenv": "^17.4.2",
6161
"execa": "^9.6.1",
6262
"open": "^11.0.0"
6363
},
6464
"devDependencies": {
65-
"@prisma/composer": "0.13.0",
66-
"@repo/cli-conformance": "workspace:8.0.0-rc.9",
67-
"@repo/cli-telemetry": "workspace:8.0.0-rc.9",
68-
"@repo/tsconfig": "workspace:8.0.0-rc.9",
65+
"@prisma/composer": "0.14.0",
66+
"@repo/cli-conformance": "workspace:8.0.0-rc.10",
67+
"@repo/cli-telemetry": "workspace:8.0.0-rc.10",
68+
"@repo/tsconfig": "workspace:8.0.0-rc.10",
6969
"@types/node": "^22.19.19",
7070
"tsdown": "^0.21.10",
7171
"tsx": "^4.22.4",

packages/cli/scripts/conformance.ts

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -109,34 +109,13 @@ async function tarball(): Promise<readonly Finding[]> {
109109
shellPackage: "@prisma/cli",
110110
enginePackage: "@prisma/cli-engine",
111111
familyPackages: ["@prisma/composer-cli", "@prisma/orm-toolchain"],
112-
// The empty list is the goal state: both families peering the
113-
// exact engine version this repo ships, one engine per install
114-
// (ADR 0004). The two entries below are an engine version
115-
// transition in flight — a family cannot peer an engine version
116-
// that is not on the registry, so the engine publishes first and
117-
// the mismatch is real until both families release against it.
118-
// The entries expire with the versions they name, and the PR
119-
// that pins the families' 0.2.3 releases removes them; while
120-
// they stand, a release could ship the two-engine install they
121-
// describe, which is why they must not outlive the transition.
122-
exceptions: [
123-
{
124-
familyPackage: "@prisma/composer-cli",
125-
familyPin: "0.2.2",
126-
shellPin: "0.2.3",
127-
reason: "engine 0.2.3 must publish before composer-cli can peer it",
128-
removeWhen:
129-
"composer-cli releases peering 0.2.3 and the follow-up bump PR pins that release",
130-
},
131-
{
132-
familyPackage: "@prisma/orm-toolchain",
133-
familyPin: "0.2.2",
134-
shellPin: "0.2.3",
135-
reason: "engine 0.2.3 must publish before orm-toolchain can peer it",
136-
removeWhen:
137-
"orm-toolchain releases peering 0.2.3 and the follow-up bump PR pins that release",
138-
},
139-
],
112+
// No exceptions. Both families declare @prisma/cli-engine as an
113+
// exact peer at the version this repo ships, so one engine
114+
// resolves in an install — what ADR 0004 asks for. An entry here
115+
// exists only while an engine version transition is in flight
116+
// (the engine must publish before a family can peer it), and the
117+
// release PR that pins the families' new versions removes it.
118+
exceptions: [],
140119
channel: CHANNEL,
141120
sandboxDir: join(WORK_DIR, "sandbox"),
142121
},

packages/compute/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"test": "vitest run"
4343
},
4444
"devDependencies": {
45-
"@repo/tsconfig": "workspace:8.0.0-rc.9",
45+
"@repo/tsconfig": "workspace:8.0.0-rc.10",
4646
"@types/node": "^22.19.19",
4747
"tsdown": "^0.21.10",
4848
"typescript": "^6.0.3",

packages/prisma/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "prisma",
3-
"version": "8.0.0-rc.9",
3+
"version": "8.0.0-rc.10",
44
"description": "The Prisma CLI: one binary for the ORM, Composer, and the Prisma Developer Platform.",
55
"type": "module",
66
"bin": {
@@ -50,21 +50,21 @@
5050
"dependencies": {
5151
"@manypkg/tools": "^2.1.2",
5252
"@prisma/cli-engine": "workspace:0.2.3",
53-
"@prisma/composer-cli": "0.13.0",
53+
"@prisma/composer-cli": "0.14.0",
5454
"@prisma/compute-sdk": "0.39.0",
5555
"@prisma/credentials-store": "^7.8.0",
5656
"@prisma/management-api-sdk": "1.55.0",
57-
"@prisma/orm-toolchain": "8.0.0-rc.6",
57+
"@prisma/orm-toolchain": "8.0.0-rc.7",
5858
"@vercel/detect-agent": "^1.2.3",
5959
"better-result": "^2.9.2",
6060
"dotenv": "^17.4.2",
6161
"execa": "^9.6.1",
6262
"open": "^11.0.0"
6363
},
6464
"devDependencies": {
65-
"@prisma/cli": "workspace:8.0.0-rc.9",
66-
"@repo/cli-telemetry": "workspace:8.0.0-rc.9",
67-
"@repo/tsconfig": "workspace:8.0.0-rc.9",
65+
"@prisma/cli": "workspace:8.0.0-rc.10",
66+
"@repo/cli-telemetry": "workspace:8.0.0-rc.10",
67+
"@repo/tsconfig": "workspace:8.0.0-rc.10",
6868
"@types/node": "^22.19.19",
6969
"tsdown": "^0.21.10",
7070
"typescript": "^6.0.3",

0 commit comments

Comments
 (0)