Feature Specification: Component git-pages
Created: 2026-10-07
Status: Implemented
Input: Reconstructed from the code at 093e68b6f (core/components/dev/default.nix, core/components/dev/git-pages/default.nix, core/components/dev/git-pages/git-pages.nix, core/components/dev/git-pages/sites.nix, core/components/dev/forgejo/default.nix), pull requests #1383, #1554 and #2016.
git-pages is a NixOS module of the dev group, not a component. It has no
components.git-pages entry, and core/components/dev/default.nix imports
only ./forgejo and ./forgejo-runner. The dev group imports the module
into the host config of the forge machine and sets
fediversity.git-pages.enable. The group adds the names of the sites to the
extraDomains of the forgejo component. The family spec is
../spec.md.
User Scenarios & Testing (mandatory)
User Story 1 - Readers open the documentation sites (Priority: P1)
A reader opens https://<site>.<domain>/, where <domain> is fediversity.git-pages.domain (pages.git.fediversity.eu in the dev group). nginx on the
forge host terminates TLS and sends the request to the git-pages server.
The server serves the content of the repository that sites.nix maps to
that site.
Why this priority: The documentation sites are the only output of this helper.
Independent Test: core/setups/dev-config-test.nix pins the vhosts, the listen addresses and the certificate names of the dev forge. The test-forgejo-service NixOS test (core/components/dev/forgejo/test.nix) runs the module next to the forgejo modules, with plain HTTP in place of TLS. It gets an uploaded site through the nginx vhost of a site, and checks the Cache-Control of a file that a _headers rule matches and of a file that no rule matches.
Acceptance Scenarios:
- Given a site in
sites.nix, When the forge host deploys, Then nginx has one vhost<site>.<domain>that proxies to the git-pages server. - Given a site in
sites.nix, When theforgejocomponent of thedevgroup builds its TLS request, Then the certificate has a SAN for that site. - Given a site with a
_headersfile that setsCache-Controlfor a path, When a reader gets a file under that path, Then the response has thatCache-Controlheader. - Given a file that no
_headersrule matches, When a reader gets it, Then the response has the defaultCache-Control: max-age=60, stale-while-revalidate=3600of git-pages.
User Story 2 - A repository publishes a site from CI (Priority: P2)
A maintainer of a repository publishes the site from a workflow. The
workflow runs git-pages-cli in a run: step of
.forgejo/workflows/publish-<name>.yaml. git-pages checks the upload
against the forge, because each wildcard entry has
authorization = "forgejo".
Why this priority: Publication is the write path. It is less frequent than reads.
Independent Test: core/setups/dev-config-test.nix pins the wildcard entries of the dev forge. test-forgejo-service uploads a site for fediversity/fediversity with the forge token of a user that can push to the repository, and with the token of a user that cannot. git-pages accepts only the first, and does not serve the site after the second.
Acceptance Scenarios:
- Given a repository in
sites.nix, When the workflow of that repository uploads, Then git-pages accepts it after the forge authorizes it. - Given a repository that is not in
sites.nix, When it uploads, Then git-pages has nowildcardentry for it.
Edge Cases
- A new site needs an entry in
sites.nixand its own publish workflow. - TLS uses per-site SANs over HTTP-01. There is no wildcard certificate, because there is no DNS-01 credential for the external
git.fediversity.euzone. - The runners have no Docker, so the publish step runs
git-pages-clinatively.
Requirements (mandatory)
Functional Requirements
- FR-001:
default.nixMUST exportnixosModule = ./git-pages.nixand the functionsslDomains, which gives one<site>.<domain>per site for adomain. - FR-002:
git-pages.nixMUST import the git-pages NixOS module from thenixpkgs-git-pagesnpins pin, and MUST declarefediversity.git-pages.enable. It MUST setservices.git-pagesonly when that option is true. It MUST declarefediversity.git-pages.domainandfediversity.git-pages.forgeUrlwith no default. - FR-003:
services.git-pagesMUST be enabled withlog-format = "text",server.pages = "tcp/localhost:3003"andserver.caddy = "-". - FR-004: Each repository in
sites.nixMUST become onewildcardentry withdomain = cfg.domain,clone-url = "<cfg.forgeUrl>/<path>.git"andauthorization = "forgejo". - FR-005: nginx MUST have one vhost per name of
sslDomains cfg.domain, which listens only on the addresses that thenetworkresource gives the node. - FR-006:
sites.nixMUST map the repository pathfediversity/fediversitytoswagger,asyncapi,api,panelandcore, andfediversity/nix-module-form,fediversity/module-schemaandfediversity/nix-tf-schemato one site each. - FR-007:
services.git-pages.settings.limits.allowed-custom-headersMUST beX-Clacks-Overhead(the default of git-pages) andCache-Control, so that a site can set the cache lifetime of its files in its_headersfile. - FR-008: The
devgroup MUST importnixosModuleinto the host config of theforgejomachine, MUST setfediversity.git-pages.enable = truethere, and MUST setfediversity.git-pages.domain = "pages.<forge domain>",fediversity.git-pages.forgeUrl = "https://<forge domain>"andforgejo.extraDomains = sslDomains "pages.<forge domain>". The forge domain isgit.fediversity.eu.
Key Entities
sites.nix: The map from the path of a repository on the forge to site names.sslDomains: The function that gives the names of the sites for a domain. The module makes one nginx vhost per name. Thedevgroup gives the same list toextraDomainsof theforgejocomponent, which adds it to itssslrequest._headers: A file in the uploaded site, in the Netlify format, that sets response headers for paths. git-pages applies only the headers inallowed-custom-headers.services.git-pages: The server onlocalhost:3003, with metrics on its default port:3002.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: Each site in
sites.nixanswers over HTTPS with a valid certificate. - SC-002: The
devgroup evaluates with thenixpkgs-git-pagespin. - SC-003:
test-forgejo-servicepasses.
Assumptions
- git-pages runs on the forge host, because the forge is the authorization source of the uploads.
- The ports
:3000(Forgejo),:3001(Anubis) and:3002(git-pages metrics) are in use on the host, so the pages server uses:3003.
Known Deviations
- git-pages is a NixOS module, not a component, because a node runs one component and git-pages shares the forge node with
forgejo.core/components/dev/default.nixdoes not import it, and a deployment can add it only through the host config of a machine (principle IV, #2126). - The NixOS module comes from the
nixpkgs-git-pagespin of a nixpkgs pull request, not from the upstreamnixpkgspin (Constraints). The comment says to drop the pin when the module is innixpkgs.