Skip to main content

Configure GitLab CI for Deploy Change Investigator

Last updated on

Send build and deployment data from GitLab CI/CD pipelines to the Deploy Change Investigator using webhook jobs.

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.
  • GitLab project access: Maintainer role to edit .gitlab-ci.yml and configure CI/CD variables.
  • Webhook URLs: Build and deploy webhook URLs from AI SRE integrations page.

Store webhook URLs as CI/CD variables

Store webhook URLs securely in GitLab CI/CD variables:

  1. Navigate to project SettingsCI/CD
  2. Expand Variables section
  3. Click Add variable
  4. Configure build webhook:
    • Key: AISRE_BUILD_WEBHOOK_URL
    • Value: Build webhook URL from AI SRE
    • Type: Variable
    • Flags: Protect variable, Mask variable
  5. Click Add variable
  6. Repeat for deploy webhook:
    • Key: AISRE_DEPLOY_WEBHOOK_URL
    • Value: Deploy webhook URL from AI SRE

Configure build webhooks

Add a webhook notification job to your pipeline after build completes.

Docker build pipeline

stages:
- build
- notify

variables:
REGISTRY: registry.gitlab.com
IMAGE_NAME: $CI_PROJECT_PATH

build:
stage: build
image: docker:24.0.5
services:
- docker:24.0.5-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA .
- docker push $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
only:
- main
- develop

notify-build:
stage: notify
image: curlimages/curl:latest
script:
- |
curl -X POST "$AISRE_BUILD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"artifact": {
"name": "'"$REGISTRY/$IMAGE_NAME"'",
"version": "'"$CI_COMMIT_SHORT_SHA"'"
},
"source": {
"commitSha": "'"$CI_COMMIT_SHA"'",
"kind": "branch",
"value": "'"$CI_COMMIT_REF_NAME"'",
"repository_url": "'"$CI_PROJECT_URL"'"
},
"service": {
"name": "'"$CI_PROJECT_NAME"'",
"version": "'"$CI_COMMIT_SHORT_SHA"'"
},
"buildId": "'"$CI_PIPELINE_ID"'"
}'
dependencies:
- build
only:
- main
- develop
when: on_success

GitLab CI predefined variables

GitLab CI provides these predefined variables automatically:

VariableDescriptionExample
CI_COMMIT_SHAFull commit SHA1ecfd275763eff1d6b4844ea3168962458c9f27a
CI_COMMIT_SHORT_SHAShort commit SHA (first 8 characters)1ecfd275
CI_COMMIT_REF_NAMEBranch or tag namemain
CI_PROJECT_PATHProject path with namespacegroup/project
CI_PROJECT_NAMEProject name onlyproject
CI_PROJECT_URLFull project URLhttps://gitlab.com/group/project
CI_PIPELINE_IDUnique pipeline ID1234567
CI_REGISTRYGitLab Container Registry URLregistry.gitlab.com

Access variables using shell syntax: $CI_COMMIT_SHA or ${CI_COMMIT_SHA}


Configure deploy webhooks

Add webhook notification jobs to deployment pipelines after deployment completes.

Kubernetes deployment pipeline

stages:
- build
- deploy
- notify

variables:
KUBE_NAMESPACE: production
SERVICE_NAME: myapp

deploy-production:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl config use-context $KUBE_CONTEXT
- kubectl set image deployment/$SERVICE_NAME
$SERVICE_NAME=$REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
-n $KUBE_NAMESPACE
- kubectl rollout status deployment/$SERVICE_NAME
-n $KUBE_NAMESPACE
--timeout=5m
environment:
name: production
only:
- main

notify-deploy-success:
stage: notify
image: curlimages/curl:latest
script:
- |
curl -X POST "$AISRE_DEPLOY_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"services": [{
"service": "'"$SERVICE_NAME"'",
"version": "'"$CI_COMMIT_SHORT_SHA"'"
}],
"environments": ["production"],
"changeId": "'"$CI_PIPELINE_ID"'",
"status": "SUCCESS",
"deployedBy": "'"$GITLAB_USER_LOGIN"'",
"deployTimestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}'
dependencies:
- deploy-production
environment:
name: production
only:
- main
when: on_success

notify-deploy-failure:
stage: notify
image: curlimages/curl:latest
script:
- |
curl -X POST "$AISRE_DEPLOY_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"services": [{
"service": "'"$SERVICE_NAME"'",
"version": "'"$CI_COMMIT_SHORT_SHA"'"
}],
"environments": ["production"],
"changeId": "'"$CI_PIPELINE_ID"'",
"status": "FAILURE",
"deployedBy": "'"$GITLAB_USER_LOGIN"'",
"deployTimestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}'
dependencies:
- deploy-production
environment:
name: production
only:
- main
when: on_failure

Job execution conditions

Control when jobs execute using when and only keywords:

KeywordPurpose
when: on_successRun if previous jobs succeeded
when: on_failureRun if previous jobs failed
when: alwaysRun regardless of previous job status
when: manualRequire manual trigger
only: [main]Run only on specified branches
except: [develop]Skip on specified branches

Example with conditions:

notify-always:
stage: notify
script:
- echo "Pipeline finished"
when: always

notify-success:
stage: notify
script:
- curl -X POST $WEBHOOK_URL -d '{"status": "SUCCESS"}'
when: on_success

notify-failure:
stage: notify
script:
- curl -X POST $WEBHOOK_URL -d '{"status": "FAILURE"}'
when: on_failure

Multi-service deployments

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

notify-deploy:
stage: notify
image: curlimages/curl:latest
script:
- |
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": "'"$CI_PIPELINE_ID"'",
"status": "SUCCESS",
"deployedBy": "'"$GITLAB_USER_LOGIN"'",
"deployTimestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}'
when: on_success

Reusable templates

Create reusable webhook notification templates using include:

Create template file

Create .gitlab/ci/webhook-notify.yml:

.notify-build:
stage: notify
image: curlimages/curl:latest
script:
- |
curl -X POST "$AISRE_BUILD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"artifact": {"name": "'"$REGISTRY/$IMAGE_NAME"'", "version": "'"$VERSION"'"},
"source": {
"commitSha": "'"$CI_COMMIT_SHA"'",
"kind": "branch",
"value": "'"$CI_COMMIT_REF_NAME"'",
"repository_url": "'"$CI_PROJECT_URL"'"
},
"service": {"name": "'"$SERVICE_NAME"'", "version": "'"$VERSION"'"},
"buildId": "'"$CI_PIPELINE_ID"'"
}'
when: on_success

.notify-deploy:
stage: notify
image: curlimages/curl:latest
script:
- |
curl -X POST "$AISRE_DEPLOY_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"services": [{"service": "'"$SERVICE_NAME"'", "version": "'"$VERSION"'"}],
"environments": ["'"$ENVIRONMENT"'"],
"changeId": "'"$CI_PIPELINE_ID"'",
"status": "SUCCESS",
"deployedBy": "'"$GITLAB_USER_LOGIN"'",
"deployTimestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}'
when: on_success

Use templates

Include and extend templates in main pipeline:

include:
- local: '.gitlab/ci/webhook-notify.yml'

notify-build:
extends: .notify-build
variables:
SERVICE_NAME: $CI_PROJECT_NAME
VERSION: $CI_COMMIT_SHORT_SHA

notify-deploy:
extends: .notify-deploy
variables:
SERVICE_NAME: $CI_PROJECT_NAME
VERSION: $CI_COMMIT_SHORT_SHA
ENVIRONMENT: production

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 ($CI_COMMIT_SHORT_SHA) in both build and deploy webhooks to ensure versions match.


Testing webhooks

Test build webhook

  1. Push a commit or create merge request
  2. Check pipeline job logs for notify-build job
  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 pipeline
  2. Check notify-deploy 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:

  • CI/CD variable AISRE_BUILD_WEBHOOK_URL or AISRE_DEPLOY_WEBHOOK_URL is configured
  • Curl command executed in job logs
  • Network allows outbound HTTPS from GitLab runners
  • 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:

script:
- |
curl -d '{
"service": "'"$CI_PROJECT_NAME"'",
"version": "'"$CI_COMMIT_SHORT_SHA"'"
}' $WEBHOOK_URL

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

Job fails with protected variable

Issue: Protected variables only available on protected branches

Solution: Either unprotect the variable or run webhook jobs only on protected branches:

notify-build:
only:
- main
- /^release\/.*$/

Next steps