Install
$ agentstack add skill-atelier-fashion-adlc-toolkit-canary ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
/canary — Canary Deployment with Smoke Tests
You are deploying code through a canary process: deploy a zero-traffic revision, verify it works, then promote to live traffic. This prevents broken deploys from reaching users.
Ethos
!sh .adlc/partials/ethos-include.sh 2>/dev/null || sh ~/.claude/skills/partials/ethos-include.sh
Context
- Current directory: !
pwd - Current branch: !
git branch --show-current 2>/dev/null || echo "Not a git repo" - GCP project: !
gcloud config get-value project 2>/dev/null || echo "No GCP project configured" - Active Cloud Run services: !
gcloud run services list --format="table(SERVICE,REGION,URL)" 2>/dev/null || echo "gcloud not configured"
Input
Target: $ARGUMENTS
Prerequisites
gcloudCLI must be authenticated and configured with the correct project- The service must already exist on Cloud Run (this skill deploys revisions, not new services)
- A Docker image must be available (either build locally or use the latest from Artifact Registry)
Service Resolution
Service configuration lives in .adlc/config.yml in the primary repo under a services: block, keyed by repo id. This is the single source of truth — no service names, regions, or image paths should be hardcoded in this skill.
Expected config shape (primary repo .adlc/config.yml):
repos:
api:
path: ../api
web:
path: ../web
services:
api:
cloud_run_service: api
region: us-central1
image_path: us-central1-docker.pkg.dev//api/api
web:
cloud_run_service: web
region: us-central1
image_path: us-central1-docker.pkg.dev//web/web
Resolution order:
- If
$ARGUMENTSis a repo id defined underrepos:in the primary's config, look upservices[]and use that. If the repo id has noservices:entry, stop and ask the user to add one. - If
$ARGUMENTSis a Cloud Run service name already (e.g., the user passedapiand it matchesservices.*.cloud_run_service), use that entry. - If no argument: detect which repo the current cwd is inside by walking up to find a git root and matching it against
repos[*].path(resolve each to an absolute path first). Then look up its service. - If the project has no
.adlc/config.yml(single-repo legacy setup) AND the current repo has a top-levelDockerfileand a single Cloud Run service name that matches the repo basename, fall back to auto-detection: service name = repo basename, region =us-central1, image path =$(gcloud config get-value project)/. Surface this fallback in the logs so the user knows it's being inferred. - If none of the above resolves, stop with a clear error: "Could not determine Cloud Run service. Add a
services:block to.adlc/config.ymlor pass the service name as an argument."
Operating worktree: if the resolved repo has a feature-branch worktree (e.g., .worktrees/REQ-xxx) that matches the current /proceed pipeline, build from inside that worktree. Otherwise build from the repo's main checkout. The caller can also pass the worktree path explicitly.
Note (post-REQ-380, REQ-381): /canary is no longer auto-invoked from /proceed (REQ-380) or /bugfix (REQ-381). Operators run it manually when a production canary is needed.
Instructions
Step 1: Build and Push Image
- Determine the image tag: use the current git SHA (
git rev-parse --short HEAD) - Build the Docker image:
``bash docker build -t :canary- ./ ``
- Push to Artifact Registry:
``bash docker push :canary- ``
If the user says "use latest" or the image was already built by CI, skip the build and use the :latest tag from Artifact Registry.
Step 2: Deploy Canary Revision (Zero Traffic)
Deploy a new revision that receives NO traffic:
gcloud run deploy \
--image=:canary- \
--region=us-central1 \
--no-traffic \
--tag=canary \
--format="json"
This creates a tagged revision accessible at https://canary----.a.run.app without affecting production traffic.
Capture the canary URL from the output.
Step 3: Health Checks
Run basic health checks against the canary URL:
- Liveness:
curl -s -o /dev/null -w "%{http_code}" /health
- Expected:
200 - Retry up to 3 times with 5-second intervals (cold start grace period)
- Readiness:
curl -s -o /dev/null -w "%{http_code}" /api/health
- Expected:
200(or the service's documented readiness endpoint)
If health checks fail after 3 retries, go to Step 6 (Rollback).
Step 4: Smoke Tests
Run smoke tests against the canary URL. Load test definitions from the primary repo's .adlc/context/smoke-tests.md if it exists, otherwise use defaults. In cross-repo mode the primary's smoke-tests.md is the authoritative source for every service — sibling repos do not need their own copy.
Default smoke tests (API services):
GET /health -> 200
GET /api/health -> 200
Custom smoke tests (from .adlc/context/smoke-tests.md): Each entry should specify: method, path, expected status, optional body pattern.
For each test:
RESPONSE=$(curl -s -w "\n%{http_code}" )
STATUS=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | head -n -1)
Report results:
## Smoke Test Results
| Test | Method | Path | Expected | Actual | Status |
|------|--------|------|----------|--------|--------|
| Health | GET | /health | 200 | 200 | PASS |
| API Health | GET | /api/health | 200 | 200 | PASS |
Result: 2/2 passed
If any test fails, go to Step 6 (Rollback).
Step 5: Promote to Production
All checks passed — promote the canary revision to 100% traffic:
gcloud run services update-traffic \
--region=us-central1 \
--to-tags=canary=100
Verify promotion:
gcloud run services describe \
--region=us-central1 \
--format="table(status.traffic[].percent,status.traffic[].revisionName,status.traffic[].tag)"
Confirm canary revision is now serving 100% traffic.
Remove the canary tag (clean up):
gcloud run services update-traffic \
--region=us-central1 \
--remove-tags=canary
Report:
Canary promoted to production.
Service:
Revision:
URL:
All smoke tests passed.
Step 6: Rollback (Failure Path)
If health checks or smoke tests fail:
- Delete the canary revision tag (so it's not addressable):
``bash gcloud run services update-traffic \ --region=us-central1 \ --remove-tags=canary ``
- Report the failure:
``` CANARY FAILED — rolled back. Service: Failed revision: canary-
Failures:
- [list failed health checks or smoke tests]
Production traffic is unchanged — still serving the previous revision. ```
- Suggest next steps:
- Check Cloud Run logs:
gcloud run services logs read --region=us-central1 --limit=50 - Investigate the failure locally
- Fix and re-run
/canary
Step 7: Update Pipeline State (if in /proceed context)
If pipeline-state.json exists for the current REQ:
- Add a
canaryentry tophaseHistorywith the result (passed/failed) - Include: service name, revision, smoke test results, canary URL
Smoke Test Configuration
To customize smoke tests, create .adlc/context/smoke-tests.md with this format:
# Smoke Tests
## api
| Method | Path | Expected Status | Body Pattern |
|--------|------|-----------------|--------------|
| GET | /health | 200 | |
| GET | /api/health | 200 | |
| GET | /api/v1/config | 200 | "version" |
## web
| Method | Path | Expected Status | Body Pattern |
|--------|------|-----------------|--------------|
| GET | / | 200 | |
| GET | /api/health | 200 | |
The keys above (api, web) are repo ids — the same ids you used under repos: in .adlc/config.yml. /canary looks up the smoke tests for the service it's deploying by matching repo id.
What This Skill Does NOT Do
- It does not create new Cloud Run services — the service must already exist
- It does not handle iOS deployments — TestFlight is already a canary-like process
- It does not modify CI/CD workflows — it's a manual deployment confidence tool
- It does not handle database migrations — run those separately before deploying
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: atelier-fashion
- Source: atelier-fashion/adlc-toolkit
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.