Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ paths:
.github/workflows/cd-staging.yml:
ignore:
- '^unexpected key "cache-mode" for "workflow" section\.'
.github/workflows/docs-pages.yml:
ignore:
- '^unexpected key "cache-mode" for "workflow" section\.'
39 changes: 39 additions & 0 deletions .github/actions/docs/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Build documentation
description: Build and validate the rendered documentation site, then retain review evidence.

inputs:
install-dotnet:
description: Install the SDK pinned by global.json when the caller has not already done so.
required: false
default: "true"

runs:
using: composite
steps:
- uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
if: ${{ inputs.install-dotnet == 'true' }}
env:
# Keep the pinned SDK isolated from runner-installed workload manifests.
DOTNET_INSTALL_DIR: ${{ runner.temp }}/ogb-dotnet
with:
global-json-file: global.json

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
package-manager-cache: false

- name: Build and validate documentation
shell: pwsh
run: ./scripts/check-docs.ps1

- name: Upload rendered documentation and diagnostics
if: ${{ always() && !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ci-docs-${{ github.run_attempt }}
path: |
artifacts/docs/site/
artifacts/docs/*.log
if-no-files-found: warn
retention-days: 7
23 changes: 23 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,29 @@ updates:
cooldown:
default-days: 3

# DocFX is isolated from opt-in developer tools.
- package-ecosystem: "nuget"
directory: "/docs"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "America/Indiana/Indianapolis"
open-pull-requests-limit: 2
cooldown:
default-days: 3

- package-ecosystem: "github-actions"
directory: "/.github/actions/docs"
schedule:
interval: "weekly"
day: "tuesday"
time: "09:15"
timezone: "America/Indiana/Indianapolis"
open-pull-requests-limit: 3
cooldown:
default-days: 3

# API Dockerfile base images.
- package-ecosystem: "docker"
directory: "/src/OpenGameBuilder.Api"
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ jobs:
mode: content
artifact-name: ci-documentation-validation

- name: Build and validate documentation site
uses: ./.github/actions/docs

windows:
name: Windows solution
needs: select-checks
Expand Down Expand Up @@ -91,6 +94,11 @@ jobs:
with:
artifact-name: ci-linux-validation

- name: Build and validate documentation site
uses: ./.github/actions/docs
with:
install-dotnet: "false"

- name: Build API image
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
Expand Down
62 changes: 62 additions & 0 deletions .github/workflows/docs-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Publish documentation

cache-mode: none

# Publication is an explicit maintainer action, never a side effect of a PR.
on:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: documentation-pages
cancel-in-progress: false

jobs:
build:
name: Validate protected documentation
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Require protected main
env:
SOURCE_REF: ${{ github.ref }}
SOURCE_PROTECTED: ${{ github.ref_protected }}
run: |
if [[ "$SOURCE_REF" != refs/heads/main || "$SOURCE_PROTECTED" != true ]]; then
echo 'Documentation publication requires a dispatch from protected main.' >&2
exit 1
fi
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}
persist-credentials: false
- name: Validate source content
uses: ./.github/actions/validate
with:
mode: content
artifact-name: pages-content-validation
- name: Build and check the documentation site
uses: ./.github/actions/docs
- name: Package the validated site
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
with:
path: artifacts/docs/site

deploy:
name: Publish validated documentation
needs: build
if: ${{ github.ref == 'refs/heads/main' && github.ref_protected }}
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Publish to GitHub Pages
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
25 changes: 25 additions & 0 deletions docfx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/docfx/main/schemas/docfx.schema.json",
"rules": {
"InvalidHref": "error",
"InvalidFileLink": "info"
},
"build": {
"content": [
{
"files": ["*.md", "docs/**/*.md", "toc.yml"],
"exclude": ["AGENTS.md", "docs/foundation-checklist.md"]
}
],
"output": "artifacts/docs/site",
"fileMetadataFiles": ["artifacts/docs/source-metadata.json"],
"template": ["default", "modern"],
"globalMetadata": {
"_appName": "OpenGameBuilder",
"_appTitle": "OpenGameBuilder documentation",
"_enableSearch": true,
"_appLogoPath": "",
"_gitUrlPattern": "github"
}
}
}
11 changes: 11 additions & 0 deletions docs/.config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": 1,
"isRoot": true,
"tools": {
"docfx": {
"version": "2.80.1",
"commands": ["docfx"],
"rollForward": false
}
}
}
4 changes: 4 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ application. The [public roadmap](https://github.com/orgs/OpenGameBuilder/projec
tracks project work. There is no game runtime or editor yet; the first engine
milestone's behavior and acceptance criteria remain to be agreed.

These guides also build as a searchable site. See
[documentation maintenance](setup/documentation.md) for the build, PR preview,
and publication procedure.

## Working on the application

| Task | Read |
Expand Down
22 changes: 20 additions & 2 deletions docs/foundation-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -540,11 +540,11 @@ Sources: [Playwright servers](https://playwright.dev/docs/test-webserver),

### 17. Publish searchable documentation and checked examples

- [ ] Build a DocFX site with its modern template from the existing Markdown.
- [x] Build a DocFX site with its modern template from the existing Markdown.
Keep one source copy per document, generated HTML untracked, and concise
navigation for setup, contribution, architecture, testing, and operations.
Exclude this temporary plan from site content and navigation.
- [ ] Add search and edit links, a PR site build, and checks of rendered local
- [x] Add search and edit links, a PR site build, and checks of rendered local
links/anchors. Use appropriate failing diagnostic severities for broken content.
Keep external-link maintenance separate as described in step 14.
- [ ] Configure publication from validated protected content when authorized,
Expand All @@ -561,6 +561,24 @@ generation do not block the first engine slice.
Sources: [DocFX template](https://dotnet.github.io/docfx/docs/template.html),
[.NET reference](https://dotnet.github.io/docfx/docs/dotnet-api-docs.html).

**Result (2026-09-22, local acceptance):** DocFX 2.80.1 builds 27 existing-source
pages with the modern template, task navigation, search, and original-source edit
links. The temporary plan and agent instructions are excluded; generated output
stays under ignored `artifacts/docs/site`. Repository-file links stay relative in
Markdown and resolve to the built source revision in the site. `check-docs.ps1` passed with zero build
warnings, all rendered local links/anchors, search and edit-link inventory, and
four regression groups rejecting deliberate content defects. Both selected PR
lanes run the gate and retain review artifacts. `check.ps1 full -Serial` also
passed, including the 72 .NET tests, content and CI-policy regressions, frontend
packaging, and five shell suites.

The manual protected-`main` Pages workflow and guarded `github-pages` environment
are configured, but the workflow has not been dispatched. Actual hosted acceptance
remains pending. The first hosted run of the new PR checks is also unverified. The engine-example and
filtered-reference item remains open because steps 7–8 have no implemented slice
to compile or reuse. [Documentation maintenance](setup/documentation.md) records
the permanent build, publication, evidence, and example-adoption procedures.

### 18. Clarify branches and make release notes useful

- [ ] Document protected `main`, short-lived branches, draft PRs, squash merges,
Expand Down
3 changes: 2 additions & 1 deletion docs/quality/content-checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ content prerequisites before opting into the hook. See
GitHub supports [`cache-mode: none`](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#cache-mode),
but actionlint 1.7.12 does not recognize that key. The
[actionlint configuration](../../.github/actionlint.yaml) suppresses only that
specific root-key diagnostic in the three protected-source deployment workflows.
specific root-key diagnostic in the protected-source deployment workflows,
including manual documentation publication.
The [cache-policy check](../../scripts/workflow-cache-policy.mjs) independently
requires `none` and rejects job overrides that permit caching. Other workflow
errors still fail, and the regression suite covers missing/changed cache policy.
Expand Down
28 changes: 24 additions & 4 deletions docs/quality/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ lane. An empty range, any other path, patch-branch push, or manual run selects
full validation. A failed comparison fails selection and the required gate;
it cannot silently skip validation. The selector logs the paths and decision.

| Selection | Required validation |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Documentation | Ubuntu runs `check.ps1 content`: first-party formatting, lint, workflow/shell checks, and all local Markdown links/anchors. Checking all documents catches backlinks broken by deletions or renames. No solution build or container runs. |
| Full | Windows runs `check.ps1 quick -Serial` for locked restore, C# format, Release build, and tests. Ubuntu runs `check.ps1 full`, then builds and checks the API container. |
| Selection | Required validation |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Documentation | Ubuntu runs `check.ps1 content` and `check-docs.ps1`: source formatting, lint, workflow/shell checks, local Markdown links, and the DocFX site with rendered link/anchor and search checks. No application solution build or container runs. |
| Full | Windows runs `check.ps1 quick -Serial` for locked restore, C# format, Release build, and tests. Ubuntu runs `check.ps1 full` and `check-docs.ps1`, then builds and checks the API container. |

Both platforms restore and build the entire solution, including the AppHost,
and run both test projects. Only the shipped API and Web Client have committed
Expand Down Expand Up @@ -126,6 +126,26 @@ These tests exercise real temporary Git histories and lane-result combinations;
they do not prove GitHub scheduling or merge enforcement. The hosted acceptance
procedure is in [GitHub setup](../setup/github.md#ci-merge-gate).

### Documentation site validation

Run `pwsh ./scripts/check-docs.ps1` after installing the content prerequisites.
It restores the pinned DocFX tool, builds the existing guides with warnings as
errors, checks rendered links and anchors offline, and verifies search entries
and edit links against the original Markdown. Regression fixtures require an
unresolved document, missing rendered page, renamed anchor, missing stylesheet,
missing search entry, and accidentally included temporary plan to fail.
Additional fixtures check relative page links and repository-source links at two
different commits, reject omitted documentation and assets, and preserve the
source Markdown. See the [link resolution rules](../setup/documentation.md#build-and-check).

Both selected Ubuntu lanes run this command through the documentation action;
the required `build-test` check cannot pass when it fails. The `ci-docs` artifact
retains the rendered site and available logs for seven days. The command does
not start an application or browser. See [documentation maintenance](../setup/documentation.md)
for preview, publication, and the separate hosted acceptance procedure. It is
separate from `check.ps1 full`, so application deployment validation does not
acquire an unrelated site build.

### Recorded platform CI acceptance

The [clean hosted run](https://github.com/OpenGameBuilder/opengamebuilder/actions/runs/35748017596)
Expand Down
Loading
Loading