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>
4.3 KiB
4.3 KiB
name, description
| name | description |
|---|---|
| deploy | 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)
just deployrunsinfra/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 fillsPUBLIC_KEYCLOAK_URL+KEYCLOAK_CLIENT_SECRETand re-runs. - Pre-deploy DB backup:
pg_dumpallfrom the proddbcontainer →backups/predeploy-<ts>-<sha>.sql.gzon ambrosio. Aborts the deploy if the dump is < 1 KiB. Keeps the newest 10 backups. - Rebuilds the
appimage withGIT_SHAbuild-arg (so__APP_COMMIT__lands in the bundle, Fase 14.3). docker compose up -dbrings 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.
- Captures the local short SHA (
- Site smoke:
curl -I https://erosi.limonia.net/should return 200.
Reverse (rollback)
just rollback-listprints recent rows from.deploys.logso the user can pick a target.just rollbackrolls back code + DB to the previous deploy (last but one line of.deploys.log).just rollback-to <sha>rolls back to a specific deploy.just rollback-coderolls 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 / storagebefore the DB restore so they don't observe inconsistent state. gunzip | psql -v ON_ERROR_STOP=1restores the dump.- Rebuilds the app image at the rolled-back SHA and brings the stack up.
- Does not write a new
.deploys.logline — 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.shnever runssudo.--no-verify/--amendare 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-listoutput, ask which SHA, confirm destructive nature.
After running:
- Print the new
.deploys.logtail (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-coderecipes.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.