Skip to content

CI/CD Pipeline - GitHub Pages Documentation

Overview

Automated pipeline for building and deploying MkDocs documentation to GitHub Pages.

Pipeline Flow:

Local Commit → GitHub Push → GitHub Actions (pages.yml) → GitHub Pages → wiki.scandora.net

Result: Private documentation automatically deployed at https://wiki.scandora.net (restricted to GitHub repository members)

Components

1. GitHub Repository (Primary)

Repository: scandora/scandora.net Branch: main Purpose: Primary source of truth; documentation source lives in docs/

2. GitHub Actions (Build + Deploy)

Workflow: .github/workflows/pages.yml Trigger: Every push to main branch, manual dispatch Jobs:

Job Runner What It Does
build ubuntu-latest Installs MkDocs Material, runs mkdocs build --strict, uploads site/ as Pages artifact
deploy ubuntu-latest Deploys artifact to GitHub Pages via OIDC (no secrets required)

Permissions:

permissions:
  contents: read
  pages: write
  id-token: write

No secrets required — uses OIDC federation (id-token: write) for secure deployment.

3. GitHub Pages (Hosting)

URL: https://wiki.scandora.net Access: Restricted to GitHub repository members Updates: Automatic on every successful build Content: MkDocs documentation with Material theme Custom Domain: wiki.scandora.net (CNAME → scandora.github.io)

DNS Configuration

The custom domain is managed in Terraform:

File: cloud/terraform/environments/production/network/cloudflare-dns/records.tf

Record Type Value
wiki.scandora.net CNAME scandora.github.io (DNS-only, TTL 3600)
_github-pages-challenge-scandora.wiki.scandora.net TXT GitHub domain verification token

Apply changes:

scripts/terraform/tf-run.sh network cloudflare-dns plan
scripts/terraform/tf-run.sh network cloudflare-dns apply

Local Development

Preview Locally

# Install dependencies (one-time)
pip install -r requirements-docs.txt

# Serve locally
mkdocs serve
# Opens http://localhost:8000

Validate Before Commit

The MkDocs validation pre-commit hook runs automatically on every commit:

- id: mkdocs-validate
  name: 📚 MkDocs - Validate documentation
  entry: bash -c 'mkdocs build --strict --quiet'
  files: '^(docs/.*\.md|mkdocs\.yml|requirements-docs\.txt)$'

Catches:

  • Broken links (relative and absolute)
  • Missing files referenced in navigation
  • Invalid markdown syntax
  • MkDocs configuration errors

Manual validation:

mkdocs build --strict --verbose

Monitoring

GitHub Actions Status

# Check recent runs
gh run list --workflow=pages.yml --limit 5

# View specific run logs
gh run view RUN_ID --log

# Trigger a manual deploy
gh workflow run pages.yml

Expected:

  • build job: ~30-45 seconds
  • deploy job: ~10-15 seconds

GitHub Pages Deployment

# Check via GitHub CLI
gh api repos/scandora/scandora.net/pages

# View in browser
https://github.com/scandora/scandora.net/settings/pages

Expected:

  • Status: Active
  • Custom domain: wiki.scandora.net (verified, HTTPS enforced)
  • Source: GitHub Actions

Troubleshooting

Build Failing — Strict Mode Warnings

Symptoms: build job fails with Aborted with N warnings in strict mode!

Common Issues:

  1. Broken relative links:
WARNING - Doc file 'operations/file.md' contains a link '../path/file.md',
but the target is not found

Fix: Reproduce locally with mkdocs build --strict, fix broken link, commit.

  1. Missing nav entry:
WARNING - 'docs/path/file.md' is not found in the docs directory

Fix: Either add the file or remove it from nav: in mkdocs.yml.

  1. Missing dependencies:
ERROR: Could not find a version that satisfies the requirement

Fix: Update requirements-docs.txt.

Pages Not Updating

Symptoms: wiki.scandora.net shows old content

Check:

  1. Confirm pages.yml run completed successfully: gh run list --workflow=pages.yml --limit 3
  2. Check deployment status: gh api repos/scandora/scandora.net/pages
  3. Hard-refresh browser (Cmd+Shift+R)
  4. Wait ~1 minute for DNS/CDN propagation

Custom Domain Not Working

Symptoms: wiki.scandora.net returns 404 or cert error

Check:

  1. Verify DNS: dig wiki.scandora.net CNAME → should return scandora.github.io
  2. Verify TXT record: dig _github-pages-challenge-scandora.wiki.scandora.net TXT
  3. Check GitHub Pages settings: Custom domain should show "DNS check successful"
  4. Confirm Terraform records were applied: scripts/terraform/tf-run.sh network cloudflare-dns plan

Configuration Files

Required Files

File Purpose
.github/workflows/pages.yml GitHub Actions build + deploy workflow
mkdocs.yml MkDocs site configuration (site_url: https://wiki.scandora.net)
docs/CNAME Custom domain declaration for GitHub Pages
requirements-docs.txt Python dependencies for building docs
.pre-commit-config.yaml Pre-commit hooks including MkDocs validation
cloud/terraform/environments/production/network/cloudflare-dns/records.tf CNAME + TXT DNS records

GitHub Repository Settings

Setting Value
Settings → Pages → Source GitHub Actions
Settings → Pages → Custom domain wiki.scandora.net
Settings → Pages → Restrict access Repository members only
Settings → Pages → Enforce HTTPS Enabled