promote master → production: shadow-canary 0.5.0 - #19
Merged
Merged
Conversation
Vercel Deployment Protection intercepts raw *.vercel.app deploy URLs with HTTP 401 "Authentication Required" by default. The SLO check in canary-ramp.yml has to curl the raw prod deploy URL (we need per-deployment routing for the canary model — a production alias would point at exactly one version at a time), so without a bypass every check fails and the workflow rolls back the canary to 0% every 15 min. Observed before this fix: SLO check 1 → HTTP 401 :: <!doctype html>...<title>Authentication Required SLO check 2 → HTTP 401 :: ... → ok=0 → rollback to 0% Fix: - Read VERCEL_AUTOMATION_BYPASS_SECRET from repo secrets (already set via `gh secret set`). - When the secret is present, send `x-vercel-protection-bypass: <SECRET>` on the SLO curl. This is the official Vercel bypass mechanism, documented at https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection. - Fall through cleanly (no header) when the secret is unset, so projects that disable protection aren't forced to set a dummy secret. Verified manually: same URL that returned 401 now returns 200 with `{"ok":true,"deployment":"...","commit":"4474bd7","branch":"production"}`. Note: this patch is local to Stargaze. The same issue affects any project that uses @dotworld/shadow-canary-templates workflows with Vercel Deployment Protection enabled — worth upstreaming into the templates package so new adopters don't hit the silent-rollback trap. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…bypass fix(canary): send Vercel Deployment Protection bypass on SLO check
The "Record SLO check in Edge Config (ring buffer, last 10)" step injects
step outputs into the shell script via ${{ steps.slo.outputs.body_excerpt }},
which GitHub Actions substitutes as raw text (not shell-escaped). The body
excerpt starts with `{"ok":true,...` — those embedded `"` characters break
the surrounding "…" shell string and the script fails to parse:
/home/runner/work/_temp/....sh: line 34: unexpected EOF while looking for
matching `"'
##[error]Process completed with exit code 2.
Observed on the first run after enabling the Vercel bypass (run 24879157669):
SLO check itself returned 200, bump landed, ring-buffer record step crashed.
Fix: pass step outputs through the step's `env` block instead of ${{ }}
substitution. GitHub properly escapes env values, so `$SLO_BODY_EXCERPT`
stays intact regardless of its content. Also fixes the symmetric (latent)
issue on code1/code2/pct even though those currently hold digits only —
safer to keep them all on the same path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fix(canary): escape JSON body in SLO record step via env
Bumps @dotworld/shadow-canary-core from 0.4.0 to 0.5.0.
New in this release:
- /api/admin/shadow-history — returns last 20 shadow deploys with
sha/ref/message/time (fetched on-demand
from the Vercel API, not stored inline)
- Admin UI "Shadow deploys récents" scrollable list, each row with a
Rollback button. Current shadow gets a "current" badge.
- Admin MANUEL section: configurable step input (1-50). Buttons relabel to
-N% / +N% live as the input changes.
- deploy-shadow.yml now prepends the outgoing shadow URL to a shadowHistory
ring buffer (max 20, deduped), replacing the single-slot
deploymentDomainShadowPrevious field. The old field is still written
(points at shadowHistory[0]) so a v0.4.x admin UI mid-deploy does not
break.
- Ring-buffer SLO body_excerpt trim bumped 80 to 500 chars so failures show
the full JSON / truncated stack.
Local patches re-applied on top of the templates copy:
- Vercel Deployment Protection bypass on the SLO curl (VERCEL_AUTOMATION_BYPASS_SECRET).
- SLO-ring-buffer step outputs passed through env block to avoid shell quote
injection on JSON body_excerpt. Both were merged as PR #16 and #17 on
v0.4.x; neither is upstream in shadow-canary-templates@0.5.0 yet.
Upstream manifest note: shadow-canary-templates@0.5.0 still ships a
manifest.json that reports version 0.2.1 and omits 3 files from the copy
list (bucket-info, rollback-shadow, shadow-history). Copied those manually
from the package's files/ directory. Same workaround as the 0.4.0 bump.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chore(shadow-canary): bump to 0.5.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promotes `master` to `production` to ship the `@dotworld/shadow-canary-core` 0.5.0 upgrade (PR #18).
What ships
No breaking changes — Edge Config key unchanged, middleware contract unchanged, `/api/slo` unchanged. Normal canary ramp is safe.
After merge
Test plan
🤖 Generated with Claude Code