thermograph/.forgejo/workflows/ops-cron.yml
Emi Griffith 9be4d495e4 Reconcile Forgejo workflows with the real infrastructure now in place (#238)
The Swarm/Forgejo standup (a parallel infra track, see INFRA.md) landed real
.forgejo/workflows/{build,pr-build,deploy,deploy-dev}.yml before this PR
merged, making ci.yml a redundant duplicate of their build.yml (same build
gate, same job). Drop it.

Fix the remaining two files to match the real, already-deployed conventions
those files established rather than the guesses this PR shipped with:
runs-on: [self-hosted, thermograph] -> docker (the actual Docker-in-Docker
Swarm-hosted runner label), and appleboy/ssh-action referenced by full GitHub
URL (confirmed not mirrored on this Forgejo instance's default action
registry, per deploy.yml's own header comment) rather than the short form.
actions/checkout needed no change - already confirmed to resolve unchanged
from Forgejo's default mirror.

build-push.yml (image registry push) and ops-cron.yml (backup + IndexNow)
stay: neither duplicates anything in the real mirror, which faithfully
replicates the OLD git-checkout-and-build-in-place deploy model rather than
the registry-based one, and has no scheduled ops jobs at all.
2026-07-21 01:08:09 +00:00

67 lines
2.7 KiB
YAML

name: Ops cron (backup + IndexNow)
# Scheduled operational jobs that don't belong in the app's own worker-tier
# scheduler (notifications/scheduler.py, Track A chunk 5) because they're
# infra/ops concerns rather than app-domain background work -- see the job
# classification table in
# docs/architecture/repo-topology-and-infrastructure.md §7.
#
# Both jobs SSH into the prod host and run inside the already-running compose
# stack (docker compose exec), the same way deploy.sh already runs its own
# post-deploy IndexNow ping -- no new network exposure, no separate dependency
# install. Runs on the `docker` label (the always-on Swarm-hosted runner
# deploy/forgejo/ stood up) and reuses the same SSH secrets deploy.yml already
# has (SSH_HOST/SSH_USER/SSH_KEY/SSH_PORT) -- inherits, and will automatically
# benefit from a fix to, deploy.yml's own flagged branch/host mismatch (that
# workflow's header comment: it still targets `main`, while
# terraform.tfvars.example names prod's branch `release`).
on:
schedule:
# 03:00 UTC daily -- a low-traffic window for both jobs.
- cron: '0 3 * * *'
workflow_dispatch: {}
jobs:
backup:
name: pg_dump backup
runs-on: docker
steps:
- name: Dump the prod database over SSH
uses: https://github.com/appleboy/ssh-action@v1.2.0
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT }}
script: |
set -euo pipefail
cd /opt/thermograph
backup_dir="$HOME/thermograph-backups"
mkdir -p "$backup_dir"
stamp="$(date -u +%Y%m%dT%H%M%SZ)"
out="$backup_dir/thermograph-$stamp.dump"
docker compose exec -T db pg_dump -U thermograph -d thermograph \
--format=custom > "$out"
echo "wrote $out ($(du -h "$out" | cut -f1))"
# The dumps are the disaster-recovery copy, not a versioned
# archive -- keep the last 14 days and let the rest age out.
find "$backup_dir" -name 'thermograph-*.dump' -mtime +14 -delete
indexnow:
name: IndexNow ping
runs-on: docker
steps:
- name: Ping IndexNow if the URL set changed
uses: https://github.com/appleboy/ssh-action@v1.2.0
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT }}
script: |
set -euo pipefail
cd /opt/thermograph
set -a; . /etc/thermograph.env 2>/dev/null || true; set +a
docker compose exec -T app python indexnow.py --if-changed \
"${THERMOGRAPH_BASE_URL:-https://thermograph.org}"