Commit graph

28 commits

Author SHA1 Message Date
Viktor Barzin
c2acbf5d2e CI: migrate Docker build/push from Woodpecker to GitHub Actions
Was: Woodpecker built+pushed to DockerHub, then `kubectl set image` patched
the four Deployments to a pinned numeric tag. With Deployments pinned to
:51 (immutable tag), Keel polled forever and never saw a digest bump — and
no DockerHub pull-secret meant Keel hit 401 on the private repo at every
poll. The 4-Deployment setup also had a latent ImagePullBackOff risk: if a
node was replaced, fresh pulls would fail.

Now: GHA builds+pushes (.github/workflows/build-{api,frontend}.yml) on push
to master. Cluster Deployments reference :latest with an imagePullSecret
sourced from Vault via ESO (codified in infra/stacks/real-estate-crawler/
main.tf, separate commit). Keel polls :latest, sees the new digest after
each GHA build, and rolls all four Deployments.

- .github/workflows/build-api.yml: pytest (unit + integration/regression/
  e2e/test_listing_geojson) + buildx push viktorbarzin/realestatecrawler
  to {<8-char-sha>, latest}.
- .github/workflows/build-frontend.yml: vitest (all 4 ex-shards in one
  run) + Vite build with VITE_MAPBOX_TOKEN from GHA secret + buildx push
  viktorbarzin/immoweb to {<8-char-sha>, latest}.
- .woodpecker/{api,frontend}.yml renamed to
  .woodpecker/build-fallback-{api,frontend}.yml with `event: deployment`
  so they no longer fire on push — kept as manual-only fallback if GHA
  is down (CLAUDE.md convention from the 10 already-migrated projects).
- .claude/CLAUDE.md: Git Workflow section updated to reflect GHA as
  primary + the dockerhub-pull-secret wiring.

GHA repo secrets DOCKERHUB_TOKEN and MAPBOX_TOKEN populated from Vault
fields viktor.dockerhub_registry_password and ci/global.wrongmove-mapbox-token
respectively (DOCKERHUB_USERNAME=viktorbarzin was already set).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 19:11:31 +00:00
Viktor Barzin
9bb5320e2b wrongmove: write VITE_MAPBOX_TOKEN to .env.production in CI (replaces broken build_args)
The previous attempt passed the Mapbox token via `--build-arg`, but
the docker-buildx plugin's KEY=VALUE list-parser mangled the value
(the rendered command was `--build-arg *=VITE_MAPBOX_TOKEN=********`,
key got lost). Inspecting `viktorbarzin/immoweb:45` confirmed
`pk.eyJ...` was nowhere in the bundle.

Switching to the idiomatic Vite path: a new `prepare-frontend-env`
commands step writes `frontend/.env.production` from the
`wrongmove-mapbox-token` Woodpecker secret. `COPY . .` in the
Dockerfile pulls the file into the build context, and Vite
auto-loads `.env.production` during `npx vite build`.

Net diff:
- `.woodpecker/frontend.yml`: new prepare step, build step now
  depends on it, dropped the build_args line.
- `frontend/Dockerfile`: dropped the ARG/ENV lines (no longer needed,
  also silences `SecretsUsedInArgOrEnv` linter warning).
- `frontend/.gitignore`: ignore `.env.production` / `.env.local` so
  the CI-written file never gets accidentally committed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 22:10:25 +00:00
Viktor Barzin
d03a9a0fe2 wrongmove: inline VITE_MAPBOX_TOKEN as a build_arg (drop secret indirection)
The previous attempt used a step-level `environment:` block with
`from_secret:`, which the Woodpecker linter rejected on plugin steps
("Should not configure both `environment` and `settings`"). Net effect
was build-and-push-frontend reverted to a commands step and the
docker daemon never started.

The Mapbox `pk.*` token ends up baked into the public bundle anyway —
its security model is domain restrictions in the Mapbox dashboard, not
build-time secrecy. Inlining the value in `build_args` is the simplest
working path and avoids the secret-indirection footgun. The token also
still lives in Vault at `secret/ci/global/wrongmove-mapbox-token` for
the day we adopt a private style URL or replace this with a different
provider.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 21:54:40 +00:00
Viktor Barzin
25458fd2a2 wrongmove: bake VITE_MAPBOX_TOKEN into the frontend build
Adds a build-arg path so the Mapbox public token is injected at
`vite build` time instead of being hardcoded in the bundle:

- `frontend/Dockerfile` declares `ARG VITE_MAPBOX_TOKEN` in the
  builder stage and re-exports it via `ENV` so Vite picks it up.
- `.woodpecker/frontend.yml` maps the global `wrongmove-mapbox-token`
  Woodpecker secret into a step-level `VITE_MAPBOX_TOKEN` env var,
  then forwards it via `build_args_from_env`.

Token is a domain-restricted `pk.*` public token (Mapbox), so bundle
exposure is the intended threat model. Vault-stored at
`secret/ci/global/wrongmove-mapbox-token`; synced to Woodpecker by
the existing vault-woodpecker-sync CronJob every 6h.

Replaces the post-Fix-4 "Map unavailable — set VITE_MAPBOX_TOKEN"
banner with a working basemap.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 21:42:40 +00:00
Viktor Barzin
73823bd381 ci: bump frontend test-shard memory to 2Gi (fix exit-137 OOM)
The 4 vitest shards were getting SIGKILL (exit code 137) because the
container memory limit was tighter than NODE_OPTIONS=--max-old-space-size=1024,
and 1024 wasn't enough headroom for the test workers either.

Set explicit kubernetes resources (request 1Gi / limit 2Gi) and bump
the V8 heap to 1.5Gi on install-frontend-deps and all 4 test shards.

Confirmed-by: pipeline 2081 step states (test-shard-1..4 all
state=failure exit_code=137; build/deploy steps then skipped).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 19:43:38 +00:00
Viktor Barzin
f5a92dc0c9
fix: increase install-api-deps memory to 1Gi for CI
LimitRange defaults to 192Mi which is too low for pip installing
~30 packages. Set 512Mi request / 1Gi limit.
2026-03-15 23:47:30 +00:00
Viktor Barzin
546f6957e3
ci: migrate from plugins/docker to woodpeckerci/plugin-docker-buildx
Replace the old Docker-in-Docker build approach (plugins/docker) with
the modern buildx plugin that natively supports BuildKit. This fixes:
- "Cannot connect to the Docker daemon" errors (no DinD needed)
- "the --mount option requires BuildKit" errors (buildx = BuildKit)
- OOM in publish step (skopeo no longer needed, buildx pushes directly)

Also removes the intermediate build-tag/skopeo-copy/publish dance —
buildx pushes both versioned and latest tags in a single step.
2026-03-15 22:52:01 +00:00
Viktor Barzin
94e3ec7408
ci: remove slack notification step (secret not configured) 2026-02-28 21:48:30 +00:00
Viktor Barzin
99e75177b5
ci: make slack notification non-blocking when secret is missing 2026-02-28 20:22:49 +00:00
Viktor Barzin
c7c3331d30
Migrate CI from Drone to Woodpecker
Replace .drone.yml with .woodpecker/ pipeline configs (frontend.yml, api.yml).
Convert Drone env vars to Woodpecker equivalents (CI_PIPELINE_NUMBER, CI_COMMIT_SHA),
use woodpeckerci/plugin-git for clone with retry, woodpeckerci/plugin-slack for
notifications, and plugins/docker for image builds. Update all docs and skills.
2026-02-23 22:00:09 +00:00
Viktor Barzin
6dcb0d8787 fix clone backoff duration format 2026-02-22 23:40:50 +00:00
Viktor Barzin
af29295793 fix clone backoff duration format 2026-02-22 23:40:49 +00:00
Viktor Barzin
b2904c03c2 [ci skip] Add clone retry settings for DNS resilience 2026-02-22 23:37:21 +00:00
Viktor Barzin
c68841e499 [ci skip] Add clone retry settings for DNS resilience 2026-02-22 23:37:19 +00:00
Viktor Barzin
432ceb575d Remove custom clone override, use built-in Woodpecker clone 2026-02-22 23:30:38 +00:00
Viktor Barzin
62fe594be2 Remove custom clone override, use built-in Woodpecker clone 2026-02-22 23:30:38 +00:00
Viktor Barzin
3efe7e251a Fix clone: no-op clone override + step-level auth 2026-02-22 23:02:54 +00:00
Viktor Barzin
2000ea5403 Fix clone: no-op clone override + step-level auth 2026-02-22 23:02:53 +00:00
Viktor Barzin
d3b8cb1f84 Standardize clone: skip_clone + step-level retry 2026-02-22 22:55:12 +00:00
Viktor Barzin
9e702a3f5f Standardize clone: skip_clone + step-level retry 2026-02-22 22:54:43 +00:00
Viktor Barzin
4e881780d9 Fix clone: use GitHub token for auth + DNS retry 2026-02-22 22:49:03 +00:00
Viktor Barzin
3a875c70a7 Fix clone: use GitHub token for auth + DNS retry 2026-02-22 22:48:31 +00:00
Viktor Barzin
813a0d7379 Fix clone: add netrc auth + cleanup between retries 2026-02-22 22:28:49 +00:00
Viktor Barzin
8747db4aaf Fix clone: add netrc auth + cleanup between retries 2026-02-22 22:28:16 +00:00
Viktor Barzin
32b38c432b Add clone retry logic for DNS resilience 2026-02-22 22:13:53 +00:00
Viktor Barzin
71f1d324a1 Add clone retry logic for DNS resilience 2026-02-22 22:13:22 +00:00
Viktor Barzin
23b544f73a Add Woodpecker CI API pipeline 2026-02-22 21:43:26 +00:00
Viktor Barzin
7c857cab75 Add Woodpecker CI frontend pipeline 2026-02-22 21:43:00 +00:00