build: migrate project to pnpm

This commit is contained in:
saltbo
2026-06-01 10:44:33 -04:00
parent 312413d0a8
commit 30bc6e1a12
26 changed files with 11157 additions and 18291 deletions
+18 -24
View File
@@ -17,19 +17,15 @@ jobs:
if: github.repository == 'saltbo/zpan'
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
with:
node-version: 24
- uses: actions/cache@v4
id: deps
with:
path: node_modules
key: node-modules-${{ hashFiles('package-lock.json') }}
- if: steps.deps.outputs.cache-hit != 'true'
run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npx vitest run --project unit --coverage
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm exec vitest run --project unit --coverage
- uses: codecov/codecov-action@v5
if: always()
with:
@@ -37,7 +33,7 @@ jobs:
flags: unit
fail_ci_if_error: false
handle_no_reports_found: true
- run: npx vitest run --project integration --coverage
- run: pnpm exec vitest run --project integration --coverage
- uses: codecov/codecov-action@v5
if: always()
with:
@@ -46,7 +42,7 @@ jobs:
fail_ci_if_error: false
handle_no_reports_found: true
- run: mkdir -p dist
- run: npm run test:cf
- run: pnpm test:cf
e2e-node:
name: E2E (Node)
@@ -56,19 +52,18 @@ jobs:
BETTER_AUTH_SECRET: ci-test-secret-that-is-at-least-32-chars
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
with:
node-version: 24
- uses: actions/cache@v4
with:
path: node_modules
key: node-modules-${{ hashFiles('package-lock.json') }}
- run: npx playwright install --with-deps chromium
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm exec playwright install --with-deps chromium
- name: Install cloudflared
run: |
curl -L --fail --output cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
chmod +x cloudflared
- run: CLOUDFLARED_BIN=./cloudflared npm run e2e:cloud -- --runtime node
- run: CLOUDFLARED_BIN=./cloudflared pnpm e2e:cloud -- --runtime node
- uses: actions/upload-artifact@v4
if: failure()
with:
@@ -82,19 +77,18 @@ jobs:
needs: check
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
with:
node-version: 24
- uses: actions/cache@v4
with:
path: node_modules
key: node-modules-${{ hashFiles('package-lock.json') }}
- run: npx playwright install --with-deps chromium
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm exec playwright install --with-deps chromium
- name: Install cloudflared
run: |
curl -L --fail --output cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
chmod +x cloudflared
- run: CLOUDFLARED_BIN=./cloudflared npm run e2e:cloud:cf
- run: CLOUDFLARED_BIN=./cloudflared pnpm e2e:cloud:cf
- uses: actions/upload-artifact@v4
if: failure()
with:
+7 -5
View File
@@ -73,9 +73,11 @@ jobs:
repository: saltbo/zpan
ref: ${{ steps.release.outputs.version }}
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
node-version: 24
cache: pnpm
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
@@ -87,7 +89,7 @@ jobs:
- name: Setup SAM CLI
uses: aws-actions/setup-sam@v2
- run: npm ci
- run: pnpm install --frozen-lockfile
- name: Ensure SAM artifact bucket exists
id: bucket
@@ -106,7 +108,7 @@ jobs:
env:
TURSO_DATABASE_URL: ${{ secrets.TURSO_DATABASE_URL }}
TURSO_AUTH_TOKEN: ${{ secrets.TURSO_AUTH_TOKEN }}
run: npx drizzle-kit migrate
run: pnpm exec drizzle-kit migrate
- name: Resolve existing deployment state
id: state
@@ -139,10 +141,10 @@ jobs:
- name: Build
run: |
npx vite build --mode node
pnpm exec vite build --mode node
# Bundle Lambda entry; @libsql/client is external (native binding)
npx tsup server/entry-lambda.ts --format cjs --outDir dist-lambda --external @libsql/client
pnpm exec tsup server/entry-lambda.ts --format cjs --outDir dist-lambda --external @libsql/client
# Assemble minimal Lambda deployment package
mkdir -p dist-lambda-pkg
+7 -6
View File
@@ -89,12 +89,13 @@ jobs:
# ------------------------------------------------------------------
# Step 3 — Node.js setup + install dependencies.
# ------------------------------------------------------------------
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
node-version: 24
cache: pnpm
- run: npm ci
- run: pnpm install --frozen-lockfile
# ------------------------------------------------------------------
# Step 4 — Log in to Azure using the service-principal credentials.
@@ -202,7 +203,7 @@ jobs:
# Step 7 — Build frontend + Azure Functions bundle.
# ------------------------------------------------------------------
- name: Build
run: npm run build:azure
run: pnpm build:azure
# ------------------------------------------------------------------
# Step 8 — Run database migrations against Turso.
@@ -211,7 +212,7 @@ jobs:
env:
TURSO_DATABASE_URL: ${{ secrets.TURSO_DATABASE_URL }}
TURSO_AUTH_TOKEN: ${{ secrets.TURSO_AUTH_TOKEN }}
run: npm run db:migrate
run: pnpm db:migrate
# ------------------------------------------------------------------
# Step 9 — Install Azure Functions Core Tools and publish.
@@ -219,7 +220,7 @@ jobs:
# are already in place before this step runs.
# ------------------------------------------------------------------
- name: Install Azure Functions Core Tools
run: npm install -g azure-functions-core-tools@4 --unsafe-perm true
run: pnpm add --global azure-functions-core-tools@4
- name: Publish to Azure Functions
working-directory: azure-functions
+4 -2
View File
@@ -71,9 +71,11 @@ jobs:
repository: saltbo/zpan
ref: ${{ steps.release.outputs.version }}
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
@@ -90,8 +92,8 @@ jobs:
TURSO_DATABASE_URL: ${{ secrets.TURSO_DATABASE_URL }}
TURSO_AUTH_TOKEN: ${{ secrets.TURSO_AUTH_TOKEN }}
run: |
npm ci
npm run db:migrate
pnpm install --frozen-lockfile
pnpm db:migrate
- name: Store required secrets in Secret Manager
env:
+12 -10
View File
@@ -63,11 +63,13 @@ jobs:
repository: saltbo/zpan
ref: ${{ steps.release.outputs.version }}
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
- run: npm ci
- run: pnpm install --frozen-lockfile
- name: Ensure D1 database exists
id: d1
@@ -75,10 +77,10 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: |
DB_ID=$(npx wrangler d1 list --json | jq -r '.[] | select(.name == "zpan-db") | .uuid')
DB_ID=$(pnpm exec wrangler d1 list --json | jq -r '.[] | select(.name == "zpan-db") | .uuid')
if [ -z "$DB_ID" ]; then
# wrangler d1 create does not support --json; parse the TOML snippet it prints.
DB_ID=$(npx wrangler d1 create zpan-db | awk -F'"' '/database_id/{print $2; exit}')
DB_ID=$(pnpm exec wrangler d1 create zpan-db | awk -F'"' '/database_id/{print $2; exit}')
echo "Created D1 database: $DB_ID"
else
echo "Reusing D1 database: $DB_ID"
@@ -142,10 +144,10 @@ jobs:
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: npx wrangler d1 migrations apply DB --remote
run: pnpm exec wrangler d1 migrations apply DB --remote
- name: Build
run: npx vite build
run: pnpm exec vite build
- name: Deploy
env:
@@ -156,7 +158,7 @@ jobs:
# built Worker (dist/zpan/wrangler.json). Cd'ing into dist/zpan instead
# causes wrangler 4.x to error on conflicting base paths between the
# two configs.
run: npx wrangler deploy
run: pnpm exec wrangler deploy
- name: Set BETTER_AUTH_SECRET (first deploy only)
env:
@@ -164,12 +166,12 @@ jobs:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
USER_SECRET: ${{ secrets.BETTER_AUTH_SECRET }}
run: |
EXISTS=$(npx wrangler secret list --format json | jq -r '.[] | select(.name == "BETTER_AUTH_SECRET") | .name')
EXISTS=$(pnpm exec wrangler secret list --format json | jq -r '.[] | select(.name == "BETTER_AUTH_SECRET") | .name')
if [ -n "$USER_SECRET" ]; then
echo "$USER_SECRET" | npx wrangler secret put BETTER_AUTH_SECRET
echo "$USER_SECRET" | pnpm exec wrangler secret put BETTER_AUTH_SECRET
echo "Set BETTER_AUTH_SECRET from GitHub secret"
elif [ -z "$EXISTS" ]; then
openssl rand -base64 32 | npx wrangler secret put BETTER_AUTH_SECRET
openssl rand -base64 32 | pnpm exec wrangler secret put BETTER_AUTH_SECRET
echo "Auto-generated BETTER_AUTH_SECRET"
else
echo "BETTER_AUTH_SECRET already set, skipping"
@@ -180,5 +182,5 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: |
echo "${{ steps.r2.outputs.url }}" | npx wrangler secret put PUBLIC_IMAGES_URL
echo "${{ steps.r2.outputs.url }}" | pnpm exec wrangler secret put PUBLIC_IMAGES_URL
echo "Set PUBLIC_IMAGES_URL = ${{ steps.r2.outputs.url }}"
+10 -8
View File
@@ -66,28 +66,30 @@ jobs:
repository: saltbo/zpan
ref: ${{ steps.release.outputs.version }}
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: pnpm
- run: npm ci
- run: pnpm install --frozen-lockfile
- name: Apply Turso migrations
env:
TURSO_DATABASE_URL: ${{ secrets.TURSO_DATABASE_URL }}
TURSO_AUTH_TOKEN: ${{ secrets.TURSO_AUTH_TOKEN }}
run: npx drizzle-kit migrate
run: pnpm exec drizzle-kit migrate
- name: Ensure BETTER_AUTH_SECRET is set (first deploy only)
env:
USER_SECRET: ${{ secrets.BETTER_AUTH_SECRET }}
run: |
EXISTING=$(npx netlify env:get BETTER_AUTH_SECRET 2>&1 || true)
EXISTING=$(pnpm exec netlify env:get BETTER_AUTH_SECRET 2>&1 || true)
if [ -n "$USER_SECRET" ]; then
npx netlify env:set BETTER_AUTH_SECRET "$USER_SECRET" --context production
pnpm exec netlify env:set BETTER_AUTH_SECRET "$USER_SECRET" --context production
echo "Set BETTER_AUTH_SECRET from GitHub secret"
elif [ -z "$EXISTING" ]; then
npx netlify env:set BETTER_AUTH_SECRET "$(openssl rand -base64 32)" --context production
pnpm exec netlify env:set BETTER_AUTH_SECRET "$(openssl rand -base64 32)" --context production
echo "Auto-generated BETTER_AUTH_SECRET"
else
echo "BETTER_AUTH_SECRET already set, skipping"
@@ -95,8 +97,8 @@ jobs:
- name: Build
run: |
npm run build
npm run build:netlify
pnpm build
pnpm build:netlify
- name: Deploy
id: deploy
@@ -104,7 +106,7 @@ jobs:
TURSO_DATABASE_URL: ${{ secrets.TURSO_DATABASE_URL }}
TURSO_AUTH_TOKEN: ${{ secrets.TURSO_AUTH_TOKEN }}
run: |
OUTPUT=$(npx netlify deploy \
OUTPUT=$(pnpm exec netlify deploy \
--prod \
--dir=dist \
--functions=netlify/functions \
+10 -8
View File
@@ -61,21 +61,23 @@ jobs:
repository: saltbo/zpan
ref: ${{ steps.release.outputs.version }}
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
- name: Install dependencies
run: npm ci
run: pnpm install --frozen-lockfile
- name: Run migrations (Turso)
env:
TURSO_DATABASE_URL: ${{ secrets.TURSO_DATABASE_URL }}
TURSO_AUTH_TOKEN: ${{ secrets.TURSO_AUTH_TOKEN }}
run: npm run db:migrate
run: pnpm db:migrate
- name: Build
run: npm run build:vercel
run: pnpm build:vercel
- name: Link or create Vercel project
env:
@@ -84,7 +86,7 @@ jobs:
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
run: |
cp deploy/vercel/vercel.json vercel.json
npx vercel link --yes \
pnpm exec vercel link --yes \
--token "$VERCEL_TOKEN" \
--scope "$VERCEL_ORG_ID"
@@ -93,15 +95,15 @@ jobs:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
USER_SECRET: ${{ secrets.BETTER_AUTH_SECRET }}
run: |
EXISTS=$(npx vercel env ls production --token "$VERCEL_TOKEN" 2>/dev/null | grep -c "^BETTER_AUTH_SECRET" || true)
EXISTS=$(pnpm exec vercel env ls production --token "$VERCEL_TOKEN" 2>/dev/null | grep -c "^BETTER_AUTH_SECRET" || true)
if [ -n "$USER_SECRET" ]; then
# User supplied their own secret — persist it (upsert).
echo "$USER_SECRET" | npx vercel env add BETTER_AUTH_SECRET production --token "$VERCEL_TOKEN" --force
echo "$USER_SECRET" | pnpm exec vercel env add BETTER_AUTH_SECRET production --token "$VERCEL_TOKEN" --force
echo "Set BETTER_AUTH_SECRET from GitHub secret."
elif [ "$EXISTS" -eq 0 ]; then
# First deploy and no user secret — auto-generate and persist.
SECRET=$(openssl rand -base64 32)
echo "$SECRET" | npx vercel env add BETTER_AUTH_SECRET production --token "$VERCEL_TOKEN"
echo "$SECRET" | pnpm exec vercel env add BETTER_AUTH_SECRET production --token "$VERCEL_TOKEN"
echo "auto_generated=true" >> "$GITHUB_OUTPUT"
echo "Auto-generated BETTER_AUTH_SECRET and stored in Vercel project env."
else
@@ -120,7 +122,7 @@ jobs:
BETTER_AUTH_URL: ${{ secrets.BETTER_AUTH_URL }}
TRUSTED_ORIGINS: ${{ secrets.TRUSTED_ORIGINS }}
run: |
DEPLOY_URL=$(npx vercel deploy --prod --token "$VERCEL_TOKEN" \
DEPLOY_URL=$(pnpm exec vercel deploy --prod --token "$VERCEL_TOKEN" \
--env TURSO_DATABASE_URL="$TURSO_DATABASE_URL" \
--env TURSO_AUTH_TOKEN="$TURSO_AUTH_TOKEN" \
--env BETTER_AUTH_URL="$BETTER_AUTH_URL" \
+7 -6
View File
@@ -13,16 +13,17 @@ jobs:
contents: read
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm test
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm test
- run: mkdir -p dist # required by vitest cloudflare config
- run: npm run test:cf
- run: pnpm test:cf
docker:
name: Docker Image