Stratify
Engineering

Jenkins

docs/jenkins.md

Source updated 03. Aug. 2026

Jenkins — Stratify v2.1

The pipeline is declared in Jenkinsfile at the repo root. It runs locally only — there is no remote Jenkins. The controller runs on this Mac at http://localhost:8080; builds execute on a local mac agent under ~/services/jenkins-agent.

Update (2026-07-14): this doc's original premise — Jenkins as sole CI, GitHub Actions disabled — no longer holds. .github/workflows/dos-ci.yml (typecheck/lint/test/build + secret scan) and .github/workflows/deploy.yml (auto-deploy to prod on merge to mainnot functional, see below) currently gate every PR. Whether this local Jenkins setup still runs in parallel or is now vestigial hasn't been reconfirmed — treat GitHub Actions as the enforced gate until someone checks.

Jenkins is a CI gate only: typecheck, lint, test, OpenAPI lint, web build. It does not build iOS and does not deploy. iOS release is a separate local fastlane flow (docs/runbooks/mobile-release.md); web deploy is infra/hetzner/deploy-web-hetzner.sh.

What it does

StageAction
ToolchainInstalls Node 24 + activates pnpm 9.12 via corepack.
Installpnpm install --frozen-lockfile
Typecheckpnpm typecheck (TS strict across all workspaces)
Lintpnpm --filter @stratify/web lint
Unit testspnpm --filter @stratify/web test (Vitest, incl. audit-chain replay tests)
OpenAPI lintpnpm api:lint (redocly)
Build webpnpm --filter @stratify/web build with placeholder envs

Total runtime ~3–5 min on the local mac agent.

The Postman drift stage was removedopenapi-to-postmanv2 emits non-deterministic UUIDs + faker data per run, so a strict drift gate is structurally broken. The collection is documentation: regenerate locally with pnpm api:postman and commit when the OpenAPI spec actually changes.
The Mobile · EAS (tag mobile-v*) stage still present in the Jenkinsfile is defunct — EAS is dead (see docs/runbooks/mobile-release.md). It only fires on a mobile-v* tag, which we no longer cut. Ignore it; iOS ships via local fastlane.

Required Jenkins credentials

These are build-time only — runtime secrets live in the Hetzner deploy env (/data/stratify/web/.env, written by infra/hetzner/deploy-web-hetzner.sh) and macOS Keychain (see docs/secrets.md). For CI you can use real values or placeholders; the build never talks to a live Supabase.

IDTypeValue example
STRATIFY_SUPABASE_URLSecret texthttps://placeholder.supabase.co
STRATIFY_SUPABASE_ANON_KEYSecret textplaceholder-anon-key
STRATIFY_APP_URLSecret texthttps://app.stratifyinvest.com

Setup (local controller + mac agent)

The controller (localhost:8080) and a single mac agent (~/services/jenkins-agent) are already provisioned on this machine.

  1. Create credentials: Manage Jenkins → Credentials → add the three

string credentials with the IDs listed above.

  1. Create a Pipeline job:
  • Pipeline → Definition: "Pipeline script from SCM"
  • SCM: Git → local repo path → main branch
  • Script path: Jenkinsfile
  1. First build: click "Build Now" once after job creation so Jenkins

indexes the credentials.

The Jenkinsfile declares agent any, bootstraps Node 24 into the workspace, and activates pnpm via corepack — so the mac agent needs no preinstalled Node.

Running the same checks locally (no Jenkins)

Mirror the gate from a shell:

pnpm install --frozen-lockfile
pnpm typecheck
pnpm --filter @stratify/web lint
pnpm --filter @stratify/web test
pnpm api:lint
pnpm --filter @stratify/web build

If that passes, the Jenkins pipeline will pass too.

Troubleshooting

  • `pnpm: command not found` — corepack didn't activate. Ensure the agent's

Node is ≥ 22 and PATH wasn't overridden.

  • Build stage fails on missing `NEXT_PUBLIC_SUPABASE_URL` — credential not

created or ID mismatch. The build doesn't _need_ a real Supabase, but it does need the env var set (placeholder is fine).

  • Mobile · EAS stage fails — it shouldn't run (tag-gated); if you tagged

mobile-v* by accident, ignore the failure. iOS ships via local fastlane.