Deployments from CI
A deployment tells Watchtower which release is live in which environment. It becomes a chart annotation, the "new in this release" view, and (with the GitHub or GitLab connector) a comment on each pull request of the release.
Record it from CI with wtctl release create --deploy. It creates the release (idempotent by version), uploads the commits and the files they touched, and records the deployment. Use an API key with the ManageProject role in WT_API_KEY, and run it after the deploy step succeeds.
If you also installed the GitHub or GitLab connector and let the platform report deployments (deployment_status or Deployment events), do not call --deploy as well: that records the deployment twice. Either is fine on its own; keep wtctl release create (without --deploy) if you want commits before the deploy finishes.
GitHub Actions
name: deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- run: ./deploy.sh
- name: Tell Watchtower
env:
WT_API_KEY: ${{ secrets.WT_API_KEY }}
run: >
wtctl release create "${GITHUB_SHA::12}"
--api "${{ vars.WT_API_URL }}" --project "${{ vars.WT_PROJECT_ID }}"
--commits auto --deploy productionGitLab CI
deploy:
stage: deploy
environment: production
script:
- ./deploy.sh
- >
wtctl release create "${CI_COMMIT_SHORT_SHA}"
--api "$WT_API_URL" --project "$WT_PROJECT_ID"
--commits auto --deploy production
variables:
GIT_DEPTH: 0Set WT_API_KEY as a masked CI variable. The environment name must already exist in the project. Status: the snippets were checked against wtctl release create's flags, not run on a real runner.
Plain HTTP
Without wtctl, two calls do the same (API key with ManageProject in $WT_API_KEY):
curl -sS -X POST "$WT_API_URL/v1/projects/$WT_PROJECT_ID/releases" \
-H "Authorization: Bearer $WT_API_KEY" -H "Content-Type: application/json" \
-d '{"version":"'"$SHA"'","commits":[{"sha":"'"$SHA"'","repo":"owner/repo"}]}'
curl -sS -X POST "$WT_API_URL/v1/projects/$WT_PROJECT_ID/deployments" \
-H "Authorization: Bearer $WT_API_KEY" -H "Content-Type: application/json" \
-d '{"version":"'"$SHA"'","env_id":"'"$WT_ENV_ID"'","service":"api","status":"succeeded","source":"ci"}'Coolify
Coolify exposes the deployed commit to the build and the container as SOURCE_COMMIT only when the application's Include Source Commit in Build setting (include_source_commit_in_build in the API) is on; it is off by default. Turn it on, then:
set
service.versionfrom it, e.g.OTEL_RESOURCE_ATTRIBUTES=service.version=${SOURCE_COMMIT}(or the short form your releases use,${SOURCE_COMMIT:0:7}in a shell entrypoint), so spans, logs and metrics carry the release;record the deployment from a post-deployment command or your CI with the same version:
wtctl release create "$SOURCE_COMMIT" --deploy production, orPOST /v1/projects/{prj}/deploymentswithservice.
Use one form of the sha (full or short) everywhere: deploy markers, service.version, RUM release and source-map uploads must match exactly.