Skip to content

Count standing from live links, and let the recheck schedule advance … #29

Count standing from live links, and let the recheck schedule advance …

Count standing from live links, and let the recheck schedule advance … #29

Workflow file for this run

# Migrate, then build, then deploy. Pushing to main is the whole ritual.
#
# Migrations run BEFORE the deploy so the schema is never behind the code that
# depends on it. That ordering is only safe while migrations are additive: a
# column the old code does not know about is harmless, whereas a dropped or
# renamed column breaks the still-running old version the moment it applies. For
# a destructive change, ship it in two passes (stop using the column, deploy,
# then drop it in the next one) rather than reordering these steps.
name: Deploy
on:
push:
branches: [main]
# Lets you re-run a failed deploy without an empty commit.
workflow_dispatch:
# Never let two deploys race. A second push while one is mid-flight waits rather
# than applying migrations concurrently against the same database.
concurrency:
group: deploy-production
cancel-in-progress: false
jobs:
deploy:
runs-on: ubuntu-latest
defaults:
run:
working-directory: next-app
steps:
- uses: actions/checkout@v4
# package_json_file is required because the app is nested in next-app/ and
# there is no root package.json. `defaults.run.working-directory` above
# only applies to `run` steps, not to action inputs, so without this the
# action looks for ./package.json, finds nothing, and fails with "No pnpm
# version is specified". Pointing at the real manifest keeps the version
# single-sourced from its `packageManager` field rather than pinning it
# again here, where the two would drift.
- uses: pnpm/action-setup@v4
with:
package_json_file: next-app/package.json
# Node 22, not 20. `pnpm test` runs `node --test "src/**/*.test.ts"`, and
# glob patterns in the test runner only landed in Node 22. On 20 the
# pattern is treated as a literal path and the run fails having executed
# nothing, which reads like "no tests exist" rather than "wrong runtime".
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
cache-dependency-path: next-app/pnpm-lock.yaml
- run: pnpm install --frozen-lockfile
# Cheap gates first. A deploy that ships a type error or a failing test is
# worse than one that never started, and these take seconds.
- run: pnpm typecheck
- run: pnpm lint
- run: pnpm test
- name: Apply migrations
run: pnpm db:migrate
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
# NEXT_PUBLIC_* are inlined by the bundler at build time, so they have to
# be present HERE. Setting them as Worker secrets does nothing: by the time
# the Worker runs, the value is already baked into the bundle or missing
# from it. This is a repository variable, not a secret, because anything
# NEXT_PUBLIC_ is shipped to every browser that loads the page.
#
# Analytics needs nothing here: Cloudflare Web Analytics is on "Automatic
# setup", so the JS Snippet will be automatically injected at the edge.
- name: Build
run: pnpm exec opennextjs-cloudflare build
env:
NEXT_PUBLIC_SITE_URL: ${{ vars.NEXT_PUBLIC_SITE_URL }}
- name: Deploy
run: pnpm exec wrangler deploy
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}