Some checks failed
CI / skinny-install (aco) (push) Successful in 1m12s
CI / skinny-install (api) (push) Successful in 30s
CI / skinny-install (bcda) (push) Successful in 36s
CI / skinny-install (bib) (push) Successful in 35s
CI / skinny-install (bls) (push) Successful in 27s
CI / skinny-install (ccw) (push) Successful in 32s
CI / skinny-install (cli) (push) Successful in 41s
CI / skinny-install (cms) (push) Successful in 37s
CI / skinny-install (conf) (push) Successful in 38s
CI / skinny-install (opps) (push) Successful in 33s
CI / skinny-install (perf) (push) Successful in 38s
CI / skinny-install (pfs) (push) Successful in 38s
CI / skinny-install (rex) (push) Successful in 34s
Deploy / build-scan-report (push) Failing after 46s
Infra CI / notebooks (push) Failing after 25s
Infra CI / zotero (push) Successful in 12s
Infra CI / docs (push) Failing after 16s
CI / lint-test (push) Failing after 11m2s
Infra CI / mc (push) Successful in 21s
Infra CI / api (push) Successful in 29s
Package Supply Chain / pkg-supply-chain (push) Failing after 41s
Mail: Maddy on DO (corwins.media+Resend, fhirworx.io+Postmark), touchless/stateless/idempotent. Gitea SMTP via env_file. CMS inbox at cmsupdates@mail.fhirworx.io with IMAP→bib poller. Bib: regulations.gov v4 client, Federal Register discovery, 164K comment backfill (running), IMAP email ingest, Zotero sync routing. PRISMA: altcha PoW solver, CrossRef DOI resolution, 83/129 PDFs. Zotero: schema parity, ops module, CLI, fail-fast guard. CI: docs.Dockerfile COPY glob fix (tracks #341). Infra: Gitea+marimo fhirworx themes, IOM/OIG modules.
133 lines
5.3 KiB
Markdown
133 lines
5.3 KiB
Markdown
# Fhirworx Gitea image
|
|
|
|
This directory builds `fhirworx/gitea:<tag>` — upstream `go-gitea/gitea` at a
|
|
pinned tag with the fhirworx theme baked in via `bindata`. **No source
|
|
changes to upstream**; we only inject one CSS file and two brand SVGs into
|
|
the upstream tree before its own build runs.
|
|
|
|
## Layout
|
|
|
|
```
|
|
infra/gitea/
|
|
├── Dockerfile # multi-stage build, see below
|
|
├── .dockerignore
|
|
├── theme/
|
|
│ └── theme-fhirworx.css # ONE css file = the entire theme
|
|
├── brand/
|
|
│ ├── logo.svg # → assets/logo.svg → make generate-images
|
|
│ └── favicon.svg # → assets/favicon.svg
|
|
├── custom/ # bind-mounted at runtime as /var/lib/gitea/custom
|
|
│ └── templates/
|
|
│ └── home.tmpl # custom anonymous landing page
|
|
└── README.md # this file
|
|
```
|
|
|
|
## Staying downstream from upstream Gitea
|
|
|
|
Goal: track upstream cleanly, never fork the source.
|
|
|
|
The build does only three things to the upstream tree:
|
|
|
|
1. `COPY theme/theme-fhirworx.css web_src/css/themes/theme-fhirworx.css`
|
|
2. `COPY brand/logo.svg assets/logo.svg`
|
|
3. `COPY brand/favicon.svg assets/favicon.svg`
|
|
|
|
After these, the upstream `make clean-all build` runs unmodified — webpack
|
|
processes our theme into `public/assets/css/theme-fhirworx.css`, the image
|
|
generator regenerates every PNG/SVG variant from our SVGs, and `bindata`
|
|
embeds the whole `public/` tree into the Go binary.
|
|
|
|
### Bumping Gitea
|
|
|
|
```
|
|
# 1. Update the pinned tag
|
|
sed -i 's/GITEA_VERSION=v1\.[0-9.]\+/GITEA_VERSION=v1.NEW.VER/' Dockerfile
|
|
# 2. Diff our theme against upstream's reference
|
|
diff theme/theme-fhirworx.css \
|
|
<(curl -sL https://raw.githubusercontent.com/go-gitea/gitea/v1.NEW.VER/web_src/css/themes/theme-gitea-light.css)
|
|
# 3. Add any new --color-* vars upstream introduced
|
|
# 4. Rebuild
|
|
docker compose build gitea && docker compose up -d gitea
|
|
```
|
|
|
|
The theme file's variable order **mirrors upstream's `theme-gitea-light.css`
|
|
1:1**, on purpose, so step 2 produces a clean readable diff. Add variables
|
|
upstream added; refresh values you've remapped.
|
|
|
|
## Theme contract
|
|
|
|
The theme is a complete drop-in replacement for upstream's
|
|
`theme-gitea-light.css`. It defines:
|
|
|
|
- **All ~140 `--color-*` variables** Gitea references. Any var left undefined
|
|
resolves to CSS `initial` (transparent bg / black text), which breaks
|
|
surfaces like the navbar, secondary-nav, footer, clone panel, menu hover
|
|
states. Historical bug: an early version defined ~30 vars and many
|
|
components broke.
|
|
|
|
- **`--fonts-override`** — Gitea's `base.css` composes
|
|
`--fonts-regular: var(--fonts-override, var(--fonts-proportional)), ...`.
|
|
Setting `--fonts-override` propagates the editorial type (Source Serif 4)
|
|
through every Fomantic UI component (menus, buttons, tabs, inputs).
|
|
|
|
- **A defensive `#navbar` color sweep**. Fhirworx is the only design
|
|
(compared against awesome-gitea's full theme list — Catppuccin, Rainnny
|
|
GitHub, lutinglt, Earl Grey, Dark Arc, etc.) that puts a *dark* navbar
|
|
over a *light* body. Every reference theme keeps both surfaces in the
|
|
same luminance class. Because of that, Gitea's base CSS doesn't anticipate
|
|
the inversion: any Fomantic class with `color: var(--color-text)` (e.g.
|
|
`.ui.button` for the hamburger `#navbar-expand-toggle`) leaks near-black
|
|
text into the dark navbar. The sweep at the end of theme-fhirworx.css
|
|
forces nav-text on every text/icon element inside `#navbar`, and flips
|
|
dropdown popouts back to the light body palette since they float over
|
|
the page, not the bar.
|
|
|
|
## Custom templates (still bind-mounted)
|
|
|
|
`custom/templates/home.tmpl` is the anonymous landing page. It overrides
|
|
upstream's stock dashboard for unauthenticated visitors and renders the
|
|
homelab service grid. It's bind-mounted via `compose.yml`, not baked in,
|
|
because it's content not theme — easier to edit without rebuilding.
|
|
|
|
## Compose wiring
|
|
|
|
```yaml
|
|
gitea:
|
|
build:
|
|
context: ./infra/gitea
|
|
args:
|
|
GITEA_VERSION: v1.25.4
|
|
image: fhirworx/gitea:v1.25.4
|
|
environment:
|
|
- GITEA__ui__THEMES=fhirworx
|
|
- GITEA__ui__DEFAULT_THEME=fhirworx
|
|
volumes:
|
|
- gitea_data:/var/lib/gitea
|
|
- gitea_config:/etc/gitea
|
|
- ./infra/gitea/custom:/var/lib/gitea/custom
|
|
```
|
|
|
|
`THEMES=fhirworx` (single option) — no gitea-auto/light/dark/protanopia
|
|
variants are exposed in the user appearance dropdown. fhirworx is the only
|
|
choice and it's the default. Per-user `theme` column in the postgres
|
|
`"user"` table should be set to `'fhirworx'`.
|
|
|
|
## What goes wrong if you bypass the build
|
|
|
|
Earlier iterations bind-mounted raw CSS files into stock
|
|
`gitea/gitea:1.25.4-rootless`. Two persistent failures:
|
|
|
|
- **Inode drift**: Docker's single-file bind mount tracks by inode. The
|
|
`Edit`/`Write` tools rewrite atomically, replacing the inode. The container
|
|
keeps pointing at the now-orphaned old inode and sees nothing change.
|
|
Required `docker restart` after every edit.
|
|
|
|
- **Cache + version-pinning**: The asset URL embeds Gitea's version
|
|
(`?v=1.25.4`). Browsers cache aggressively for 6h. Edits to the CSS file
|
|
don't change the URL → cache hit serves stale CSS forever (or until the
|
|
user knows to hard-refresh). On Cloudflare it's even longer.
|
|
|
|
Baking the theme into bindata sidesteps both. The CSS only changes when you
|
|
rebuild the image, which means the version string actually changes in the
|
|
binary's metadata, and there's no inode tracking to drift.
|