Feature Specification: Component git-pages
Created: 2026-10-07
Status: Implemented
Input: Reconstructed from the code of core/components/dev/git-pages/ and the dev group at 14504f80d, pull requests #1383, #1554 and #2016.
git-pages is a NixOS module of the dev group, not a component. The group turns it on in the host config of the forge machine, and adds the site names to the certificate of forgejo. The family spec is ../spec.md.
User Scenarios & Testing (mandatory)
User Story 1 - Readers open the documentation sites (Priority: P1)
A reader opens a documentation site on its own name below the pages domain. nginx on the forge host terminates TLS and sends the request to the git-pages server, which serves what the repository of the site published.
Why this priority: The sites are the only output of this helper.
Independent Test: A unit test of the dev group pins the virtual hosts, the listen addresses and the certificate names. The VM test of forgejo runs the module with plain HTTP, gets an uploaded site, and checks the cache header with and without a matching header rule.
Acceptance Scenarios:
- Given a site in the site list, When the forge host deploys, Then nginx has a virtual host for the site, and the certificate covers it.
- Given a header rule that sets a cache lifetime for a path, When a reader gets a file there, Then the response has that lifetime. Else it has the default of git-pages.
User Story 2 - A repository publishes a site from CI (Priority: P2)
A workflow of the repository uploads the site. git-pages asks the forge if the uploader can push to the repository, and accepts the upload only then.
Why this priority: Publication is less frequent than reads.
Independent Test: The VM test uploads with the token of a user that can push and 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 that is not in the site list, When it uploads, Then git-pages refuses it.
Edge Cases
- A new site needs an entry in the site list and its own publish workflow.
- TLS uses one name per site over HTTP-01, because there is no DNS-01 credential for the external zone of the forge.
- The runners have no Docker, so the publish step runs the git-pages client natively.
Requirements (mandatory)
Functional Requirements
- FR-001: The helper MUST export its NixOS module and a function that gives the site names below a domain.
- FR-002: The module MUST configure git-pages only when it is on. The pages domain and the forge URL MUST have no default.
- FR-003: The server MUST listen only locally, MUST log as text, and MUST NOT run its own TLS.
- FR-004: Each repository in the site list MUST get one publish entry, which clones from the forge and lets the forge authorize uploads.
- FR-005: nginx MUST have one virtual host per site name, only on the addresses of the
networkresource. - FR-006: The site list MUST map the main repository to the sites of its API, event API, panel and core documentation, and each schema and form library repository to one site.
- FR-007: A site MUST be able to set the cache lifetime of its files in its header file. git-pages MUST accept no other custom header.
- FR-008: The
devgroup MUST turn the module on on the forge machine, with a pages domain below the forge domain and the HTTPS URL of the forge, and MUST give the site names to thesslrequest offorgejo.
Key Entities
- Site list: The map from a repository on the forge to site names.
- Header file: A file in the site, in the Netlify format, that sets response headers for paths.
- git-pages server: The local server that stores and serves the sites, and exposes metrics.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: Each site answers over HTTPS with a valid certificate.
- SC-002: The
devgroup evaluates, and the VM test offorgejopasses.
Assumptions
- git-pages runs on the forge host, because the forge authorizes the uploads.
Known Deviations
- git-pages is a NixOS module, not a component, because a node runs one component and git-pages shares the forge node. The catalog does not import it (principle IV, #2126).
- The module comes from a separate pin of a nixpkgs pull request, not from the main pin (Constraints), until it is in
nixpkgs.