diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
index 6fe1bae04..82271590b 100644
--- a/.github/workflows/checks.yml
+++ b/.github/workflows/checks.yml
@@ -131,12 +131,20 @@ jobs:
- if: ${{needs.get.outputs.filelist}}
name: Check out repo.
uses: actions/checkout@v6
+ - if: ${{needs.get.outputs.filelist}}
+ name: Install dependencies
+ run: pip3 install titlecase
- if: ${{needs.get.outputs.filelist}}
name: Check markdown meta.
run: |
- pip3 install titlecase
shopt -s globstar extglob
python3 checks/run_meta_check.py ${{needs.get.outputs.filelist}}
+ - if: ${{needs.get.outputs.filelist}}
+ name: Run ARIA reference check (meta checks)
+ run: |
+ pip3 install -r requirements.txt
+ mkdocs build
+ python3 checks/run_aria_check.py
slurmcheck:
name: Check slurm scripts
if: ${{github.event_name != 'workflow_dispatch'|| inputs.checkSlurm}}
@@ -165,3 +173,4 @@ jobs:
fetch-depth: 0
- run: pip3 install -r requirements.txt
- run: ./checks/run_test_build.py
+ - run: python3 checks/run_aria_check.py
diff --git a/checks/run_aria_check.py b/checks/run_aria_check.py
new file mode 100644
index 000000000..aa08dce7c
--- /dev/null
+++ b/checks/run_aria_check.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+"""Check built HTML for broken ARIA id references."""
+
+from html.parser import HTMLParser
+from pathlib import Path
+import sys
+
+
+class AriaParser(HTMLParser):
+ def __init__(self):
+ super().__init__()
+ self.ids = set()
+ self.refs = []
+
+ def handle_starttag(self, tag, attrs):
+ d = dict(attrs)
+ if "id" in d:
+ self.ids.add(d["id"])
+ for key in ["aria-labelledby", "aria-describedby", "aria-controls"]:
+ if key in d:
+ for ref in d[key].split():
+ self.refs.append((key, ref, tag))
+
+
+def main():
+ base = Path("public")
+ if not base.exists():
+ print("::error file=checks/run_aria_check.py,title=missing_public_dir::public folder not found. Run mkdocs build first.")
+ return 1
+
+ broken = []
+ for path in sorted(base.rglob("*.html")):
+ text = path.read_text(encoding="utf-8", errors="ignore")
+ parser = AriaParser()
+ parser.feed(text)
+ for key, ref, tag in parser.refs:
+ if ref not in parser.ids:
+ broken.append((path, key, ref, tag))
+
+ if broken:
+ for path, key, ref, tag in broken:
+ print(f"::error file={path},title=broken_aria_reference,col=0,endColumn=0,line=0::{key} reference '{ref}' missing id in tag <{tag}>")
+ print(f"Found {len(broken)} broken aria references.")
+ return 1
+
+ print("ARIA reference check passed.")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index 3a22347d9..4dee04426 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -108,6 +108,9 @@ From a pull request, the status of these checks can be seen in the 'Checks' tab,
Will give three levels of output, **Errors** (serious issues that will prevent merging into main), **Warnings** (non-critical suggestions for improvement) and **Info** (pedantry).
+### ARIA and accessibility checks
+
+The CI now includes an ARIA reference validation step that checks generated HTML for broken references like `aria-labelledby`, `aria-describedby`, and `aria-controls` IDs. If this check fails, the PR will show an error in the 'Checks' tab and the broken ARIA reference will be indicated.
### Codespace Environment
@@ -170,7 +173,7 @@ After a few minutes, a preview of the source branch will be deployed, a bot will
Assign a reviewer if you wish.
-Adding the tag will cause the request to be merged at midnight, if all checks passed.
+Adding the tag will cause the request to be merged at midnight, if all checks passed.
### Reviewing A Merge Request
diff --git a/docs/index.md b/docs/index.md
index 74440b44c..198f2b8fb 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -31,17 +31,17 @@ Technical documentation for our High Performance Computing (HPC) platforms.
Access the cluster Via the OnDemand web application.
-
+
Resources
What CPUs and GPUs are available on the REANNZ Cluster.
-
+
Data Transfer
Getting your data on and off the cluster.
-
+
Job Scheduler
How to use our job scheduler, Slurm.
diff --git a/overrides/partials/header.html b/overrides/partials/header.html
index ecc51dda4..0df13b6ab 100644
--- a/overrides/partials/header.html
+++ b/overrides/partials/header.html
@@ -1,6 +1,3 @@
-{#-
- This file was automatically generated - do not edit
- -#}
{% set class = "md-header" %}
{% if "navigation.tabs.sticky" in features %}
{% set class = class ~ " md-header--shadow md-header--lifted" %}
@@ -9,10 +6,10 @@
{% endif %}