Record a deployment from CI
Tell Clanker Ship which build is running after every deploy, with one API call from your pipeline.
A deployment records where a product runs in one environment and which build is there. This example
sends the commit SHA to Clanker Ship after each production deploy of the storefront, so test runs
and people see what is running. It needs one PATCH request, so the deploy job does not need the
clanker CLI.
Before you begin
You need an account API key with the member role, stored in your CI as CLANKER_API_KEY. See
Publish test runs from CI
for how to create one.
1. Create the deployment once
Each product has at most one deployment per environment. Create the storefront's production deployment with its base URL, from your computer or a one-off job, with Create a deployment:
curl --fail-with-body https://api.clankertest.com/v1/workspaces/acme/deployments \ -H "Authorization: Bearer $CLANKER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "product": "storefront", "environment": "production", "baseUrl": "https://shop.acme.dev" }'
Running it again fails with 409 and the message Storefront is already deployed to Production.,
so it is safe to keep in a setup script.
2. Record each deploy
After the deploy succeeds, send the new version with
Update a deployment. Only version changes:
curl --fail-with-body -X PATCH \ https://api.clankertest.com/v1/workspaces/acme/deployments/storefront/production \ -H "Authorization: Bearer $CLANKER_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"version\": \"$GIT_SHA\" }"
The response is the deployment. The server sets versionUpdatedAt whenever the version changes:
{ "id": "Dp9LmT4kVx2R", "product": { "id": "Pr4GtY9sLm3B", "slug": "storefront", "name": "Storefront", "type": "website", "archived": false }, "environment": { "id": "En1MwX6cTb7F", "slug": "production", "name": "Production", "class": "production", "emoji": null, "archived": false }, "baseUrl": "https://shop.acme.dev", "fixtureUrl": null, "version": "4b7e0d2c91a35f8e6d0b7a2c4e1f9a8b3c5d6e7f", "versionUpdatedAt": "2026-10-14T09:05:12.000Z", "active": true, "createdAt": "2026-10-01T16:20:00.000Z", "updatedAt": "2026-10-14T09:05:12.000Z" }
version is free text up to 100 characters, so a tag such as v2.4.1 works as well as a SHA.
In GitHub Actions
Add a step after your deploy step:
- name: Record the deployment in Clanker Ship env: CLANKER_API_KEY: ${{ secrets.CLANKER_API_KEY }} run: | curl --fail-with-body -X PATCH \ https://api.clankertest.com/v1/workspaces/acme/deployments/storefront/production \ -H "Authorization: Bearer $CLANKER_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"version\": \"$GITHUB_SHA\" }"
--fail-with-body makes the step fail on an error and prints the error body, such as
{"message":"Storefront is archived. Restore it before changing it or its deployments.","_tag":"Conflict"}.
See Errors.
With the CLI
When the job already has the clanker CLI, the same update is one command. It uses the workspace in
clanker.json, or --workspace:
clanker deployment update storefront production --deployed-version "$GITHUB_SHA"Variations
- Move the base URL. Send
baseUrlin the samePATCH. Website and API products always need one; for other product types,nullclears it. - Point test runs at a Fixture API. Send
fixtureUrlin the samePATCH, such ashttps://shop.acme.dev/fixtures, so each run makes its test data there.nullclears it. - Record several environments. Each environment has its own deployment:
PATCH /deployments/storefront/stagingafter a staging deploy. - Let an agent do it. Agents call update_deployment with the same fields.