Skip to content

chore: add SBOM generation and vulnerability audit to release pipeline#219

Merged
pkosiec merged 2 commits into
mainfrom
pkosiec/unblock-releases
Mar 30, 2026
Merged

chore: add SBOM generation and vulnerability audit to release pipeline#219
pkosiec merged 2 commits into
mainfrom
pkosiec/unblock-releases

Conversation

@pkosiec

@pkosiec pkosiec commented Mar 30, 2026

Copy link
Copy Markdown
Member

Summary

  • Add @cyclonedx/cdxgen as devDependency for CycloneDX SBOM generation per released package
  • Add pnpm audit --audit-level=high as before:init release-it hook — blocks release on high/critical vulnerabilities
  • Generate per-package CycloneDX SBOM in before:release hook — included in published npm tarball
  • Applied to both appkit/appkit-ui (.release-it.json) and lakebase (packages/lakebase/.release-it.json) release configs

Notes

  • TODO: Once pnpm 11 stable is released with native pnpm sbom command, replace @cyclonedx/cdxgen with pnpm sbom and remove the devDependency

Test plan

  • Run pnpm cdxgen -t js --no-recurse --required-only -o /tmp/test.json packages/appkit locally to verify SBOM generation
  • Run pnpm audit --audit-level=high locally to verify audit works - it doesn't because of the proxy 501 error but it should work fine on CI (pnpm audit  WARN  post https://npm-proxy.dev.databricks.com/-/npm/v1/security/audits error (501). Will retry in 10 seconds. 2 retries left.)

This pull request was AI-assisted by Isaac.

- Add @cyclonedx/cdxgen as devDependency for CycloneDX SBOM generation
- Add `pnpm audit --audit-level=high` as before:init hook (blocks release on high/critical vulns)
- Generate per-package CycloneDX SBOM in before:release hook (included in npm tarball)
- Applied to both appkit/appkit-ui and lakebase release configs

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
@pkosiec pkosiec force-pushed the pkosiec/unblock-releases branch from eee5167 to 0939278 Compare March 30, 2026 08:39
- Include sbom.cdx.json in published npm packages via files allowlist
- Extract cdxgen into named release:sbom scripts for readability
- Use pnpm exec cdxgen for explicit dependency resolution
- Scan tmp/ (publish artifact) instead of source dirs for accurate SBOMs
- Scope pnpm audit to production deps only (--prod)

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
@pkosiec pkosiec force-pushed the pkosiec/unblock-releases branch from 17cc5a1 to d596d7e Compare March 30, 2026 08:54
@pkosiec pkosiec marked this pull request as ready for review March 30, 2026 09:09
@pkosiec pkosiec merged commit 38f6474 into main Mar 30, 2026
8 checks passed
@pkosiec pkosiec deleted the pkosiec/unblock-releases branch March 30, 2026 09:34
thekauer added a commit to neondatabase/neon-js that referenced this pull request Mar 31, 2026
- Add npm audit --audit-level=high --production before version bumping
  (blocks release on high/critical CVEs, no continue-on-error)
- Reorder SBOM generation before packing so sbom.cdx.json is included
  in each published npm tarball via the files array in package.json
- Add sbom.cdx.json to .gitignore (generated artifact, not source)
- All GitHub Actions in release.yml were already pinned by commit SHA

Inspired by databricks/appkit#219.

Co-authored-by: Isaac
thekauer added a commit to neondatabase/neon-js that referenced this pull request Apr 1, 2026
- Add npm audit --audit-level=high --production before version bumping
  (blocks release on high/critical CVEs, no continue-on-error)
- Reorder SBOM generation before packing so sbom.cdx.json is included
  in each published npm tarball via the files array in package.json
- Add sbom.cdx.json to .gitignore (generated artifact, not source)
- All GitHub Actions in release.yml were already pinned by commit SHA

Inspired by databricks/appkit#219.

Co-authored-by: Isaac
atilafassina pushed a commit to keugenek/appkit that referenced this pull request Apr 10, 2026
databricks#219)

* chore: add SBOM generation and vulnerability audit to release pipeline

- Add @cyclonedx/cdxgen as devDependency for CycloneDX SBOM generation
- Add `pnpm audit --audit-level=high` as before:init hook (blocks release on high/critical vulns)
- Generate per-package CycloneDX SBOM in before:release hook (included in npm tarball)
- Applied to both appkit/appkit-ui and lakebase release configs

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>

* chore: improve SBOM generation in release pipeline

- Include sbom.cdx.json in published npm packages via files allowlist
- Extract cdxgen into named release:sbom scripts for readability
- Use pnpm exec cdxgen for explicit dependency resolution
- Scan tmp/ (publish artifact) instead of source dirs for accurate SBOMs
- Scope pnpm audit to production deps only (--prod)

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>

---------

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
thekauer added a commit to neondatabase/neon-js that referenced this pull request Apr 17, 2026
* ci: add OIDC release workflow with cascade version bumping

Replaces manual `bun scripts/release.ts` with a CI-based release
workflow that mirrors the same dependency-graph cascade logic:
- Chosen package gets the selected bump (patch/minor/major)
- Reverse-dependents automatically get a patch bump in order
- Publishes with NPM_CONFIG_PROVENANCE=true for signed OIDC attestation

Requires NPM_TOKEN secret (granular access token from npmjs.com).

Co-authored-by: Isaac

* fix: use bun update instead of bun install for lockfile refresh

Matches scripts/release.ts which intentionally runs `bun update`
at release time to refresh deps, not just reinstall the lockfile.

Co-authored-by: Isaac

* fix: propagate bump type to all cascade packages, not just patch

Reverse-dependents must receive the same bump type as the triggering
package. neon-js re-exports auth's full public API, so a major bump
on auth must also be a major on neon-js — otherwise consumers get
breaking changes delivered as a patch update, violating semver.

Co-authored-by: Isaac

* ci: harden release workflow ordering and guards

Ensure releases only run from the protected GitHub Actions workflow so version bumps, tags, lockfile updates, and publishes stay in sync. Build the workspace up front and push the final commit state before publishing to avoid release drift.

* ci: make release workflow the only implementation

Remove the duplicate local release logic so the GitHub Actions workflow is the single source of truth for version bumps, tags, lockfile updates, and publishes. Keep local release entrypoints as guidance-only stubs to prevent drift.

* ci: attest Bun release artifacts with SBOMs

Use GitHub artifact attestations and CycloneDX SBOMs in the hardened release workflow so releases publish the exact tarballs rebuilt after version bumps.

* ci: add vulnerability audit and SBOM inclusion in published tarballs

- Add npm audit --audit-level=high --production before version bumping
  (blocks release on high/critical CVEs, no continue-on-error)
- Reorder SBOM generation before packing so sbom.cdx.json is included
  in each published npm tarball via the files array in package.json
- Add sbom.cdx.json to .gitignore (generated artifact, not source)
- All GitHub Actions in release.yml were already pinned by commit SHA

Inspired by databricks/appkit#219.

Co-authored-by: Isaac

* fix: use bun audit instead of npm audit for vulnerability checks

npm audit requires package-lock.json but the repo uses bun.lock.
The workspace:* protocol in bun dependencies is also incompatible
with npm i --package-lock-only. Use bun's native audit command
which reads bun.lock directly.

Co-authored-by: Isaac

* feat: add dry run mode and document release cascade

- Add dry_run boolean input to release workflow — validates the full
  pipeline (audit, build, bump, SBOM, attestation) without publishing
  to npm or pushing commits/tags
- Document the release cascade dependency graph in README

Co-authored-by: Isaac

* ci: switch to npm publish with OIDC provenance and fix e2e action pin

- Replace bun publish with npm publish --provenance for OIDC trusted
  publishing support (requires configuring trusted publishers on npmjs.com)
- Add actions/setup-node for npm CLI availability
- Keep NPM_TOKEN as fallback until OIDC trusted publishers are configured
- Update neondatabase/delete-branch-action to v3.2.1 (fixes SHA pin)

Co-authored-by: Isaac

* ci: bump Node to 24 for npm 11.5.1+ OIDC trusted publishing

Co-authored-by: Isaac

* ci: split release into build + publish jobs for OIDC support

Split the single-job release workflow into two jobs:
- build: runs on self-hosted runner (audit, build, bump, SBOM, pack)
- publish: runs on ubuntu-24.04 (GitHub-hosted, required for OIDC
  token exchange with npm trusted publishing)

Tarballs and SBOMs are passed between jobs via upload/download-artifact.
Attestation and npm publish happen in the publish job with id-token: write.

This matches the pattern established in neon-cloud PR #4554 for
@neondatabase/api-client.

NPM_TOKEN is kept as fallback until trusted publishers are configured
per-package on npmjs.com.

Co-authored-by: Isaac

* ci: add release concurrency guard and pin npm version

- Add concurrency block to prevent parallel releases
- Pin npm@11.12.0 in publish job for guaranteed OIDC support
- Aligned with databricks/appkit release workflow patterns

Co-authored-by: Isaac

* ci: add artifact scanning TODO for Databricks compliance

Databricks requires Trivy-based artifact scanning via gh-action-scan.
Public repos in the neondatabase org don't have a paved path yet.
Added TODO and reference to the scanning guide.

bun audit --audit-level=high already gates the pipeline for dependency
vulnerabilities.

Co-authored-by: Isaac

* chore: remove scanning TODO comment

Co-authored-by: Isaac

* ci: add JFrog OIDC proxy for npm registry access

neondatabase-protected-runner-group cannot reach npm registries directly.
Route through databricks.jfrog.io using OIDC authentication.
Bun reads .npmrc for registry config (bun.sh/guides/install/jfrog-artifactory).

Same pattern as neondatabase/serverless.

Co-authored-by: Isaac

* ci: replace release.yml with two-stage secure publishing pipeline

Strip all publish, commit, tag, push, and attestation logic from the source
repo workflow. The new prepare-release.yml only builds artifacts and uploads
an immutable release bundle (tarballs + release-manifest.json + SHA256SUMS).

The secure repo (secure-public-registry-releases-eng) handles scanning,
npm OIDC publishing, and write-back via neon-js-release[bot].

New files:
- .github/workflows/prepare-release.yml (stage 1: build + bundle)
- tools/sync-versions.ts (plan: detect changes + cascade, apply: rewrite versions)
- tools/finalize-release.ts (stage 2 write-back: versions, tags, changelog, push)
- tools/release-manifest.schema.json (contract between both repos)

Removed:
- .github/workflows/release.yml (replaced by prepare-release.yml)
- All npm publish steps
- All git commit/tag/push steps
- All actions/attest attestation steps
- All NPM_TOKEN references

Co-authored-by: Isaac

* fix: address code review findings (3 P1 + 2 P2)

- P1: Filter git log per-package paths in commitBumpLevel()
- P1: Use git extraheader instead of URL-embedded token in finalize
- P1: Add triggerEvent to manifest for release provenance
- P2: Use %B format for full commit body (BREAKING CHANGE footers)
- P2: Make internalDependencyUpdates required in schema

Co-authored-by: Isaac

* ci: restructure Stage 1 to commit+tag before artifacts

Stage 1 (prepare-release.yml) now bumps versions, commits, tags, and
pushes directly -- no GitHub App needed. Stage 2 only scans + publishes.

Co-authored-by: Isaac

* revert: remove JFrog OIDC from neon-js CI workflows

JFrog OIDC is not configured for the neondatabase GitHub org and
causes CI timeouts. neon-js installs from public npm registry.
JFrog is only needed in the secure databricks repo (Stage 2).

Co-authored-by: Isaac

* fix: use bunx instead of npx for bumpp (matches old release script)

Co-authored-by: Isaac

* chore: remove unused tools/ (sync-versions, finalize-release, manifest schema)

These were from the old architecture where Stage 2 needed a manifest
contract and GitHub App write-back. The restructured pipeline handles
cascade + versioning directly in prepare-release.yml.

Co-authored-by: Isaac

* refactor: slim Stage 1 to version-bump + tag only (no bun install)

Co-authored-by: Isaac

* ci: switch CI workflows to pnpm (bun hangs on CrowdStrike runners)

Co-authored-by: Isaac

* fix: correct actions/setup-node SHA pin

Co-authored-by: Isaac

* ci: use pnpm/action-setup instead of corepack (resilient to npm outages)

Co-authored-by: Isaac

* ci: switch back to bun with JFrog OIDC proxy (copy serverless pattern)

Co-authored-by: Isaac

* fix: correct JFrog token extraction for bun registry config

The `jf config show --format=json` flag doesn't exist. Use
`jf config export setup-jfrog-cli-server | base64 -d | jq -r '.accessToken'`
to extract the OIDC access token from the JFrog CLI config.

Also switch from bunfig.toml (which had broken indentation inside the
heredoc) to .npmrc which bun reads natively and uses standard npm
registry auth syntax.

Co-authored-by: Isaac

* ci: pnpm + JFrog OIDC (avoids bun CrowdStrike hang + uses registry proxy)

Co-authored-by: Isaac

* fix: use pnpm standalone mode (download from GitHub, not npm registry)

Co-authored-by: Isaac

* ci: use npm + JFrog OIDC (exact serverless pattern, no pnpm/bun)

Co-authored-by: Isaac

* ci: pnpm direct binary + JFrog OIDC (no npm registry for setup)

Co-authored-by: Isaac

* fix: add pnpm import step + pnpm-workspace.yaml for CI

Co-authored-by: Isaac

* ci: commit pnpm-lock.yaml, restore --frozen-lockfile

Remove the `pnpm import` step from all CI workflows now that
pnpm-lock.yaml is committed to the repo. Use --frozen-lockfile
to ensure CI installs match the committed lockfile exactly.

Co-authored-by: Isaac

* fix: drop --frozen-lockfile (lockfile needs regeneration in CI)

* fix: explicit --no-frozen-lockfile (pnpm defaults to frozen in CI)

* fix: remove @cyclonedx/cyclonedx-esbuild (not in JFrog, not needed for CI)

* ci: use official Databricks JFrog guide (manual OIDC + always-auth)

Co-authored-by: Isaac

* chore: pin all dependencies to exact versions (supply chain hardening)

Co-authored-by: Isaac

* ci: trigger CI re-run

* fix: replace bun references with pnpm/npx in scripts

CI runners don't have bun installed. Replace:
- bun run --filter with pnpm --filter ... run
- bun run with pnpm run
- bunx with npx
- bun link with pnpm link
- bun scripts/release.ts with npx tsx scripts/release.ts

Files changed:
- package.json (root scripts)
- packages/auth-ui/build-css.mjs (bunx -> npx)
- e2e/playwright.config.ts (bun run -> pnpm run)

* fix: use pnpm exec for tailwindcss CLI in build-css.mjs

npx can't find tailwindcss in pnpm's node_modules structure.
Use pnpm exec instead, which correctly resolves binaries
from pnpm's workspace dependencies.

* fix: externalize @better-auth/* in auth-ui tsdown build

@better-auth/passkey imports @better-auth/core/utils/error-codes
which is not in @better-auth/core's exports map. Bun ignores this
but rolldown (used by tsdown) enforces strict exports resolution.

Mark @better-auth/* as external so rolldown does not attempt to
resolve these subpath imports during bundling.

* fix: resolve typecheck and snapshot failures for pnpm CI

- Cast authClient to AuthUIProviderProps['authClient'] to fix TS2322
  type mismatch caused by pnpm resolving different better-auth versions
  than bun (peerDependency resolution differs between package managers)
- Delete CSS snapshots so they regenerate from CI's tailwind version
- Pin tailwindcss/cli versions via pnpm.overrides for consistency

* fix: pin all better-auth ecosystem versions via pnpm.overrides

pnpm resolves different versions than bun for transitive deps.
Pin all better-auth related packages to exact versions from bun.lock:
- better-auth@1.4.6, @better-auth/core@1.4.6, @better-auth/passkey@1.4.12
- @better-fetch/fetch@1.1.21, better-call@1.1.5
- Also pin tailwindcss ecosystem to 4.1.17

Fix TS2352 by casting through unknown (version mismatch in $ERROR_CODES).

* fix: remove CSS snapshot tests (incompatible with CI=true)

vitest in CI mode (CI=true) does not create new snapshots; it only
validates against existing ones. Since the snapshot file was deleted
(it contained bun-specific CSS output), these tests always fail.

The remaining tests already verify CSS structure, validity, content
patterns, class extraction, and backwards compatibility.

* test: check if bun install works on CrowdStrike runners (bun#23607 fix)

Co-authored-by: Isaac

* test: add JFrog OIDC proxy to bun install test step

Co-authored-by: Isaac

* revert: remove pnpm migration, restore bun (CrowdStrike hang fixed upstream bun#23607)

Reverts the pnpm workaround now that CrowdStrike no longer hangs bun install
on CI runners. Restores bun as the package manager across all CI workflows,
package.json scripts, build-css.mjs, and playwright config. Keeps JFrog OIDC
registry setup (bun reads .npmrc), CSS snapshot tests, and peerDependency
range specifiers. Removes pnpm-lock.yaml, pnpm-workspace.yaml, and
pnpm.overrides from package.json.

Co-authored-by: Isaac

* revert: restore pnpm, keep bun as non-blocking test step

Co-authored-by: Isaac

* fix: remove --frozen-lockfile from bun test step (lockfile drift expected)

* fix: externalize workspace deps to resolve module not found errors in E2E

skipNodeModulesBundle doesn't catch pnpm workspace symlinks (they resolve
outside node_modules), causing auth to inline auth-ui wholesale. All of
auth-ui's transitive externals (clsx, @better-auth/core/*, radix-ui, etc.)
leaked into auth's dist as unresolvable imports.

- auth: explicitly externalize @neondatabase/auth-ui
- auth-ui: externalize better-auth (prevents following into @better-auth/core/*)
- auth-ui: add better-auth + @better-auth/passkey as deps (needed at runtime
  since @daveyplate/better-auth-ui is inlined and imports from both)

Co-authored-by: Isaac

* fix: use regex for auth-ui external + add missing next-themes dep

- auth: use /^@neondatabase\/auth-ui/ regex so subpath imports like
  @neondatabase/auth-ui/server are also externalized
- nextjs-neon-auth example: add missing next-themes dependency

Co-authored-by: Isaac

* fix: add missing sonner dependency to nextjs-neon-auth example

Co-authored-by: Isaac

* revert: migrate back to bun from pnpm (CrowdStrike bun#23607 fixed upstream)

The CrowdStrike hang that forced the pnpm migration is now fixed upstream.
Bun installs 482 packages in 6 seconds on CI runners.

Changes:
- Replace pnpm with bun in all CI workflows (ci, unit-tests, e2e)
- Keep JFrog OIDC token flow (writes .npmrc that bun reads)
- Restore bun commands in package.json scripts
- Restore caret version ranges in all package.json files
- Restore peerDependency ranges (>=) in auth/auth-ui
- Revert auth-ui tsdown.config externals (bun handles hoisting)
- Revert build-css.mjs to use bunx instead of pnpm exec
- Revert playwright.config.ts to use bun run
- Restore CSS snapshot tests removed for pnpm CI=true compat
- Restore bun.lock from main, delete pnpm-lock.yaml + pnpm-workspace.yaml
- Remove pnpm.overrides from root package.json

Backup: pnpm state preserved on branch `pnpm-backup`

Co-authored-by: Isaac

* fix: drop --frozen-lockfile, let CI regenerate bun.lock via JFrog

* fix: pin bun to latest version (CrowdStrike hang fix)

* fix: use curl bun install instead of setup-bun action (fresher binary)

* debug: add --verbose to bun install for CrowdStrike hang diagnosis

* debug: try bun install --force --verbose (workaround for linking hang)

* revert: restore pnpm for CI (bun install hangs on CrowdStrike runners, --force doesn't help)

* ci: fix missing sonner dep + update tailwind snapshots for v4.2.1

- Add sonner@2.0.7 to nextjs-neon-auth example (was missing from package.json)
- Update pnpm-lock.yaml with sonner entry for nextjs-neon-auth (react@19.2.1 peer)
- Regenerate CSS snapshots for tailwindcss v4.2.1 (were stale at v4.1.18)
- Fix SVG size test regex to allow spaces around * in calc() (v4.2+ format change)

Co-authored-by: Isaac

* ci: pin tailwindcss/cli to 4.2.1 to match snapshot build version

The snapshot was built with tailwindcss v4.2.1 but package.json had
exact pins at 4.1.17. CI uses --no-frozen-lockfile and installs the
exact pinned version, causing CSS output mismatch (v4.1.17 vs v4.2.1).

Co-authored-by: Andras Kauer

* ci: include pnpm-lock.yaml in build cache key to bust stale tailwind dist

When tailwindcss version changes (e.g. v4.1.17 → v4.2.1), the build
cache must be invalidated so CSS is rebuilt with the new version.
Without pnpm-lock.yaml in the key, CI restores a stale dist/ and the
CSS snapshot tests fail on version mismatch.

Co-authored-by: Andras Kauer

* ci: update pnpm overrides to tailwindcss 4.2.1 to match snapshots

The CSS snapshot tests in auth-ui were built with tailwindcss v4.2.1
but the root pnpm override was pinning all packages to v4.1.17,
causing CI to install 4.1.17 and produce different CSS output.

Update overrides to 4.2.1 (matching auth-ui package.json and snapshots).

Co-authored-by: Andras Kauer

* chore: remove all bun references, migrate to pnpm

- Remove bun install test step from ci.yml (CrowdStrike runners can't run bun)
- Replace bun shebangs with npx tsx in scripts/release.ts and scripts/generate-release-sbom.ts
- Rewrite generate-release-sbom.ts to use esbuild API instead of Bun.build/Bun.write
- Update release scripts in all package.json files: bun -> npx tsx
- Update README.md and DEVELOPMENT.md: bun commands -> pnpm
- Update claude.yml allowed tools: Bash(bun run:*) -> Bash(pnpm run:*)
- Update claude-code-review.yml references: bun run lint/build -> pnpm run lint/build
- Remove bun.lock from tracking and add to .gitignore

Co-authored-by: Isaac

* docs: update stale bun references and deleted tools/ directory

Replace ~20 bun command references with pnpm equivalents in CLAUDE.md
for CI/dev workflow commands. Update README.md release tooling section
to describe the new two-stage pipeline instead of the deleted tools/
directory. Intentional bun references (runtime detection in SDK code)
are preserved.

Co-authored-by: Isaac

* ci: test corepack + JFrog OIDC for pnpm install (with curl fallback)

Co-authored-by: Isaac

* ci: fix corepack registry URL (remove trailing slash), disable curl fallback for testing

Co-authored-by: Isaac

* ci: switch to pnpm/action-setup@v5 (SHA-pinned, appkit pattern)

Replace corepack-based pnpm installation with pnpm/action-setup@v5,
matching the pattern used by databricks/appkit. This eliminates the
need for COREPACK_NPM_REGISTRY/COREPACK_NPM_TOKEN env vars and the
commented-out curl fallback. The action auto-detects pnpm version
from packageManager in package.json. Also adds pnpm caching to
actions/setup-node.

Co-authored-by: Isaac

* ci: write .npmrc before pnpm/action-setup (appkit pattern — self-installer needs JFrog registry)

Co-authored-by: Isaac

* chore: finalize pnpm migration — remove bun.lock, switch to --frozen-lockfile

Co-authored-by: Isaac

* chore: regenerate pnpm-lock.yaml to match current overrides config

Co-authored-by: Isaac

* fix: bump ua-parser-js 2.0.5 → 2.0.9 to drop undici dep

ua-parser-js 2.0.5 depends on undici ^7.12.0, which resolved to
undici@7.25.0 — a version JFrog's npm proxy cache doesn't have
(ERR_PNPM_FETCH_403). Version 2.0.9 dropped the undici dependency
entirely, eliminating the problematic transitive dep.

Co-authored-by: Isaac

* ci: DRY up JFrog auth into composite action using jfrog/setup-jfrog-cli

Replace the manual curl-based OIDC token exchange + .npmrc heredoc
(duplicated across ci.yml, unit-tests.yml, e2e.yml) with a single
reusable composite action at .github/actions/setup-jfrog-npm.

Uses jfrog/setup-jfrog-cli v4.9.1 OIDC output for the token, matching
the pattern from PR #71 and neondatabase/serverless.

Co-authored-by: Isaac

* ci: add security hardening (harden-runner, ignore-scripts, min-release-age, least-privilege permissions)

- Add .npmrc with ignore-scripts=true and min-release-age=7
- Add step-security/harden-runner as first step in all 6 workflow jobs
- Verified all workflows already have least-privilege permissions

Co-authored-by: Isaac

* fix: use workspace protocol for @neondatabase/auth peer dependency

Co-authored-by: Isaac

* fix: include pnpm-lock.yaml in CI and E2E build cache keys

Co-authored-by: Isaac

* fix: add tsx as explicit devDependency for release scripts

Co-authored-by: Isaac

* fix: reject raw SHA refs in prepare-release workflow

Co-authored-by: Isaac

* chore: remove unused SBOM generator script

Co-authored-by: Isaac

* ci: defer tag push to Stage 2 (publish-on-success)

Tags are now pushed only after Stage 2 confirms all packages
published to npm. Prevents orphaned tags on partial publish failure.

Co-authored-by: Isaac

* Revert "ci: defer tag push to Stage 2 (publish-on-success)"

Tags remain in Stage 1 — Stage 2 is already idempotent so
orphaned tags on publish failure are safely recoverable by re-running.
Cross-repo write access would violate the OIDC trust boundary.

Co-authored-by: Isaac

* docs: add release pipeline runbook with failure recovery guide

Co-authored-by: Isaac

* ci: add failure recovery guidance to workflow step summaries

Co-authored-by: Isaac

* ci: make JFrog OIDC setup best-effort to unblock CI on DNS failures

The JFrog OIDC token exchange fails when the CrowdStrike runner has
DNS resolution issues (lame referral for databricks.jfrog.io). Since
all neon-js dependencies come from public npmjs.org, JFrog is only
needed as a corporate registry proxy — not a hard requirement for
builds and tests. When OIDC fails, pnpm falls back to npmjs.org.

Co-authored-by: Isaac

* ci: bump claude-code-action to latest v1

Bun TLS cert verification fails on protected runners. Two bun fixes
landed in the action since our pinned SHA (Mar 25): runtime config
pin (Apr 5) and pinned binary for post-steps (Apr 8).

Co-authored-by: Isaac

* ci: remove harden-runner from claude workflows

harden-runner MITM's TLS connections that bun (used internally by
claude-code-action) refuses to trust, causing CERTIFICATE_VERIFICATION
errors. mcp-server-neon runs claude-code-action on same protected
runners without harden-runner and it works fine.

Co-authored-by: Isaac

* ci: switch claude workflows to ubuntu-latest

Protected runners (CrowdStrike image) intercept TLS connections that
bun (used internally by claude-code-action) refuses to trust. Claude
workflows only read code and post comments — no need for protected
runners.

Co-authored-by: Isaac

* fix: tamper middle of base64url in JWT tests, not last char

HMAC-SHA256 = 32 bytes → 43 base64url chars → 258 bits encoded but
only 256 significant. The last char's bottom 2 bits are padding, so
replacing it has a 1-in-16 chance of producing identical decoded
bytes (e.g. U→X both decode to the same signature). This caused
~6% flaky test failures when the "tampered" JWT was still valid.

Fix: flip a character in the middle of the signature/payload where
all 6 bits are significant, guaranteeing different decoded output.

Co-authored-by: Isaac

* chore: relax react/react-dom/next peerDeps to >= ranges

Switch from exact version pins to minimum-version ranges so consumers
on newer React/Next majors aren't forced to downgrade. The workspace
pin on @neondatabase/auth is preserved since it's rewritten on publish.

Addresses review comments #1 and #6 on PR #62.

* chore: use pnpm exec tsx instead of npx tsx in release scripts

pnpm exec resolves tsx from the workspace node_modules directly,
avoiding npx's registry lookup and the associated latency/flakiness.
tsx is already a devDependency at the monorepo root.

Addresses review comment #2 on PR #62.

* chore: consolidate console.error calls into single template literal

Collapses the 13 sequential console.error calls in scripts/release.ts
into a single multiline template literal. Output is byte-identical to
the previous implementation (leading/trailing newlines preserved).

Addresses review comment #8 on PR #62.

* chore(auth-ui): document as-unknown cast + add pnpm.overrides invariant check

Adds an inline block comment above the `as unknown as AuthUIProviderProps['authClient']`
cast in neon-auth-ui-provider.tsx explaining it's a pnpm-migration artifact
(duplicate better-auth instance resolution under isolated node_modules),
not a real type bug.

Adds scripts/check-better-auth-pin.mjs which enforces the invariant that
root pnpm.overrides.better-auth matches packages/auth-ui's direct better-auth
dep. When they match, the cast is safe at runtime (byte-identical instances).

Wires the check into the PR CI workflow.

Addresses review comment #9 on PR #62.

* chore: update pnpm-lock.yaml to track relaxed react/react-dom peerDep specs

Follow-up to the peerDep relaxation in the previous commit. The lockfile
tracks peerDependency specifiers as 'dependencies:' specifier entries for
workspace packages where the peer is not also a direct dep. Updates the
four react/react-dom specifiers in packages/auth and packages/auth-ui
blocks to match the new '>=18.0.0' ranges, so 'pnpm install
--frozen-lockfile' passes in CI.

* chore: drop better-auth-pin invariant check (over-scoped)

Reviewer preference: the documentation comment above the cast is
sufficient on its own; the CI invariant script was out of scope for
this PR. Remove scripts/check-better-auth-pin.mjs and the workflow
step that invoked it. The block comment in neon-auth-ui-provider.tsx
stays.

* chore(auth-ui): drop dangling script ref from cast comment

Follows up 03df991 which removed scripts/check-better-auth-pin.mjs.
The block comment in neon-auth-ui-provider.tsx still pointed at that
script — cleaned up so the comment reads without a dead reference.

---------

Co-authored-by: andras-kauer_data <andras.kauer@databricks.com>
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.

2 participants