Files
saqib mirandClaude Sonnet 5 2dffe58496 feat: implement CI pipeline (Jenkinsfile) for 001-ci-pipeline
Implements tasks T001-T016, T018-T022, T024-T026 from
specs/001-ci-pipeline/tasks.md (T017/T023 need a real Jenkins
instance to verify and are left for manual follow-up).

- Add Jenkinsfile: checkout -> install -> environment validation
  -> typecheck -> lint (+ architecture check) -> format check ->
  unit -> integration -> E2E -> build -> Docker build -> publish
  -> deploy, matching the constitution's required stage order.
  Secrets are always injected from Jenkins credentials at runtime,
  never read from a repo-committed file. Publish/Deploy are skipped
  (not failed) on branches with no resolved deploy target.
- Fix docker-compose.test.yml: remove fixed container_name on
  app/postgres/redis, which would have made concurrent CI runs
  collide (FR-009). Verified locally that two runs under different
  -p project names no longer share container/volume/network names.
- Document the pipeline and local .env setup in README.md.
- Mark completed tasks in specs/001-ci-pipeline/tasks.md and record
  the container_name/compose-down-env-file findings in the spec's
  requirements checklist notes.

Locally verified passing: Dockerfile build, typecheck, lint,
architecture check, format check, unit test suite, and the edited
docker-compose.test.yml bringing up postgres/redis with isolated
per-project container names.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 17:25:46 +05:30

11 KiB

description
description
Task list for 001-ci-pipeline

Tasks: Continuous Integration Pipeline

Input: Design documents from specs/001-ci-pipeline/

Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/pipeline-stage-contract.md, quickstart.md

Tests: Not requested in spec.md as automated test tasks — this feature's own "tests" are the 5 quickstart scenarios, run manually against a real Jenkins instance and included as verification tasks within each story below.

Organization: Tasks are grouped by user story (US1 = P1, US2 = P2) to enable independent implementation and testing of each story.

Format: [ID] [P?] [Story] Description

  • [P]: Can run in parallel (different files/independent stage blocks, no dependency on an incomplete task)
  • [Story]: Which user story this task belongs to (US1, US2)
  • All file paths are relative to supporthub-api/ (repo root)

Path Conventions

Single project — this feature adds one new root-level file, Jenkinsfile, plus edits to .gitignore/docs. No src/ changes (this feature adds no application code, per plan.md).


Phase 1: Setup

Purpose: Get a buildable pipeline skeleton and confirm the container build this pipeline will drive actually works today, before wiring stage logic into it.

  • T001 Create Jenkinsfile at repo root with declarative pipeline skeleton: agent, options { disableConcurrentMultipleBuilds... }, empty stages {} block, and a post block placeholder — in Jenkinsfile
  • T002 [P] Verify the existing multi-stage Dockerfile builds cleanly outside CI (docker build --build-arg BUILD_COMMAND="npm run build:prod" -t supporthub-api-ci .) so the pipeline's Docker build stage has a known-good target — no file changes, verification only

Checkpoint: A no-op pipeline exists and the Docker build it will call is confirmed working.


Phase 2: Foundational (Blocking Prerequisites)

Purpose: The stages every user story's stages sit on top of — checkout, dependency install, env validation, and Prisma client generation, all required regardless of which story's stages run next.

⚠️ CRITICAL: No user-story stage work can be added until this phase is complete.

  • T003 Add Checkout stage (SCM checkout) to Jenkinsfile
  • T004 Add Install stage (npm ci) to Jenkinsfile (depends on T003)
  • T005 Add Environment validation stage to Jenkinsfile: materialize .env.<target> from Jenkins credentials (per research.md's secrets decision — never read the repo's .env.*), then invoke the existing Zod schema in src/config/env.ts so a missing/malformed variable fails immediately with its existing descriptive error (FR-002) (depends on T004)
  • T006 [P] Add a Generate Prisma client step (npm run prisma:generate) to Jenkinsfile, required before Typecheck/Build can succeed (depends on T004)

Checkpoint: Checkout → install → env validation → Prisma generate all run and pass on a clean commit. User Story 1's stages can now be added.


Phase 3: User Story 1 - Every change is automatically validated before merge (Priority: P1) 🎯 MVP

Goal: A proposed change is automatically checked out, installed, environment-validated, and run through typecheck/lint/format/unit/integration/E2E/build/docker-build, stopping at the first failure and reporting which stage failed with its output.

Independent Test: Push a commit with a deliberate lint violation and confirm the pipeline fails at Lint and never reaches later stages (Quickstart Scenario 1); push a commit with a missing required env var and confirm Environment validation fails first (Quickstart Scenario 2).

Implementation for User Story 1

  • T007 [US1] Add Typecheck stage (npm run typecheck) to Jenkinsfile (depends on T006)
  • T008 [US1] Add Lint stage to Jenkinsfile, running both npm run lint and npx tsx scripts/check-architecture.ts (module-boundary check, matches .husky/pre-commit and enforces Constitution Principle III server-side) (depends on T007)
  • T009 [US1] Add Format check stage (npm run format:check) to Jenkinsfile (depends on T008)
  • T010 [US1] Add Unit test stage (npm run test:unit) to Jenkinsfile (depends on T009)
  • T011 [US1] Add a step before Integration test that brings up ephemeral postgres/redis via docker-compose.test.yml, with the Compose project name parameterized by ${BUILD_NUMBER} for run isolation (FR-009), in Jenkinsfile (depends on T010)
  • T012 [US1] Add Integration test stage (npm run test:integration) to Jenkinsfile (depends on T011)
  • T013 [US1] Add E2E test stage (npm run test:e2e) to Jenkinsfile (depends on T011)
  • T014 [US1] Add Build stage (npm run build:prod, or the target-specific build:* script matching the resolved Deploy Target) to Jenkinsfile (depends on T012, T013)
  • T015 [US1] Add Docker build stage using the root Dockerfile (T002's verified command) to Jenkinsfile (depends on T014)
  • T016 [US1] Add a post block to Jenkinsfile that surfaces which stage failed and its captured output on failure (FR-004, SC-002), and tears down the ephemeral docker-compose.test.yml stack (always) regardless of outcome
  • T017 [US1] Manually run Quickstart Scenarios 1, 2, and 5 from specs/001-ci-pipeline/quickstart.md against a real Jenkins job and confirm all three pass

Checkpoint: User Story 1 is fully functional — every proposed change is validated end-to-end through Docker build, and failures are diagnosable from the Jenkins UI alone. This is a deployable/demoable increment even before US2 exists (Publish/Deploy just wouldn't run yet).


Phase 4: User Story 2 - A validated build can be published and deployed without manual steps (Priority: P2)

Goal: A build that has passed every Phase 3 stage is published (image pushed to a registry) and deployed to its target environment automatically, using environment-specific credentials — with Publish/Deploy skipped (not failed) on changes that have no configured Deploy Target.

Independent Test: Merge a clean change into the branch mapped to the test Deploy Target and confirm the test environment is running the new image afterward with zero manual deploy commands (Quickstart Scenario 3); push to a branch with no Deploy Target and confirm Publish/Deploy are skipped, not attempted (Quickstart Scenario 4).

Implementation for User Story 2

  • T018 [US2] Add branch → Deploy Target resolution logic to Jenkinsfile (e.g. main → prod, a designated test branch → test; everything else → no Deploy Target) (depends on T015)
  • T019 [US2] Add Publish stage to Jenkinsfile: push the Docker build image to a container registry, guarded to run only when a Deploy Target was resolved (T018) (depends on T018)
  • T020 [US2] Add a step to Jenkinsfile that generates the target's .env.<target> from Jenkins credentials immediately before deploy (never from the repo copy, per research.md), scoped to the Deploy stage's workspace only (depends on T018)
  • T021 [US2] Add Deploy stage to Jenkinsfile: run docker compose --env-file <generated> -f docker-compose.<target>.yml up -d against the resolved Deploy Target, guarded the same way as Publish (depends on T019, T020)
  • T022 [US2] Confirm (via Jenkinsfile when conditions) that Publish/Deploy are marked skipped, not failed, on runs with no resolved Deploy Target (depends on T018)
  • T023 [US2] Manually run Quickstart Scenarios 3 and 4 from specs/001-ci-pipeline/quickstart.md against a real Jenkins job and confirm both pass, including verifying no step reads .env.test/.env.prod from the repository checkout

Checkpoint: Both user stories work independently and together — a validated change now reaches its target environment with no manual deploy step, and unvalidated/no-target changes stop cleanly after Docker build.


Phase 5: Polish & Cross-Cutting Concerns

Purpose: Documentation and final verification once both stories are implemented.

  • T024 [P] Add a short "CI/CD" section to README.md describing how the pipeline is triggered, where to view run status, and how to configure required Jenkins credentials (cross-reference specs/001-ci-pipeline/quickstart.md)
  • T025 [P] Review Jenkinsfile line-by-line to confirm no credential value or literal environment secret was hardcoded anywhere in the file (SC-004) — should only ever reference Jenkins credential IDs, never raw values
  • T026 Update specs/001-ci-pipeline/checklists/requirements.md Notes if implementation surfaced any spec gap not previously captured

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): No dependencies — start immediately
  • Foundational (Phase 2): Depends on Setup (T001) — BLOCKS both user stories
  • User Story 1 (Phase 3): Depends on Foundational completion — no dependency on US2
  • User Story 2 (Phase 4): Depends on User Story 1's Docker build stage existing (T015) — unlike a typical spec-kit feature, US2 is not independently implementable before US1 here, because "publish/deploy a validated build" has nothing to publish/deploy until US1's build stages exist. US2 remains independently testable (Quickstart Scenarios 3-4 are separate from 1-2-5) even though it isn't independently implementable first.
  • Polish (Phase 5): Depends on both user stories being complete

Parallel Opportunities

  • T002 (Dockerfile verification) can run in parallel with T001 (Jenkinsfile skeleton creation)
  • T006 (Prisma generate step) can run in parallel with T005 (env validation step) once T004 is done
  • T024 and T025 in Polish can run in parallel

Implementation Strategy

MVP First (User Story 1 Only)

  1. Complete Phase 1: Setup (T001-T002)
  2. Complete Phase 2: Foundational (T003-T006)
  3. Complete Phase 3: User Story 1 (T007-T017)
  4. STOP and VALIDATE: Run Quickstart Scenarios 1, 2, 5 against a real Jenkins job
  5. This alone satisfies SC-001, SC-002, and half of SC-005 — a real, demoable safety net — before any deploy automation exists

Incremental Delivery

  1. Setup + Foundational → pipeline skeleton runs and validates environment
  2. Add User Story 1 → validate/build automatically on every change (MVP)
  3. Add User Story 2 → validated builds deploy automatically, still skipping cleanly when there's no target
  4. Polish → documentation and a final secrets/hardcoding review