Commit Graph

38 Commits

Author SHA1 Message Date
Flea Flicker 5b4562d5d7 fix: let Kustomize images transformer set seed/migrate image tags
The promote-to-uat workflow was bypassing the Kustomize images transformer
by hardcoding image tags directly on the Job spec containers. Since Jobs
use immutable templates, Flux cannot update a running Job's pod template
when the image tag changes. Instead, let the UAT overlay's images: newTag
field handle tag injection via the images transformer, which correctly
produces the updated image reference in the rendered manifest before Flux
reconciles it.

This reverts the explicit image tag writes added in 916a207 for migrate
and seed, while keeping the Job name (with short SHA) and deploy-version
annotation updates which are correctly handled separately.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-10 10:36:42 +00:00
Flea Flicker 7f405ccc67 fix: remove dead kubectl delete step from promote-to-uat workflow
The CTO correctly identified that the delete step was dead code:
- gcloud/kubectl silently fail in the runner (no GKE credentials)
- Architecturally wrong for GitOps (Flux handles reconciliation)
- Unique Job names + ttlSecondsAfterFinished handle lifecycle

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-10 06:07:22 +00:00
Flea Flicker 916a2071d9 fix: update seed job image tag in promote-to-uat workflow
The workflow was not updating the seed job image tag when promoting to UAT,
causing Flux to apply a stale image. Now it updates the image like it
does for the migrate job.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-10 06:05:41 +00:00
Flea Flicker 0c135ac580 Revert "chore: update migrate and seed Job image tags during UAT promotion" image update for seed
The hardcoded image update for seedJob conflicts with Kustomize images transformer
override. Reverting only the seed image line (line 70), keeping migrate image update
and Job deletion step.

Root cause: Kustomize images transformer correctly overrides ghcr.io/groombook/seed
when newTag is set in UAT overlay. Overwriting the container[0].image directly in
the workflow causes the old tag (2026.04.05-b090f8b) to be baked into the YAML that
Flux reconciles, bypassing the Kustomize override.

Fix: groombook/groombook#247

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-10 05:12:54 +00:00
Flea Flicker 4c1207a5ae chore: update migrate and seed Job image tags during UAT promotion
Previously the Kustomize images transformer was not overriding the hardcoded
image tags in migrate-job.yaml and seed-job.yaml (base/ containers), causing
UAT deployments to use stale image tags. This change adds explicit yq updates
to set the correct image tag on both Job containers during promotion.

Fixes: groombook/groombook#247
2026-04-10 04:59:56 +00:00
Flea Flicker 9be6a87105 chore: implement hourly reset CronJob for prod and UAT
- Add ALLOW_RESET env var override to reset.ts safety guard
- Add reset Docker build target to Dockerfile
- Add reset image build step to CI docker job
- Add reset image tag update to CD job dev overlay update

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-07 20:01:56 +00:00
Flea Flicker 25ac34828f fix(ci): remove dead kubectl steps and misleading TTL fallback lines
These steps always fail because the runner has no kubeconfig. Job names
are already unique per deploy (include SHORT_SHA), and base manifests
already set ttlSecondsAfterFinished: 120 for auto-cleanup.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-05 16:32:23 +00:00
Flea Flicker 006c05ac77 fix(ci): delete completed Jobs before Flux reconciles (GRO-481)
Both promote-to-uat and promote-prod workflows now delete any
existing completed Jobs with the same short SHA suffix before Flux
reconciles. This prevents the immutable-podTemplate error that was
blocking UAT at image tag a67e541:

  Job.batch "migrate-schema-xxx" is invalid: spec.template: field is immutable

Also added missing failure notification step to promote-prod workflow.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-05 15:47:04 +00:00
Flea Flicker 90ad46f0d5 fix(ci): rename base Jobs in promote-to-uat and promote-prod workflows (GRO-311)
Both workflows now update base migration/seed Job names with short SHA
extracted from the image tag, matching the dev CI cd job pattern.
This prevents Flux immutable-field errors on consecutive UAT/prod
promotions.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-05 11:14:17 +00:00
Pawla Abdul 784a79b284 chore(GRO-429): add promote-to-uat workflow for CTO-triggered UAT promotion
Adds a manual workflow_dispatch workflow to promote a specific image tag
to the UAT environment. This separates UAT promotion from the automated
dev pipeline, enforcing the 3-stage SDLC review gate.

- Triggers via workflow_dispatch with image_tag input
- Updates UAT overlay image tags in groombook/infra
- Creates and auto-merges infra PR for UAT only
- Requires GRO-427 (UAT overlay) to be complete first

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-03 20:44:31 +00:00
groombook-engineer[bot] 15fdd1cb5d fix(ci): use --merge instead of --auto --merge for infra PR
groombook/infra has no required status checks, so GitHub refuses to
enable auto-merge (PR is immediately in clean status). Replace
--auto --merge with --merge for immediate merge since there are no
checks to wait for.

Fixes: GRO-378

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-02 01:17:19 +00:00
groombook-engineer[bot] e1f6b7a9cb Merge branch 'main' into feature/gro-306-playwright-e2e-suite 2026-04-01 12:29:41 +00:00
groombook-cto[bot] ef403a0aa4 fix(ci): replace yq //= with expanded form (.field // default) (GRO-360)
The //= compound assignment operator is not supported in the version
of yq installed in CI. Replace both usages with the equivalent
(.spec.ttlSecondsAfterFinished // 86400) form.

Fixes GRO-360.

Co-authored-by: groombook-engineer[bot] <3141748+groombook-engineer[bot]@users.noreply.github.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-01 12:13:40 +00:00
groombook-engineer[bot] 66024d2e77 fix(ci): export SHORT_SHA for yq env() + fix(db): deterministic staff IDs (GRO-352, GRO-355)
yq env(SHORT_SHA) on lines 330 and 339 requires SHORT_SHA as an
environment variable, not just a shell variable. Without export, yq
receives an empty value and the Update Infra Image Tags job fails on
every merge to main.

Regression from GRO-311 fix (commit 0d610f5).

Co-authored-by: Barkley Trimsworth <barkley@groombook.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-01 10:21:41 +00:00
Flea Flicker fa9aa5cff1 feat(e2e): add Playwright E2E test suite for critical user journeys (GRO-306)
Implements the automated Playwright E2E suite as the pre-UAT gate following
the UAT failures identified in GRO-299. Creates 5 test files in apps/web/e2e/:

- portal-auth.spec.ts: verifies client portal auth (client name shown, not "Hi, Guest")
- portal-data.spec.ts: verifies portal sections render without auth gates
- admin-services.spec.ts: asserts no duplicate service names in admin/services and booking wizard
- admin-reports.spec.ts: verifies reports page shows non-zero data for last 60 days
- console-health.spec.ts: asserts no 404s for favicon/PWA assets and no JS exceptions

Also adds:
- apps/web/e2e/ with Playwright config targeting groombook.dev.farh.net
- Shared fixtures with storageState-based auth via dev login selector
- test:e2e npm script in apps/web/package.json
- web-e2e CI job targeting PRs (runs after deploy-dev)

Note: Tests 1 & 2 (portal auth/data) depend on GRO-300 being deployed.
Tests 3-5 run against current dev state.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-31 21:43:06 +00:00
groombook-engineer[bot] 0d610f5114 fix(ci): use unique Job names per deploy to prevent Flux immutability errors (GRO-311)
Since Kubernetes Job spec.template is immutable, Flux cannot update a
completed Job with a new image tag. This change ensures the CI workflow
updates both the image newTag AND the Job metadata.name to include the
short SHA (e.g., migrate-schema-026a2c8), making each deploy's Job
unique and allowing Flux to reconcile consecutive deploys without
immutable field errors.

Co-authored-by: Barkley Trimsworth <barkley@groombook.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-03-31 02:29:35 +00:00
Paperclip f572e0a8f8 fix(ci): use valid GitHub Actions expression syntax for SHA
- Replace invalid ${{ github.sha::7 }} with ${{ github.sha }}
  and shell ${SHA::7} for substring extraction
- Add SHA env var to deploy-dev job

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-30 13:35:47 +00:00
groombook-ci[bot] db21947323 fix(ci): include GitHub SHA in image tag to prevent stale cache reuse
Each CI build now produces an immutable tag (pr-N-sha7 or
YYYY.MM.DD-sha7) so that docker/build-push-action cache-from
type=gha cannot cross-contaminate between commits.

Previously the shared pr-N tag caused GHA layer cache to reuse
stale JS bundles from earlier builds of the same PR.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 13:33:10 +00:00
Barkley Trimsworth bf1b93aead ci: add workflow_dispatch trigger for manual CI runs
GitHub App token pushes do not trigger pull_request workflow events,
blocking CI on bot-authored PRs. Add workflow_dispatch to allow manual
CI runs via: gh workflow run ci.yml --ref <branch>

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-30 12:37:13 +00:00
groombook-ceo[bot] 20920022a6 fix: increase deployment rollout timeout to 300s (GRO-147) (#148)
Squash merge. CTO + QA approved, all CI checks green.

- Helm progressDeadlineSeconds: 120s → 300s (api + web)
- CI kubectl rollout timeout: 120s → 300s

Fixes groombook-dev CI deploy step timing out while pods complete successfully.

cc @cpfarhood
2026-03-29 14:07:21 +00:00
groombook-engineer[bot] b09606f5f0 ci: add production promotion workflow
Manual workflow_dispatch trigger to promote a tested image tag
to production by creating an infra PR. No auto-merge — UAT sign-off
required before prod deploy.

Co-authored-by: groombook-ci[bot] <ci@groombook.bot>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: groombook-ceo[bot] <269735724+groombook-ceo[bot]@users.noreply.github.com>
2026-03-29 12:36:08 +00:00
groombook-engineer[bot] 8de0a00a2b ci: update cd job to target dev overlay (#156)
Squash merge. All checks green, CTO + QA approved.

cc @cpfarhood
2026-03-29 09:46:37 +00:00
groombook-engineer[bot] 3834e45b66 feat: add cd job to update groombook/infra image tags on main merge (GRO-178) (#147)
* feat: add cd job to update groombook/infra image tags on main merge (GRO-178)

- Adds `cd` job that runs after `docker` on main branch pushes only
- Uses tibdex/github-app-token to get infra repo push token
- Updates image tags in apps/groombook/base/{api,web,migrate-job,seed-job}.yaml
- Opens auto-merge PR on groombook/infra

Trade-off: deploy-dev continues using kubectl set image directly for PR
previews (speed over full GitOps auditability for short-lived previews).

Co-Authored-By: Paperclip <noreply@paperclip.ing>

* fix: correct --head branch format and use --enable-auto-merge (GRO-178)

CTO review fixes:
- Remove bogus "groombook-engineer[bot]:" prefix from --head — gh pr
  create does not use owner:branch syntax when pushing from a cloned
  repo; just the branch name is needed
- Replace invalid --auto-merges-branch=main flag with
  --enable-auto-merge (valid gh flag that activates repo auto-merge)

Co-Authored-By: Paperclip <noreply@paperclip.ing>

* fix: broaden annotation sed pattern, fix PR body link, remove error swallowing (GRO-178)

CTO review remaining fixes:
- Annotation sed pattern: broaden [a-f0-9]* to [a-zA-Z0-9-]* since
  migrate-job and seed-job use "groXXX" suffixes (e.g. "2026.03.28-gro177")
  which contain non-hex letters
- PR body link: fix /d50d9792/issues/GRO-178 → /GRO/issues/GRO-178
- Remove error swallowing: "|| echo" was hiding PR creation failures;
  let the step fail naturally so CI catches it

Co-Authored-By: Paperclip <noreply@paperclip.ing>

* fix(cd): split --enable-auto-merge into separate merge command

CTO review fix: gh pr create does not support --enable-auto-merge flag.
Split into two commands: create PR, then gh pr merge with --auto --merge.

Co-Authored-By: Paperclip <noreply@paperclip.ing>

---------

Co-authored-by: groombook-engineer[bot] <3141748+groombook-engineer[bot]@users.noreply.github.com>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Flea Flicker <flea-flicker@groombook.io>
Co-authored-by: groombook-engineer[bot] <269742240+groombook-engineer[bot]@users.noreply.github.com>
2026-03-28 23:19:29 +00:00
groombook-engineer[bot] dcdc792875 Add Helm chart scaffold with Chart.yaml, values.yaml, helpers, and all templates
Adds full Helm chart for GroomBook including migration job (pre-install/pre-upgrade hook), CNPG cluster (operator mode), DragonflyDB (integrated + operator modes), API/web deployments, services, and ingress templates.

Resolves GRO-89.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-27 18:36:28 +00:00
groombook-cto[bot] d576876f56 fix(ci): use correct postgres secret for dev deploys
Fixes CI workflow to reference groombook-postgres-credentials-dev in groombook-dev namespace. Unblocks all dev PR deploys.
2026-03-27 16:54:03 +00:00
Groom Book CTO f1235c6d3d fix: install kubectl on ARC runner for deploy-dev job
ARC self-hosted runners don't include kubectl. Download it before
running the deployment commands.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-25 11:03:38 +00:00
Groom Book CTO 2b6c437446 feat: add PR preview deployment to groombook-dev
Extend CI to build PR-tagged Docker images and auto-deploy them to
groombook-dev when all checks pass. This unblocks Flea Flicker UAT
validation for open PRs.

Changes:
- Docker build job now runs on PRs (tagged as pr-{number}) and main
- New deploy-dev job uses self-hosted runners with kubectl access
- Runs migration, updates api/web deployments, comments on PR

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-25 11:03:38 +00:00
groombook-paperclip[bot] ea5450651d ci: remove 'Update Infra Image Tags' deploy job (#73)
The deploy job required INFRA_DEPLOY_TOKEN (a GitHub PAT) stored as a
repo secret, which violates the board directive against storing tokens
in repo secrets. Flux Image Automation will handle image tag updates
in the infra repo instead.

Fixes #72

Co-authored-by: Groom Book CTO <cto@groombook.dev>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 21:12:02 +00:00
groombook-paperclip[bot] 5b52c07219 ci: switch Docker image tags to CalVer versioning (#71)
Replace raw 40-char git SHA tags with CalVer format (e.g. 2026.03.19-19e0f5e)
for better readability and proper release date versioning. The deploy job now
consumes a version output from the docker job instead of using raw SHA.

Co-authored-by: Groom Book CTO <cto@groombook.dev>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-03-19 20:56:10 +00:00
groombook-paperclip[bot] 3b7b2b346f ci: auto-update infra image tags after Docker push (#70)
Adds a deploy job that runs after Docker images are pushed to GHCR.
It checks out groombook/infra, updates all image SHA tags in the
Kubernetes manifests, and commits directly to main.

This ensures Flux always picks up new images after a successful build,
preventing the previous issue where :latest tags caused no manifest
diff and pods weren't updated.

Requires INFRA_DEPLOY_TOKEN secret with push access to groombook/infra.

Co-authored-by: Groom Book CTO <cto@groombook.dev>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-03-19 20:18:04 +00:00
groombook-cto[bot] a045749673 Add Playwright E2E testing infrastructure
- New apps/e2e workspace with @playwright/test
- playwright.config.ts targeting Docker Compose stack (http://localhost:8080)
- navigation.spec.ts: smoke tests for all pages
- book.spec.ts: full booking wizard happy-path with API mocking
- clients.spec.ts: client list and detail panel tests
- CI job: spins up docker compose, installs Playwright chromium, runs tests
- Playwright report uploaded as artifact on failure
- README docs for running E2E tests locally

Closes #40

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-18 02:41:24 +00:00
groombook-paperclip[bot] 227a687e97 Add seed Docker stage and push migrate/seed images in CI (#37)
- Add seed stage to API Dockerfile (FROM builder, runs pnpm db:seed)
- Add explicit target: runner to API image build (prevents building wrong stage)
- Add CI steps to push ghcr.io/groombook/migrate and ghcr.io/groombook/seed images

Co-authored-by: Groom Book CEO <ceo@groombook.dev>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-03-17 23:47:56 +00:00
groombook-paperclip[bot] 1c54c4264d Update CI to push Docker images to ghcr.io (#35)
Enable image pushing to GitHub Container Registry on main branch
merges. Tags images with both commit SHA and latest.

Co-authored-by: Groom Book CTO <cto@groombook.app>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-03-17 22:23:33 +00:00
groombook-paperclip[bot] 49e6d8136d fix(ci): restore pnpm cache now that lockfile is on main
pnpm-lock.yaml landed with PR #15, so setup-node can cache pnpm deps
again. This speeds up CI by avoiding full re-installs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-17 19:01:49 +00:00
groombook-paperclip[bot] fd65679ca1 fix(ci): remove pnpm cache — no lockfile on main yet
setup-node's cache: pnpm requires pnpm-lock.yaml to exist. The lockfile
is coming in PR #15 but isn't on main yet. Remove caching for now —
it'll be re-enabled once the lockfile lands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 18:40:08 +00:00
groombook-paperclip[bot] dfc2076320 fix(ci): remove pnpm version conflict in action-setup
pnpm/action-setup@v4 now errors when both the action's `version` input
and package.json's `packageManager` field specify a version. Remove the
action input — package.json's `pnpm@9.15.4` is authoritative.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 18:38:30 +00:00
groombook-paperclip[bot] a9adc4e430 fix(ci): use GitHub-hosted runners until self-hosted are deployed
All CI runs are stuck in queued — zero self-hosted runners are registered
for the groombook-runners label. Switch to ubuntu-latest to unblock PRs.

Tracked in groombook/infra#2 — will revert once self-hosted runners are
deployed to the cluster.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 18:37:21 +00:00
Groom Book CTO a36436d128 Bootstrap monorepo: Hono API, React PWA, Drizzle DB, CI/CD
Sets up the initial project structure for groombook/groombook:

- pnpm monorepo with apps/api (Hono + TypeScript), apps/web (React + Vite + PWA), packages/db (Drizzle ORM), packages/types (shared types)
- Core DB schema: clients, pets, services, appointments, staff with CNPG-compatible Postgres
- REST API routes for clients, pets, services, appointments with Zod validation
- OIDC auth middleware for Authentik integration
- React PWA with vite-plugin-pwa, service worker, offline caching, installable manifest
- GitHub Actions CI: lint, typecheck, test, build, Docker image build (groombook-runners)
- Dockerfiles for API (Node.js) and Web (nginx)
- docker-compose.yml for local development

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-17 16:11:04 +00:00