Skip to main content

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

VariableDescription
NODE_VERSIONNode.js version
REGISTRY_URLContainer registry URL

cortex-dev-secrets

VariableDescription
DATABASE_URLDev database connection
JWT_SECRETDev 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