Skip to main content

Configure CircleCI for Deploy Change Investigator

Last updated on

Send build and deployment data from CircleCI workflows to the Deploy Change Investigator using webhook steps.

Before you begin

  • Deploy Change Investigator setup: Build and deploy webhook integrations created in AI SRE. Go to Deploy Change Investigator to create webhook endpoints.
  • CircleCI project access: Permission to edit .circleci/config.yml and manage environment variables.
  • Webhook URLs: Build and deploy webhook URLs from AI SRE integrations page.

Store webhook URLs as environment variables

Store webhook URLs securely in CircleCI project settings:

  1. Navigate to project in CircleCI dashboard
  2. Click Project Settings
  3. Select Environment Variables
  4. Click Add Environment Variable
  5. Create build webhook variable:
    • Name: AISRE_BUILD_WEBHOOK_URL
    • Value: Build webhook URL from AI SRE
  6. Click Add Environment Variable
  7. Create deploy webhook variable:
    • Name: AISRE_DEPLOY_WEBHOOK_URL
    • Value: Deploy webhook URL from AI SRE

Configure build webhooks

Add a webhook step to your build job after artifacts are published.

Docker build workflow

version: 2.1

orbs:
docker: circleci/docker@2.4.0

jobs:
build:
docker:
- image: cimg/base:stable
steps:
- checkout
- setup_remote_docker:
docker_layer_caching: true

- run:
name: Build Docker image
command: |
docker build -t registry.example.com/myapp:$CIRCLE_SHA1 .

- run:
name: Push Docker image
command: |
echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin registry.example.com
docker push registry.example.com/myapp:$CIRCLE_SHA1

- run:
name: Send build webhook to AI SRE
when: on_success
command: |
curl -X POST "$AISRE_BUILD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"artifact": {
"name": "registry.example.com/myapp",
"version": "'"$CIRCLE_SHA1"'"
},
"source": {
"commitSha": "'"$CIRCLE_SHA1"'",
"kind": "branch",
"value": "'"$CIRCLE_BRANCH"'",
"repository_url": "'"$CIRCLE_REPOSITORY_URL"'"
},
"service": {
"name": "'"$CIRCLE_PROJECT_REPONAME"'",
"version": "'"$CIRCLE_SHA1"'"
},
"buildId": "'"$CIRCLE_WORKFLOW_ID"'"
}'

workflows:
version: 2
build-and-deploy:
jobs:
- build:
filters:
branches:
only:
- main
- develop

CircleCI environment variables

CircleCI provides these environment variables automatically:

VariableDescriptionExample
CIRCLE_SHA1Full commit SHAffac537e6cbbf934b08745a378932722df287a53
CIRCLE_BRANCHBranch namemain
CIRCLE_PROJECT_REPONAMERepository namemyapp
CIRCLE_PROJECT_USERNAMEGitHub or Bitbucket usernamemyorg
CIRCLE_REPOSITORY_URLGit repository URLhttps://github.com/myorg/myapp
CIRCLE_WORKFLOW_IDUnique workflow identifierabc123-def456-ghi789
CIRCLE_BUILD_NUMBuild number1234
CIRCLE_USERNAMEUser who triggered buildusername

Access variables using shell syntax: $CIRCLE_SHA1


Configure deploy webhooks

Add webhook steps to deployment jobs after deployment completes.

Kubernetes deployment workflow

version: 2.1

orbs:
kubernetes: circleci/kubernetes@1.3.1

jobs:
deploy:
docker:
- image: cimg/base:stable
parameters:
environment:
type: string
default: production
steps:
- checkout

- kubernetes/install-kubectl

- run:
name: Configure kubectl
command: |
echo $KUBE_CONFIG | base64 -d > kubeconfig.yaml
export KUBECONFIG=kubeconfig.yaml

- run:
name: Deploy to Kubernetes
command: |
kubectl set image deployment/$CIRCLE_PROJECT_REPONAME \
$CIRCLE_PROJECT_REPONAME=registry.example.com/$CIRCLE_PROJECT_REPONAME:$CIRCLE_SHA1 \
-n << parameters.environment >>
kubectl rollout status deployment/$CIRCLE_PROJECT_REPONAME \
-n << parameters.environment >> \
--timeout=5m

- run:
name: Send deploy webhook to AI SRE
when: on_success
command: |
curl -X POST "$AISRE_DEPLOY_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"services": [{
"service": "'"$CIRCLE_PROJECT_REPONAME"'",
"version": "'"$CIRCLE_SHA1"'"
}],
"environments": ["<< parameters.environment >>"],
"changeId": "'"$CIRCLE_WORKFLOW_ID"'",
"status": "SUCCESS",
"deployedBy": "'"$CIRCLE_USERNAME"'",
"deployTimestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}'

- run:
name: Send failure webhook to AI SRE
when: on_fail
command: |
curl -X POST "$AISRE_DEPLOY_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"services": [{
"service": "'"$CIRCLE_PROJECT_REPONAME"'",
"version": "'"$CIRCLE_SHA1"'"
}],
"environments": ["<< parameters.environment >>"],
"changeId": "'"$CIRCLE_WORKFLOW_ID"'",
"status": "FAILURE",
"deployedBy": "'"$CIRCLE_USERNAME"'",
"deployTimestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}'

workflows:
version: 2
build-and-deploy:
jobs:
- build:
filters:
branches:
only: main
- deploy:
environment: production
requires:
- build
filters:
branches:
only: main

Step execution conditions

Control when steps execute using when attribute:

ConditionWhen it runs
when: on_successPrevious steps succeeded
when: on_failPrevious steps failed
when: alwaysRuns regardless of status

Example with conditions:

- run:
name: Notify always
when: always
command: echo "Job finished"

- run:
name: Notify on success
when: on_success
command: curl -X POST $WEBHOOK_URL -d '{"status": "SUCCESS"}'

- run:
name: Notify on failure
when: on_fail
command: curl -X POST $WEBHOOK_URL -d '{"status": "FAILURE"}'

Multi-service deployments

For workflows that deploy multiple services, send all services in one webhook:

- run:
name: Send deploy webhook to AI SRE
when: on_success
command: |
curl -X POST "$AISRE_DEPLOY_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"services": [
{"service": "frontend", "version": "'"$FRONTEND_VERSION"'"},
{"service": "backend", "version": "'"$BACKEND_VERSION"'"},
{"service": "worker", "version": "'"$WORKER_VERSION"'"}
],
"environments": ["production"],
"changeId": "'"$CIRCLE_WORKFLOW_ID"'",
"status": "SUCCESS",
"deployedBy": "'"$CIRCLE_USERNAME"'",
"deployTimestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}'

Reusable commands

Create reusable commands to standardize webhook notifications:

version: 2.1

commands:
notify-build:
parameters:
service:
type: string
version:
type: string
steps:
- run:
name: Send build webhook to AI SRE
command: |
curl -X POST "$AISRE_BUILD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"artifact": {
"name": "registry.example.com/<< parameters.service >>",
"version": "<< parameters.version >>"
},
"source": {
"commitSha": "'"$CIRCLE_SHA1"'",
"kind": "branch",
"value": "'"$CIRCLE_BRANCH"'",
"repository_url": "'"$CIRCLE_REPOSITORY_URL"'"
},
"service": {
"name": "<< parameters.service >>",
"version": "<< parameters.version >>"
},
"buildId": "'"$CIRCLE_WORKFLOW_ID"'"
}'

notify-deploy:
parameters:
service:
type: string
version:
type: string
environment:
type: string
steps:
- run:
name: Send deploy webhook to AI SRE
when: on_success
command: |
curl -X POST "$AISRE_DEPLOY_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"services": [{
"service": "<< parameters.service >>",
"version": "<< parameters.version >>"
}],
"environments": ["<< parameters.environment >>"],
"changeId": "'"$CIRCLE_WORKFLOW_ID"'",
"status": "SUCCESS",
"deployedBy": "'"$CIRCLE_USERNAME"'",
"deployTimestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}'

jobs:
build:
docker:
- image: cimg/base:stable
steps:
- checkout
- run: docker build -t registry.example.com/myapp:$CIRCLE_SHA1 .
- run: docker push registry.example.com/myapp:$CIRCLE_SHA1
- notify-build:
service: myapp
version: $CIRCLE_SHA1

deploy:
docker:
- image: cimg/base:stable
steps:
- checkout
# Deployment steps here
- notify-deploy:
service: myapp
version: $CIRCLE_SHA1
environment: production

Workflow filters

Control which branches trigger jobs using filters:

workflows:
version: 2
build-and-deploy:
jobs:
- build:
filters:
branches:
only:
- main
- develop

- deploy-staging:
requires:
- build
filters:
branches:
only: develop

- deploy-production:
requires:
- build
filters:
branches:
only: main

Service and version mapping

The Deploy Change Investigator requires exact matches between build and deploy webhooks:

Build webhookDeploy webhookMust match
service.nameservices[].service✅ Required
artifact.version or service.versionservices[].version✅ Required

Use the same variable ($CIRCLE_SHA1) in both build and deploy webhooks to ensure versions match.


Testing webhooks

Test build webhook

  1. Push a commit to trigger build
  2. Check build logs for webhook step
  3. Verify curl command executed successfully
  4. Navigate to AI SREIntegrations
  5. Click ... menu on BUILD integration
  6. Select Debug
  7. Verify webhook appears with correct payload

Test deploy webhook

  1. Trigger deployment workflow
  2. Check deployment job logs
  3. Navigate to AI SREIntegrations
  4. Click ... menu on DEPLOY integration
  5. Select Debug
  6. Verify webhook appears

Verify correlation

After sending both webhooks:

  1. Navigate to AI SREChange Management
  2. Deployments should appear linked to builds
  3. Click a deployment to see artifact versions and commit information

Troubleshooting

Webhook not received

Check:

  • Environment variable AISRE_BUILD_WEBHOOK_URL or AISRE_DEPLOY_WEBHOOK_URL is configured
  • Curl command executed in job logs
  • Network allows outbound HTTPS from CircleCI executors
  • JSON payload has no syntax errors

Test manually:

curl -v -X POST "$AISRE_BUILD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{"test": "payload"}'

Deployments not linked to builds

Verify:

  • services[].service in deploy webhook matches service.name in build webhook exactly
  • services[].version in deploy webhook matches build webhook version exactly
  • Both webhooks sent successfully (check Debug view)

Variable interpolation issues

Problem: Shell variables not expanding in JSON

Solution: Use proper quoting for variable expansion:

command: |
curl -d '{
"service": "'"$CIRCLE_PROJECT_REPONAME"'",
"version": "'"$CIRCLE_SHA1"'"
}' $WEBHOOK_URL

Note the quote pattern: "'"$VARIABLE"'" for proper JSON escaping.


Next steps