fix(plugin-auth): pin the better-auth family to an exact 1.7.2, and gate the declared range against our own import surface #5563
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Validate Dependencies | |
| on: | |
| pull_request: | |
| paths: | |
| - '**/package.json' | |
| - 'pnpm-lock.yaml' | |
| - '.changeset/config.json' | |
| - 'pnpm-workspace.yaml' | |
| - 'scripts/check-changeset-fixed.mjs' | |
| - 'scripts/check-override-consistency.mjs' | |
| # The consumer-resolution half of the same question (#16186) — an edit to | |
| # the gate must be exercised on the PR that makes it. | |
| - 'scripts/check-vendor-export-contract.mjs' | |
| # The OSV exemption ledger and its check: a PR that touches either must | |
| # run this workflow, or an exemption could be added without the gate | |
| # that governs it ever running on the PR that adds it. | |
| - 'osv-scanner.toml' | |
| - 'scripts/check-osv-exemptions.mjs' | |
| # Re-run when the workflow itself changes, so edits to these gates are | |
| # exercised on the PR that introduces them. | |
| - '.github/workflows/validate-deps.yml' | |
| schedule: | |
| # Run daily at 03:00 UTC — narrows the discovery window for a new OSV | |
| # advisory from up to six days (weekly) to one, so the scheduled scan | |
| # is more likely to surface a red before an unrelated PR's blocking | |
| # trigger collides with it (#14645). | |
| - cron: '0 3 * * *' | |
| workflow_dispatch: | |
| jobs: | |
| validate: | |
| name: Validate Package Dependencies | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| issues: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v7 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v7 | |
| with: | |
| node-version: '22' | |
| - name: Setup pnpm | |
| uses: ./.github/actions/setup-pnpm | |
| - name: Get pnpm store directory | |
| shell: bash | |
| run: | | |
| echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV | |
| - name: Setup pnpm cache | |
| uses: actions/cache@v6 | |
| with: | |
| path: ${{ env.STORE_PATH }} | |
| key: ${{ runner.os }}-pnpm-store-v3-${{ hashFiles('**/pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pnpm-store-v3- | |
| - name: Verify lockfile is up to date | |
| run: | | |
| pnpm install --frozen-lockfile --prefer-offline | |
| - name: Verify Changesets "fixed" group covers every public package | |
| run: node scripts/check-changeset-fixed.mjs | |
| # pnpm overrides pin what THIS workspace resolves, but they do not ship | |
| # with published packages — downstream installs see only the declared | |
| # ranges. If an override target isn't reachable from a publishable | |
| # package's declared range, we test one dependency graph and publish | |
| # another (the 15.1.0 quickstart shipped exactly that: plugin-auth | |
| # declared better-auth ^1.6.23 while CI ran the 1.7.0-rc.1 override, | |
| # and every fresh project 500'd on auth). | |
| # | |
| # The same run also prints two informational censuses (#6046): overrides | |
| # nothing in the dependency tree consumes, and selectors whose upper | |
| # bound excludes their own target (#4961 / #5032). Both are REPORTS and | |
| # never fail the job — an unconsumed override is a legitimate posture | |
| # (#5835 ruling A). `--self-test` proves the check in both directions, | |
| # so run the `check:override-consistency` chain rather than the bare | |
| # script: a self-test nothing invokes is a phantom check. | |
| - name: Verify overrides are reflected in published manifests | |
| run: pnpm check:override-consistency | |
| # The half check-override-consistency structurally cannot cover (#16186). | |
| # It asks whether the override TARGET is reachable from the declared | |
| # range; `^1.7.2` and `^1.7.2` agreed perfectly while both floated onto | |
| # `@better-auth/core@1.7.3`, a PATCH that deleted the export plugin-auth | |
| # imports statically. Three published releases could not load on a fresh | |
| # install and nothing here went red, because pnpm-lock.yaml held 1.7.2. | |
| # | |
| # `--resolve` deliberately ignores the lockfile: for every version the | |
| # DECLARED range admits on the registry -- the way a downstream project | |
| # resolves -- it installs that version outside this workspace and checks | |
| # the export surface. It fails if ANY admitted version is missing a symbol | |
| # we import. With the ranges pinned exact that is one small install per | |
| # vendor; under a caret it is one per published version, which is the cost | |
| # of the risk being taken. | |
| # | |
| # It lives HERE rather than in the lint farm because it needs the network, | |
| # which this job already has, and because the daily schedule is what turns | |
| # "a vendor published something today" into a red in this repo instead of | |
| # in a customer's install. An unreachable registry exits 3 | |
| # (PREREQUISITE NOT MET), never a green. | |
| - name: Verify the declared ranges cannot resolve past our import surface | |
| run: pnpm check:vendor-export-contract-resolve | |
| # Fail the workflow if known vulnerabilities are found — enforces | |
| # security compliance before merging. | |
| # | |
| # Previously this ran `pnpm audit --audit-level=high`, but npm retired the | |
| # audit endpoint (HTTP 410, "This endpoint is being retired. Use the bulk | |
| # advisory endpoint instead.") and pnpm has not migrated, so `pnpm audit` | |
| # now fails unconditionally on every branch (see issue #2974). OSV-Scanner | |
| # reads pnpm-lock.yaml directly against the OSV database and exits non-zero | |
| # when any advisory matches, restoring a working blocking gate. | |
| # | |
| # Note: OSV-Scanner blocks on any severity, not just high/critical. When | |
| # the advisory has a fixed version you take the fix. The ONLY escape | |
| # hatch, for an advisory with no fix available, is an `[[IgnoredVulns]]` | |
| # entry in `osv-scanner.toml` at the repo root — never lowering the gate. | |
| # | |
| # That escape hatch is governed by three conventions (#4965), stated in | |
| # full in the header of osv-scanner.toml: `ignoreUntil` mandatory | |
| # (default 30 days, ceiling 90), `reason` mandatory with an advisory link | |
| # plus a sentence on why it cannot be fixed, and exemptions land in their | |
| # own `osv-exemption`-labelled PR. The scanner enforces none of that — it | |
| # reads a missing `ignoreUntil` as "ignore forever", silently — so the | |
| # step below runs first and fails on any exemption that is missing, | |
| # quoted, expired, over the ceiling, or unexplained. `--self-test` proves | |
| # the check in both directions. | |
| - name: Verify OSV exemptions carry an expiry and a reason | |
| run: | | |
| node scripts/check-osv-exemptions.mjs --self-test | |
| node scripts/check-osv-exemptions.mjs | |
| - name: Audit dependencies for known vulnerabilities (OSV-Scanner) | |
| uses: google/osv-scanner-action/osv-scanner-action@f4cfcc01edc9c8b756a9b873b7a623ca674da51e # v2.3.8 | |
| with: | |
| scan-args: |- | |
| --lockfile=pnpm-lock.yaml | |
| - name: List outdated packages | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| run: | | |
| pnpm outdated --recursive || true |