Every `just deploy` now takes a pg_dumpall to /opt/colectivo/backups/predeploy-<ts>-<sha>.sql.gz BEFORE rebuilding the app or applying migrations, aborts the deploy if the dump is < 1 KiB, and (on success) appends `<iso-ts> \t <sha> \t <backup-file>` to /opt/colectivo/.deploys.log on ambrosio. Keeps the newest 10 backups (prunes older predeploy-* files). New `infra/scripts/rollback-erosi.sh` reads .deploys.log and pairs a code rollback with a DB restore atomically: just rollback-list # show recent deploys just rollback # roll back to N-1 just rollback-to <sha> # roll back to a specific deploy just rollback-code # roll back code only, keep current DB Rollback safety: - 5-second abort window. - Verifies the target SHA exists locally + the backup is still on prod (warns if it's been pruned past the 10-deploy window). - Uses a temporary git worktree so the user's working tree isn't disturbed. - Stops app/auth/rest/realtime/storage before the gunzip|psql restore. - Rebuilds the app image at the rolled-back SHA with the same GIT_SHA build-arg path the deploy uses (so __APP_COMMIT__ in the bundle matches the running code). - Does NOT write a new .deploys.log entry — rollback is intentionally not a deploy event; the next `just deploy` is from current HEAD. - Storage volume (/var/lib/storage user uploads) is NOT rolled back. Justfile `deploy` recipe repointed from the stale `deploy.sh` (which referenced GHCR pull) to `deploy-erosi.sh` (the active prod path). New project-scoped skill: `.claude/skills/deploy/SKILL.md` documents the flow + safety boundaries for Claude-assisted invocations. `.gitignore` keeps `.claude/settings.local.json` ignored but tracks `.claude/skills/`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
77 lines
4.3 KiB
Markdown
77 lines
4.3 KiB
Markdown
---
|
|
name: deploy
|
|
description: Ship the colectivo stack to ambrosio (https://erosi.limonia.net) with pre-deploy DB backup, or roll back code + DB to a previous deploy. Trigger when the user asks to deploy, ship, push to prod, roll back, or undo a deploy.
|
|
---
|
|
|
|
# Deploy + rollback skill
|
|
|
|
Deploys and rollbacks for the production stack on ambrosio. **Every deploy takes a paired DB backup first**, every successful deploy is logged with `(timestamp, git-sha, backup-filename)`, and rollback uses that log to restore both code and DB atomically.
|
|
|
|
## Trigger
|
|
|
|
Use this skill when the user says any of:
|
|
- "deploy", "deploy to ambrosio", "deploy to prod", "ship it"
|
|
- "roll back", "rollback", "undo the deploy", "revert prod"
|
|
- "list deploys", "what was the last deploy"
|
|
|
|
## What the skill does
|
|
|
|
### Forward (deploy)
|
|
|
|
1. **`just deploy`** runs `infra/scripts/deploy-erosi.sh`:
|
|
- Captures the local short SHA (`git rev-parse --short HEAD`).
|
|
- rsyncs the working tree to `ambrosio:/opt/colectivo/` (excludes `.git`, `node_modules`, `**/.env`, etc.).
|
|
- On a fresh `.env`, generates secrets and bails — operator fills `PUBLIC_KEYCLOAK_URL` + `KEYCLOAK_CLIENT_SECRET` and re-runs.
|
|
- **Pre-deploy DB backup**: `pg_dumpall` from the prod `db` container → `backups/predeploy-<ts>-<sha>.sql.gz` on ambrosio. Aborts the deploy if the dump is < 1 KiB. Keeps the newest 10 backups.
|
|
- Rebuilds the `app` image with `GIT_SHA` build-arg (so `__APP_COMMIT__` lands in the bundle, Fase 14.3).
|
|
- `docker compose up -d` brings the stack to the new image.
|
|
- Applies any pending DB migrations.
|
|
- On success, appends `<iso-ts>\t<sha>\t<backup-file>` to `/opt/colectivo/.deploys.log`.
|
|
2. Site smoke: `curl -I https://erosi.limonia.net/` should return 200.
|
|
|
|
### Reverse (rollback)
|
|
|
|
1. **`just rollback-list`** prints recent rows from `.deploys.log` so the user can pick a target.
|
|
2. **`just rollback`** rolls back code + DB to the previous deploy (last but one line of `.deploys.log`).
|
|
3. **`just rollback-to <sha>`** rolls back to a specific deploy.
|
|
4. **`just rollback-code`** rolls back code only, leaves the DB at current state — useful when the regression is UI-only and the DB schema is compatible.
|
|
|
|
`infra/scripts/rollback-erosi.sh` enforces:
|
|
- Confirms with a 5-second abort window before doing anything destructive.
|
|
- Verifies the target SHA is reachable locally (`git cat-file -e`) and that the backup file still exists on ambrosio.
|
|
- Materialises the target commit into a temporary `git worktree`, rsyncs from there, never disturbs the user's working tree.
|
|
- Stops `app / auth / rest / realtime / storage` before the DB restore so they don't observe inconsistent state.
|
|
- `gunzip | psql -v ON_ERROR_STOP=1` restores the dump.
|
|
- Rebuilds the app image at the rolled-back SHA and brings the stack up.
|
|
- **Does not** write a new `.deploys.log` line — rollback is intentionally not a deploy event.
|
|
|
|
## Safety boundaries
|
|
|
|
- The stack lives on ambrosio. The external proxy + TLS terminator are off-stack (`docs/deployment.md`). Neither this skill nor the scripts ever touch host TLS or the external proxy.
|
|
- `infra/scripts/deploy-erosi.sh` never runs `sudo`.
|
|
- `--no-verify` / `--amend` are never used. Pre-commit hooks must pass.
|
|
- Always confirm with the user before invoking `just rollback*` — DB restore is destructive and irreversible.
|
|
- Storage volume (`/var/lib/storage`, user uploads) is **not** part of the rollback. Treated as append-only.
|
|
|
|
## What to tell the user
|
|
|
|
Before running anything:
|
|
- Show the local short SHA + branch + remote.
|
|
- For deploy: confirm with the user. Mention "this will take a fresh DB backup before deploying."
|
|
- For rollback: show `just rollback-list` output, ask which SHA, confirm destructive nature.
|
|
|
|
After running:
|
|
- Print the new `.deploys.log` tail (or the rollback target).
|
|
- Curl-probe the site and report.
|
|
|
|
## Files this skill touches
|
|
|
|
- `infra/scripts/deploy-erosi.sh` — deploy, with pre-deploy backup + .deploys.log writing.
|
|
- `infra/scripts/rollback-erosi.sh` — rollback, paired code + DB.
|
|
- `Justfile` — `deploy`, `rollback`, `rollback-list`, `rollback-to`, `rollback-code` recipes.
|
|
- `docs/deployment.md` — runbook for both flows.
|
|
|
|
## Anti-trigger
|
|
|
|
If the user is just asking *what would happen* on deploy (status, dry-run-style questions), DO NOT run anything. Answer from the script content.
|