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:

  1. 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.
  2. Given a site in sites.nix, When the forgejo component of the dev group builds its TLS request, Then the certificate has a SAN for that site.
  3. Given a site with a _headers file that sets Cache-Control for a path, When a reader gets a file under that path, Then the response has that Cache-Control header.
  4. Given a file that no _headers rule matches, When a reader gets it, Then the response has the default Cache-Control: max-age=60, stale-while-revalidate=3600 of 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:

  1. Given a repository in sites.nix, When the workflow of that repository uploads, Then git-pages accepts it after the forge authorizes it.
  2. Given a repository that is not in sites.nix, When it uploads, Then git-pages has no wildcard entry for it.

Edge Cases

  • A new site needs an entry in sites.nix and 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.eu zone.
  • The runners have no Docker, so the publish step runs git-pages-cli natively.

Requirements (mandatory)

Functional Requirements

  • FR-001: default.nix MUST export nixosModule = ./git-pages.nix and the function sslDomains, which gives one <site>.<domain> per site for a domain.
  • FR-002: git-pages.nix MUST import the git-pages NixOS module from the nixpkgs-git-pages npins pin, and MUST declare fediversity.git-pages.enable. It MUST set services.git-pages only when that option is true. It MUST declare fediversity.git-pages.domain and fediversity.git-pages.forgeUrl with no default.
  • FR-003: services.git-pages MUST be enabled with log-format = "text", server.pages = "tcp/localhost:3003" and server.caddy = "-".
  • FR-004: Each repository in sites.nix MUST become one wildcard entry with domain = cfg.domain, clone-url = "<cfg.forgeUrl>/<path>.git" and authorization = "forgejo".
  • FR-005: nginx MUST have one vhost per name of sslDomains cfg.domain, which listens only on the addresses that the network resource gives the node.
  • FR-006: sites.nix MUST map the repository path fediversity/fediversity to swagger, asyncapi, api, panel and core, and fediversity/nix-module-form, fediversity/module-schema and fediversity/nix-tf-schema to one site each.
  • FR-007: services.git-pages.settings.limits.allowed-custom-headers MUST be X-Clacks-Overhead (the default of git-pages) and Cache-Control, so that a site can set the cache lifetime of its files in its _headers file.
  • FR-008: The dev group MUST import nixosModule into the host config of the forgejo machine, MUST set fediversity.git-pages.enable = true there, and MUST set fediversity.git-pages.domain = "pages.<forge domain>", fediversity.git-pages.forgeUrl = "https://<forge domain>" and forgejo.extraDomains = sslDomains "pages.<forge domain>". The forge domain is git.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. The dev group gives the same list to extraDomains of the forgejo component, which adds it to its ssl request.
  • _headers: A file in the uploaded site, in the Netlify format, that sets response headers for paths. git-pages applies only the headers in allowed-custom-headers.
  • services.git-pages: The server on localhost:3003, with metrics on its default port :3002.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: Each site in sites.nix answers over HTTPS with a valid certificate.
  • SC-002: The dev group evaluates with the nixpkgs-git-pages pin.
  • SC-003: test-forgejo-service passes.

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.nix does 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-pages pin of a nixpkgs pull request, not from the upstream nixpkgs pin (Constraints). The comment says to drop the pin when the module is in nixpkgs.