Announce releases
An announce is one call from your deploy pipeline that tells Tiden a version went out to an environment. Run it once per deploy, after the rollout succeeds.
Why announce
Without an announce, Tiden learns about a release only when error tracking sends the first event for that version. A build that ships with no errors is never recorded. The release time is the moment the first error arrived, and the release has no name, URL or description.
An announce records the release at deploy time. It also captures the
Quality Gate for the release, so the release
keeps that verdict as evidence after main moves on.
Send the commit the release was built from as its build SHA, and the gate is
computed from the test results reported for that commit only. Until they are
in, the release's gate shows as pending, and Tiden captures it when the
commit's runs finish. Without a build SHA, the capture copies the main gate
as it is at the announce, so a blocked main makes the release blocked too.
Release captures says exactly
what counts and when Tiden captures.
Four rules
- Use the same version and environment as your telemetry SDK. Pass the
version string your SDK sends as
release(orTIDEN_RELEASE) and the environment slug it sends asenvironment. Tiden keys a release on product, version and environment, so a different string creates a second release and your errors land on the other one. - Announce after the rollout succeeds. A failed or rolled-back deploy should not appear as a release.
- Never let the announce fail the deploy. Mark the step
continue-on-error, or end the command with|| echoto log a warning. Repeating an announce is safe: it updates the name, URL and description of the existing release. It changes the gate only when it brings a new build SHA: Tiden then captures from that commit once its runs finish. - Send the commit your tests ran on. The build SHA must be the full 40- or 64-character commit SHA that your test runs report (see Build SHA). The API refuses the whole announce when it is short or not hexadecimal, so the GitHub Actions step below checks it first. If the tests run only on a pull request's merge ref, or before a squash merge, they report another commit and the release stays pending.
Prerequisites
- A product id.
- A Tiden API token with full access, stored as a CI secret. Use a product token with Full access to this product, created in Product settings > API tokens. A publish-only token cannot create releases. See API authentication.
- The version string your telemetry SDK reports for this build.
Let your coding agent wire it
The release-wireup skill does the pipeline edit for you. Install it:
tiden skill install release-wireup
tiden setup installs it too, and tiden skill update refreshes it. Confirm it
is present:
tiden skill list --format text
Then ask your agent to "announce releases to Tiden". The skill finds the deploy step in your CI (GitHub Actions first), reads the version and environment your telemetry SDK sends, and adds one best-effort announce step after each successful rollout, using those same values so the release never forks into a second row. The step calls the REST API, so your pipeline does not need the Tiden CLI.
The step also sends the deployed commit as the build SHA. The skill asks you
when it cannot tell the version or the environment, or whether your test runs
report the deployed commit. It never writes a token into the repository: it
names the TIDEN_API_TOKEN CI secret for you to create. It leaves the change
as a diff to review and never pushes or deploys.
The manual snippets below remain the alternative.
GitHub Actions
Add a step after the step that deploys. It is one curl call to the REST
API, so the runner needs no Tiden CLI; jq, which GitHub-hosted runners
ship with, builds the request body.
- name: Announce release to Tiden
if: success()
continue-on-error: true
env:
TIDEN_API_TOKEN: ${{ secrets.TIDEN_API_TOKEN }}
RELEASE: my-app@${{ github.sha }}
RELEASE_ENVIRONMENT: production
BUILD_SHA: ${{ github.sha }}
run: |
if [ -z "$TIDEN_API_TOKEN" ]; then
echo "::warning::release not announced: TIDEN_API_TOKEN is not set"; exit 0
fi
# A short or non-hex SHA would make the API refuse the whole announce:
# drop it with a warning and announce without it.
BUILD_SHA=$(printf '%s' "$BUILD_SHA" | tr '[:upper:]' '[:lower:]')
case "${#BUILD_SHA}:$BUILD_SHA" in
40:*|64:*) ;;
*) echo "::warning::'$BUILD_SHA' is not a full commit SHA; announced without it"; BUILD_SHA= ;;
esac
case "$BUILD_SHA" in
*[!0-9a-f]*) echo "::warning::'$BUILD_SHA' is not a full commit SHA; announced without it"; BUILD_SHA= ;;
esac
body=$(jq -cn --arg version "$RELEASE" --arg environment "$RELEASE_ENVIRONMENT" \
--arg releasedAt "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg description "commit $BUILD_SHA" \
--arg buildSha "$BUILD_SHA" \
'{version: $version, environment: $environment, name: $version, releasedAt: $releasedAt, description: $description}
+ (if $buildSha == "" then {} else {buildSha: $buildSha} end)')
code=$(curl -sS -o tiden-release.json -w '%{http_code}' -X POST \
"https://api.tiden.ai/v1/products/<productId>/releases" \
-H "Authorization: Bearer $TIDEN_API_TOKEN" -H 'Content-Type: application/json' \
-d "$body") || code=000
case "$code" in
200|201) echo "Announced release $RELEASE ($RELEASE_ENVIRONMENT) to Tiden" ;;
*) echo "::warning::release $RELEASE not announced (HTTP $code): $(cat tiden-release.json 2>/dev/null)" ;;
esac
Set RELEASE and RELEASE_ENVIRONMENT to the same values your application
passes to its telemetry SDK. If the SDK reads TIDEN_RELEASE at runtime, build
both from one variable. Set BUILD_SHA to the commit you deployed: in a
workflow triggered by deployment_status that is
${{ github.event.deployment.sha }}, and by workflow_run it is
${{ github.event.workflow_run.head_sha }}. A missing token, a network error
or an error response only adds a warning to the run; the deploy job stays
green.
Other CI systems use the same request; see REST API below.
CLI
From a machine that already has the Tiden CLI, for example to announce or backfill a release by hand:
tiden release create \
--product-id <productId> \
--version my-app@1.2.3 \
--environment production \
--build-sha "$(git rev-parse HEAD)" \
--name "my-app 1.2.3" \
--url https://github.com/acme/app/releases/tag/v1.2.3 \
--description "Checkout retry and new invoice export"
| Flag | Required | Purpose |
|---|---|---|
--version | Yes | Version string, the same one your telemetry SDK sends |
--environment | No | Environment slug. An unknown slug creates the environment |
--build-sha | No | Full commit SHA the release was built from. The gate is captured from that commit's test results |
--name | No | Display name for the release |
--url | No | Link to the build, tag or changelog |
--description | No | Free-text notes, for example the commit or a summary |
--released-at | No | Release time in RFC 3339, for example 2026-10-20T14:05:00Z |
When you omit --released-at, the release time is the time of the announce.
Pass it only when you announce after the fact, for example when you backfill
earlier deploys.
REST API
curl -X POST "https://api.tiden.ai/v1/products/<productId>/releases" \
-H "Authorization: Bearer $TIDEN_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"version": "my-app@1.2.3",
"environment": "production",
"name": "my-app 1.2.3",
"url": "https://github.com/acme/app/releases/tag/v1.2.3",
"description": "commit 4f2c9e1",
"releasedAt": "2026-10-20T14:05:00Z",
"buildSha": "4f2c9e1d7a3b5c6e8f9012a3b4c5d6e7f8091a2b"
}'
Only version is required. As with the CLI, an omitted releasedAt means
the release time is the time of the announce. In a deploy script, add
|| echo "release not announced" so a failed call does not stop the deploy.
Capture the gate again
A release keeps every capture of its gate, and the newest one is what Tiden shows. Capture again when:
- a test job for the commit created its run only after the other jobs had finished, so the automatic capture missed it (jobs that run side by side are all counted);
- a release has no capture, for example one recorded before you sent build SHAs.
tiden release capture <release-id>
tiden release capture --product-id <productId> --version my-app@1.2.3 --environment production
--product-id is needed with --version unless the repository is linked with
tiden setup. A capture reads the test results the release's own commit has
now; it does not wait for open runs. To gate a different commit, announce a new
release for it, or pass --build-sha <sha>, which sets or replaces the
release's build SHA first. When nothing changed since the current capture, no
new capture is added. The command exits with code 3 while the commit has no
test results yet. The REST equivalent is
POST /v1/releases/<releaseId>/quality-gate:capture with an optional
{"buildSha": "…"} body.
Check the result
Open Releases for the product. The new release shows its environment,
release time and its gate verdict, or
pending while its commit's test
runs are still to finish. The release page names where the verdict came from:
a build SHA, or a copy of main. Errors that telemetry reports with the same
version and environment appear on that release. To review a release before you promote it, see
Review release readiness.