← Back to Documentation

CI/CD Integration

Automate deployment brief generation in your CI/CD pipelines with GitHub Actions and Azure Pipelines.

Overview

Integrate DeployBrief into your CI/CD pipelines to automatically generate deployment briefs after successful builds or deployments. This ensures documentation is always up-to-date and available for auditing and compliance.

Prerequisites

  • DeployBrief API key with briefs:write scope
  • Pipeline preset configured in DeployBrief (recommended)
  • Azure DevOps connection established

See API Authentication to create an API key.

GitHub Actions

Setup

  1. Add API key as a GitHub repository secret: DEPLOYBRIEF_API_KEY
  2. Add preset ID as a secret or variable: DEPLOYBRIEF_PRESET_ID
  3. Create workflow file: .github/workflows/deploy.yml

Complete Example

name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Build and test
        run: |
          npm install
          npm run build
          npm test

      - name: Deploy to Azure
        run: |
          # Your deployment commands here
          echo "Deploying..."

      - name: Generate Deployment Brief
        env:
          DEPLOYBRIEF_API_KEY: $${{secrets.DEPLOYBRIEF_API_KEY}}  
          PRESET_ID: $${{secrets.DEPLOYBRIEF_PRESET_ID}}  
        run: |
          curl -X POST https://api.deploybrief.com/api/briefs/generate-from-preset \
            -H "Authorization: Bearer $${ DEPLOYBRIEF_API_KEY }" \
            -H "Content-Type: application/json" \
            -d "{
              \"presetId\": \"$${ PRESET_ID }\",
              \"buildId\": $${{github.run_id}}            }"

      - name: Comment PR with Brief
        if: github.event_name == 'pull_request'
        run: |
          # Optional: Post brief link to PR comment
          echo "Deployment brief generated!"

Using Reusable Actions

Create a reusable action for consistency across repositories:

# .github/actions/generate-brief/action.yml
name: 'Generate DeployBrief'
description: 'Generate a deployment brief'
inputs:
  api-key:
    description: 'DeployBrief API key'
    required: true
  preset-id:
    description: 'Preset ID'
    required: true
  build-id:
    description: 'Build ID'
    required: false
    default: $${{github.run_id}}  

runs:
  using: 'composite'
  steps:
    - shell: bash
      run: |
        curl -X POST https://api.deploybrief.com/api/briefs/generate-from-preset \
          -H "Authorization: Bearer $${{inputs.api-key}}  " \
          -H "Content-Type: application/json" \
          -d "{
            \"presetId\": \"$${{inputs.preset-id}}  \",
            \"buildId\": $${{inputs.build-id}}          }"

Azure Pipelines

Setup

  1. Add pipeline variable: DEPLOYBRIEF_API_KEY (mark as secret)
  2. Add variable: DEPLOYBRIEF_PRESET_ID
  3. Update azure-pipelines.yml

Complete Example

trigger:
  branches:
    include:
      - main

pool:
  vmImage: 'ubuntu-latest'

variables:
  - name: DEPLOYBRIEF_PRESET_ID
    value: 'preset-abc-123'

stages:
- stage: Build
  jobs:
  - job: BuildJob
    steps:
    - task: Npm@1
      inputs:
        command: 'install'
    
    - task: Npm@1
      inputs:
        command: 'custom'
        customCommand: 'run build'
    
    - task: Npm@1
      inputs:
        command: 'custom'
        customCommand: 'test'

- stage: Deploy
  dependsOn: Build
  jobs:
  - deployment: DeployProduction
    environment: 'production'
    strategy:
      runOnce:
        deploy:
          steps:
          - script: |
              echo "Deploying to production..."
              # Your deployment commands
            displayName: 'Deploy Application'

          - task: PowerShell@2
            displayName: 'Generate Deployment Brief'
            inputs:
              targetType: 'inline'
              script: |
                $headers = @{
                  'Authorization' = "Bearer $(DEPLOYBRIEF_API_KEY)"
                  'Content-Type' = 'application/json'
                }
                
                $body = @{
                  presetId = "$(DEPLOYBRIEF_PRESET_ID)"
                  buildId = "$(Build.BuildId)"
                } | ConvertTo-Json
                
                $response = Invoke-RestMethod `
                  -Uri 'https://api.deploybrief.com/api/briefs/generate-from-preset' `
                  -Method Post `
                  -Headers $headers `
                  -Body $body
                
                Write-Host "Brief generated: $($response.briefUrl)"

Using Bash Script

- bash: |
    curl -X POST https://api.deploybrief.com/api/briefs/generate-from-preset \
      -H "Authorization: Bearer $$(DEPLOYBRIEF_API_KEY)" \
      -H "Content-Type: application/json" \
      -d "{
        \"presetId\": \"$$(DEPLOYBRIEF_PRESET_ID)\",
        \"buildId\": \"$$(Build.BuildId)\"
      }"
  displayName: 'Generate Deployment Brief'

Advanced Patterns

Conditional Brief Generation

Only generate briefs for specific branches or environments:

pipeline {\n    agent any
    
    environment {\n        DEPLOYBRIEF_API_KEY = credentials('deploybrief-api-key')
        DEPLOYBRIEF_PRESET_ID = 'preset-abc-123'
    }\n    \n    stages {\n        stage('Build') {\n            steps {\n                sh 'npm install'
                sh 'npm run build'
                sh 'npm test'
            }\n        }
        
        stage('Deploy') {\n            steps {\n                sh 'echo \"Deploying...\"'\n                // Your deployment commands\n            }\n        }
        
        stage('Generate Brief') {
            steps {
                script {
                    sh """
                        curl -X POST https://api.deploybrief.com/api/briefs/generate-from-preset \\
                          -H "Authorization: Bearer ${DEPLOYBRIEF_API_KEY}" \\
                          -H "Content-Type: application/json" \\
                          -d '{ 
                            "presetId": "${DEPLOYBRIEF_PRESET_ID}",
                            "buildId": "${BUILD_ID}"
                          }'
                    """
                }
            }
        }
    }
    
    post {
        success {
            echo 'Deployment successful! Brief generated.'
        }
        failure {
            echo 'Deployment failed!'
        }
    }
}

Scripted Pipeline Example

node {
    withCredentials([string(credentialsId: 'deploybrief-api-key', variable: 'API_KEY')]) {
        stage('Build') {
            sh 'npm install && npm run build'
        }
        
        stage('Deploy') {
            sh 'echo "Deploying..."'
        }
        
        stage('Generate Brief') {
            sh """
                curl -X POST https://api.deploybrief.com/api/briefs/generate-from-preset \\
                  -H "Authorization: Bearer ${ API_KEY }" \\
                  -H "Content-Type: application/json" \\
                  -d '{ 
                    "presetId": "preset-abc-123",
                    "buildId": "${ BUILD_ID }"
                  }'
            """
        }
    }
}

Advanced Patterns

Conditional Brief Generation

Only generate briefs for specific branches or environments:

# GitHub Actions
- name: Generate Brief
  if: github.ref == 'refs/heads/main'
  run: |
    # Generate brief only on main branch

# Azure Pipelines
- script: |
    # Generate brief
  condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')

Error Handling

Handle API errors gracefully:

#!/bin/bash
response=$(curl -s -w "\n%{ http_code }" -X POST \
  https://api.deploybrief.com/api/briefs/generate-from-preset \
  -H "Authorization: Bearer ${ DEPLOYBRIEF_API_KEY }" \
  -H "Content-Type: application/json" \
  -d "{ 
    \"presetId\": \"${ PRESET_ID }\",
    \"buildId\": \"${ BUILD_ID }\"
  }")

http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')

if [ "$http_code" -eq 201 ]; then
  echo "✓ Brief generated successfully"
  echo "$body"
else
  echo "✗ Failed to generate brief (HTTP $http_code)"
  echo "$body"
  exit 1
fi

Posting Brief Link to Slack

#!/bin/bash
response=$(curl -s -X POST https://api.deploybrief.com/api/briefs/generate-from-preset \
  -H "Authorization: Bearer ${ DEPLOYBRIEF_API_KEY }" \
  -H "Content-Type: application/json" \
  -d "{ \"presetId\": \"${ PRESET_ID }\", \"buildId\": \"${ BUILD_ID }\" }")

brief_url=$(echo "$response" | jq -r '.briefUrl')

curl -X POST "${ SLACK_WEBHOOK_URL }" \
  -H "Content-Type: application/json" \
  -d "{ 
    \"text\": \"🚀 Deployment completed!\",
    \"attachments\": [{ 
      \"text\": \"View deployment brief: https://deploybrief.com$brief_url\"
    }]
  }"

Multi-Environment Deployment

Use different presets for different environments:

# Azure Pipelines
- script: |
    if [ "$(Build.SourceBranch)" == "refs/heads/main" ]; then
      PRESET_ID="preset-production"
    elif [ "$(Build.SourceBranch)" == "refs/heads/staging" ]; then
      PRESET_ID="preset-staging"
    else
      PRESET_ID="preset-dev"
    fi
    
    curl -X POST https://api.deploybrief.com/api/briefs/generate-from-preset \
      -H "Authorization: Bearer $(DEPLOYBRIEF_API_KEY)" \
      -d "{ \"presetId\": \"$PRESET_ID\", \"buildId\": \"$(Build.BuildId)\" }"

Best Practices

  • Generate after successful deployment: Only create briefs when deployment succeeds
  • Use presets: Simplifies integration and maintains consistency
  • Store API keys securely: Use CI/CD secrets, never commit to code
  • Add error handling: Gracefully handle API failures without breaking pipelines
  • Tag builds: Include git tags or version numbers in build IDs
  • Notify teams: Post brief links to Slack, Teams, or email
  • Environment-specific presets: Use different presets for prod, staging, dev
  • Test in lower environments: Validate integration before production

Next Steps