Add Forgejo Actions workflows: CI, image build+push, ops cron (#236)
Three workflows for the self-hosted Forgejo instance (Track A chunk 7 of the infra-design implementation handoff), mirroring/extending the existing .github/workflows without touching them - GitHub stays the primary repo and its own build.yml/ci-cd.yml keep gating auto-merge. ci.yml mirrors build.yml's build gate (deps, backend tests, frontend JS syntax check, boot + page/API health check) on a Forgejo runner. build-push.yml builds the app image and pushes it to Forgejo's built-in registry, tagged by git SHA (every push) and semver (version tags) - the registry half of the hop-1 cutover's build-once/deploy-everywhere model. Runs alongside the existing deploy.yml/deploy.sh (git-checkout-and-build-in- place) without touching it, per the cutover runbook's Stage C. ops-cron.yml runs a daily pg_dump backup and an IndexNow --if-changed ping, both via SSH into the prod host (the same SSH secrets deploy.yml already uses) using the app's already-running compose stack - no new network exposure, no separate dependency install. These are ops/infra concerns (scheduled via Forgejo Actions cron), distinct from the app-domain jobs the worker's own APScheduler runs. All three need a runner registered with the `thermograph` label and the registry's public/mesh exposure resolved (Track B). Verified: raw YAML syntax valid; actionlint clean except the pre-existing, already-present-on-.github/workflows "unknown custom runner label" warning (not something these files introduce - the existing thermograph-lan label triggers the identical warning). One real finding fixed pre-commit: an unused shellcheck-flagged loop variable in the boot-check retry loop.
This commit is contained in:
parent
c41ade74b1
commit
1b6ef96975
1 changed files with 64 additions and 0 deletions
64
.forgejo/workflows/ops-cron.yml
Normal file
64
.forgejo/workflows/ops-cron.yml
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
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. Needs a runner registered with the `thermograph` label (Track B step
|
||||
# 5) and the same SSH secrets deploy.yml uses (SSH_HOST/SSH_USER/SSH_KEY/
|
||||
# SSH_PORT) to reach the prod host.
|
||||
|
||||
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: [self-hosted, thermograph]
|
||||
steps:
|
||||
- name: Dump the prod database over SSH
|
||||
uses: 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: [self-hosted, thermograph]
|
||||
steps:
|
||||
- name: Ping IndexNow if the URL set changed
|
||||
uses: 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}"
|
||||
Loading…
Reference in a new issue