cmd / deploy
deploy is a Go CLI that deploys services to Render
from the latest origin/main.
Run it:
go run ./cmd/deploy
It reads these environment variables from .env:
RENDER_API_KEY
Flow
- Fetch
origin/mainmerged by sockeye. - Compare each service's live commit to
origin/main. - If new commits exist, show the log and prompt to deploy.
- Deploy the selected services at
origin/main. - Wait for
app-jobsto reachliveso its migration finishes beforeapp-web. - Record each service in sockeye as it reaches
live.
Example session:
$ go run ./cmd/deploy
From https://sockeye.example.com/git/app
* branch main -> FETCH_HEAD
Check https://status.render.com/ for incidents before continuing.
Press any key to continue or ctrl+c to exit...
```
a1b2c3d4e fix session expiry on token refresh
f5e6d7c8b add retry logic to webhook delivery
```
deploy app-jobs? (y/n) y
deploying app-jobs...
waiting for app-jobs deploy dep-abc123 to go live...
app-jobs live
skipping app-web, already up to date...
Render API client
The render package (render/client.go) wraps these endpoints:
GET /services/:id/deploys?limit=5: find the live deploy's commit SHAPOST /services/:id/deploys: trigger a deploy at a specific commitGET /services/:id/deploys/:deployID: poll deploy status untillive
WaitForDeploy polls every 10s with a 30 minute timeout. Any terminal
state other than live is an error. A failed migration appears as
pre_deploy_failed.
Recording the deploy
The script POSTs a record to sockeye as
each service reaches live. A failure partway through still records what
shipped.
The script holds no sockeye token. It asks git for the token that
soc login stored for the host:
in := "protocol=https\nhost=sockeye.example.com\n\n"
c := exec.Command("git", "credential", "fill")
c.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0")
The script retrieves the token first, so a missing token halts the deploy before any service deploys without a record. Recording deploys connects errors to the release SHA that introduced them.
Design
The script reads origin/main, so it runs from any branch or
git worktree. If I skip
app-jobs, the script warns that subsequent services may run against an
older schema. Each service prompts individually, allowing partial
deploys.