CI/CD Pipeline
CORTEX uses Azure DevOps Pipelines for continuous integration and deployment.
Pipeline Overview
┌─────────────────────────────────────────────────────────────┐
│ Git Push │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Build Stage │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Lint │ │ Test │ │ Build │ │ Scan │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Deploy to Dev │
│ • Auto-deploy on main branch │
│ • Run smoke tests │
└─────────────────────────┬───────────────────────────────────┘
│
▼ (manual approval)
┌─────────────────────────────────────────────────────────────┐
│ Deploy to Staging │
│ • Full E2E test suite │
│ • Performance tests │
└─────────────────────────┬───────────────────────────────────┘
│
▼ (manual approval)
┌─────────────────────────────────────────────────────────────┐
│ Deploy to Production │
│ • Blue-green deployment │
│ • Health check validation │
└─────────────────────────────────────────────────────────────┘
Pipeline Configuration
azure-pipelines.yml
trigger:
branches:
include:
- main
- develop
paths:
exclude:
- '*.md'
- 'docs/**'
pool:
vmImage: 'ubuntu-latest'
variables:
- group: cortex-common
- name: NODE_VERSION
value: '20.x'
stages:
- stage: Build
displayName: 'Build & Test'
jobs:
- job: BuildAndTest
steps:
- task: NodeTool@0
inputs:
versionSpec: $(NODE_VERSION)
displayName: 'Install Node.js'
- script: |
corepack enable
pnpm install --frozen-lockfile
displayName: 'Install dependencies'
- script: pnpm lint
displayName: 'Lint'
- script: pnpm test
displayName: 'Run tests'
- script: pnpm build
displayName: 'Build'
- task: Docker@2
displayName: 'Build Docker image'
inputs:
command: build
Dockerfile: 'apps/core/Dockerfile'
tags: |
$(Build.BuildId)
latest
- stage: DeployDev
displayName: 'Deploy to Dev'
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: DeployDev
environment: 'cortex-dev'
strategy:
runOnce:
deploy:
steps:
- task: AzureContainerApps@1
inputs:
appSourcePath: '$(System.DefaultWorkingDirectory)'
azureSubscription: 'cortex-dev-connection'
containerAppName: 'cortex-core-dev'
- stage: DeployStaging
displayName: 'Deploy to Staging'
dependsOn: DeployDev
jobs:
- deployment: DeployStaging
environment: 'cortex-staging'
strategy:
runOnce:
deploy:
steps:
- task: AzureContainerApps@1
inputs:
azureSubscription: 'cortex-staging-connection'
containerAppName: 'cortex-core-staging'
- stage: DeployProd
displayName: 'Deploy to Production'
dependsOn: DeployStaging
jobs:
- deployment: DeployProd
environment: 'cortex-prod'
strategy:
runOnce:
deploy:
steps:
- task: AzureContainerApps@1
inputs:
azureSubscription: 'cortex-prod-connection'
containerAppName: 'cortex-core-prod'
Build Steps Detail
1. Lint
- script: pnpm lint
displayName: 'Lint code'
Runs ESLint on all packages.
2. Test
- script: pnpm test
displayName: 'Run unit tests'
- task: PublishTestResults@2
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '**/junit.xml'
3. Build
- script: pnpm build
displayName: 'Build all packages'
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: 'apps/core/dist'
artifactName: 'core-build'
4. Docker Build
- task: Docker@2
displayName: 'Build and push image'
inputs:
containerRegistry: 'cortex-acr'
repository: 'cortex-core'
command: 'buildAndPush'
Dockerfile: 'apps/core/Dockerfile'
Environment Approvals
environments:
- name: cortex-staging
approvals:
- type: 'preDeployment'
approvers:
- 'team-leads'
- name: cortex-prod
approvals:
- type: 'preDeployment'
approvers:
- 'release-managers'
Variable Groups
cortex-common
| Variable | Description |
|---|---|
NODE_VERSION | Node.js version |
REGISTRY_URL | Container registry URL |
cortex-dev-secrets
| Variable | Description |
|---|---|
DATABASE_URL | Dev database connection |
JWT_SECRET | Dev JWT secret |
Branch Policies
main branch
- Require PR with at least 1 approval
- Build must succeed
- All comments resolved
- Squash merge only
develop branch
- Require PR
- Build must succeed
Rollback Procedure
# Revert to previous revision
az containerapp revision list \
--name cortex-core \
--resource-group cortex-prod
az containerapp ingress traffic set \
--name cortex-core \
--resource-group cortex-prod \
--revision-weight cortex-core--previous=100