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
5 changes: 3 additions & 2 deletions .github/scripts/ci-changes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ RUST=(
.github/scripts/test-timings-summary.sh .github/scripts/oci-e2e.sh
.github/scripts/raw-e2e.sh .github/scripts/npm-e2e.sh
)
# fmt's second check: the changelog fragments.
CHANGELOG=(docs/changes)
# fmt's other checks: the changelog fragments, and the links of the
# documentation site's pages (the README, docs/ and the changelog).
CHANGELOG=(docs README.md CHANGELOG.md)
# What xtask's tests, which fmt runs too (#363), read from outside xtask: the
# version lines `cargo xtask release` sets, and the release workflow's channel
# script.
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: .github/scripts/ci-changes.sh

# ── Formatting, the changelog fragments and xtask's tests ──────────────────
# The fragment check and the tests build only xtask, which has no
# ── Formatting, the changelog fragments, the docs' links, xtask's tests ────
# The fragment and link checks and the tests build only xtask, which has no
# dependencies. On a pull request the fragment check sees the merge with
# the base, so a fragment under a milestone that was released after the
# pull request was written fails. xtask's tests run in `test` as well; here
Expand All @@ -149,6 +149,11 @@ jobs:
run: cargo fmt --all --check
- name: Changelog fragments (docs/changes)
run: cargo xtask changelog --check
# The pages of the documentation site: every link goes to a page, a
# heading or a file that exists, and SUMMARY.md lists every guide. A
# change to the crates can break them too (a link to a renamed file).
- name: Documentation links (docs/SUMMARY.md)
run: cargo xtask docs --check
- name: cargo test -p xtask
run: cargo test -p xtask

Expand Down
75 changes: 75 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Pages

# The documentation site, https://forgepkg.github.io/forge/: `cargo xtask
# docs` builds the pages docs/SUMMARY.md lists with mdBook, and a push to the
# default branch that changes them deploys the build to GitHub Pages
# (Settings → Pages → Source: GitHub Actions). A pull request that changes how
# the site is built only builds it; CI's fmt job checks the links of every
# pull request (`cargo xtask docs --check`).
on:
push:
branches: [main]
paths:
- README.md
- CHANGELOG.md
- docs/**
- xtask/src/docs.rs
- .github/workflows/pages.yml
pull_request:
branches: [main]
paths:
- docs/book.toml
- docs/SUMMARY.md
- xtask/src/docs.rs
- .github/workflows/pages.yml
workflow_dispatch:

# A deployment is never cancelled halfway; a newer one waits for it. A pull
# request's newer commit supersedes its running build.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'deploy' }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
contents: read

# Every third-party action is pinned to a full commit SHA (the tag it was
# resolved from is in the trailing comment); Dependabot
# (.github/dependabot.yml) proposes updates.

jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Rust toolchain (rust-toolchain.toml)
uses: dtolnay/rust-toolchain@d124f86f28ff42855784ff3319f48ac182c248f8 # 1.99.1
# The version xtask/src/docs.rs names (MDBOOK).
- name: Install mdBook (prebuilt, pinned)
uses: taiki-e/install-action@a4d3f3f761dcd95cce1b72cb61cb6d1963438177 # v2.87.30
with:
tool: mdbook@0.5.4
- name: cargo xtask docs
run: cargo xtask docs
- name: Upload the site
if: ${{ github.event_name != 'pull_request' }}
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: target/docs/book

deploy:
name: deploy
if: ${{ github.event_name != 'pull_request' }}
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
32 changes: 32 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,9 @@ Docker image: `docker-build` · `docker-run` (wired to the `Dockerfile`).
Changelog: `changelog <milestone>` (fold a milestone's fragments into
`CHANGELOG.md`) · `changelog --check` (see [Changelog entries](#changelog-entries)).

Documentation site: `docs` (build it) · `docs --check` (its links only; see
[Documentation site](#documentation-site)).

Release: `release <version> [--no-tag]` (see [Releasing](#releasing)).

## Single-container Docker image
Expand Down Expand Up @@ -1079,6 +1082,35 @@ fragment, and a fragment whose milestone is released already. When a pull
request written before a release merges after it, move its fragment to the
next milestone.

## Documentation site

The guides are also a site, https://forgepkg.github.io/forge/, built with
[mdBook](https://rust-lang.github.io/mdBook/) from the pages
[docs/SUMMARY.md](docs/SUMMARY.md) lists: the README (the start page), the
guides in `docs/` and the changelog. `docs/book.toml` configures it.

```bash
cargo install mdbook --version 0.5.4 --locked
cargo xtask docs
```

`cargo xtask docs` stages the pages into `target/docs/src` and builds the
site into `target/docs/book`; open `target/docs/book/index.html`. The pages
keep linking each other and the source tree relatively, as GitHub shows
them. The staging rewrites a link to another page into that page of the
site, and a link into the source tree (`../crates/…`) into the file on
GitHub, on `main`. It fails on a link to a file or heading that does not
exist, and on a Markdown file directly in `docs/` that SUMMARY.md does not
list: a new guide goes into SUMMARY.md, under its part. `cargo xtask docs
--check` runs the staging without mdBook; CI's `fmt` job runs it for a change
to the pages or to the Rust code, whose files the pages link.

The Pages workflow (`.github/workflows/pages.yml`) deploys the site when a
push to `main` changes a page, and builds it for a pull request that changes
the site's configuration. It needs **Settings → Pages → Source: GitHub
Actions** in the repository. mdBook's version is pinned in the workflow and
in `xtask/src/docs.rs`; change both together.

## Releasing

A `v<version>` tag on the default branch publishes the release: the release
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ curl -u admin@example.com:<TOKEN> http://localhost:8421/repository/binaries/tool

## Documentation

The guides below are also a site, with navigation and search:
**<https://forgepkg.github.io/forge/>**.

- **[Production deployment](./docs/deployment.md)** — required settings, TLS
and reverse proxy, secret encryption, health probes, backup/restore and
upgrades. Kubernetes: a Helm chart published with every release
Expand Down
26 changes: 26 additions & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Summary

[Forge](../README.md)

# Running Forge

- [Production deployment](deployment.md)
- [Retention size budgets](retention.md)
- [Importing from Nexus](nexus-import.md)

# Formats

- [Docker / OCI registry](docker.md)
- [npm registries](npm.md)
- [Raw file repositories](raw.md)
- [Format plugins](format-plugins.md)

# CI and publishing

- [Trusted publishing](trusted-publishing.md)
- [GitLab CI with workload identity](gitlab-ci.md)
- [CI with service accounts](ci-service-accounts.md)

---

[Changelog](../CHANGELOG.md)
29 changes: 29 additions & 0 deletions docs/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# The documentation site, https://forgepkg.github.io/forge/.
#
# `cargo xtask docs` stages the pages SUMMARY.md lists (the README, the guides
# in this directory and the changelog) into target/docs/src, with their links
# rewritten for the site, and builds them with mdBook into target/docs/book.
# The Pages workflow (.github/workflows/pages.yml) publishes the build of main.

[book]
title = "Forge"
description = "A self-hosted NuGet, npm, Docker / OCI and raw file registry"
language = "en"
src = "src"

[build]
# A page SUMMARY.md lists but the staging did not write is an error, not an
# empty page.
create-missing = false

[output.html]
site-url = "/forge/"
git-repository-url = "https://github.com/forgepkg/forge"
default-theme = "light"
preferred-dark-theme = "navy"
# The pages have no chapter numbers of their own.
no-section-label = true

# The Rust snippets are excerpts, not programs to run.
[output.html.playground]
runnable = false
5 changes: 5 additions & 0 deletions docs/changes/2.1.1/622.docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
The guides, the README and the changelog are a site,
<https://forgepkg.github.io/forge/>, with navigation and search, built from
`main`. `cargo xtask docs` builds it with mdBook (see
[DEVELOPMENT.md](DEVELOPMENT.md#documentation-site)), and CI checks that
every link of its pages goes to a page, heading or file that exists.
2 changes: 1 addition & 1 deletion xtask/src/changelog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ fn leading_blank(lines: &[String]) -> usize {

/// The repository's URL, from the `[Unreleased]: <repo>/compare/…` link at
/// the bottom of the changelog (`<repo>/commits/…` before the first release).
fn repo_url(changelog: &str) -> Option<&str> {
pub(crate) fn repo_url(changelog: &str) -> Option<&str> {
changelog.lines().find_map(|line| {
let url = line.strip_prefix("[Unreleased]: ")?;
let (repo, _) = url
Expand Down
Loading
Loading