Search the docs

Search guides, API endpoints and MCP tools.

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:

bash
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:

bash
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:

json
{
  "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:

yaml
- 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:

bash
clanker deployment update storefront production --deployed-version "$GITHUB_SHA"

Variations

  • Move the base URL. Send baseUrl in the same PATCH. Website and API products always need one; for other product types, null clears it.
  • Point test runs at a Fixture API. Send fixtureUrl in the same PATCH, such as https://shop.acme.dev/fixtures, so each run makes its test data there. null clears it.
  • Record several environments. Each environment has its own deployment: PATCH /deployments/storefront/staging after a staging deploy.
  • Let an agent do it. Agents call update_deployment with the same fields.