diff --git a/.github/workflows/vercel.yml b/.github/workflows/vercel.yml index c41f4ea69..a982ba751 100644 --- a/.github/workflows/vercel.yml +++ b/.github/workflows/vercel.yml @@ -1,4 +1,4 @@ -name: Vercel compatibility +name: Vercel Compatibility on: pull_request: @@ -62,21 +62,20 @@ jobs: - name: Build Vercel artifact against isolated PostgreSQL run: | mkdir -p .vercel - node --input-type=module - <<'JS' - import { writeFileSync } from 'node:fs'; - writeFileSync('.vercel/project.json', JSON.stringify({ - projectId: 'prj_ci', orgId: 'team_ci', projectName: 'reactive-resume-ci', - settings: { framework: 'services', nodeVersion: '24.x', createdAt: 0 } - })); - JS - pnpm dlx --allow-build=esbuild vercel@61.0.0 build --prod --yes --global-config "$RUNNER_TEMP/vercel-offline" + cat > .vercel/project.json <<'JSON' + { + "projectId": "prj_ci", "orgId": "team_ci", "projectName": "reactive-resume-ci", + "settings": { "framework": "services", "nodeVersion": "24.x", "createdAt": 0 } + } + JSON + pnpm dlx --allow-build=esbuild vercel@61.0.0 build --prod --standalone --yes --global-config "$RUNNER_TEMP/vercel-offline" # Runs the backend Function from a copy outside the checkout, so a dependency the build left out fails here. - name: Check backend Function loading and budget run: | node --no-experimental-require-module --input-type=module - <<'JS' import assert from 'node:assert/strict'; - import { cpSync, lstatSync, mkdirSync, readFileSync, readlinkSync, symlinkSync } from 'node:fs'; - import { dirname, join } from 'node:path'; + import { cpSync, readFileSync } from 'node:fs'; + import { join } from 'node:path'; const func = '.vercel/output/services/backend/functions/index.func'; const config = JSON.parse(readFileSync(`${func}/.vc-config.json`)); assert.equal(config.runtime, 'nodejs24.x'); @@ -84,11 +83,6 @@ jobs: assert.equal(config.handler, 'apps/server/vercel.mjs'); const root = join(process.env.RUNNER_TEMP, 'backend-function'); cpSync(func, root, { recursive: true, verbatimSymlinks: true }); - for (const [path, source] of Object.entries(config.filePathMap ?? {})) { - mkdirSync(dirname(join(root, path)), { recursive: true }); - if (lstatSync(source).isSymbolicLink()) symlinkSync(readlinkSync(source), join(root, path)); - else cpSync(source, join(root, path)); - } const { default: app } = await import(join(root, config.handler)); const stage = await app.fetch(new Request('http://localhost:3000/api/storage/stage', { method: 'POST', body: '{}' })); assert.equal(stage.status, 401); diff --git a/docs/contributing/deployment-checks.mdx b/docs/contributing/deployment-checks.mdx index 379a709b7..ddf62c51a 100644 --- a/docs/contributing/deployment-checks.mdx +++ b/docs/contributing/deployment-checks.mdx @@ -3,7 +3,7 @@ title: "Deployment checks" description: "How CI verifies the Vercel build artifact on every pull request, and how to run the deployment smoke test against a Vercel or Docker installation." --- -Reactive Resume ships as a Docker image and as a Vercel project. The **Vercel compatibility** workflow (`.github/workflows/vercel.yml`) catches problems that only show up in a deployed build. It has two jobs: an offline artifact build that runs on every pull request, and a live smoke test you start by hand. You can run the same smoke test against your own installation. +Reactive Resume ships as a Docker image and as a Vercel project. The **Vercel Compatibility** workflow (`.github/workflows/vercel.yml`) catches problems that only show up in a deployed build. It has two jobs: an offline artifact build that runs on every pull request, and a live smoke test you start by hand. You can run the same smoke test against your own installation. ## Artifact build @@ -12,7 +12,7 @@ The `artifact` job runs on every pull request, every push to `main`, and every m The job: 1. Starts an isolated PostgreSQL service. -2. Writes a local `.vercel/project.json` with the `services` framework, then runs `vercel build --prod` offline with placeholder Blob credentials. The build applies migrations to the isolated database. +2. Writes a local `.vercel/project.json` with the `services` framework, then runs `vercel build --prod --standalone` offline with placeholder Blob credentials. Vercel packages dependencies into the Function output; the build applies migrations to the isolated database. 3. Checks the `backend` service Function: - its runtime is `nodejs24.x`, `maxDuration` is `300`, and its handler is `apps/server/vercel.mjs`; - a copy of the Function outside the checkout loads with `--no-experimental-require-module`, like the Vercel runtime does, so a dependency the build left out fails the job;