diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a57a4c1c..43d93c9f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ **BREAKING CHANGES** ENHANCEMENTS: +* Add `make docs` to build and preview documentation ([#5007](https://github.com/microsoft/AzureTRE/issues/5007)) ## (0.29.0) (August 14, 2026) **BREAKING CHANGES** diff --git a/Makefile b/Makefile index c315a8795..e26000191 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: bootstrap-init mgmt-deploy mgmt-destroy build-api-image push-api-image tre-deploy tre-destroy letsencrypt +.PHONY: bootstrap-init mgmt-deploy mgmt-destroy build-api-image push-api-image tre-deploy tre-destroy letsencrypt docs .DEFAULT_GOAL := help SHELL:=/bin/bash @@ -265,6 +265,14 @@ lint: ## 🧹 Lint all files lint-docs: LINTER_REGEX_INCLUDE='./docs/.*\|./mkdocs.yml' $(MAKE) lint +# Description: Documentation helper target +# Single target `make docs` will install deps and serve the site locally (default). Set MODE=build for build-only mode. +# Example: make docs -> installs deps and serves site locally +# Example: make docs MODE=build -> installs deps and builds site only +docs: ## Install docs deps and build/serve the MkDocs site + @bash ./devops/scripts/docs.sh $(MODE) + + # Description: Build the bundle with Porter. # # check-params is called at the end since it needs the bundle image, # # so we build it first and then run the check. diff --git a/devops/scripts/docs.sh b/devops/scripts/docs.sh new file mode 100755 index 000000000..163a731e6 --- /dev/null +++ b/devops/scripts/docs.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +set -euo pipefail + +PY=python3 +VENV=.venv +REQS=docs/requirements.txt + +PORT=${PORT:-8000} + +usage(){ + echo "Usage: $0 [build|serve|install]" >&2 + exit 2 +} + +if [ "$#" -gt 1 ]; then + usage +fi + +CMD=${1:-serve} + +if [ ! -f "$REQS" ]; then + echo "Requirements file not found: $REQS" >&2 + exit 1 +fi + +if [ ! -d "$VENV" ]; then + echo "Creating virtualenv at $VENV" + $PY -m venv "$VENV" +fi + +# shellcheck disable=SC1091 +source "$VENV/bin/activate" + +pip install --upgrade pip +pip install -r "$REQS" + +get_free_port() { + local start_port="${1:-8000}" + "$PY" -c " +import socket +start = $start_port +for p in range(start, start + 100): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + try: + s.bind(('127.0.0.1', p)) + print(p) + break + except OSError: + continue +" +} + +case "$CMD" in + build) + echo "Building mkdocs site..." + "$VENV/bin/mkdocs" build --strict + ;; + serve) + FREE_PORT=$(get_free_port "$PORT") + if [ "$FREE_PORT" != "$PORT" ]; then + echo "Port $PORT is in use. Using next available port: $FREE_PORT" + fi + echo "Starting mkdocs serve (http://127.0.0.1:${FREE_PORT})..." + "$VENV/bin/mkdocs" serve -a "127.0.0.1:${FREE_PORT}" + ;; + install) + echo "Installed documentation dependencies into $VENV" + ;; + *) + usage + ;; +esac diff --git a/docs/contributing.md b/docs/contributing.md index 888983d1b..6aaacaf45 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -28,4 +28,29 @@ * [Report an Issue or Make a Suggestion](https://github.com/microsoft/AzureTRE/issues/new/choose) +## Building and Serving Documentation Locally + +To preview and test changes to the documentation site locally: + +* **Serve documentation locally (default)**: + ```bash + make docs + ``` + This installs required dependencies, selects the first available port (starting at `8000`), and starts the local MkDocs server. + + You can also specify a custom port: + ```bash + PORT=8100 make docs + ``` + +* **Build documentation (build-only)**: + ```bash + make docs MODE=build + ``` + +* **Lint documentation files**: + ```bash + make lint-docs + ``` + Thanks! :heart: :heart: :heart: