wrongmove/.github/workflows/build-frontend.yml
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

77 lines
2.3 KiB
YAML

name: Build and Push Frontend
# Migrated from .woodpecker/frontend.yml on 2026-05-18. GHA builds + pushes
# to DockerHub; Keel polls :latest and rolls the realestate-crawler-ui
# Deployment. The .env.production file carries VITE_MAPBOX_TOKEN at build
# time (Vite reads it from the build context) — same shape as the
# Woodpecker pipeline, just sourced from a GHA secret instead.
on:
push:
branches: [master]
paths:
- 'frontend/**'
- '.github/workflows/build-frontend.yml'
concurrency:
group: build-frontend-${{ github.ref }}
cancel-in-progress: true
env:
IMAGE: viktorbarzin/immoweb
jobs:
test-and-build:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Install deps
working-directory: frontend
run: npm ci
# Vitest runs all 4 Woodpecker shards in one job — single GHA runner
# is plenty fast and avoids matrix-cost x4.
- name: Vitest
working-directory: frontend
run: npx vitest run --reporter=verbose
# Writes .env.production for Vite's build-time read. Secret is piped
# via env (not `${{ }}` directly in run:) so shell metacharacters in
# the value, if any, can't break out.
- name: Write .env.production for Vite build
env:
MAPBOX_TOKEN: ${{ secrets.MAPBOX_TOKEN }}
run: printf 'VITE_MAPBOX_TOKEN=%s\n' "$MAPBOX_TOKEN" > frontend/.env.production
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
username: viktorbarzin
password: ${{ secrets.DOCKERHUB_TOKEN }}
- id: meta
env:
GIT_SHA: ${{ github.sha }}
run: echo "sha=$(printf '%s' "$GIT_SHA" | cut -c1-8)" >> "$GITHUB_OUTPUT"
- uses: docker/build-push-action@v6
with:
context: frontend
file: frontend/Dockerfile
target: production
platforms: linux/amd64
push: true
tags: |
${{ env.IMAGE }}:${{ steps.meta.outputs.sha }}
${{ env.IMAGE }}:latest
cache-from: type=gha,scope=frontend
cache-to: type=gha,scope=frontend,mode=max