docs: local publish script for Codeberg Pages; drop inert CI workflow

Codeberg doesn't execute Forgejo Actions (no runners), so the docs.yml
workflow never ran. Replace it with scripts/publish-docs.sh: build the
mdBook and force-push docs/book/ to the `pages` branch that Codeberg
Pages serves. Installs mdbook on demand, derives the Pages URL from the
origin remote, and honors CODEBERG_TOKEN for non-interactive auth.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Luna 2026-06-07 03:22:57 -07:00
parent 0861c8e394
commit 9da16ca65f
2 changed files with 83 additions and 44 deletions

View file

@ -1,44 +0,0 @@
# Build the mdBook docs and publish them to Codeberg Pages.
#
# Codeberg serves the `pages` branch of a repo (or a dedicated `pages`
# repo) at https://<user>.codeberg.page/<repo>/. This workflow builds the
# book on a push to main that touches docs/ and pushes the rendered HTML
# to the `pages` branch.
name: docs
on:
push:
branches: [main]
paths:
- 'docs/**'
- '.forgejo/workflows/docs.yml'
workflow_dispatch:
jobs:
build:
runs-on: docker
container:
image: rust:1.85-bookworm
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install mdBook
run: cargo install mdbook --no-default-features --features search
- name: Build the book
run: mdbook build docs
- name: Publish to the pages branch
# forgejo-release isn't right here; push the built docs/book/ to a
# `pages` branch that Codeberg Pages serves. Uses the repo token.
env:
TOKEN: ${{ secrets.PAGES_TOKEN }}
run: |
cd docs/book
git init -q
git config user.name "ci"
git config user.email "ci@localhost"
git add -A
git commit -q -m "docs build ${{ github.sha }}"
git push -f "https://x:${TOKEN}@codeberg.org/${{ github.repository }}.git" HEAD:pages

83
scripts/publish-docs.sh Executable file
View file

@ -0,0 +1,83 @@
#!/usr/bin/env bash
# Build the mdBook docs and publish them to Codeberg Pages.
#
# Usage:
# scripts/publish-docs.sh
#
# Codeberg serves the `pages` branch of a repo at
# https://<user>.codeberg.page/<repo>/. This script renders docs/ with
# mdBook and force-pushes the rendered HTML to that branch. The source
# (docs/src/) is untouched; only the orphan `pages` branch is rewritten.
#
# We do this locally rather than in CI because Codeberg does not execute
# Forgejo Actions (no runners) — see ROADMAP / docs/architecture.
#
# Auth: pushes via `origin`'s configured credentials by default. To use a
# scoped token non-interactively (e.g. write:repository only), export
# CODEBERG_TOKEN=<token>
# and it will be injected into the push URL for this run only.
#
# Prerequisites are installed on demand:
# - mdbook → cargo install mdbook --no-default-features --features search
set -uo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT" || exit 1
BRANCH="pages"
die() { echo "error: $*" >&2; exit 1; }
# cargo-installed binaries (mdbook) aren't on PATH in non-interactive shells.
export PATH="${CARGO_HOME:-$HOME/.cargo}/bin:$PATH"
# --- mdbook -----------------------------------------------------------------
if ! command -v mdbook >/dev/null 2>&1; then
echo "==> mdbook not found; installing via cargo"
cargo install mdbook --no-default-features --features search \
|| die "could not install mdbook"
fi
# --- build ------------------------------------------------------------------
echo "==> building the book"
mdbook build docs || die "mdbook build failed"
[ -f docs/book/index.html ] || die "no docs/book/index.html after build"
# --- resolve push URL + the resulting Pages URL -----------------------------
origin="$(git remote get-url origin 2>/dev/null)" \
|| die "no 'origin' remote — run from a clone with a Codeberg remote"
push_url="$origin"
if [ -n "${CODEBERG_TOKEN:-}" ]; then
# Inject token into an https remote: https://<token>@host/owner/repo.git
push_url="$(printf '%s' "$origin" | sed -E "s#^https://([^@/]+@)?#https://${CODEBERG_TOKEN}@#")"
fi
# owner/repo from the remote → https://<owner>.codeberg.page/<repo>/
# Handles both https://host/owner/repo(.git) and git@host:owner/repo(.git).
clean="${origin%.git}" # drop trailing .git
repo="${clean##*/}" # last path component
rest="${clean%/*}" # everything before it
owner="${rest##*[:/]}" # component after the last ':' or '/'
pages_url="https://${owner}.codeberg.page/${repo}/"
# --- publish ----------------------------------------------------------------
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
cp -r docs/book/. "$work"/
echo "==> publishing to '$BRANCH'"
(
cd "$work" || exit 1
git init -q
git config user.name "$(git -C "$ROOT" config user.name || echo docs)"
git config user.email "$(git -C "$ROOT" config user.email || echo docs@localhost)"
git add -A
git commit -q -m "docs build $(date -u +%Y-%m-%dT%H:%M:%SZ)"
git push -f "$push_url" "HEAD:$BRANCH"
) || die "push to '$BRANCH' failed"
echo
echo "==> published. Live (allow a minute on first deploy) at:"
echo " $pages_url"