The Deployments API enables registering deployments in DX from any data source. The Deployments API is a flexible solution that can handle a wide range of deployment mechanisms, whereas deploy inference rules are a no-code solution for simple deployment workflows.
The Deployments API supports several paths to attributing deployments to code changes:
When only the
repository
argument is provided, the deployment is attributed to all non-deployed pull requests in the specified repository with base refs equal to the default branch of the repository.When the
commit_sha
andrepository
arguments are provided, the deployment is attributed to the matching pull request as well as all previous non-deployed pull requests with the same repository and and base ref as the matching pull request.When the
commit_sha
,repository
, andintegration_branch
arguments are provided, the deployment is attributed only to pull requests merged into the integration_branch. The time range used to identify pull requests comes from the pull request matching the SHA, and the one from the previous deployment.When the
merge_commit_shas
argument is provided, the deployment is attributed to the specific pull requests that correspond to the provided SHAs.
For the latter two scenarios described above, DX attributes deployments to historical pull requests to fill in presumed gaps. For example, if given the commits and deployments shown below, commits A and B are attributed to Deployment 1, and commits C, D, and E are attributed to Deployment 2.
Commit Deployment Id Deploy Timestamp
------ ------------- ----------------
A
B 1 2024-03-01
C
D
E 2 2024-06-01
Attribution is attempted immediately. Since there is no guarantee that the related repository data has been imported yet, attribution will be retried until relevant data is found for up to three days.
API methods
deployments.create
Creates a new deployment.
Required arguments
Name | Description |
deployed_at | integer - Unix timestamp of when the deployment occurred.
Example:
|
service | string - The name of the service that the code was deployed to.
Example:
|
If attributing deployments to code via single commit SHA:
Name | Description |
repository | string - Repository name associated with the deployment including the organization prefix.
Example:
*For ADO, prefix repo name with the project name instead of organization. |
commit_sha | string - SHA of the commit being deployed to production. Length must be min 7, max 40 chars. If SHA is not provided then deployment attribution will be done by deployed_at timestamps which is less accurate.
Example:
|
If attributing deployments to specific commit SHAs:
Name | Description |
merge_commit_shas | array - An array of commit SHA strings being deployed to production. Length must be min 7, max 40 chars. Used for deployment attribution to pull requests.
Example:
|
Optional arguments
Name | Description |
reference_id | string - Unique identifier for the deployment to supports idempotency. If not provided, a new UUID is generated. Returns a
Example:
|
source_url | string - A external URL containing more information about your deployment. This will be displayed in the UI when exploring your data.
Example:
|
source_name | string - An arbitrary name you use to represent the source for the deployment. This will help you to differentiate and compare data generated from different types of deploy systems.
Example:
|
metadata | JSON Object - You may pass a metadata object with additional data about your deployment that you define. { "version": "v1.11.23" } |
integration_branch | string - Set this value if you are using a branch to integrate changes before merging to a release branch.
Example: develop |
Example
curl -X POST https://yourinstance.getdx.net/api/deployments.create \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_bearer_token_here" \
--data '{
"reference_id": "globally-unique-identifier",
"deployed_at": 1680723287,
"service": "my_service",
"commit_sha": "d1a34f0",
"repository": "my_org/payment_api"
}'
Error codes
Error Code | Description |
| This error occurs if the API request does not include a valid API key for authentication. |
| The provided API key is invalid. This can happen if the key is expired or does not exist. |
| One or more required parameters were not provided in the request. |
| The provided repository could not be found. |
| The provided commit SHA is not valid or does not meet the required length. |
| The reference_id already exists β a unique value is required. |
| The metadata was not able to be processed. Metadata must be an object and keys may include letters, numbers, dashes and underscores. |
| The integration branch must be a valid pul request |
| You must provide either |
| The provided |
| One or more of the |
| One or more of the |
deployments.setPullServices
For monorepos, there is an additional step needed to accurately attribute pull request to deployments. Since DX associates pull requests to a deployment that have been merged since the previous deployment, this can lead to the problem where past pull requests are attributed to deployments for the wrong service.
The setPullServices endpoint pre-associates pull requests with services, ensuring that they are attributed correctly when deployment data is later captured. For example, suppose the following events occur:
10 am - merge PR#1 (changes service_a)
11 am - merge PR#2 (changes service_b)
12 pm - merge PR#3 (changes service_a)
12:01 - deploy service_a
If setPullServices has been used after each merge:
pull requests 1 and 3 will associate to the deployment
2 will not be considered deployed
If setPullServices has not been used:
pull requests 1, 2, and 3 will all be considered deployed.
Required arguments
Name | Description |
github_pull_id | integer - The unique id provided by GitHub.
Example:
|
services | array - An array of strings representing the services that have been changed as part of this merge.
Example:
|
If pull_request_id cannot be provide, you can pass repository and pull request number instead:
Name | Description |
repository | string - Repository name associated with the deployment including the organization prefix.
Example:
|
pull_number | integer - The GitHub PR number.
Example:
|
Example
curl -X POST\
https://yourinstance.getdx.net/api/deployments.setPullServices\
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_bearer_token_here" \
-d '{
"github_pull_id": 1497468863,
"services": ["serviceA", "other-service"]
}'
Error codes
Error Code | Description |
| This error occurs if the API request does not include a valid API key for authentication. |
| The provided API key is invalid. This can happen if the key is expired or does not exist. |
| The user account associated with the API key is deactivated or suspended. |
| The JSON body of the request could not be parsed. This usually indicates a syntax error. |
| One or more required parameters were not provided in the request. |
| The specified repository could not be found. This could be due to a typo or an incorrect repository name. |
Backfill deployments
You can backfill historical deployments by providing a CSV containing the same fields as used for the deployments.create
endpoint. To get started, check out our deployments backfill template in Google Sheets. Each row in the spreadsheet represents one deployment. We will associated code that is merged between deployments automatically.
β
Once you the CSV ready, contact your DX account representative to get your CSV imported.
β
GitHub Actions Example
Below is an example of a GitHub Actions workflow that registers deployments after pull requests are merged.
name: Register deploy in DX Data Cloud
on:
pull_request:
types:
- closed
jobs:
register_deploy:
runs-on: ubuntu-latest
env:
API_TOKEN: ${{ secrets.DX_DEPLOYMENT_API_TOKEN }}
DATACLOUD_HOST: ${{ secrets.DX_DATACLOUD_HOST }}
steps:
- name: Register deploy
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main' # Change 'main' to your base branch name
run: |
sha=$(git rev-parse HEAD)
ts=$(date +%s)
repo=${{ github.repository }}
# This is optional - drop from curl if not used
service="My service"
json_payload=$(jq -n \
--arg service "$service" \
--arg repo "$repo" \
--arg sha "$sha" \
--arg ts "$ts" \
'{
service: $service,
repository: $repo,
commit_sha: $sha,
deployed_at: $ts
}')
RESPONSE_CODE=$(curl \
"https://${DATACLOUD_HOST}/api/deployments.create"\
-s -o response.txt\
-w "%{http_code}" -X POST \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" \
-d "$json_payload"
)
if [ "$RESPONSE" -ne 200 ]; then
ERROR_MESSAGE=$(jq -r '.message' response.txt)
ERROR_TYPE=$(jq -r '.error' response.txt)
echo "Error response from API: HTTP status code $RESPONSE"
echo "Error type: $ERROR_TYPE"
echo "Error message: $ERROR_MESSAGE"
exit 1 # Fail the step explicitly if an error is detected
fi
GitHub Actions Example (monorepo)
Below is an example of a Github Actions workflow that gets the name of the services from the folder structure and file changes in the commit when a PR is merged.
name: Scan Changed Files in PR
on:
pull_request:
types:
- closed
branches:
- 'main'
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
fetch-depth: 50 # pick an appropriate number
- name: Get list of changed files
id: getfile
run: |
files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} --)
echo "Changed files: $files"
echo "Changed files: $files" >> changed_files.txt
- name: Identify affected services
id: services
run: |
services=""
while read -r file; do
service=$(echo $file | awk -F'/' '{print $1}')
services="$services $service"
done < changed_files.txt
unique_services=$(echo $services | xargs -n1 | sort -u | xargs)
echo "Affected services: $unique_services"
echo "::set-output name=affected_services::$unique_services"
- name: Post affected services
run: |
json_payload=$(jq -n \
--arg github_pull_id ${{ github.event.pull_request.id }} \
--arg services '[${{ steps.services.outputs.affected_services }}]' \
'{
github_pull_id: $github_pull_id,
services: $services
}')
curl -X POST \
http://yourinstance.getdx.net/api/deployments.setPullServices \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_BEARER_TOKEN_HERE" \
-d "$json_payload"
if [ "$RESPONSE_CODE" -ne 200 ]; then
ERROR_MESSAGE=$(jq -r '.message' response.txt)
ERROR_TYPE=$(jq -r '.error' response.txt)
echo "Error response from API: HTTP status code $RESPONSE"
echo "Error type: $ERROR_TYPE"
echo "Error message: $ERROR_MESSAGE"
exit 1 # Fail the step explicitly if an error is detected
fi