ci: remove GitHub mirror workflows and dead Gitea manual workflows

Gitea (git.copse.top) is the only CI/CD control plane; GitHub is a
read-only mirror whose Actions are being disabled in repository settings.

- Delete all 11 `.github/workflows/*.yml` (stale copies of the old design).
- Delete unused Gitea manual workflows `ci.yml`, `test.yml`,
  `publish-pypi.yml`, `apply-supabase-profile-migrations.yml`
  (0-1 historical runs, no remaining target).
- Fold the full `python -m pytest` tree and `tests/run_all.py` into
  `release-quality-gate.yml`, which previously only ran the curated
  release profile; update the `run_quality_gate.py` comment accordingly.
- Port `reset-staging-account.yml` to Gitea: `runs-on: xiaoxin`, bounded
  exact-SHA checkout, `refs/heads/staging` only, `staging-mutation`
  concurrency, same email/confirmation/host/port/user/path assertions.
- Repoint frontend workflow tests at `.gitea/workflows/`, drop the
  GitHub-only assertions, add coverage for the new reset workflow, and
  remove `tests/test_supabase_profile_migration_workflow.py`.
- Update AGENTS.md §6.8, README.md, and deploy/README.md to the current
  production/mirror facts and document the staging account reset.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VawU7Xfd5jS9wUEXz1XYmS
This commit is contained in:
Jesse_Chen
2026-09-02 04:02:04 +00:00
co-authored by Claude Fable 5.1
parent 1a3e14e726
commit fb69e43c90
25 changed files with 208 additions and 1586 deletions
+7 -3
View File
@@ -8,14 +8,14 @@ This file is the operational source of truth for Jyotisha deployment. The produc
| --- | --- |
| Public domain | `https://jyotisha.chat` |
| DNS | Spaceship nameservers (`launch1.spaceship.net`, `launch2.spaceship.net`) |
| Current public host | Old VPS; keep as a rollback asset until reconciliation completes |
| Current public host | `118.194.235.34`; production health reports the local business/identity PostgreSQL databases. The old VPS `103.117.123.53` is no longer a deployment target |
| Target host | `118.194.235.34`, Ubuntu x86_64 |
| Target SSH | dedicated `deploy` user, confirmed variable port, public-key authentication only |
| Target capacity | 2 vCPU / 4 GB RAM; no application builds on host |
| Target app directory | `/opt/jyotisha-production` |
| Target environment files | `.env.production` and `.env.production.database` (`0600`) |
| Primary source repository | `https://git.copse.top/root/Jyotisha.git` |
| GitHub upstream/mirror | `https://github.com/jesse-ux/Jyotisha.git` |
| GitHub mirror | `https://github.com/jesse-ux/Jyotisha.git` (read-only mirror; no workflows, Actions disabled) |
| Migration source | Supabase project `vtvnfqmonbfuxmqkqdlc` + Supabase Auth |
| Migration target | private PostgreSQL 17 + Better Auth |
@@ -159,7 +159,7 @@ Staging is isolated from production:
| Identity | Better Auth + Resend OTP on the same private PostgreSQL cluster |
| Actions control plane | Gitea 1.26.2 (`git.copse.top`) |
Gitea is the primary source repository and Actions control plane. Gitea automatically injects the per-job `${{ secrets.GITEA_TOKEN }}` token; its access is limited by each workflow's `permissions` block and it must not be configured as a repository secret. Configure repository Actions secrets `REGISTRY_USERNAME`, `REGISTRY_PASSWORD`, and `STAGING_SSH_PRIVATE_KEY`, plus variables `STAGING_HOST`, `STAGING_PORT`, `STAGING_USER`, `STAGING_PATH`, `STAGING_URL`, and `STAGING_KNOWN_HOSTS`. `STAGING_SSH_PRIVATE_KEY` must be the private-key file encoded as one unwrapped base64 line (for example, `base64 < key | tr -d '\n'`), not a multiline PEM/OpenSSH value; staging workflows decode it only into a mode-`0600` temporary file and validate it with `ssh-keygen`. Staging is an independent test line and is not required to equal or remain inside `main` history. A push to `staging` runs the exact-SHA quality gate; its publish job creates immutable API/web image digests plus an allowlisted controller bundle from that same staging SHA, then explicitly dispatches `Deploy staging` from `refs/heads/staging`. The deploy workflow validates the source gate run, consumes only that gate-attested artifact, rejects stale normal releases, and never checks out or executes an untested branch controller. The staging key, database, Resend key, and model-provider keys must not be shared with production. Staging image publishing has no Supabase build variables. GitHub workflows are upstream/mirror fallback only, not the normal staging release path.
Gitea is the primary source repository and Actions control plane. Gitea automatically injects the per-job `${{ secrets.GITEA_TOKEN }}` token; its access is limited by each workflow's `permissions` block and it must not be configured as a repository secret. Configure repository Actions secrets `REGISTRY_USERNAME`, `REGISTRY_PASSWORD`, and `STAGING_SSH_PRIVATE_KEY`, plus variables `STAGING_HOST`, `STAGING_PORT`, `STAGING_USER`, `STAGING_PATH`, `STAGING_URL`, and `STAGING_KNOWN_HOSTS`. `STAGING_SSH_PRIVATE_KEY` must be the private-key file encoded as one unwrapped base64 line (for example, `base64 < key | tr -d '\n'`), not a multiline PEM/OpenSSH value; staging workflows decode it only into a mode-`0600` temporary file and validate it with `ssh-keygen`. Staging is an independent test line and is not required to equal or remain inside `main` history. A push to `staging` runs the exact-SHA quality gate; its publish job creates immutable API/web image digests plus an allowlisted controller bundle from that same staging SHA, then explicitly dispatches `Deploy staging` from `refs/heads/staging`. The deploy workflow validates the source gate run, consumes only that gate-attested artifact, rejects stale normal releases, and never checks out or executes an untested branch controller. The staging key, database, Resend key, and model-provider keys must not be shared with production. Staging image publishing has no Supabase build variables. GitHub is a read-only mirror with no workflow files and Actions disabled; every staging and production workflow runs only in Gitea.
`Independent Staging Quality Gate` runs for relevant `pull_request` paths, pushes to `staging`, and `workflow_dispatch`. It validates the Python/database/frontend contract; only a successful push to `staging` publishes the API/web images and a run-bound artifact containing their `sha256` digests plus the allowlisted controller bundle. The publish job rechecks the current staging head and dispatches `.gitea/workflows/deploy-staging.yml` from `refs/heads/staging` with the exact SHA and source gate run ID. The deploy workflow waits for that gate's success, validates the artifact against the full 40-character commit, and deploys digest references rather than trusting discoverability tags.
@@ -196,6 +196,10 @@ After source sync and before `up`, the workflow validates `.env.staging` mode/se
6. If the read-only checker reports a pending migration, stop app deployment and run `Migrate Staging Database` manually using **Use workflow from: staging** with the same full SHA. Migration success does not dispatch deployment.
7. After migration succeeds, manually start `Deploy staging` from `staging` with that same exact SHA and `allow_rollback=false`, then confirm `https://staging.jyotisha.chat/api/health` reports it and private API health.
### Resetting one staging account
`.gitea/workflows/reset-staging-account.yml` (`Reset Staging Account (manual only)`) wipes the onboarding profile, chat sessions, chart profiles, and synastry reports of exactly one staging account while preserving its identity rows, credits, and ledgers. Dispatch it from **Use workflow from: staging** with `expected_deploy_sha` equal to the SHA currently reported by `https://staging.jyotisha.chat/api/health`, `email` set to the exact account address, and `confirmation` typed as `RESET <email>`. It shares the `staging-mutation` concurrency group and the on-host `mutation.lock` with deploy and migration, refuses to run unless the deployed revision matches `expected_deploy_sha`, and pipes `deploy/reset-staging-account.sh` to the staging host over the same pinned `STAGING_SSH_PRIVATE_KEY` / `STAGING_KNOWN_HOSTS` channel. It never touches production variables or hosts.
Application rollback uses the same workflow: manually dispatch `Deploy staging` using **Use workflow from: staging** with a previous known-good full SHA that has a successful `Independent Staging Quality Gate` push run, leave `gate_run_id` empty, and explicitly set `allow_rollback=true`. The requested SHA must be an ancestor of the current `staging` head. Normal deployments reject stale or divergent revisions. Rollback still consumes the selected gate run's digest and controller artifact and is supported only during that artifact's 30-day retention window; after expiry, stop and prepare a separately reviewed republish/recovery change rather than substituting a mutable tag or assuming the old run can still be rerun. Database migrations are separate and are not rolled back by an application deployment. Restore a staging database backup before running any destructive migration rehearsal.
Inspect staging without printing secrets: