From c543d3df1a954a09648d62a18cda6d1bab26ae50 Mon Sep 17 00:00:00 2001 From: WorkClub Automation Date: Fri, 6 Mar 2026 22:02:24 +0100 Subject: [PATCH] docs(plan): append gitea ci/cd pipeline requirements --- .sisyphus/drafts/club-work-manager.md | 12 ++- .sisyphus/plans/club-work-manager.md | 117 ++++++++++++++++++++++++-- 2 files changed, 121 insertions(+), 8 deletions(-) diff --git a/.sisyphus/drafts/club-work-manager.md b/.sisyphus/drafts/club-work-manager.md index 94304ad..721fe81 100644 --- a/.sisyphus/drafts/club-work-manager.md +++ b/.sisyphus/drafts/club-work-manager.md @@ -11,6 +11,7 @@ - **Frontend**: Next.js with Bun - **Deployment (prod)**: Kubernetes cluster - **Deployment (local)**: Docker Compose +- **New request**: Append CI/CD pipeline planning for the Gitea-hosted repository (`https://code.hal9000.damnserver.com/MasterMito/work-club-manager`) ## Technical Decisions - **Multi-tenancy strategy**: RLS + EF Core global query filters (defense-in-depth) @@ -51,9 +52,16 @@ ## Decisions (Round 4) - **Git repository**: Initialize git repo as first step in Task 1 — `git init` + comprehensive `.gitignore` (dotnet + node + IDE) + initial commit +## Decisions (Round 5) +- **CI/CD requested**: User wants plan extension for pipeline on Gitea server +- **Repository host**: Self-hosted Gitea instance (`code.hal9000.damnserver.com`) +- **Pipeline scope**: CI-only (no deployment automation in this extension) +- **Release policy input**: User prefers release-tag based trigger if CD is added later +- **Registry input**: Gitea Container Registry preferred + ## Open Questions -- (none remaining — all critical decisions made, ready for plan generation) +- (none blocking — CI scope confirmed; CD trigger/registry captured for future extension) ## Scope Boundaries -- INCLUDE: Full backend API, frontend app, Docker Compose, Kubernetes manifests (Kustomize), database schema + EF Core migrations, Keycloak integration, work item CRUD, time-slot shift management with sign-up, club-switcher, role-based access control (4 roles), PostgreSQL RLS +- INCLUDE: Full backend API, frontend app, Docker Compose, Kubernetes manifests (Kustomize), database schema + EF Core migrations, Keycloak integration, work item CRUD, time-slot shift management with sign-up, club-switcher, role-based access control (4 roles), PostgreSQL RLS, Gitea CI workflow (build/test/lint/manifest validation) - EXCLUDE: Billing/subscriptions, email/push notifications, mobile app, recurring shift patterns (future), custom roles, reporting/analytics dashboard diff --git a/.sisyphus/plans/club-work-manager.md b/.sisyphus/plans/club-work-manager.md index 80dd7b8..675e64b 100644 --- a/.sisyphus/plans/club-work-manager.md +++ b/.sisyphus/plans/club-work-manager.md @@ -11,6 +11,7 @@ > - PostgreSQL schema with RLS policies and EF Core migrations > - Docker Compose for local development (hot reload, Keycloak, PostgreSQL) > - Kubernetes manifests (Kustomize base + dev overlay) +> - Gitea CI pipeline (`.gitea/workflows/ci.yml`) for backend/frontend/infrastructure validation > - Comprehensive TDD test suite (xUnit + Testcontainers, Vitest + RTL, Playwright E2E) > - Seed data for development (2 clubs, 5 users, sample tasks + shifts) > @@ -34,6 +35,8 @@ Build a multi-tenant internet application for managing work items over several m - **Scale**: MVP — 1-5 clubs, <100 users. - **Testing**: TDD approach (tests first). - **Notifications**: None for MVP. +- **CI extension**: Add Gitea-hosted CI pipeline for this repository. +- **Pipeline scope**: CI-only (build/test/lint/manifest validation), no auto-deploy in this iteration. **Research Findings**: - **Finbuckle.MultiTenant**: ClaimStrategy + HeaderStrategy fallback is production-proven (fullstackhero/dotnet-starter-kit pattern). @@ -69,6 +72,7 @@ Deliver a working multi-tenant club work management application where authentica - `/frontend/` — Next.js 15 App Router project with Tailwind + shadcn/ui - `/docker-compose.yml` — Local dev stack (PostgreSQL, Keycloak, .NET API, Next.js) - `/infra/k8s/` — Kustomize manifests (base + dev overlay) +- `/.gitea/workflows/ci.yml` — Gitea Actions CI pipeline (parallel backend/frontend/infra checks) - PostgreSQL database with RLS policies on all tenant-scoped tables - Keycloak realm configuration with test users and club memberships - Seed data for development @@ -84,6 +88,7 @@ Deliver a working multi-tenant club work management application where authentica - [x] `dotnet test` passes all unit + integration tests - [x] `bun run test` passes all frontend tests - [x] `kustomize build infra/k8s/overlays/dev` produces valid YAML +- [ ] Gitea Actions CI passes on push/PR with backend + frontend + infra jobs ### Must Have - Credential-based multi-tenancy (JWT claims + X-Tenant-Id header) @@ -99,6 +104,8 @@ Deliver a working multi-tenant club work management application where authentica - Docker Compose with hot reload for .NET and Next.js - Kubernetes Kustomize manifests (base + dev overlay) - TDD: all backend features have tests BEFORE implementation +- Gitea-hosted CI pipeline for this repository (`code.hal9000.damnserver.com/MasterMito/work-club-manager`) +- CI jobs run in parallel (backend, frontend, infrastructure validation) ### Must NOT Have (Guardrails) - **No CQRS/MediatR** — Direct service injection from controllers/endpoints @@ -117,6 +124,7 @@ Deliver a working multi-tenant club work management application where authentica - **No in-memory database for tests** — Real PostgreSQL via Testcontainers - **No billing, subscriptions, or analytics dashboard** - **No mobile app** +- **No automatic deployment in this CI extension** — CD remains out-of-scope for this append --- @@ -188,7 +196,8 @@ Wave 5 (After Wave 4 — polish + Docker): Wave 6 (After Wave 5 — E2E + integration): ├── Task 26: Playwright E2E tests — auth flow + club switching (depends: 21, 22) [unspecified-high] ├── Task 27: Playwright E2E tests — task management flow (depends: 19, 22) [unspecified-high] -└── Task 28: Playwright E2E tests — shift sign-up flow (depends: 20, 22) [unspecified-high] +├── Task 28: Playwright E2E tests — shift sign-up flow (depends: 20, 22) [unspecified-high] +└── Task 29: Gitea CI workflow (backend + frontend + infra checks) (depends: 12, 17, 23, 24, 25) [unspecified-high] Wave FINAL (After ALL tasks — independent review, 4 parallel): ├── Task F1: Plan compliance audit (oracle) @@ -196,8 +205,8 @@ Wave FINAL (After ALL tasks — independent review, 4 parallel): ├── Task F3: Real manual QA (unspecified-high) └── Task F4: Scope fidelity check (deep) -Critical Path: Task 1 → Task 7 → Task 8 → Task 13 → Task 14 → Task 18 → Task 22 → Task 26 → F1-F4 -Parallel Speedup: ~65% faster than sequential +Critical Path: Task 1 → Task 5 → Task 17 → Task 18 → Task 24 → Task 25 → Task 29 → F1-F4 +Parallel Speedup: ~68% faster than sequential Max Concurrent: 6 (Wave 1) ``` @@ -233,6 +242,7 @@ Max Concurrent: 6 (Wave 1) | 26 | 21, 22 | — | 6 | | 27 | 19, 22 | — | 6 | | 28 | 20, 22 | — | 6 | +| 29 | 12, 17, 23, 24, 25 | F1-F4 | 6 | | F1-F4 | ALL | — | FINAL | ### Agent Dispatch Summary @@ -242,7 +252,7 @@ Max Concurrent: 6 (Wave 1) - **Wave 3 (5 tasks)**: T13 → `deep`, T14 → `deep`, T15 → `deep`, T16 → `unspecified-high`, T17 → `quick` - **Wave 4 (4 tasks)**: T18 → `visual-engineering`, T19 → `visual-engineering`, T20 → `visual-engineering`, T21 → `visual-engineering` - **Wave 5 (4 tasks)**: T22 → `unspecified-high`, T23 → `quick`, T24 → `quick`, T25 → `unspecified-high` -- **Wave 6 (3 tasks)**: T26 → `unspecified-high`, T27 → `unspecified-high`, T28 → `unspecified-high` +- **Wave 6 (4 tasks)**: T26 → `unspecified-high`, T27 → `unspecified-high`, T28 → `unspecified-high`, T29 → `unspecified-high` - **FINAL (4 tasks)**: F1 → `oracle`, F2 → `unspecified-high`, F3 → `unspecified-high`, F4 → `deep` --- @@ -2515,6 +2525,96 @@ Max Concurrent: 6 (Wave 1) - Files: `frontend/tests/e2e/shifts.spec.ts` - Pre-commit: `bunx playwright test tests/e2e/shifts.spec.ts` +- [ ] 29. Gitea CI Pipeline — Backend + Frontend + Infra Validation + + **What to do**: + - Create `.gitea/workflows/ci.yml` for repository `code.hal9000.damnserver.com/MasterMito/work-club-manager` + - Configure triggers: + - `push` on `main` and feature branches + - `pull_request` targeting `main` + - `workflow_dispatch` for manual reruns + - Structure pipeline into parallel jobs (fail-fast disabled so all diagnostics are visible): + - `backend-ci`: setup .NET 10 SDK, restore, build, run backend unit/integration tests + - `frontend-ci`: setup Bun, install deps, run lint, type-check, unit tests, production build + - `infra-ci`: validate Docker Compose and Kustomize manifests + - Add path filters so docs-only changes skip heavy jobs when possible + - Add dependency caching: + - NuGet cache keyed by `**/*.csproj` + lock/context + - Bun cache keyed by `bun.lockb` + - Add artifact upload on failure: + - `backend-test-results` (trx/log output) + - `frontend-test-results` (vitest output) + - `infra-validation-output` + - Enforce branch protection expectation in plan notes: + - Required checks: `backend-ci`, `frontend-ci`, `infra-ci` + - Keep CD out-of-scope in this append (no image push, no deploy steps) + + **Must NOT do**: + - Do NOT add deployment jobs (Kubernetes apply/helm/kustomize deploy) + - Do NOT add secrets for registry push in this CI-only iteration + - Do NOT couple CI workflow to release-tag deployment behavior + + **Recommended Agent Profile**: + - **Category**: `unspecified-high` + - Reason: CI pipeline design spans backend/frontend/infra validation and requires careful runner orchestration + - **Skills**: [] + + **Parallelization**: + - **Can Run In Parallel**: YES + - **Parallel Group**: Wave 6 (with Tasks 26, 27, 28) + - **Blocks**: Final Verification Wave (F1-F4) + - **Blocked By**: Tasks 12, 17, 23, 24, 25 + + **References**: + + **Pattern References**: + - `docker-compose.yml` — Source of truth for `docker compose config` validation + - `infra/k8s/base/kustomization.yaml` and `infra/k8s/overlays/dev/kustomization.yaml` — Kustomize build inputs used by infra-ci job + - `backend/WorkClub.sln` — Backend restore/build/test entrypoint for .NET job + - `frontend/package.json` + `frontend/bun.lockb` — Frontend scripts and cache key anchor + + **External References**: + - Gitea Actions docs: workflow syntax and trigger model (`.gitea/workflows/*.yml`) + - `actions/setup-dotnet` usage for .NET 10 SDK installation + - `oven-sh/setup-bun` usage for Bun runtime setup + - Upload artifact action compatible with Gitea Actions runner implementation + + **Acceptance Criteria**: + + **QA Scenarios (MANDATORY):** + + ``` + Scenario: CI workflow validates backend/frontend/infra in parallel + Tool: Bash (Gitea API) + Preconditions: `.gitea/workflows/ci.yml` pushed to repository, `GITEA_TOKEN` available + Steps: + 1. Trigger workflow via API or push a CI-test branch commit + 2. Query latest workflow run status for `ci.yml` + 3. Assert jobs `backend-ci`, `frontend-ci`, and `infra-ci` all executed + 4. Assert final workflow conclusion is `success` + Expected Result: All three CI jobs pass in one run + Failure Indicators: Missing job, skipped required job, or non-success conclusion + Evidence: .sisyphus/evidence/task-29-gitea-ci-success.json + + Scenario: Pipeline fails on intentional backend break + Tool: Bash (git + Gitea API) + Preconditions: Temporary branch available, ability to push test commit + Steps: + 1. Create a temporary branch with an intentional backend compile break + 2. Push branch and wait for CI run + 3. Assert `backend-ci` fails + 4. Assert workflow conclusion is `failure` + 5. Revert test commit / delete branch + Expected Result: CI correctly rejects broken code and reports failure + Failure Indicators: Broken backend still reports success + Evidence: .sisyphus/evidence/task-29-gitea-ci-failure.json + ``` + + **Commit**: YES + - Message: `ci(gitea): add parallel CI workflow for backend, frontend, and infra validation` + - Files: `.gitea/workflows/ci.yml` + - Pre-commit: `docker compose config && kustomize build infra/k8s/overlays/dev > /dev/null` + --- ## Final Verification Wave @@ -2522,11 +2622,11 @@ Max Concurrent: 6 (Wave 1) > 4 review agents run in PARALLEL. ALL must APPROVE. Rejection → fix → re-run. - [x] F1. **Plan Compliance Audit** — `oracle` - Read the plan end-to-end. For each "Must Have": verify implementation exists (read file, curl endpoint, run command). For each "Must NOT Have": search codebase for forbidden patterns (`MediatR`, `IRepository`, `Swashbuckle`, `IsMultiTenant()`, `SET app.current_tenant` without `LOCAL`) — reject with file:line if found. Check evidence files exist in `.sisyphus/evidence/`. Compare deliverables against plan. + Read the plan end-to-end. For each "Must Have": verify implementation exists (read file, curl endpoint, run command). For each "Must NOT Have": search codebase for forbidden patterns (`MediatR`, `IRepository`, `Swashbuckle`, `IsMultiTenant()`, `SET app.current_tenant` without `LOCAL`) — reject with file:line if found. Validate CI appendix by checking `.gitea/workflows/ci.yml` exists and includes `backend-ci`, `frontend-ci`, `infra-ci` jobs with push + pull_request triggers. Check evidence files exist in `.sisyphus/evidence/`. Compare deliverables against plan. Output: `Must Have [N/N] | Must NOT Have [N/N] | Tasks [N/N] | VERDICT: APPROVE/REJECT` - [x] F2. **Code Quality Review** — `unspecified-high` - Run `dotnet build` + `dotnet format --verify-no-changes` + `dotnet test` + `bun run build` + `bun run lint`. Review all changed files for: `as any`/`@ts-ignore`, empty catches, `console.log` in prod, commented-out code, unused imports, `// TODO` without ticket. Check AI slop: excessive comments, over-abstraction, generic names (data/result/item/temp), unnecessary null checks on non-nullable types. + Run `dotnet build` + `dotnet format --verify-no-changes` + `dotnet test` + `bun run build` + `bun run lint`. Validate CI config integrity by running YAML lint/syntax check on `.gitea/workflows/ci.yml` and verifying all referenced commands exist in repo scripts/paths. Review all changed files for: `as any`/`@ts-ignore`, empty catches, `console.log` in prod, commented-out code, unused imports, `// TODO` without ticket. Check AI slop: excessive comments, over-abstraction, generic names (data/result/item/temp), unnecessary null checks on non-nullable types. Output: `Build [PASS/FAIL] | Format [PASS/FAIL] | Tests [N pass/N fail] | Lint [PASS/FAIL] | Files [N clean/N issues] | VERDICT` - [x] F3. **Real Manual QA** — `unspecified-high` (+ `playwright` skill) @@ -2562,6 +2662,7 @@ Max Concurrent: 6 (Wave 1) | 4 | T18-T21 | `feat(ui): add layout, club-switcher, login, task and shift pages` | frontend/src/app/**/*.tsx, frontend/src/components/**/*.tsx | `bun run build && bun run test` | | 5 | T22-T25 | `infra(deploy): add full Docker Compose stack, Dockerfiles, and Kustomize dev overlay` | docker-compose.yml, **/Dockerfile*, infra/k8s/overlays/dev/**/*.yaml | `docker compose config && kustomize build infra/k8s/overlays/dev` | | 6 | T26-T28 | `test(e2e): add Playwright E2E tests for auth, tasks, and shifts` | frontend/tests/e2e/**/*.spec.ts | `bunx playwright test` | +| 6 | T29 | `ci(gitea): add parallel CI workflow for backend, frontend, and infra validation` | .gitea/workflows/ci.yml | `docker compose config && kustomize build infra/k8s/overlays/dev > /dev/null` | --- @@ -2595,6 +2696,9 @@ bun run test # Expected: All pass # K8s manifests valid kustomize build infra/k8s/overlays/dev > /dev/null # Expected: Exit 0 + +# CI workflow file present and includes required jobs +grep -E "backend-ci|frontend-ci|infra-ci" .gitea/workflows/ci.yml # Expected: all 3 job names present ``` ### Final Checklist @@ -2605,6 +2709,7 @@ kustomize build infra/k8s/overlays/dev > /dev/null # Expected: Exit 0 - [x] All E2E tests pass (`bunx playwright test`) - [x] Docker Compose stack starts clean and healthy - [x] Kustomize manifests build without errors +- [ ] Gitea CI workflow exists and references backend-ci/frontend-ci/infra-ci - [x] RLS isolation proven at database level - [x] Cross-tenant access returns 403 - [x] Task state machine rejects invalid transitions (422)