CI/CD Pipeline
Automated pipeline using GitHub Actions + ArgoCD for the LuckyPlans monorepo.
Pipeline Overview
PR / Push to main Merge to main After Docker push
┌──────────────┐ ┌───────────────────┐ ┌───────────────────┐
│ CI │──ok──│ Docker Build │──ok──│ Update Tags │
│ │ │ & Push │ │ │
│ lint │ │ build 3 images │ │ commit new tags │
│ type-check │ │ push to ghcr.io │ │ to values files │
│ test │ │ tag: sha + latest │ │ [skip ci] │
│ build │ │ Trivy image scan │ │ │
│ Trivy scans │ │ │ │ │
│ Helm lint │ │ │ │ │
└──────────────┘ └───────────────────┘ └───────────────────┘
│
▼
ArgoCD detects change
└── Prod: auto-sync
Workflows
1. CI (.github/workflows/ci.yml)
Triggers: Push to main (excluding values file changes), pull requests to main.
Runs lint, type-check, test, and build using Turborepo. On PRs, only affected
packages are checked via --filter=...[origin/main].
Concurrency groups cancel superseded PR runs automatically.
Security scanning is integrated into CI via Trivy :
- Dependency scan (
fsmode): Scanspnpm-lock.yamland other dependency manifests for known CRITICAL/HIGH vulnerabilities. Fails the build if found. - IaC/Dockerfile config scan (
configmode): Checks Dockerfiles, Helm templates, and Kubernetes manifests for misconfigurations. Fails on CRITICAL/HIGH. - SARIF upload: A vulnerability report is uploaded to GitHub Security tab for persistent tracking.
Additionally validates Helm chart templates by piping helm template output
through kubeconform for all environment variants.
2. Docker Build & Push (.github/workflows/docker-build.yml)
Triggers: After CI passes on main, or manual dispatch.
Builds Docker images for all three services in parallel via a matrix strategy:
| Service | Dockerfile | Image |
|---|---|---|
| web | apps/web/Dockerfile | ghcr.io/<owner>/web |
| api-gateway | apps/api-gateway/Dockerfile | ghcr.io/<owner>/api-gateway |
| service-core | apps/service-core/Dockerfile | ghcr.io/<owner>/service-core |
Images are tagged with:
sha-<7-char-commit-sha>— immutable, used for deploymentslatest— convenience pointer to the most recent build
Images are pushed with SBOM and provenance attestations enabled, providing supply chain transparency.
3. Update Image Tags (.github/workflows/update-tags.yml)
Triggers: After Docker build completes on main, or manual dispatch with a specific image tag.
The workflow:
- Computes the image tag (
sha-<7char>from the triggering commit) - Uses
yqto update all 3 service image tags invalues.prod.yaml - Commits with
[skip ci]to prevent re-triggering CI - Pushes to
main
ArgoCD then detects the change and auto-syncs the new image tags.
4. ArgoCD Sync & Post-Sync Hooks
After ArgoCD syncs the Helm chart, post-sync hooks run as Kubernetes Jobs:
- Smoke tests verify API Gateway health, web frontend, and GraphQL endpoint
- Job results are visible in the ArgoCD UI (sync status: Healthy or Degraded)
- Failed smoke tests mark the sync as Degraded but do not auto-rollback
See ArgoCD for full operational documentation.
5. AI PR Review (.github/workflows/pr-review.yml)
Triggers: Manual only (workflow_dispatch) — run from the Actions tab by entering a PR number.
Runs an AI-powered code review using Claude against the project’s architecture,
security, and convention rules (.claude/rules/). Posts inline review comments
on changed files.
This workflow is opt-in to control API costs. To review a PR:
- Go to Actions → “AI PR Review” → Run workflow
- Enter the PR number and click “Run workflow”
This workflow is informational only — it posts comments, does not block merging.
Cost controls:
- Opt-in only — never runs automatically
- Skips PRs with more than 2000 changed lines
- Excludes generated files (
src/generated/, lock files) - Uses Claude Sonnet (not Opus) for cost efficiency
- 10-minute timeout per review
Required GitHub Configuration
Secrets
| Secret | Scope | Description |
|---|---|---|
GITHUB_TOKEN | Automatic | Provided by GitHub Actions. Used for ghcr.io auth. |
CD_PUSH_TOKEN | Repository | Required with branch protection. Fine-grained PAT with Contents: read+write scope. Used by update-tags.yml to push tag commits to main. |
ANTHROPIC_API_KEY | Repository | API key for Claude AI PR review. Configure spending limits in the Anthropic console. |
Branch Protection (recommended)
Configure on the main branch:
- Require a pull request before merging
- Require at least 1 approval
- Require status checks to pass (select the
cijob)
Important: With branch protection enabled,
GITHUB_TOKENcannot push tag update commits tomain. You must create aCD_PUSH_TOKENsecret.
Turborepo Caching
The CI workflow caches Turborepo artifacts in .turbo/ using actions/cache.
On PRs, the --filter=...[origin/main] flag limits execution to packages
affected by the changes, significantly reducing CI time.
Troubleshooting
CI fails on lint/type-check
pnpm turbo run lint --filter=<package-name>
pnpm turbo run type-check --filter=<package-name>
Docker build fails
docker build -f apps/<service>/Dockerfile .
ArgoCD sync fails or shows Degraded
kubectl -n luckyplans get pods
kubectl -n luckyplans describe pod <pod-name>
kubectl -n argocd get application luckyplans-prod -o yaml