diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index a0a2ac7e7..3cd6beec9 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -3,24 +3,104 @@ on:
push:
branches:
- develop
+
+ tags:
+ - 'v*'
+
+ paths:
+ - 'docs/**'
+ - 'mkdocs.yml'
+ - '.github/workflows/docs.yml'
+
permissions:
contents: write
+
+concurrency:
+ group: docs-deploy
+ cancel-in-progress: false
+
jobs:
deploy:
runs-on: ubuntu-latest
+
steps:
- name: Checkout Repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
fetch-depth: 0
+
- name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
- python-version: 3.x
+ python-version: '3.x'
+
- name: Install Dependencies
run: |
- pip3 install mkdocs-material
+ pip3 install mkdocs-material mike
pip3 install mkdocs-git-revision-date-localized-plugin
pip3 install mkdocs-redirects
- - name: Publish Shiled Documentation
- run: mkdocs gh-deploy --force
+
+ - name: Fetch gh-pages
+ run: git fetch origin gh-pages --depth=1 || true
+
+ - name: Configure git
+ run: |
+ git config user.name github-actions[bot]
+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
+
+ - name: Deploy docs with mike
+ shell: bash
+ run: |
+ set -e
+
+ deploy_version () {
+ local VERSION="$1"
+ local UPDATE_LATEST="${2:-false}"
+
+ VERSION="${VERSION#v}"
+
+ MINOR=$(echo "$VERSION" | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
+
+ echo "Deploying docs version: $MINOR"
+
+ if [ "$UPDATE_LATEST" = "true" ]; then
+ mike deploy --push --update-aliases "$MINOR" latest
+ return
+ fi
+
+ mike deploy --push "$MINOR"
+ }
+
+ #
+ # Develop branch
+ #
+ if [ "${{ github.ref_type }}" = "branch" ] && [ "${{ github.ref_name }}" = "develop" ]; then
+ echo "Deploying dev docs"
+
+ mike deploy --push dev
+
+ exit 0
+ fi
+
+ #
+ # Release tags
+ #
+ if [ "${{ github.ref_type }}" = "tag" ]; then
+ VERSION="${{ github.ref_name }}"
+
+ if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+ echo "Skipping non-stable release tag: $VERSION"
+ exit 0
+ fi
+
+ deploy_version "$VERSION" true
+
+ echo "Setting default docs version: latest"
+
+ mike set-default --push latest
+
+ exit 0
+ fi
+
+ echo "Unsupported ref"
+ exit 1
diff --git a/admin/how_to_build_docs.md b/admin/how_to_build_docs.md
index 9162fd73b..f6b1d2cca 100644
--- a/admin/how_to_build_docs.md
+++ b/admin/how_to_build_docs.md
@@ -15,25 +15,57 @@ pip3 install mkdocs
pip3 install mkdocs-material
pip3 install mkdocs-git-revision-date-localized-plugin
pip3 install mkdocs-redirects
+pip3 install mike
```
## Build the Docs
-```consolse
+```console
mkdocs build
```
## See the Docs
-```consolse
+```console
mkdocs serve
```
+To preview the versioned site (with the version selector), use `mike` instead:
+
+```console
+mike serve
+```
+
+## Versioning
+
+The published documentation is versioned with
+[mike](https://github.com/jimporter/mike). Each version lives in its own
+subdirectory on the `gh-pages` branch:
+
+- `dev` — the latest `develop` branch.
+- `X.Y` — a published stable release (e.g. `1.5`), with the `latest` alias
+ pointing at the most recent one. `latest` is also the default version users
+ land on.
+
## Deploy Manually
-The documentation is built and deployed automatically by GitHub Actions. But if
-you need to deploy manually, run the following command:
+The documentation is built and deployed automatically by GitHub Actions:
+pushes to `develop` publish the `dev` version, and pushing a `vX.Y.Z` tag
+publishes the matching `X.Y` version and updates `latest`.
+
+> **Warning:** Do **not** run `mkdocs gh-deploy`. It overwrites the root of the
+> `gh-pages` branch and would destroy the versioned structure managed by mike.
+
+If you need to deploy manually, use `mike`. For example, to publish a stable
+release and point `latest` at it:
+
+```console
+mike deploy --push --update-aliases X.Y latest
+mike set-default --push latest
+```
+
+Or to (re)publish the development docs:
```console
-mkdocs gh-deploy
+mike deploy --push dev
```
diff --git a/docs/CNAME b/docs/CNAME
deleted file mode 100644
index c30bf3c28..000000000
--- a/docs/CNAME
+++ /dev/null
@@ -1 +0,0 @@
-shield.codeigniter.com
diff --git a/docs/overrides/main.html b/docs/overrides/main.html
new file mode 100644
index 000000000..bd5293a8a
--- /dev/null
+++ b/docs/overrides/main.html
@@ -0,0 +1,16 @@
+{% extends "base.html" %}
+
+{% block outdated %}
+ {% if config.site_url.rstrip("/").endswith("/dev") %}
+ You're viewing the development version.
+ Some features may not be available in a stable release yet.
+
+ Go to the latest stable version.
+
+ {% else %}
+ You're not viewing the latest version.
+
+ Click here to go to latest.
+
+ {% endif %}
+{% endblock %}
diff --git a/mkdocs.yml b/mkdocs.yml
index 12a177683..73d4466ee 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,8 +1,12 @@
site_name: CodeIgniter Shield
site_description: Documentation for the official Authentication and Authorization framework for CodeIgniter 4
+exclude_docs: |
+ overrides/
+
theme:
name: material
+ custom_dir: docs/overrides
logo: assets/flame.svg
favicon: assets/favicon.ico
icon:
@@ -39,6 +43,8 @@ theme:
extra:
homepage: https://codeigniter.com
generator: false
+ version:
+ provider: mike
social:
- icon: material/github