docs: add deployment operation skills
Validate and deploy production / validate (push) Successful in 21s
Validate and deploy staging / validate (push) Successful in 24s
Validate and deploy production / deploy (push) Successful in 55s
Validate and deploy staging / deploy (push) Successful in 26s

This commit is contained in:
jb
2026-07-31 22:06:07 -04:00
parent 11406e3ec6
commit d98705cc9b
3 changed files with 90 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
---
name: deploy-production
description: Deploy SHD.build main to production through Gitea Actions and verify the live application. Use for a production release or a failed production deployment.
---
# Deploy Production
Production deploys from `main` through `Validate and deploy production`. The workflow builds the candidate while the current app remains online, stops only the SHD app and scheduler, creates a database backup, migrates, then health-checks the replacement.
## Workflow
1. Confirm that the commit passed `npm run check` and `npm run build`, then push it to `main` through `git@git.jb.codes:jb/shd.build.git`.
2. Open the Gitea production workflow for that commit. Confirm `validate` and `deploy` both succeed.
3. Verify `https://shd.build/api/health`. Confirm `ready` is true and the database check reports `ok`.
4. When host access is required, use `ssh f302` and inspect `/opt/shd-build-production` with its `.env.deploy` and `compose.production.yml` files. Confirm the app is healthy and the scheduler is running.
## Migration Failure
1. Open the failed `Deploy production` log and identify the failing statement and target schema state.
2. Do not patch the production database by hand. Fix the idempotent migration in source, validate it locally, commit it, and push a new commit.
3. The next workflow deployment creates a new production backup before it retries the migration. Confirm the recovery deployment reaches a healthy app state.
## Guardrails
- Do not use `docker compose down --volumes` or delete production volumes.
- Do not run a second manual deployment while a Gitea deployment is active.
- Routine deployment preserves production data. Use `replace-production-database` only with explicit approval for a full clone.
- Report the commit SHA, workflow result, production health response, and backup path from any migration attempt.
+24
View File
@@ -0,0 +1,24 @@
---
name: deploy-staging
description: Deploy SHD.build main to staging, inspect Gitea Actions results, and verify the staged application. Use for a staging release or a failed staging deployment.
---
# Deploy Staging
Push the intended commit to `main` over the configured SSH remote. The `Validate and deploy staging` workflow builds the image, creates a database backup, applies migrations, and starts the app and scheduler.
## Workflow
1. Inspect `git status`, the staged diff, recent commits, and the current branch. Do not commit generated caches such as Python `__pycache__` directories.
2. Run the relevant tests. Source changes require `npm run check` and `npm run build` before deployment.
3. Commit only the intended files, then push with `git push git@git.jb.codes:jb/shd.build.git main`.
4. Open Gitea Actions and inspect the workflow run for the pushed commit. Wait for both `validate` and `deploy` to succeed.
5. If the deploy job fails, open the failed step output. Do not retry a database migration without reading its error and checking the generated SQL against the target schema.
6. Verify `https://stage.shd.build/api/health` through the staging access layer or from the deployment host. Confirm the app container reports healthy and the scheduler runs.
## Guardrails
- The workflow owns the staging database lifecycle. Do not run `docker compose down --volumes`.
- A failed migration stops the application. Fix and test the migration, commit the repair, and push a new commit. The workflow creates another backup before retrying.
- Keep staging data intact during routine deployment. Use the explicit bootstrap or ISAC-import workflows for data replacement.
- Report the workflow run, commit SHA, health result, and any backup path printed by the deployment logs.
@@ -0,0 +1,38 @@
---
name: replace-production-database
description: Replace the populated SHD.build production database with a local full bootstrap bundle after verified backups. Use only when the user explicitly authorizes replacement of all production data.
---
# Replace Production Database
This procedure overwrites production users, sessions, builds, guides, audits, proposals, settings, and source data. Obtain explicit approval for a full replacement. Use the ISAC import flow when the request only concerns canonical game data.
## Export
1. Stop only this repository's local development server. The embedded database must be closed during export.
2. Run `npm run production:bootstrap:export`. Record the generated bundle beneath `data/backups/`; it includes private account data and uploaded assets.
3. Transfer the bundle to `f302` over SSH. Keep it outside Git and confirm the remote copy is nonempty.
## Replace
1. Confirm the current production deployment is healthy and no Gitea production deployment is running.
2. On `f302`, stop only the production `app` and `scheduler` services from `/opt/shd-build-production`.
3. Run `node scripts/db-backup.mjs` through the production Compose service. Record and retain the JSON backup path before any destructive work.
4. Reset the production database file and its embedded-database support files. Keep the persistent volume and existing upload directories; the import writes the local avatar and managed-image files without deleting retained files.
5. Run `node scripts/db-migrate.mjs` through the production Compose service to create the current empty schema.
6. Run `environment-bootstrap-import.mjs` with `ALLOW_PRODUCTION_BOOTSTRAP=true`, the copied bundle mounted read-only, `--target production`, and `--confirm-empty-target-replace`.
7. Start `app` and `scheduler`, wait for app health, then remove the remote transfer bundle.
## Verify
1. Confirm the importer reports the expected row, avatar, and managed-image counts.
2. Confirm `https://shd.build/api/health` returns `ready: true` with an `ok` database check.
3. Confirm the production app container is healthy and its scheduler is running.
4. Restart the local development server and verify it accepts an HTTP request.
## Guardrails
- Never replace a populated production database without explicit user approval.
- Never delete the production Compose volume.
- Do not replace the database while the app or scheduler can write to it.
- Keep the verified pre-replacement backup. It is the recovery source if the import or restart fails.