Skip to content

Local Development

Maintainer material

This page is for people editing and building the course website. Students do not need it.

How to build and preview the course website on your own machine, and how to run the checks before proposing a change.


What you need

Requirement Notes
Python 3.9+ The documentation toolchain is Python-based
Git To clone and branch
A text editor Any editor is fine; the content is plain Markdown

You do not need Node, Ruby, or a JavaScript toolchain. The site is built with MkDocs and the Material for MkDocs theme, both installed from requirements-docs.txt.


Set up

git clone https://github.com/nadeem-majeedch/Software-Project-Management.git
cd Software-Project-Management

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate

pip install -r requirements-docs.txt

The virtual environment keeps the toolchain out of your system Python. .venv/ is already git-ignored.


Preview the site

mkdocs serve

Open http://127.0.0.1:8000. The preview reloads automatically when you save a file, so keep it running while you write.

If port 8000 is busy — common if you have other dev servers running — pick another:

mkdocs serve --dev-addr 127.0.0.1:8010

Validate before you commit

Three groups of checks, in order of speed:

# 1. Structure, naming, and internal links. Needs only Python and PyYAML.
python tools/validate-structure.py
python tools/check-templates.py
python tools/spm-calculators.py --check
python tools/check-public-content.py
python tools/check-workflows.py

# 2. Content integrity: the 32-session curriculum, the lesson standard, the lab
#    standard, and the capstone. Standard library only.
python tools/check-curriculum.py
python tools/check-lessons.py
python tools/check-labs.py
python tools/check-capstone.py

# 3. The authoritative build. Warnings become errors.
mkdocs build --strict

# 4. Verify the output really contains every page. Run this after every build:
#    `--strict` does not fail on files MkDocs excludes by default.
python tools/check-build-output.py

# 5. Contrast, structure, text alternatives, and diagram descriptions.
#    Also reads the built site, so it must follow a build.
python tools/check-accessibility.py

mkdocs build --strict fails on broken internal links, pages missing from nav, malformed configuration, and unrecognised links. If it passes locally, the CI build will pass.

The tools/ scripts are deliberately dependency-light — standard library, or PyYAML at most — so they run even before you have installed the documentation toolchain.


What the checks catch

Tool Catches
validate-structure.py Broken relative links (in docs/ and in the root documents such as README.md), missing nav entries, orphan pages, non-kebab-case filenames, missing or duplicate H1 headings, Markdown tables whose rows disagree on the number of columns
check-curriculum.py A dropped session, a missing module or topic, non-contiguous module sessions, forward prerequisites, non-measurable objectives
check-lessons.py A lesson missing a required section, a numbering gap, or a module whose lessons no longer match its session count
check-labs.py A lab missing its self-check criteria or its lesson link, a lab absent from the index, an answer-key gap
check-templates.py A template missing a required element, a malformed CSV, a template absent from the catalogue
check-capstone.py A missing capstone deliverable, milestone, or rubric dimension; an advanced topic with no lesson
check-public-content.py An unlabelled instructor page, a committed email address or credential, wording that misstates the status of the published answer keys, an inconsistent instructor name
mkdocs build --strict Everything MkDocs itself validates, including bad config and links inside code blocks
check-build-output.py A page that is in the source and in nav but absent from the built site — the failure --strict does not catch — or a lesson whose self-assessment questions and hidden answers have ended up on the wrong side of the rendered disclosure
check-accessibility.py A contrast pair below its WCAG threshold (recomputed from the shipped stylesheet, both colour schemes), a missing contrast override, a skipped heading level, a missing main, skip link, or mobile viewport declaration, an image without alt, a table without a header row, a link with no accessible name, a diagram without accTitle/accDescr
check-workflows.py A deployment configuration that cannot work: wrong triggers or permissions, an uploaded directory that is not site_dir, an action pinned to a branch, a workflow that needs a secret

How the site is organised

mkdocs.yml              site configuration and navigation
docs/                   the published website (docs_dir)
  index.md              homepage
  start-here.md         orientation
  curriculum-roadmap.md the 32-session teaching plan
  course-content/       the 13 modules
  labs/ case-studies/ templates/ self-assessment/
  reference/            glossary and sources
  instructor/           instructor-only material
  contributing/         this section
  assets/               images and diagrams
tools/                  local validators (not published)
site/                   build output (git-ignored)

Everything under docs/ is published. Everything else is not.


Markdown features you can use

The site config enables a specific set of extensions. These are the ones you will actually use:

Feature Syntax
Callout boxes !!! note "Title" (indented body)
Collapsible / hidden answers ??? note "Show answer"
Tabbed content === "Tab name" (indented body)
Mermaid diagrams ```mermaid fenced block
Icons :material-alarm:, usable inside grid cards
Grid cards <div class="grid cards" markdown> … </div>
Checkboxes - [ ] item
Tables, footnotes, task lists standard Markdown

Use these sparingly. The site is meant to be lightweight and distraction-free — a diagram should clarify something a paragraph could not, not decorate a page.


Adding a page — the one thing people forget

A new Markdown file under docs/ must be added to nav in mkdocs.yml. MkDocs warns about pages it finds that are not in the navigation, and --strict turns that warning into a build failure. Add the page, then refresh the preview.

A page can be in nav and still not be published

MkDocs applies a hard-coded exclusion list — ['.*', '/templates/'] — on top of anything in exclude_docs. A file matched by it is dropped from the built site, and MkDocs logs that as an INFO message, not a warning: mkdocs build --strict exits 0 and CI stays green.

docs/templates/ matches that pattern, which is why mkdocs.yml negates the default with exclude_docs: !/templates/. Without those two lines the site publishes with no template library at all while the source, nav, and 150-plus links into it all look correct.

The guard is python tools/check-build-output.py, which reads the built output instead of the source tree and fails if any page is missing. Run it after every build; CI runs it before deploying.


Troubleshooting

Symptom Cause and fix
mkdocs: command not found The virtual environment is not active — run the activate step again
ModuleNotFoundError: material Dependencies not installed — pip install -r requirements-docs.txt
Address already in use Another server holds port 8000 — use --dev-addr with a free port
Build fails on an unknown extension Check the spelling against markdown_extensions in mkdocs.yml
Page is missing from the sidebar It is not in nav
Page is in nav but missing from the built site MkDocs excludes a top-level templates/ directory by default, and logs only an INFO line for excluded files, so --strict still passes. Run python tools/check-build-output.py, and see the note below
A link breaks the structure check but the page looks fine Something that is not a link is being read as one. The validator ignores fenced code and inline code spans, so a path written inside backticks is skipped; a path outside them must resolve
Unexpected build errors after upgrading Recreate the environment: delete .venv/ and repeat setup

Next: Deployment explains how a merged change reaches the live site.