tane/site/DEPLOY.md
vjrj 11cbdf3022
All checks were successful
ci / test-commons-core (push) Successful in 56s
ci / analyze (push) Successful in 1m51s
site / deploy (push) Successful in 36s
ci / test-app-seeds (push) Successful in 7m10s
docs(site): document the automatic Forgejo Actions deploy
The manual Ansible playbook was superseded by the site.yml workflow,
which deploys on every push to main touching site/** or docs/**.
Keep Ansible documented only as the manual fallback.
2026-07-18 00:30:05 +02:00

5.2 KiB

Deploying the Tane landing site (tane.comunes.org)

Runbook for publishing changes to the landing page. Written so another agent (or a human) can reproduce it without prior context.

Architecture (what actually runs)

browser ── Cloudflare ── assange (nginx reverse proxy, TLS) ── groucho:8082 ── nginx container (static Hugo site)
  • The site source lives in this repo under site/ (Hugo). It is built into a static nginx image on the host — no Hugo on the control node, no registry.
  • site/ builds legal + about pages from docs/ (single source of truth) and serves screenshots generated by the Flutter golden harness.
  • Deploy is automatic: a Forgejo Actions workflow (.forgejo/workflows/site.yml) runs on every push to main that touches site/** or docs/**. It rsyncs site/ straight to groucho over SSH (runner and host share the internal subnet) and rebuilds the Hugo→nginx container — no Ansible run needed for routine content changes. The Ansible playbook below is now only for the one-time proxy/vhost setup and as a manual fallback (e.g. deploying uncommitted work from a worktree).
  • Two separate git repos are involved:
    • Tane repo (this one): the site/ source, docs, the screenshot harness, and the site deploy workflow.
    • Ansible repo: ~/proyectos/sync/comunes/shared-l2/ansible — the reverse-proxy vhost, and a manual-deploy fallback playbook.

One-time setup (already done; only if starting fresh)

cd ~/proyectos/sync/comunes/shared-l2/ansible
ansible-galaxy collection install -r collections/requirements.yml   # community.docker + ansible.posix
# Publish the vhost on the proxy (adds tane.comunes.org). NOT needed for content updates:
ansible-playbook -i comunes_inventory.ini proxies.yml --tags proxy-loop

DNS tane.comunes.org and the comunes.org TLS cert (must cover the subdomain) are already in place.

Routine deploy (the common case)

1. Regenerate derived content (only if you changed the sources)

Legal / About text (edited under docs/legal/**, docs/que-es-tane.md, docs/what-is-tane.md):

cd <tane-repo>/site && ./build-legal.sh          # regenerates content/legal/*.md + content/about.*.md

Screenshots (edited the harness or want fresh app shots):

cd <tane-repo>/apps/app_seeds
flutter test --update-goldens --run-skipped --tags screenshots test/screenshots/screenshots_test.dart
tool/collect_screenshots.sh                      # copies PNGs into site/assets/screenshots + fastlane

(The OG social cards site/static/og-*.png are regenerated by hand when the inventory shot changes — see the og-tpl.sh step in git history; optional.)

2. Commit & land on main

cd <tane-repo> && git add -A && git commit -m "..."
git -C ~/proyectos/dev/tane merge --ff-only <your-branch>   # land on main
git -C ~/proyectos/dev/tane push origin main

Pushing to main with changes under site/** or docs/** triggers the site Forgejo Actions workflow automatically — nothing else to run. Watch it at https://git.comunes.org/comunes/tane/actions (workflow name site), or trigger it manually via workflow_dispatch if a push didn't touch those paths.

3. Verify

curl -sI https://tane.comunes.org/ | head -1                 # 200
curl -s https://tane.comunes.org/es/about/ | grep -o '<title>[^<]*</title>'

Manual deploy fallback (Ansible)

Only needed if Forgejo Actions is down, the GROUCHO_DEPLOY_KEY secret is missing, or you want to push uncommitted work from a worktree:

cd ~/proyectos/sync/comunes/shared-l2/ansible
ansible-playbook -i comunes_inventory.ini tane-landing.yml \
  -e tane_site_src=/abs/path/to/worktree/site   # omit to use the main checkout

This rsyncs site/ to groucho:/data/tane-landing/src, rebuilds the Hugo→nginx image there, and recreates the container. proxies.yml does not need re-running for content changes.

Gotchas

  • Cloudflare + assange cache static assets ~16 days by stable URL. The screenshots and CSS are fingerprinted (… | fingerprint in the Hugo templates), so their URLs change with content and bust the cache automatically. Fixed-URL assets — og-*.png, favicon*, site.webmanifest, /logo.png — are NOT fingerprinted: if you change one, either purge Cloudflare or add a ?v=N. Symptom of a stale asset: curl <url> returns old bytes but curl <url>?v=1 returns the new ones, and the container file (docker exec tane-landing ls -l /usr/share/nginx/html/...) is already correct.
  • Screenshot golden test is skip-by-default (dart_test.yaml), so CI stays green; you must pass --run-skipped --tags screenshots to run/update it.
  • main can diverge (other sessions commit to it). If merge --ff-only fails, rebase your branch onto main first: git rebase main (site changes rarely conflict), then FF.
  • --check (dry-run) fails at the compose step ("/data/tane-landing is not a directory") because check mode doesn't create the synced dir — that's expected, not a real error; do a real run.
  • Container port is 8082 on groucho, bound 0.0.0.0 (firewall restricts it to assange). The proxy vhost lives in proxies.yml under citems (cert comunes.org).