From d98705cc9bfb9b9b325c88ae68e8fbe371885f89 Mon Sep 17 00:00:00 2001 From: JB Date: Fri, 31 Jul 2026 22:06:07 -0400 Subject: [PATCH] docs: add deployment operation skills --- .agents/skills/deploy-production/SKILL.md | 28 ++++++++++++++ .agents/skills/deploy-staging/SKILL.md | 24 ++++++++++++ .../replace-production-database/SKILL.md | 38 +++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 .agents/skills/deploy-production/SKILL.md create mode 100644 .agents/skills/deploy-staging/SKILL.md create mode 100644 .agents/skills/replace-production-database/SKILL.md diff --git a/.agents/skills/deploy-production/SKILL.md b/.agents/skills/deploy-production/SKILL.md new file mode 100644 index 0000000..338869a --- /dev/null +++ b/.agents/skills/deploy-production/SKILL.md @@ -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. diff --git a/.agents/skills/deploy-staging/SKILL.md b/.agents/skills/deploy-staging/SKILL.md new file mode 100644 index 0000000..3ab4bca --- /dev/null +++ b/.agents/skills/deploy-staging/SKILL.md @@ -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. diff --git a/.agents/skills/replace-production-database/SKILL.md b/.agents/skills/replace-production-database/SKILL.md new file mode 100644 index 0000000..b84c984 --- /dev/null +++ b/.agents/skills/replace-production-database/SKILL.md @@ -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.