GitLab and Other CI
Trigger Certyn runs from GitLab CI and other pipelines with the CI Runs API.
Use the CI Runs API for GitLab CI, Jenkins, CircleCI, Azure DevOps, Bitbucket Pipelines, Buildkite, or any runner that can execute shell commands.
The gate has three steps:
Create a CI run
POST to /api/ci/runs with projectSlug, environmentKey, and either processSlug or tags.
Poll status
GET /api/ci/runs/{runId} until the run reaches completed or cancelled.
Fail the job when needed
Exit non-zero when failed > 0 or blocked > 0.
GitLab CI
Store CERTYN_API_KEY as a protected GitLab CI/CD variable.
stages:
- test
certyn-smoke:
stage: test
script:
- |
set -euo pipefail
body=$(jq -nc \
--arg project "$CERTYN_PROJECT_SLUG" \
--arg environment "$CERTYN_ENVIRONMENT_KEY" \
--arg repository "$CI_PROJECT_PATH" \
--arg ref "$CI_COMMIT_REF_NAME" \
--arg sha "$CI_COMMIT_SHA" \
--arg url "$CI_PIPELINE_URL" \
'{projectSlug:$project,environmentKey:$environment,processSlug:"smoke-suite",repository:$repository,ref:$ref,commitSha:$sha,event:"pipeline",externalUrl:$url}')
response=$(curl -sS -X POST "$CERTYN_API_URL/api/ci/runs" \
-H "Content-Type: application/json" \
-H "X-API-Key: $CERTYN_API_KEY" \
-H "Idempotency-Key: $CI_PIPELINE_ID-$CI_JOB_ID" \
-d "$body")
run_id=$(echo "$response" | jq -r '.runId')
for i in $(seq 1 60); do
status=$(curl -sS -H "X-API-Key: $CERTYN_API_KEY" "$CERTYN_API_URL/api/ci/runs/$run_id")
state=$(echo "$status" | jq -r '.state')
failed=$(echo "$status" | jq -r '.failed')
blocked=$(echo "$status" | jq -r '.blocked')
interval=$(echo "$status" | jq -r '.retryAfterSeconds // 15')
app_url=$(echo "$status" | jq -r '.appUrl // empty')
echo "state=$state failed=$failed blocked=$blocked appUrl=$app_url"
if [ "$state" = "completed" ] || [ "$state" = "cancelled" ]; then
[ "$failed" = "0" ] && [ "$blocked" = "0" ]
exit $?
fi
sleep "$interval"
done
echo "Timed out waiting for Certyn run"
exit 1
variables:
CERTYN_API_URL: https://api.certyn.io
CERTYN_PROJECT_SLUG: my-app
CERTYN_ENVIRONMENT_KEY: staging
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH == "main"'
Generic Shell Step
This example works for most CI systems with curl and jq available.
set -euo pipefail
CERTYN_API_URL="${CERTYN_API_URL:-https://api.certyn.io}"
CERTYN_PROJECT_SLUG="${CERTYN_PROJECT_SLUG:-my-app}"
CERTYN_ENVIRONMENT_KEY="${CERTYN_ENVIRONMENT_KEY:-staging}"
body=$(jq -nc \
--arg project "$CERTYN_PROJECT_SLUG" \
--arg environment "$CERTYN_ENVIRONMENT_KEY" \
'{projectSlug:$project,environmentKey:$environment,processSlug:"smoke-suite",event:"pipeline"}')
response=$(curl -sS -X POST "$CERTYN_API_URL/api/ci/runs" \
-H "Content-Type: application/json" \
-H "X-API-Key: $CERTYN_API_KEY" \
-H "Idempotency-Key: $CI_JOB_ID" \
-d "$body")
run_id=$(echo "$response" | jq -r '.runId')
for i in $(seq 1 60); do
status=$(curl -sS -H "X-API-Key: $CERTYN_API_KEY" "$CERTYN_API_URL/api/ci/runs/$run_id")
state=$(echo "$status" | jq -r '.state')
failed=$(echo "$status" | jq -r '.failed')
blocked=$(echo "$status" | jq -r '.blocked')
interval=$(echo "$status" | jq -r '.retryAfterSeconds // 15')
if [ "$state" = "completed" ] || [ "$state" = "cancelled" ]; then
[ "$failed" = "0" ] && [ "$blocked" = "0" ]
exit $?
fi
sleep "$interval"
done
exit 1
Notes
- Use
Idempotency-Keyso CI retries do not create duplicate Certyn runs. - Use
processSlugfor a known suite such assmoke-suite. - Use
tagsinstead ofprocessSlugwhen a pipeline should select tests dynamically. - See CI Runs API for the full request and status schema.