docs: record workflow split between Gitea Actions and GitHub Pages
CI / Typecheck, test, feed (push) Successful in 12s
CI / Build site (push) Successful in 8s
CI / Container image (push) Successful in 30s

Update README, AGENTS.md, ARCHITECTURE.md, and INGESTION.md to reflect
that the scheduled refresh and container image publishing run on Gitea
Actions under .gitea/workflows/, while GitHub Actions under .github/
builds with BASE_PATH and deploys to GitHub Pages when synced.
This commit is contained in:
Lucas Winther committed 2026-09-17 09:59:41 +02:00
1 parent 0826f24db9
commit 0d1ccff6b2
4 files changed
+20 -19

No files matched your search

+1 -1
View File
@@ -40,7 +40,7 @@ progress on events that repeat daily, and lets a user mark events completed.
**Status: working app, refreshing itself on a schedule.** Schema, ten parsers, twenty-two sources across
twenty games, the full interface, offline support, a static server, a Docker image and CI all exist and
are tested. The refresh runner (`bun run refresh`) fetches, caches raw snapshots and rebuilds the
feed; `.github/workflows/refresh.yml` runs it twice a day and commits only when a page actually
feed; `.gitea/workflows/refresh.yml` runs it twice a day and commits only when a page actually
changed. The SQLite layer and the review queue are still specified in `docs/` but not built, so the
feed is a static JSON file built from snapshots, falling back to checked-in fixtures.
+12 -11
View File
@@ -339,20 +339,21 @@ Blank issues are still open for anything that fits neither form. The templates t
## CI
Both `.github/workflows/ci.yml` and `.gitlab-ci.yml` run the same gates on every push — typecheck,
tests, and a feed sanity check — then build and publish a container image from the default branch.
Both `.gitea/workflows/ci.yml`, `.github/workflows/ci.yml`, and `.gitlab-ci.yml` run the same gates on every push — typecheck,
tests, and a feed sanity check.
The workflows run on **Gitea Actions**, not GitHub's. They stay under `.github/workflows/` because
Gitea reads that directory natively, and because `test/refresh.test.ts` asserts on those two files by
path — three defects that live in YAML and fail silently otherwise. Two consequences worth knowing
before editing them:
- **On Gitea Actions** (`.gitea/workflows/ci.yml`): The default branch builds and publishes a container image to Gitea's package registry.
- **On GitHub Actions** (`.github/workflows/ci.yml`): Pushes to `main` (such as commits mirrored from Gitea) build the static site with `BASE_PATH` and deploy it to GitHub Pages.
Two consequences worth knowing for Gitea Actions:
- **`uses:` steps are written as full URLs** (`https://github.com/actions/checkout@v4`). A bare
`actions/checkout@v4` resolves against the instance's `DEFAULT_ACTIONS_URL`, which is configuration
we do not control from here. The runner needs outbound access to github.com to fetch them.
- **The image is the deploy artefact.** There is no `pages` job: Gitea has no Pages equivalent, so
the container image published to Gitea's registry is what gets deployed. `bun run build` therefore
runs without `BASE_PATH` — the image serves from `/`.
- **The image is Gitea's deploy artefact.** There is no Pages equivalent on Gitea, so the container
image published to Gitea's registry is what gets deployed. `bun run build` in `.gitea/workflows/ci.yml`
and Dockerfile therefore runs without `BASE_PATH` — the image serves from `/`. On GitHub, `.github/workflows/ci.yml`
builds with `BASE_PATH` and deploys to GitHub Pages.
The image lands at `gitea.lucaswinther.info/lucasw89/gacha-event-tracker`, tagged `latest` and with
the commit SHA. The registry host is derived from `github.server_url` rather than hardcoded, so a
@@ -387,8 +388,8 @@ pipeline always means the code changed rather than a wiki being down.
### Refreshing the data
Gitea Actions only — the GitLab pipeline still runs the gates, but nothing there fetches.
`.github/workflows/refresh.yml` runs `bun run refresh` twice a day (and on demand, with a dry-run
Gitea Actions only — the GitLab and GitHub pipelines run the gates / builds, but do not fetch wikis.
`.gitea/workflows/refresh.yml` runs `bun run refresh` twice a day (and on demand, with a dry-run
input). It fetches each source at most once per cycle, and **commits only when a page's bytes
actually changed** — a `304`, an identical body, or a fetch that fails to parse all leave the
working tree clean and produce no commit. When something did change it commits the raw snapshots and
+6 -6
View File
@@ -215,7 +215,7 @@ changing. Reads are confined to `public/` by resolving the path and checking it
string looks like.
`scripts/refresh-sources.ts` (`bun run refresh`) is what fills `snapshots/`, and it is the only code
here that touches the network. `.github/workflows/refresh.yml` runs it at 05:27 and 17:27 UTC and
here that touches the network. `.gitea/workflows/refresh.yml` runs it at 05:27 and 17:27 UTC and
commits only when a page actually changed. It stands in for the unbuilt scheduler and enforces the
same conduct in code — the 6h floor, one request, no retries, conditional headers, per-host spacing,
robots failing closed. A source that has failed `BROKEN_AFTER_FAILURES` (3) cycles running is
@@ -223,17 +223,17 @@ reported as `broken` and fails the run *after* the commit; see `AGENTS.md` § Sc
that ordering is load-bearing.
`Dockerfile` builds and serves this; the image runs typecheck and tests during build, ships no source
or toolchain, and runs unprivileged. `.github/workflows/ci.yml` and `.gitlab-ci.yml` run the same
gates and publish it.
or toolchain, and runs unprivileged. `.gitea/workflows/ci.yml` and `.gitlab-ci.yml` run the same
gates and publish it, while `.github/workflows/ci.yml` builds and deploys to GitHub Pages.
### Hosting under a subpath
Assets resolve against a `<base href>` substituted at build time, the feed URL resolves against
`document.baseURI` so deep links work, and the service worker derives its paths from its own
registration scope. `BASE_PATH=/gacha-event-tracker/ bun run build` for any host that serves the app
from a subpath; without it a subpath deploy 404s on every asset. CI no longer sets it — the container
image is what gets deployed and `serve.ts` serves from `/` — but the mechanism stays, because a
subpath deploy is a hosting decision rather than a build one.
from a subpath (such as GitHub Pages); without it a subpath deploy 404s on every asset. GitHub's
`.github/workflows/ci.yml` sets it automatically for Pages deployments, while Gitea's container
image serves from `/`.
### Offline
+1 -1
View File
@@ -392,7 +392,7 @@ annotated on the run page, listed in the job summary with its status code, and c
conduct for why that ordering is load-bearing.
**Built: `scripts/refresh-sources.ts`** (`bun run refresh`), scheduled by
`.github/workflows/refresh.yml`. It takes its adapters, store, robots gate, fetch and clock by
`.gitea/workflows/refresh.yml`. It takes its adapters, store, robots gate, fetch and clock by
injection, so the whole runner is tested offline against a fake fetch. A fetched body is *rejected*
— the previous snapshot survives — when it fails `canParse`, throws, or yields zero events; storing
an empty parse would make the feed build prefer it over the fixture and silently empty a game's