Skip to content

ci: publish-artifact smoke — install the release candidate like a user would#3100

Merged
os-zhuang merged 1 commit into
mainfrom
claude/intelligent-moore-584e50
Jul 17, 2026
Merged

ci: publish-artifact smoke — install the release candidate like a user would#3100
os-zhuang merged 1 commit into
mainfrom
claude/intelligent-moore-584e50

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Problem — the 15.1.0 blind spot (#3091)

Workspace pnpm-workspace.yaml overrides kept every in-repo CI job on better-auth 1.7.0-rc.1, but overrides don't ship with published packages — every fresh npx create-objectstack project resolved plugin-auth's own declared ranges to an untested mix that 500'd all auth endpoints. Nothing in CI ever installed the combination users actually get.

#3085 added the static gate (check-override-consistency.mjs: override targets must be reflected in published manifests). This PR adds the dynamic gate: really install the about-to-publish artifacts into a clean project and drive the first-run flow.

What's in the box

scripts/publish-smoke.sh — one driver, two modes, same probe set (locally reproducible: pnpm build && bash scripts/publish-smoke.sh):

  • pack (default): pnpm pack all 67 publishable packages (pack applies the same manifest rewrites as publish, incl. workspace:* → concrete versions), scaffold a fresh project outside the workspace with the repo-built create-objectstack, and pin every @objectstack/* to the tarballs via the project's own pnpm-workspace.yaml overrides — the project inherits nothing from the repo's workspace file, so better-auth & friends resolve exactly as they would for a downstream user. A lockfile assertion fails the run if any @objectstack/* leaked to the registry (i.e. the override map ever grows a hole).
  • registry: npx create-objectstack@latest + npm install against the real registry — catches ^-range ecosystem drift breaking already-published versions after the fact.

Probes (both modes): anonymous get-session 200 → sign-up/email 200 → sign-in/email 200 → session carries the user → REST CRUD round on the scaffolded object (POST/GET/PATCH/DELETE /api/v1/data/<obj>, 201/200/200/200) as the --fresh-seeded dev admin → zero error/fatal log lines (ANSI-stripped; three logger formats covered, incl. the #3091 signature Failed to register OIDC discovery routes).

.github/workflows/publish-smoke.yml

  • pack-smoke runs on workflow_run after each Release run. Why not on: pull_request/push: the changesets release PR is pushed with GITHUB_TOKEN, and GITHUB_TOKEN events never trigger other workflows — the release PR literally has no Actions checks today (see chore: version packages #3086: only Vercel). So the smoke fires when Release completes (the moment changesets refreshes the branch), checks out the release-branch head SHA iff an open release PR exists, and reports the verdict back as a commit status on that SHA — visible on the release PR like any check. Skips cleanly when no release PR is open. Deliberately not on normal PR CI: full build + pack + clean install is inner-loop-hostile (~25–35 min).
  • registry-canary weekly (Mon 04:47 UTC) + on dispatch; on scheduled failure it opens (or refreshes, deduped) an issue.
  • workflow_dispatch runs both modes on any ref for manual verification.

Verification

scenario result
pack mode, current tree ✅ green — all 12 probes, 0 error lines, 108 tarball-resolved lockfile entries, 0 registry leaks
pack mode, negative: plugin-auth declarations reverted to the exact 15.1.0 mix (^1.6.23 + scim 1.7.0-rc.1) ✅ red — clean project resolves core@1.6.23 + scim@1.7.0-rc.1, OIDC provider init throws the incident's modelName TypeError, log scan fails the run. (Core sign-in stays 200 thanks to the #3087 isolation — the gate still catches the broken init via the error-line scan. Pre-#3087 this would also have red-failed the sign-up/sign-in probes directly.)
registry mode against published 15.1.1 ✅ green

The negative run also flushed out two real gate-hardening fixes during development: a 403 INVALID_ORIGIN on 127.0.0.1 (probes now use localhost, matching the default trustedOrigins wildcard) and a colorized ERROR line slipping past the scan (now NO_COLOR=1 + ANSI-strip before grep).

Notes

  • better-sqlite3 stays an optionalDependency of driver-sql: if the runner can't build the native addon, install still succeeds and the runtime falls back to WASM sqlite (better-sqlite3 → wasm auto-fallback doesn't cover the persistent-file / --artifact dev path (only the zero-config :memory: branch) #2229) — the smoke never blocks on node-gyp.
  • workflow_run only fires for workflow files on the default branch, so the release-PR path can't be exercised from this PR; after merge it can be validated via workflow_dispatch and the next real release PR.
  • Relationship to scaffold-e2e.yml: that gate exercises the scaffolder against the registry and only probes /health; this one exercises the unpublished release candidate and probes the auth + CRUD surface where 15.1.0 actually broke.

Refs: #3091 · #3085 · #3087

🤖 Generated with Claude Code

…r would

The 15.1.0 incident (#3091): workspace pnpm overrides kept every in-repo CI
job on better-auth 1.7.0-rc.1, but overrides do not ship with published
packages, so every fresh `npx create-objectstack` project resolved an
untested dependency mix that 500'd all auth endpoints. #3085 added the static
gate (override ↔ declaration consistency); this adds the dynamic gate —
install the exact bits a user would get and drive the first-run flow.

scripts/publish-smoke.sh, two modes sharing one probe set:
- pack (default): pnpm-pack all 67 publishable packages (pack applies the
  same manifest rewrites as publish), scaffold a fresh project outside the
  workspace with the repo-built create-objectstack, pin @objectstack/* to
  the tarballs via the project's OWN pnpm-workspace.yaml overrides (nothing
  inherited from the repo), install, and smoke. A lockfile assertion proves
  no @objectstack/* leaked to the registry.
- registry: npx create-objectstack@latest + npm install against the real
  registry — catches ^-range ecosystem drift breaking published versions.

Probes: anonymous get-session 200 → sign-up 200 → sign-in 200 → session
carries the user → REST CRUD round (201/200/200/200) on the scaffolded
object as the seeded dev admin → zero error/fatal log lines (ANSI-stripped;
catches the #3091 'Failed to register OIDC discovery routes' signature).

.github/workflows/publish-smoke.yml:
- workflow_run after each Release run — the changesets release PR is pushed
  with GITHUB_TOKEN, whose events never trigger on:push/pull_request (the
  release PR has no Actions checks today), so the smoke runs after Release
  completes, checks out the release-branch head SHA iff an open release PR
  exists, and reports the verdict back as a commit status on that SHA so it
  is visible on the release PR. Deliberately not in normal PR CI (too slow).
- weekly registry canary (Mon 04:47 UTC) that opens/refreshes an issue on
  failure.

Verified locally: pack mode green on the current tree; a negative run with
plugin-auth's declarations reverted to the 15.1.0 mix (^1.6.23 + scim rc.1)
goes red via the log scan — core sign-in stays up thanks to the #3087
isolation, and the smoke still catches the broken optional-plugin init.
Registry mode green against published 15.1.1. better-sqlite3 stays an
optionalDependency, so a failed native build falls back to WASM sqlite
(#2229) instead of blocking the smoke.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@os-zhuang os-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Jul 17, 2026
@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 17, 2026 7:38am

Request Review

@os-zhuang
os-zhuang merged commit 89467f5 into main Jul 17, 2026
18 checks passed
@os-zhuang
os-zhuang deleted the claude/intelligent-moore-584e50 branch July 17, 2026 07:39
os-zhuang added a commit that referenced this pull request Jul 17, 2026
…all works on pnpm 11 (#3119)

`npx create-objectstack && pnpm install` exited 1 on pnpm 11 (ERR_PNPM_IGNORED_BUILDS:
better-sqlite3, esbuild). pnpm 11 turned an unapproved dependency build script from a
warning into a hard error, and the blank template declared no approvals — verified against
published 15.1.1, so the first command a new user ran failed.

The scaffold now ships a pnpm-workspace.yaml approving the two packages it depends on
building. Both keys are required: pnpm 11 honors only `allowBuilds` (understood back to
10.31), while pnpm 10.0–10.30 understand only `onlyBuiltDependencies`. npm and yarn ignore
the file.

This is why Publish Smoke had been red since #3100 introduced it. The gate was never
broken — it correctly reported a real, shipping product bug on its first run. Pinning the
smoke's pnpm to the repo's packageManager would have turned it green by testing a pnpm no
user runs: the same "in-repo settings hide the user's real resolution" mistake as #3091,
the exact failure class this gate exists to catch. The pnpm version stays unpinned and the
reasoning is recorded in the script header.

publish-smoke.sh now appends its tarball overrides to the file the template ships instead
of hand-writing the whole thing. It previously declared the approvals itself, so it proved
nothing about what users get — that is how this bug stayed invisible to a gate designed to
find it. It now fails loudly if the scaffold declares no approvals.

Verified: Publish Smoke dispatched on the fix branch went green (all 3 jobs) — the first
pass in its history. Locally reproduced under CI-identical resolution via a corepack shim
(10.31.0 in-repo, 11.13.1 in the app dir); stripping allowBuilds reproduces the exact CI
failure and restoring it passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd size/l skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant