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
10 changes: 2 additions & 8 deletions .github/workflows/docs-build-reusable.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,9 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.x'
- name: Install documentation dependencies
run: pip install --require-hashes -r docs/requirements.txt
env:
PIP_CACHE_DIR: ${{ runner.temp }}/.pip-cache
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
- name: Build documentation
run: mkdocs build --strict
run: uv run --frozen zensical build --strict
working-directory: docs
- name: Save PR metadata
run: echo "${{ github.event.pull_request.number }}" > docs/site/pr-number.txt
Expand Down
4 changes: 4 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
site/
site-base/
site-head/
compare/output/
compare/node_modules/
15 changes: 0 additions & 15 deletions docs/Dockerfile

This file was deleted.

73 changes: 58 additions & 15 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -1,31 +1,74 @@
RUNTIME ?= $(shell sh ../hack/utils.sh get_container_engine)
version := $(shell awk -f image-version.awk requirements.txt)
VERSION ?= $(if $(MKDOCS_TAG),$(MKDOCS_TAG),$(version))
IMG ?= quay.io/hypershift/mkdocs-material:$(VERSION)
IMG ?= docker.io/zensical/zensical:0.0.51
BASE ?= main

.PHONY: build
build:
mkdocs build
uv run --frozen zensical build --strict

.PHONY: build-containerized
build-containerized:
$(RUNTIME) volume create --ignore hypershift-docs-site
$(RUNTIME) run --rm -it \
-v ${PWD}:/home/docs/hypershift:Z \
-v hypershift-docs-site:/home/docs/hypershift/site \
-v ${PWD}:/docs:Z \
-v hypershift-docs-site:/docs/site \
$(IMG) build --strict

.PHONY: serve-containerized
serve-containerized:
$(RUNTIME) run --rm -it -p 8000:8000 \
-v ${PWD}:/home/docs/hypershift:Z \
-v hypershift-docs-site:/home/docs/hypershift/site \
$(IMG) serve --dev-addr 0.0.0.0:8000
-v ${PWD}:/docs:Z \
-v hypershift-docs-site:/docs/site \
$(IMG)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

.PHONY: image
image:
$(RUNTIME) build -t $(IMG) .
# Visual comparison between the current working tree and a base ref (default: main).
#
# make compare # compare against main
# make compare BASE=v4.18 # compare against a tag
#
# The report is written to compare/output/ and served on http://127.0.0.1:8883.
.PHONY: compare
compare: compare-build compare-run

.PHONY: push
push:
$(RUNTIME) push $(IMG)
.PHONY: compare-build
compare-build: compare-build-base compare-build-head

.PHONY: compare-build-base
compare-build-base:
@BASE_SHA=$$(git -C .. rev-parse "$(BASE)"); \
if [ -f site-base/.commit ] && [ "$$(cat site-base/.commit)" = "$$BASE_SHA" ]; then \
echo "site-base is up to date ($$BASE_SHA), skipping"; \
else \
rm -rf site-base; \
echo "Building base site from $(BASE) ($$BASE_SHA)..."; \
WORKTREE=$$(mktemp -d); \
trap 'git -C .. worktree remove --force "$$WORKTREE" 2>/dev/null' EXIT; \
git -C .. worktree add --detach "$$WORKTREE" "$(BASE)"; \
cd "$$WORKTREE/docs" && uv run --frozen zensical build -d "$(CURDIR)/site-base"; \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

base_ref="${BASE:-main}"

for path in docs/pyproject.toml docs/uv.lock docs/requirements.txt docs/Makefile; do
  if git cat-file -e "$base_ref:$path" 2>/dev/null; then
    printf '== %s:%s ==\n' "$base_ref" "$path"
    git show "$base_ref:$path" | sed -n '1,160p'
  else
    printf 'MISSING %s:%s\n' "$base_ref" "$path"
  fi
done

printf '== build-tool references ==\n'
git show "$base_ref:docs/Makefile" 2>/dev/null |
  rg -n 'mkdocs|zensical|uv run|pip' || true

Repository: openshift/hypershift

Length of output: 12762


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '== docs/Makefile =='
cat -n docs/Makefile | sed -n '1,110p'

printf '%s\n' '== relevant changes =='
git diff -- docs/Makefile | sed -n '1,220p'

printf '%s\n' '== related comparison/build references =='
rg -n -C 3 'WORKTREE|BASE|site-base|zensical|mkdocs|verify-parallel|comparison' . \
  -g 'Makefile' -g '*.yml' -g '*.yaml' -g '*.md' -g '*.sh'

Repository: openshift/hypershift

Length of output: 50377


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '== docs/Makefile =='
cat -n docs/Makefile | sed -n '1,100p'

printf '%s\n' '== docs/Makefile diff =='
git diff --unified=30 -- docs/Makefile | sed -n '1,240p'

printf '%s\n' '== narrow references =='
rg -n -C 5 'WORKTREE|site-base|BASE|zensical|mkdocs|verify-parallel' \
  docs/Makefile Makefile .github docs \
  -g 'Makefile' -g '*.yml' -g '*.yaml' -g '*.md' -g '*.sh' \
  --glob '!docs/site/**' --glob '!docs/site-base/**' \
  | sed -n '1,320p'

Repository: openshift/hypershift

Length of output: 21023


Build the base site with the toolchain from BASE. For the default main ref, docs/pyproject.toml and docs/uv.lock are absent, while docs/Makefile uses mkdocs build. Line 47 therefore cannot reliably build the base site. Use the BASE build command and dependency files, or add a compatibility path for MkDocs Material.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/Makefile` at line 47, The base-site build command in the Makefile target
must use the toolchain and dependency files from BASE rather than assuming the
worktree contains Zensical configuration. Update the command around the
BASE/worktree build flow to invoke BASE’s established build command with its
pyproject.toml and uv.lock, while preserving the existing output directory.

echo "$$BASE_SHA" > site-base/.commit; \
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.

.PHONY: compare-build-head
compare-build-head:
@rm -rf site-head site; \
echo "Building head site from working tree..."; \
uv run --frozen zensical build -f mkdocs.yml; \
mv site site-head

.PHONY: compare-run
compare-run:
cd compare && pnpm install --frozen-lockfile
cd compare && pnpm exec playwright install chromium
cd compare && node compare.mjs ../site-base ../site-head --output output
@echo ""
@echo "Report: compare/output/index.html"
@echo "Run 'make compare-serve' to view in a browser."

.PHONY: compare-serve
compare-serve:
@echo "Serving report at http://127.0.0.1:8883"
@cd compare/output && python3 -m http.server 8883 --bind 127.0.0.1

.PHONY: compare-clean
compare-clean:
rm -rf site-base site-head compare/output
50 changes: 20 additions & 30 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,39 @@ Any changes to the docs in this directory can be tested locally before pushing c
steps:

1. cd to this directory
2. Run `make image` to build the image
3. Run `make build-containerized` to build the containerized version of the image
4. Run `make serve-containerized` to serve up the docs website locally
2. Run `make build-containerized` to build the docs inside a container
3. Run `make serve-containerized` to serve the docs website locally

Any changes you make while the docs are served locally, will be updated in the local docs website.

## Managing Python dependencies
## Configuration

The site configuration lives in `mkdocs.yml`. Zensical still uses the MkDocs
configuration format; once Zensical ships a migration tool for its native TOML
config, we will switch over.

`requirements.txt` pins every Python dependency needed to build the docs
(mkdocs and its plugins) to an exact version and includes
`--hash=sha256:...` entries for each published artifact, enabling pip's
hash-checking mode (`pip install --require-hashes`). This is what
`.github/workflows/docs-build-reusable.yaml` installs before running
`mkdocs build --strict`.
## Managing Python dependencies

Because hash-checking mode requires every installed package — including
transitive dependencies of mkdocs-material, mkdocs-mermaid2-plugin, and
mkdocs-glightbox — to be pinned and hashed, the file lists the full resolved
dependency closure, not just the three plugins imported directly.
Dependencies are declared in `pyproject.toml` and locked with
[`uv`](https://docs.astral.sh/uv/) into `uv.lock`, which pins every
direct and transitive package to an exact version with hash verification
for supply chain security. This is what
`.github/workflows/docs-build-reusable.yaml` uses when running
`uv run --frozen zensical build --strict`.

### Adding or updating a dependency

1. Add or update the package's version constraint in `requirements.txt`
(e.g. `newplugin>=1.0.0`, or bump an existing `==` pin).
2. Regenerate the file with [`uv`](https://docs.astral.sh/uv/), compiling to
a new temporary path rather than overwriting `requirements.txt` directly,
then move it into place:
1. Add or update the package in `pyproject.toml`
(e.g. add `"newplugin>=1.0.0"` to `dependencies`, or bump an existing pin).
2. Regenerate the lockfile:

```bash
uv pip compile --generate-hashes docs/requirements.txt -o /tmp/requirements.txt.new
mv /tmp/requirements.txt.new docs/requirements.txt
uv lock
```

This resolves the full dependency graph, pins every package (direct and
transitive) to an exact version, and adds `--hash=sha256:...` entries for
all of its published wheel/sdist artifacts. Don't edit hashes by hand —
always regenerate so they're guaranteed to match the published artifact.
3. Validate the result, forcing pip to actually verify every package's hash
rather than skipping ones already present locally:
3. Confirm the docs still build:

```bash
pip install --dry-run --ignore-installed --require-hashes -r docs/requirements.txt
uv run --frozen zensical build --strict
```

4. Confirm the docs still build: `cd docs && mkdocs build --strict`
(after installing the regenerated requirements into your environment).
Loading
Loading