Fountain Coach Gitowner-controlled · read only

CILocal.git · IMPLEMENTATION_PLAN.md

CILocal.git / IMPLEMENTATION_PLAN.md

revision 228dc302b918ad4eddb3a36dd387b1f382e5de47 · complete file

# CI Control Plane – Implementation Plan

Goal: Bring this repo to a production‑ready, spec‑driven, test‑covered, and secure state that matches AGENTS.md. This plan fixes current build failures, removes ambiguity, and establishes sustainable practices.

## Scope and Principles

- Spec‑first for any HTTP surfaces; generated clients for external HTTP APIs where practical.
- Tests accompany behavior; keep dependencies minimal and avoid new runtime deps unless justified.
- Secrets never in VCS; store via Swift‑SecretStore and audit actions in FountainStore.
- Idempotent, pinned ops in scripts to ensure reproducibility.

## Phase 1 — Build Green and Hygiene

Tasks
- Fix SecretStore typing errors: replace `SecretStore.SecretStore` with `any SecretStore` and centralize store creation.
- Remove unused `import NIO` from `Sources/CIControlPlane/main.swift`.
- Update AsyncHTTPClient creation to `.singleton` and keep proper shutdown handling.
- Improve error messages when `docker`, `gitea`, `gh` or `java`/`jenkins-cli.jar` are missing.
- Add `.gitignore` entries for Swift/SwiftPM artifacts, editors, and `.DS_Store`.
- Add `LICENSE` (MIT) to align with README claim.

Acceptance Criteria
- `swift build` succeeds on macOS and Linux.
- Running `swift run cicontrol status` handles missing tools gracefully (clear errors, no crashes).
- Repository has `.gitignore` and `LICENSE` present.

## Phase 2 — Tests Baseline

Tasks
- Create `Tests/CIControlPlaneTests` with:
  - Argument parsing tests for `setup`, `status`, `mirror` (incl. defaults and required options).
  - Secret resolution tests (environment fallback when SecretStore empty). Do not persist real secrets; use a stubbed in‑memory store or conditional compilation.
  - `runShell` error behavior: missing binary returns a descriptive error.
  - Status command: verify it degrades gracefully without external services (mock HTTP to localhost or skip network).

Acceptance Criteria
- `swift test` passes locally; code paths are covered for CLI parsing, secret loading, and basic error handling.

## Phase 3 — Documentation Cleanup

Tasks
- Replace bracket line‑number “citations” with standard links and concise references in `README.md` and `docs/OVERVIEW.md`.
- Document explicit org scoping for GitHub in `status` and `mirror` usage.
- Add `docs/SECURITY.md` summarizing secret handling, token scopes, and audit logging.

Acceptance Criteria
- Docs render well without odd glyphs/citations; users can follow setup without ambiguity.

## Phase 4 — Script Hardening and Reproducibility

Tasks
- Make `scripts/setup_local_ci.sh` idempotent:
  - If containers exist, restart or recreate rather than failing; add `docker inspect` checks.
  - Add health/readiness checks (e.g., polling container health or HTTP endpoints).
- Pin images to version tags (and optionally digests) instead of `latest`/floating tags.
- Optionally provide a `docker compose` file for readability and idempotency (no new runtime deps; compose is part of Docker Desktop). Keep the shell script as a thin wrapper.

Acceptance Criteria
- Re‑running the script does not fail; services remain on expected ports with persistent volumes.
- Images are pinned to specific tags (and/or digests documented in comments).

## Phase 5 — Mirror Feature Completion

Tasks
- Replace static repository list with data from FountainStore:
  - Read repositories from FountainStore (embedded or via its HTTP API if running) using existing APIs.
- Require explicit `--org` and support `--include/--exclude` globs and `--dry-run`.
- Replace speculative Gitea CLI mirror command with REST calls:
  - Use Gitea’s push mirror API (create/update push mirror for each repo) with the admin token.
  - Handle idempotency (detect existing mirrors and update where needed).
- Log actions (repo, mirror URL, result) into FountainStore audit log collection.

Acceptance Criteria
- `cicontrol mirror --org Fountain-Coach` reads from FountainStore and configures push mirrors consistently.
- Repeated runs are idempotent; audit entries are created.

## Phase 6 — Setup, Secrets, and Audit Logs

Tasks
- `setup` command:
  - Ensure admin token generation is robust; never print tokens to stdout. If a password is generated, print once with an explicit warning.
  - Store the Gitea token via SecretStore; fall back to `GITEA_ADMIN_TOKEN` env only if not present.
  - Persist audit logs (events and minimal metadata) to FountainStore: user, time, action, subject, and redacted details.
- Add optional non‑interactive mode for `setup` to support automation (exit non‑zero on missing inputs).

Acceptance Criteria
- Tokens and secrets are never printed or logged in plaintext; audit records exist for setup operations.

## Phase 7 — Status Improvements and Observability

Tasks
- Add explicit `--org` for GitHub repo listing, and handle unauthenticated users gracefully.
- Summarize Docker containers (name, status, image) and flag unhealthy ones.
- Attempt FountainStore `/metrics` fetch only when a flag like `--metrics-url` is provided, defaulting to disabled.

Acceptance Criteria
- Status output is clear, concise, and useful even when some services are unavailable.

## Phase 8 — Spec‑Driven Integrations

Tasks
- For external HTTPs (Gitea/Jenkins), prefer generated clients over shell calls where practical:
  - Add OpenAPI specs references and generate Swift clients with Apple’s Swift OpenAPI Generator.
  - Vendor generated sources into `Sources/Generated/` to avoid runtime dependencies.
- If adding any HTTP endpoint to CIControlPlane itself, create `openapi/control-plane.yaml` and treat it as source of truth before implementation.

Acceptance Criteria
- Mirror functionality uses the Gitea HTTP API via generated or minimal native client code.
- No external spec changes are required to build/run this repo; generated code lives in tree.

## Phase 9 — Dependency and Image Security

Tasks
- Review Swift package dependencies for updates (`swift package update`) and changelogs.
- Provide optional scripts for vulnerability scanning of images (e.g., `trivy` or `docker scout`) without adding runtime deps.
- Ensure Docker images are sourced from trusted publishers; document trust and signature checks where possible.

Acceptance Criteria
- Documented, repeatable process to check for CVEs in dependencies and images; no new mandatory runtime deps added.

## Phase 10 — Code Organization and Maintenance

Tasks
- Split `Sources/CIControlPlane/main.swift` into small files as the surface grows:
  - `ProcessRunner.swift`, `Secrets.swift`, `SetupCommand.swift`, `StatusCommand.swift`, `MirrorCommand.swift`.
- Add lightweight internal logging utility (stderr vs stdout; verbosity levels) without adding new packages.

Acceptance Criteria
- Codebase is easier to navigate; commands have focused files; logging is consistent and testable.

## Deliverables Checklist

- [x] Build green on supported platforms (`swift build`).
- [x] Baseline tests in `Tests/CIControlPlaneTests` (`swift test`).
- [x] `.gitignore` updated; `LICENSE` added.
- [x] Docs updated; no bracket citations; `docs/SECURITY.md` present.
- [x] Idempotent CI bootstrap with pinned images.
- [x] Mirror uses FountainStore repo list and Gitea REST; idempotent.
- [x] Secrets stored via SecretStore; no plaintext tokens; audit logs persisted.
- [x] Status outputs are clear; flags for org/metrics; graceful degradation.
- [x] Generated clients (where used) vendored; OpenAPI specs tracked.
- [x] Security review checklist and optional scans documented.

## Work Plan and Branching

- Use feature branches per Phase (e.g., `feat/build-green`, `feat/tests-baseline`, …).
- Keep commits small and focused; include rationale in messages.
- Open PRs against `main` only after `swift test` passes and changes are reviewed.

## Notes and Non‑Goals (for now)

- No new runtime package dependencies unless strictly necessary. Developer tools (e.g., OpenAPI generator) are acceptable if outputs are vendored.
- Jenkins integration remains CLI‑based initially; HTTP client integration can follow once Gitea mirror via REST is complete.

## References

- FountainStore and Swift‑SecretStore repos for design and security practices.
- Gitea API documentation for repository push mirrors.
- Apple’s Swift OpenAPI Generator for client generation.