Klippy's repo has run a check job on every push since course A: a frozen install, typecheck, the tests (agent tests run in the Workers runtime, with the model stubbed and no network), and a dry-run build of each Worker. In this lesson CI also deploys: on main, once check passes, migrations first, then the agent, then the web app.
Verified wrangler 4.157.0
Start from f-05 on GitHub. Starting here, or behind? Get the code at that tag:
git clone https://github.com/ryanyogan/klippy cd klippy git checkout f-05
1. When it deploys
The new job sits under check in the same workflow:
Each line is a rule:
needs: check: never deploy code that failed typecheck, tests or a build.if:pushes tomainonly. Tags and pull requests never deploy.concurrencywithcancel-in-progress: false: one deploy at a time, and never cut one off halfway. A half-applied migration is worse than a late deploy.The secret gate. GitHub doesn't let an
if:readsecretsdirectly, but it can read the job'senv. Every step checksenv.CLOUDFLARE_API_TOKEN != '', and the first prints a notice when it's empty. So until you add the secrets, the job is green and does nothing, and so is every fork and fresh clone.
2. In what order
Three steps deploy, in a fixed order:
Migrations first. The one D1 database both Workers share gets new tables before new code needs them. That only works if migrations only add, so the code that's live right now keeps working while the new code rolls out. Keep them additive: never drop or rename a column that live code reads in the same deploy.
Then the agent, because the web app calls it.
Then the web app. Its build step bundles the islands first.
wranglerVersion: "4.157.0" is the version in the lockfile. When the installed Wrangler matches it, the action uses that one instead of installing another, so CI deploys with exactly the Wrangler your tests used. Copy ci.yml.
3. Secrets: the Workers' first
There are two kinds of secret, and the order you add them matters.
The Workers' secrets go in first, by hand, once. Both wrangler.jsonc files list theirs under secrets.required, and wrangler deploy refuses to deploy a Worker that's missing one. So put them before CI ever deploys:
cd apps/agent pnpm exec wrangler secret put KLIPPY_TOKEN # openssl rand -hex 32 cd ../web pnpm exec wrangler secret put KLIPPY_TOKEN # the same value as the agent's pnpm exec wrangler secret put SESSION_SECRET # openssl rand -base64 32 pnpm exec wrangler secret put GITHUB_CLIENT_ID pnpm exec wrangler secret put GITHUB_CLIENT_SECRET
CI doesn't push these. The action can, from GitHub secrets, but then each lives in two places.
Then the repository secrets, which switch the deploy on. In GitHub: Settings → Secrets and variables → Actions. Add CLOUDFLARE_ACCOUNT_ID, and CLOUDFLARE_API_TOKEN: an account-owned API token with Workers Scripts Edit and D1 Edit (plus Workers Routes once you add a custom domain in the next lesson), not your user's global key. The next push to main deploys. Add these first and that push fails on the missing Worker secrets.
4. What we saw
We haven't added the Cloudflare secrets to Klippy's repo, so there's no real deploy to show. What CI recorded is the gate working: on main, the deploy job ran green, printed "No Cloudflare secrets yet, so no deploy" and skipped every other step. On the f-06 tag, deploy didn't run at all.
Your code matches tag f-06 (changes from f-05).