Skip to content

ADR-004: GitLab CI/CD Pipeline with Staged Deployments

Date: 2026-02-15 Status: Accepted Deciders: Jeff Mosley, Brian Moore

Context

Manual deployments are error-prone and time-consuming. We need:

  1. Automated Quality Gates: Catch bugs before deployment via linting, security scans, and tests
  2. Consistent Builds: Same build process every time, no "works on my machine"
  3. Safe Deployments: Staging validation before production, with manual approval for production
  4. Dependency Security: Automated alerts and updates for vulnerable dependencies

Decision

Implement GitLab CI/CD with staged deployments and comprehensive quality gates.

Pipeline Stages

┌─────────┐    ┌──────────┐    ┌────────┐    ┌─────────┐    ┌────────────────┐    ┌───────────────────┐
│  lint   │ →  │ security │ →  │  test  │ →  │  build  │ →  │ deploy-staging │ →  │ deploy-production │
└─────────┘    └──────────┘    └────────┘    └─────────┘    └────────────────┘    └───────────────────┘
   ↓               ↓              ↓             ↓                  ↓                      ↓
golangci-lint   gosec         go test      All 4 components    Single node          HA cluster
ESLint          govulncheck   mocha        in parallel         (api1, web1)         (manual approval)
                npm audit

Stage Details

Stage Tools Components Blocking?
lint golangci-lint, ESLint All Go + TypeScript No (warning only initially)
security gosec, govulncheck, npm audit All No (warning only)
test go test -race, mocha cortex-api, cortex-indexer-v2, cortex-vscode Yes
build go build, npm run package All 4 components Yes
deploy-staging SSH + scp api1, web1 Yes
deploy-production SSH + scp api½, web½, indexer½ Manual

Deployment Targets

Environment Hosts Trigger
Staging api1 (192.168.11.132), web1 (192.168.11.136) Auto on main push
Production api½, web½, indexer½ Manual approval

Additional Tooling

  • .golangci.yml: Linter configuration with security checks (gosec), formatting (gofmt, goimports), and static analysis
  • renovate.json: Automated dependency updates with auto-merge for minor/patch, manual review for major

Consequences

Positive

  1. Quality Assurance: Every push is linted, scanned, and tested
  2. Security: Vulnerability scanning catches issues before production
  3. Consistency: Same build process, reproducible artifacts
  4. Safe Rollouts: Staging validation prevents broken production deploys
  5. Self-Aware AI: Priority Context Decision makes Cortex aware of its own deployment process

Negative

  1. Pipeline Time: Full pipeline takes ~5-10 minutes
  2. GitLab Dependency: Requires GitLab CI/CD runners
  3. SSH Key Management: Deployment keys need secure storage

Neutral

  1. Gradual Strictness: Lint/security are warnings initially, made blocking later
  2. Runner Location: Uses GitLab shared runners (can add self-hosted later)

Implementation

Key Files

File Purpose
.gitlab-ci.yml Main pipeline configuration
.golangci.yml Go linter settings
renovate.json Dependency update automation

GitLab CI/CD Variables Required

Variable Description
SSH_PRIVATE_KEY Deployment SSH private key
SSH_KNOWN_HOSTS Known hosts for target servers

Build Artifacts

Component Artifact Size
cortex-api cortex-api-linux-amd64 ~15MB
cortex-web cortex-web-linux-amd64 ~12MB
cortex-indexer cortex-indexer-linux-amd64 ~12MB
cortex-vscode cortex-ai-X.X.X.vsix ~500KB

See Also