Skip to content

Commit 03fd614

Browse files
frenchie4111claude
andauthored
site: deploy the marketing site to Vercel instead of GitHub Pages (#273)
Moves the marketing site off GitHub Pages onto Vercel, without using Vercel's Git integration. ## What's here - **`scripts/deploy-site.sh`** — builds `site/` and ships the result to Vercel as a prebuilt [Build Output API v3](https://vercel.com/docs/build-output-api/v3) upload. `--prod` for production, bare for a preview. - **`.github/workflows/deploy-site.yml`** — rewritten to call the script on pushes to `main`, same path filters as the old Pages workflow plus the script itself. - **`.gitignore`** — ignores `.vercel/`. ## Why prebuilt Vercel never runs the build. The root `package.json` pulls in Electron plus the bundled `@anthropic-ai/claude-code` platform binary — hundreds of MB of native artifacts a static site has no use for — and needs `--legacy-peer-deps` to install at all. We build in CI and Vercel just serves the upload. ## Scope safety The deploying account can also reach the user's employer team, so the target is pinned three ways: - every CLI call passes an explicit `--scope` (the CLI's implicit default is whatever `vercel switch` last set, and is not trusted) - the real org/project IDs are hardcoded and asserted against both `.vercel/project.json` and the CI env vars - the assertion re-runs after linking Verified it fails closed, before any network call: ``` $ VERCEL_ORG_ID=bogus ./scripts/deploy-site.sh --prod error: VERCEL_ORG_ID is 'bogus' but this script only deploys to 'mike-personal' (team_…). Refusing to continue. exit code: 1 ``` ## URL paths are preserved Shipped clients hardcode paths into this site — `announcements-poller.ts` polls `/announcements.json`, and the feed entries link at `/announcements/<slug>.html`. `config.json` stays `{"version":3}`: no `cleanUrls`, no `trailingSlash`, no rewrites. The script re-checks every critical path after deploying, and **deliberately does not follow redirects** — a `cleanUrls`-style `/foo.html` → `/foo` rewrite has to fail, not quietly resolve. JSON responses are parsed, not just status-checked. Live run against the production alias: ``` ==> Verifying URL paths against https://ness-pi.vercel.app ok /announcements.json 200 application/json ok /announcements/ness-rename.html 200 text/html ok /announcements.html 200 text/html ok /guide.html 200 text/html ok /releases.html 200 text/html ok / 200 text/html ``` ## Two things the original plan got wrong 1. **A bare `vercel deploy` is not a preview.** For projects with no Git integration the CLI defaults to the *production* target and moves the production alias. The script now always passes an explicit `--target=preview` / `--target=production`. 2. **Per-deployment URLs are SSO-gated even for production.** Under Vercel's default Standard Protection only the production *alias* is public. Verification therefore targets the alias for `--prod`, and previews report `gated by Deployment Protection` unless `VERCEL_AUTOMATION_BYPASS_SECRET` is set. ## Not in this PR - `src/shared/constants.ts` — `HARNESS_SITE_URL` still points at `harness.mikelyons.org`. Domain cutover is a separate phase. - `site/public/CNAME` — kept on purpose so the Pages deployment retains its domain binding as a fallback during the transition. On Vercel it's an inert `/CNAME` file. Delete once cut over. - DNS / Vercel domain configuration. ## Before merging — secrets to add `Settings → Secrets and variables → Actions`: | Secret | Value | |---|---| | `VERCEL_TOKEN` | a token from https://vercel.com/account/tokens, scoped to **Mike Personal** | | `VERCEL_ORG_ID` | `team_WPsnEYquqTM2pNOKRhusfIbg` | | `VERCEL_PROJECT_ID` | `prj_2OW4xWxb0i2khtSCDAKIoixk8khA` | Without these the workflow fails at the deploy step. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent c9f2639 commit 03fd614

3 files changed

Lines changed: 389 additions & 24 deletions

File tree

.github/workflows/deploy-site.yml

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
name: Deploy marketing site
22

3+
# Builds site/ and ships it to Vercel as a prebuilt Build Output API v3
4+
# upload. Vercel's Git integration is deliberately NOT connected — this
5+
# workflow is the only thing that deploys the site, so the root
6+
# package.json's Electron + claude-code native deps never get installed
7+
# on Vercel. See scripts/deploy-site.sh for the full rationale.
8+
39
on:
410
push:
511
branches: [main]
612
paths:
713
- 'site/**'
814
- 'package.json'
915
- 'package-lock.json'
16+
- 'scripts/deploy-site.sh'
1017
- '.github/workflows/deploy-site.yml'
1118
workflow_dispatch:
1219

1320
permissions:
1421
contents: read
15-
pages: write
16-
id-token: write
1722

23+
# Never let two deploys race for the production alias.
1824
concurrency:
19-
group: pages
25+
group: deploy-site
2026
cancel-in-progress: false
2127

2228
jobs:
23-
build:
29+
deploy:
2430
runs-on: ubuntu-latest
2531
steps:
2632
- uses: actions/checkout@v4
@@ -35,24 +41,13 @@ jobs:
3541
- name: Install dependencies
3642
run: npm install --legacy-peer-deps
3743

38-
- name: Build site
39-
run: npm run build:site
40-
41-
- name: Configure Pages
42-
uses: actions/configure-pages@v5
43-
44-
- name: Upload artifact
45-
uses: actions/upload-pages-artifact@v3
46-
with:
47-
path: site/dist
44+
# Pinned so a CLI release can't change deploy behaviour under us.
45+
- name: Install Vercel CLI
46+
run: npm i -g vercel@50.37.0
4847

49-
deploy:
50-
needs: build
51-
runs-on: ubuntu-latest
52-
environment:
53-
name: github-pages
54-
url: ${{ steps.deployment.outputs.page_url }}
55-
steps:
56-
- name: Deploy to GitHub Pages
57-
id: deployment
58-
uses: actions/deploy-pages@v4
48+
- name: Build and deploy to production
49+
run: ./scripts/deploy-site.sh --prod
50+
env:
51+
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
52+
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
53+
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ release/
1111
.DS_Store
1212
.claude/settings.local.json
1313
.claude/scheduled_tasks.lock
14+
.vercel

0 commit comments

Comments
 (0)