mirror of
https://github.com/saltbo/zpan.git
synced 2026-09-24 23:22:31 +08:00
build: migrate project to pnpm
This commit is contained in:
+18
-24
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 }}"
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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" \
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user