cmd / deploy
deploy is a Go CLI that deploys services to Render
from the latest origin/main.
Run from any branch or git worktree:
go run ./cmd/deploy
It requires these environment variables (loaded from .env):
RENDER_API_KEYSENTRY_AUTH_TOKEN
Flow
- Fetch
origin/mainto get the latest merged commit. - Prompt to check Render status for incidents.
- For each service, compare the live deploy commit to
origin/main. If there are new commits, show the log and prompt to deploy. - Deploy selected services at
origin/main. - Wait for
app-jobsto reachliveso db migrations complete before deploying other services. - If anything deployed, create and tag a Sentry release.
Example session:
$ go run ./cmd/deploy
From https://github.com/org/repo
* 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...
Services
The script deploys multiple Render services:
app-jobs(migration gate)app-web
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
Sentry release (API, not CLI)
After deploying, the script calls Sentry's API:
- Create release (version = short SHA)
- Set release refs (
repository+ full SHA) - Record deploy for
production
This connects Sentry errors to the deploy that introduced them.
Design
The script uses origin/main. This makes it work from any git worktree and
ignores local main commits that haven't been pushed yet.
app-jobs is the migration gate: waiting for it to reach live confirms
its pre-deploy db migration step finished before other services.
Each service is deployed independently with a y/n prompt, so you can skip a service if it has unrelated changes or you want to deploy incrementally.