AuthScape

Docs

Azure DevOps

Set up CI/CD pipelines for AuthScape using Azure DevOps.

Configure continuous integration and deployment (CI/CD) pipelines for AuthScape using Azure DevOps.

Pipeline Overview

A typical AuthScape deployment pipeline:

text
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Build │ -> │ Test │ -> │ Publish │ -> │ Deploy │
└─────────┘ └─────────┘ └─────────┘ └─────────┘

YAML Pipeline

Create azure-pipelines.yml in your repository:

Build Pipeline

yaml
trigger:
- main
- develop
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
dotnetVersion: '8.0.x'
stages:
- stage: Build
displayName: 'Build and Test'
jobs:
- job: BuildJob
displayName: 'Build API'
steps:
- task: UseDotNet@2
displayName: 'Install .NET SDK'
inputs:
packageType: 'sdk'
version: '$(dotnetVersion)'
- task: DotNetCoreCLI@2
displayName: 'Restore packages'
inputs:
command: 'restore'
projects: '**/*.csproj'
- task: DotNetCoreCLI@2
displayName: 'Build solution'
inputs:
command: 'build'
projects: '**/*.csproj'
arguments: '--configuration $(buildConfiguration)'
- task: DotNetCoreCLI@2
displayName: 'Run tests'
inputs:
command: 'test'
projects: '**/*Tests.csproj'
arguments: '--configuration $(buildConfiguration)'
- task: DotNetCoreCLI@2
displayName: 'Publish'
inputs:
command: 'publish'
publishWebProjects: true
arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'
zipAfterPublish: true
- task: PublishBuildArtifacts@1
displayName: 'Publish artifacts'
inputs:
pathToPublish: '$(Build.ArtifactStagingDirectory)'
artifactName: 'drop'

Deploy Pipeline

yaml
- stage: DeployStaging
displayName: 'Deploy to Staging'
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop'))
jobs:
- deployment: DeployStaging
displayName: 'Deploy to Staging'
environment: 'staging'
strategy:
runOnce:
deploy:
steps:
- task: AzureWebApp@1
displayName: 'Deploy to Azure Web App'
inputs:
azureSubscription: 'Your-Azure-Subscription'
appType: 'webAppLinux'
appName: 'authscape-staging'
package: '$(Pipeline.Workspace)/drop/*.zip'
- stage: DeployProduction
displayName: 'Deploy to Production'
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: DeployProduction
displayName: 'Deploy to Production'
environment: 'production'
strategy:
runOnce:
deploy:
steps:
- task: AzureWebApp@1
displayName: 'Deploy to Azure Web App'
inputs:
azureSubscription: 'Your-Azure-Subscription'
appType: 'webAppLinux'
appName: 'authscape-production'
package: '$(Pipeline.Workspace)/drop/*.zip'

Next.js Pipeline

For the Next.js frontend:

yaml
trigger:
paths:
include:
- AuthScape.NextJS/**
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Build
jobs:
- job: BuildNextJS
steps:
- task: NodeTool@0
inputs:
versionSpec: '20.x'
- script: |
cd AuthScape.NextJS
npm ci
npm run build
displayName: 'Build Next.js'
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: 'AuthScape.NextJS/.next'
includeRootFolder: false
archiveFile: '$(Build.ArtifactStagingDirectory)/nextjs.zip'
- publish: '$(Build.ArtifactStagingDirectory)/nextjs.zip'
artifact: 'nextjs'
- stage: Deploy
dependsOn: Build
jobs:
- deployment: DeployStaticWebApp
environment: 'production'
strategy:
runOnce:
deploy:
steps:
- task: AzureStaticWebApp@0
inputs:
app_location: 'AuthScape.NextJS'
output_location: '.next'
azure_static_web_apps_api_token: $(DEPLOYMENT_TOKEN)

Variable Groups

Store sensitive configuration in Variable Groups:

  1. Go to Pipelines > Library
  2. Create Variable Group named authscape-production
  3. Add variables:
NameValueSecret
DatabaseConnectionServer=...Yes
StripeSecretKeysk_live_...Yes
SendGridApiKeySG...Yes

Use in Pipeline

yaml
variables:
- group: authscape-production
steps:
- task: AzureWebApp@1
inputs:
appSettings: |
-AppSettings__DatabaseContext "$(DatabaseConnection)"
-AppSettings__Stripe__SecretKey "$(StripeSecretKey)"

Database Migrations

Run EF Core migrations as part of deployment:

yaml
- task: DotNetCoreCLI@2
displayName: 'Install EF Core tools'
inputs:
command: 'custom'
custom: 'tool'
arguments: 'install --global dotnet-ef'
- script: |
dotnet ef database update --project YourProject --connection "$(DatabaseConnection)"
displayName: 'Run migrations'

Slot Deployments

Use deployment slots for zero-downtime deployments:

yaml
- task: AzureWebApp@1
inputs:
azureSubscription: 'Your-Subscription'
appName: 'authscape-production'
deployToSlotOrASE: true
slotName: 'staging'
package: '$(Pipeline.Workspace)/drop/*.zip'
- task: AzureAppServiceManage@0
inputs:
azureSubscription: 'Your-Subscription'
action: 'Swap Slots'
webAppName: 'authscape-production'
sourceSlot: 'staging'
targetSlot: 'production'

Build Triggers

Branch Policies

Configure branch policies in Azure DevOps:

  1. Go to Repos > Branches
  2. Click ... on main > Branch policies
  3. Enable:
    • Require a minimum number of reviewers
    • Check for linked work items
    • Build validation (select your pipeline)

PR Triggers

yaml
pr:
branches:
include:
- main
- develop
paths:
exclude:
- docs/**
- README.md

Monitoring Pipeline

Build Status Badge

Add to your README:

markdown
[![Build Status](https://dev.azure.com/your-org/your-project/_apis/build/status/your-pipeline?branchName=main)](https://dev.azure.com/your-org/your-project/_build)

Notifications

Configure notifications in Project Settings > Notifications for:

  • Build failures
  • Deployment completions
  • Pull request updates

Best Practices

  1. Use Variable Groups for environment-specific configuration
  2. Enable approvals for production deployments
  3. Run tests before deployment
  4. Use deployment slots for zero-downtime updates
  5. Store secrets in Azure Key Vault
  6. Tag releases in source control after deployment