1 - Technical Architecture
Complete technical architecture guide for the Hugo documentation system with reusable GitHub Actions
1. Overview
The my-documents repository provides a reusable GitHub Action for building and deploying Hugo-based documentation
sites using the Docsy theme. This architecture enables multiple documentation repositories to share common
configurations, layouts, and assets while maintaining their independence.
1.1. Key Features
- Reusable GitHub Action: Single workflow definition used across multiple repositories
- Hugo Go Modules: Share layouts, assets, and configurations without file copying
- No Authentication Complexity: Uses standard
GITHUB_TOKEN (no GitHub Apps or PATs required) - Independent Deployments: Each repository controls its own build and deployment
- Shared Theme Consistency: All sites use the same Docsy theme with consistent styling
- SEO Optimized: Built-in structured data, meta tags, and sitemap generation
1.2. Managed Documentation Sites
2. Building Locally
2.1. Prerequisites
Install the required tools:
- Hugo Extended v0.155.3 or higher (with Go support)
- Go 1.24 or higher
- Git
2.2. Quick Start
# Clone the repository
git clone https://github.com/fchastanet/my-documents.git
cd my-documents
# Download Hugo modules
hugo mod get -u
# Start local development server
hugo server -D
# Open browser to http://localhost:1313/my-documents/
The site will auto-reload when you edit content in content/docs/.
2.3. Building for Production
# Build optimized static site
hugo --minify
# Output is in public/ directory
ls -la public/
3. Reusable Action Architecture
3.1. Architecture Diagram
┌─────────────────────────────────────────────────────────────────┐
│ my-documents Repository (Public) │
│ │
│ ├── .github/workflows/ │
│ │ ├── build-site-action.yml ← Reusable action definition │
│ │ └── build-site.yml ← Own site build │
│ │ │
│ ├── configs/ │
│ │ └── _base.yaml ← Shared base configuration │
│ │ │
│ └── shared/ │
│ ├── layouts/ ← Shared Hugo templates │
│ ├── assets/ ← Shared SCSS, CSS, JS │
│ └── archetypes/ ← Content templates │
│ │
└─────────────────────────────────────────────────────────────────┘
▲
│ Hugo Go Module Import
│
┌──────────────────┼──────────────────┬──────────────────┐
│ │ │ │
▼ ▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌──────────────┐
│ bash-compiler │ │ bash-tools │ │ bash-dev-env │ │ Other Repos │
│ │ │ │ │ │ │ │
│ go.mod │ │ go.mod │ │ go.mod │ │ go.mod │
│ hugo.yaml │ │ hugo.yaml │ │ hugo.yaml │ │ hugo.yaml │
│ content/ │ │ content/ │ │ content/ │ │ content/ │
│ │ │ │ │ │ │ │
│ .github/ │ │ .github/ │ │ .github/ │ │ .github/ │
│ workflows/ │ │ workflows/ │ │ workflows/ │ │ workflows/ │
│ build-site │ │ build-site │ │ build-site │ │ build-site │
│ .yml │ │ .yml │ │ .yml │ │ .yml │
│ │ │ │ │ │ │ │ │ │ │ │
│ └─────────┼──┼─────┼─────────┼──┼─────┼─────────┼──┼─────┘ │
│ │ │ │ │ │ │ │
└───────────────┘ └───────────────┘ └───────────────┘ └──────────────┘
│ │ │ │
└──────────────────┴──────────────────┴──────────────────┘
│
│ Calls reusable action
▼
fchastanet/my-documents/
.github/workflows/build-site-action.yml
│
▼
┌────────────────────────┐
│ 1. Checkout repo │
│ 2. Setup Hugo │
│ 3. Setup Go │
│ 4. Download modules │
│ 5. Build with Hugo │
│ 6. Deploy to Pages │
└────────────────────────┘
3.2. How It Works
The reusable action architecture follows this workflow:
- Developer pushes content to a documentation repository (e.g.,
bash-compiler) - GitHub Actions triggers the
build-site.yml workflow in that repository - Workflow calls
my-documents/.github/workflows/build-site-action.yml (reusable action) - Hugo downloads modules including
my-documents for shared resources - Hugo builds site using merged configuration (base + site-specific overrides)
- GitHub Pages deploys the static site from the build artifact
3.3. Key Benefits
- Zero Authentication Setup: No GitHub Apps, deploy keys, or PAT tokens required
- Independent Control: Each repository owns its build and deployment
- Shared Consistency: All sites use the same theme, layouts, and styling
- Easy Maintenance: Update reusable action once, all sites benefit
- Fast Builds: Parallel execution across repositories (~30-60s per site)
- Simple Testing: Test locally with standard
hugo server command
4. Creating a New Documentation Site
4.1. Prerequisites
Before creating a new documentation site, ensure you have:
4.2. Step-by-Step Guide
4.2.1. Create Content Structure
Create the standard Hugo directory structure in your repository:
# Create required directories
mkdir -p content/docs
mkdir -p static
# Create homepage
cat >content/_index.md <<'EOF'
---
title: My Project Documentation
description: Welcome to My Project documentation
---
# Welcome to My Project
This is the documentation homepage.
EOF
# Create first documentation page
cat >content/docs/_index.md <<'EOF'
---
title: Documentation
linkTitle: Docs
weight: 20
menu:
main:
weight: 20
---
# Documentation
Welcome to the documentation section.
EOF
4.2.2. Add go.mod for Hugo Modules
Create go.mod in the repository root:
module github.com/YOUR-USERNAME/YOUR-REPO
go 1.24
require (
github.com/google/docsy v0.11.0 // indirect
github.com/google/docsy/dependencies v0.7.2 // indirect
github.com/fchastanet/my-documents master // indirect
)
Replace YOUR-USERNAME/YOUR-REPO with your actual repository path.
4.2.3. Create hugo.yaml with Base Import
Create hugo.yaml in the repository root:
# Import base configuration from my-documents
imports:
- path: github.com/fchastanet/my-documents/configs/_base.yaml
# Site-specific overrides
baseURL: https://YOUR-USERNAME.github.io/YOUR-REPO
title: Your Project Documentation
languageCode: en-us
# Module configuration
module:
# Import my-documents for shared resources
imports:
- path: github.com/fchastanet/my-documents
mounts:
# Mount shared layouts
- source: shared/layouts
target: layouts
# Mount shared assets
- source: shared/assets
target: assets
# Mount shared archetypes
- source: shared/archetypes
target: archetypes
- path: github.com/google/docsy
- path: github.com/google/docsy/dependencies
# Site-specific parameters
params:
description: Documentation for Your Project
# Customize theme colors
ui:
navbar_bg_color: '#007bff' # Blue - choose your color
sidebar_menu_compact: false
# Repository configuration
github_repo: https://github.com/YOUR-USERNAME/YOUR-REPO
github_branch: master
# Enable search
offlineSearch: true
Replace placeholders:
YOUR-USERNAME with your GitHub usernameYOUR-REPO with your repository name- Adjust
navbar_bg_color for your preferred theme color
4.2.4. Add build-site.yml Workflow
Create .github/workflows/build-site.yml:
name: Build and Deploy Documentation
on:
push:
branches: [master]
paths:
- content/**
- static/**
- hugo.yaml
- go.mod
- .github/workflows/build-site.yml
workflow_dispatch:
# Required permissions for GitHub Pages deployment
permissions:
contents: read
pages: write
id-token: write
# Prevent concurrent deployments
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build-deploy:
name: Build and Deploy
uses: fchastanet/my-documents/.github/workflows/build-site-action.yml@master
with:
site-name: YOUR-REPO
base-url: https://YOUR-USERNAME.github.io/YOUR-REPO
checkout-repo: YOUR-USERNAME/YOUR-REPO
permissions:
contents: read
pages: write
id-token: write
Replace:
YOUR-USERNAME with your GitHub usernameYOUR-REPO with your repository name
Important: Ensure the workflow file has Unix line endings (LF), not Windows (CRLF).
4.2.5. Configure GitHub Pages
In your repository settings:
- Navigate to Settings → Pages
- Under Source, select GitHub Actions
- Click Save
Note
With GitHub Actions as the source, Pages will deploy from workflow artifacts
automatically. You do NOT need to select a branch like gh-pages.
4.2.6. Test and Deploy
Test locally first:
# Download modules
hugo mod get -u
# Start development server
hugo server -D
# Verify site at http://localhost:1313/
Deploy to GitHub Pages:
# Commit all files
git add .
git commit -m "Add Hugo documentation site"
# Push to trigger workflow
git push origin master
Monitor deployment:
- Go to Actions tab in your repository
- Watch the “Build and Deploy Documentation” workflow
- Once complete (green checkmark), visit your site at
https://YOUR-USERNAME.github.io/YOUR-REPO
4.3. Post-Creation Checklist
After creating your site, verify:
5. GitHub Configuration
5.1. GitHub Pages Settings
Required Configuration:
- Source: GitHub Actions (NOT a branch)
- Custom Domain: Optional
- Enforce HTTPS: Recommended (enabled by default)
Why GitHub Actions Source?
Using GitHub Actions as the Pages source allows workflows to deploy directly using the actions/deploy-pages action.
This is simpler than pushing to a gh-pages branch and more secure.
5.2. Workflow Permissions
Your build-site.yml workflow requires these permissions:
permissions:
contents: read # Read repository content
pages: write # Deploy to GitHub Pages
id-token: write # OIDC token for deployment
These permissions are:
- Scoped to the workflow: Only this workflow has these permissions
- Automatic: No manual configuration required
- Secure: Uses GitHub’s OIDC authentication
5.3. No Secrets Required
Unlike traditional approaches, this architecture requires zero secrets:
- ❌ No GitHub App credentials
- ❌ No Personal Access Tokens (PAT)
- ❌ No Deploy Keys
- ✅ Standard
GITHUB_TOKEN provided automatically
The workflow uses GitHub’s built-in authentication, making setup simple and secure.
6. Hugo Configuration Details
6.1. go.mod Structure
The go.mod file declares Hugo module dependencies:
module github.com/fchastanet/bash-compiler
go 1.24
require (
github.com/google/docsy v0.11.0 // indirect
github.com/google/docsy/dependencies v0.7.2 // indirect
github.com/fchastanet/my-documents master // indirect
)
Key Components:
- Module name: Must match your repository path
- Go version: 1.24 or higher recommended
- Docsy theme: Version 0.11.0 (update as needed)
- Docsy dependencies: Bootstrap, Font Awesome, etc.
- my-documents: Provides shared layouts and assets
Updating Modules:
# Update all modules to latest versions
hugo mod get -u
# Update specific module
hugo mod get -u github.com/google/docsy
# Tidy module dependencies
hugo mod tidy
6.2. hugo.yaml Structure
The hugo.yaml configuration file has two main parts:
6.2.1. Imports Section
# Import base configuration from my-documents
imports:
- path: github.com/fchastanet/my-documents/configs/_base.yaml
This imports shared configuration including:
- Hugo modules setup
- Markup and syntax highlighting
- Output formats (HTML, RSS, sitemap)
- Default theme parameters
- Language and i18n settings
6.2.2. Site-Specific Configuration
Override base settings for your site:
baseURL: https://bash-compiler.devlab.top
title: Bash Compiler Documentation
languageCode: en-us
module:
imports:
- path: github.com/fchastanet/my-documents
mounts:
- source: shared/layouts
target: layouts
- source: shared/assets
target: assets
- source: shared/archetypes
target: archetypes
- path: github.com/google/docsy
- path: github.com/google/docsy/dependencies
params:
description: Documentation for Bash Compiler
ui:
navbar_bg_color: '#007bff'
github_repo: https://github.com/fchastanet/bash-compiler
offlineSearch: true
6.3. Configuration Inheritance
Hugo merges configurations in this order:
- Base configuration (
_base.yaml from my-documents) - Site-specific overrides (your
hugo.yaml)
Merge Behavior:
- Scalar values: Site-specific overrides base
- Objects: Deep merge (keys combined)
- Arrays: Site-specific replaces base entirely
Example:
# Base (_base.yaml)
params:
ui:
showLightDarkModeMenu: true
navbar_bg_color: "#563d7c"
copyright: "My Documents"
# Site-specific (hugo.yaml)
params:
ui:
navbar_bg_color: "#007bff"
copyright: "Bash Compiler"
# Result (merged)
params:
ui:
showLightDarkModeMenu: true # From base
navbar_bg_color: "#007bff" # Overridden
copyright: "Bash Compiler" # Overridden
6.4. Site-Specific Overrides
Common parameters to override per site:
Required:
baseURL: https://YOUR-USER.github.io/YOUR-REPO
title: Your Site Title
params:
description: Your site description
github_repo: https://github.com/YOUR-USER/YOUR-REPO
Optional Theme Customization:
params:
ui:
navbar_bg_color: '#007bff' # Navbar color
sidebar_menu_compact: false # Sidebar style
navbar_logo: true # Show logo in navbar
links:
user:
- name: GitHub
url: https://github.com/YOUR-USER/YOUR-REPO
icon: fab fa-github
Navigation Menu:
menu:
main:
- name: Documentation
url: /docs/
weight: 10
- name: Blog
url: /blog/
weight: 20
7. Workflow Configuration
7.1. build-site.yml Structure
The build-site.yml workflow in each repository calls the reusable action:
name: Build and Deploy Documentation
on:
push:
branches: [master]
paths:
- content/**
- static/**
- hugo.yaml
- go.mod
- .github/workflows/build-site.yml
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build-deploy:
name: Build and Deploy
uses: fchastanet/my-documents/.github/workflows/build-site-action.yml@master
with:
site-name: bash-compiler
base-url: https://bash-compiler.devlab.top
checkout-repo: fchastanet/bash-compiler
permissions:
contents: read
pages: write
id-token: write
7.2. Calling the Reusable Action
The uses keyword calls the reusable action:
uses: fchastanet/my-documents/.github/workflows/build-site-action.yml@master
Format: OWNER/REPO/.github/workflows/WORKFLOW.yml@REF
- OWNER/REPO:
fchastanet/my-documents (the provider repository) - WORKFLOW:
build-site-action.yml (the reusable workflow file) - REF:
master (or specific tag/commit for stability)
7.3. Required Parameters
These parameters must be provided with with:
with:
site-name: bash-compiler
base-url: https://bash-compiler.devlab.top
checkout-repo: fchastanet/bash-compiler
Parameter Details:
- site-name: Identifier for the site (used in artifacts and jobs)
- base-url: Full base URL where site will be deployed
- checkout-repo: Repository to checkout (format:
owner/repo)
7.4. Optional Parameters
The reusable action may support additional parameters:
with:
hugo-version: 0.155.3 # Default: latest
go-version: '1.24' # Default: 1.24
extended: true # Default: true (Hugo Extended)
working-directory: . # Default: repository root
Check the reusable action definition for all available parameters.
7.5. Triggers Configuration
Trigger on Content Changes:
on:
push:
branches: [master]
paths:
- content/**
- static/**
- hugo.yaml
- go.mod
This triggers the workflow only when documentation-related files change, saving CI minutes.
Trigger Manually:
Allows manual workflow runs from the GitHub Actions UI.
Trigger on Schedule:
on:
schedule:
- cron: 0 0 * * 0 # Weekly on Sunday at midnight UTC
Useful for rebuilding with updated dependencies.
7.6. Permissions Details
Why These Permissions?
permissions:
contents: read # Clone repository and read content
pages: write # Upload artifact and deploy to Pages
id-token: write # Generate OIDC token for deployment
Scope:
- Permissions apply only to this workflow
- Defined at both workflow and job level for clarity
- More restrictive than repository-wide settings
Security Note:
Never grant contents: write unless absolutely necessary. The reusable action only needs read access.
8. Shared Resources Access
8.1. Hugo Go Modules Setup
Hugo modules enable sharing resources across repositories without file copying.
Module Declaration (go.mod):
require (
github.com/fchastanet/my-documents master // indirect
)
Download Modules:
# Download all declared modules
hugo mod get -u
# Verify modules downloaded
hugo mod graph
8.2. Accessing Layouts from my-documents
Module Mount Configuration:
module:
imports:
- path: github.com/fchastanet/my-documents
mounts:
- source: shared/layouts
target: layouts
Available Layouts:
shared/layouts/
├── partials/
│ └── hooks/
│ └── head-end.html # SEO meta tags, JSON-LD
├── shortcodes/
│ └── custom-shortcode.html # Custom shortcodes
└── _default/
└── baseof.html # Optional: base template override
Using Shared Partials:
<!-- In your custom layout -->
{{ partial "hooks/head-end.html" . }}
Override Priority:
- Local
layouts/ directory (highest priority) - Mounted
shared/layouts/ from my-documents - Docsy theme layouts (lowest priority)
8.3. Accessing Assets from my-documents
Module Mount Configuration:
module:
imports:
- path: github.com/fchastanet/my-documents
mounts:
- source: shared/assets
target: assets
Available Assets:
shared/assets/
└── scss/
└── _variables_project.scss # SCSS variables
Using Shared SCSS:
// Auto-imported by Docsy
// Defines custom variables used across all sites
$primary: #007bff;
$secondary: #6c757d;
Override Site-Specific Styles:
Create assets/scss/_variables_project.scss in your repository:
// Override specific variables
$primary: #ff6600; // Orange theme
// Import base variables for other defaults
@import "shared/scss/variables_project";
8.4. Accessing Archetypes from my-documents
Module Mount Configuration:
module:
imports:
- path: github.com/fchastanet/my-documents
mounts:
- source: shared/archetypes
target: archetypes
Available Archetypes:
shared/archetypes/
├── default.md # Default content template
└── docs.md # Documentation page template
Using Archetypes:
# Create new page using docs archetype
hugo new content/docs/guide.md
# Uses shared/archetypes/docs.md template
Archetype Example (docs.md):
---
title: "{{ replace .Name "-" " " | title }}"
description: ""
weight: 10
categories: []
tags: []
---
## 9. Overview
Brief overview of this topic.
## 10. Details
Detailed content here.
10.1. Module Mounts Configuration
Complete mounts example:
module:
imports:
# Mount my-documents shared resources
- path: github.com/fchastanet/my-documents
mounts:
- source: shared/layouts
target: layouts
- source: shared/assets
target: assets
- source: shared/archetypes
target: archetypes
# Mount Docsy theme
- path: github.com/google/docsy
disable: false
# Mount Docsy dependencies (Bootstrap, etc.)
- path: github.com/google/docsy/dependencies
disable: false
Mount Options:
- source: Path in the module repository
- target: Where to mount in your site
- disable: Set to
true to temporarily disable
Debugging Mounts:
# Show module dependency graph
hugo mod graph
# Verify mounts configuration
hugo config mounts
11. Troubleshooting
11.1. Workflow Not Running
Problem: Workflow doesn’t trigger on push
Solutions:
Check file paths in trigger:
on:
push:
paths:
- content/**
- static/**
- hugo.yaml
Ensure changed files match these patterns.
Verify branch name:
on:
push:
branches: [master] # Check your default branch name
Check workflow syntax:
# Validate YAML syntax
yamllint .github/workflows/build-site.yml
Permissions issue: Ensure Actions are enabled in repository settings:
- Settings → Actions → General → “Allow all actions and reusable workflows”
11.2. Hugo Build Failures
Problem: Hugo build fails with errors
Common Causes and Solutions:
11.2.1. Missing Modules
Error: module "github.com/fchastanet/my-documents" not found
Solution:
# Ensure module declared in go.mod
hugo mod get -u
# Verify modules
hugo mod graph
11.2.2. Configuration Errors
Error: failed to unmarshal YAML
Solution:
# Validate YAML syntax
yamllint hugo.yaml
# Check Hugo config
hugo config
11.2.3. Front Matter Errors
Error: invalid front matter
Solution:
<!-- Ensure front matter uses valid YAML -->
---
title: "My Page"
date: 2024-02-22
draft: false
---
11.2.4. Template Errors
Error: template: partial "missing.html" not found
Solution:
# Check partial exists in layouts/partials/
ls shared/layouts/partials/
# Verify module mounts
hugo config mounts
11.3. Hugo Modules Issues
Problem: Modules not updating or wrong version
Solutions:
Clean module cache:
hugo mod clean
hugo mod get -u
Verify module versions:
# Show dependency graph
hugo mod graph
# Check go.sum for versions
cat go.sum
Force module update:
# Remove go.sum and rebuild
rm go.sum
hugo mod get -u
hugo mod tidy
Check module path:
# Ensure correct repository path
imports:
- path: github.com/fchastanet/my-documents
11.4. Deployment Failures
Problem: Build succeeds but deployment fails
Solutions:
Check Pages source:
- Settings → Pages → Source must be “GitHub Actions”
Verify permissions:
permissions:
contents: read
pages: write
id-token: write
Check deployment logs:
- Actions tab → Click workflow run → Expand “Deploy to GitHub Pages” step
Concurrency conflict:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true # Cancel in-progress runs to ensure only the latest commit is deployed
Artifact upload size:
# Check public/ directory size
du -sh public/
# GitHub has 10GB limit per artifact
# Optimize images and remove unnecessary files
11.5. Content and Link Issues
Problem: Broken links or missing pages
Solutions:
Check relative links:
<!-- Correct -->
[Guide](/docs/guide/)
<!-- Incorrect -->
[Guide](docs/guide/) <!-- Missing leading slash -->
Verify baseURL:
# Must match deployment URL exactly
baseURL: https://username.github.io/repo-name
Check content organization:
content/
└── en/
├── _index.md
└── docs/
├── _index.md
└── guide.md
Front matter issues:
---
title: "Guide"
# Check for typos in keys
linkTitle: "User Guide"
weight: 10
---
Test links locally:
hugo server -D
# Check all links work at http://localhost:1313
11.6. Debugging Checklist
When troubleshooting, work through this checklist:
Verbose Build Output:
# Local debugging with verbose output
hugo --minify --verbose --debug
# Check Hugo environment
hugo env
Check GitHub Actions Logs:
- Go to repository → Actions tab
- Click failing workflow run
- Expand each step to see detailed output
- Look for ERROR or WARN messages
12. Advanced Topics
12.1. Per-Site Theme Customization
Each site can customize the Docsy theme while maintaining shared base styles.
Color Customization:
# hugo.yaml
params:
ui:
navbar_bg_color: '#007bff' # Blue navbar
sidebar_bg_color: '#f8f9fa' # Light gray sidebar
navbar_text_color: '#ffffff' # White text
Custom SCSS Variables:
Create assets/scss/_variables_project.scss in your repository:
// Override primary color
$primary: #ff6600;
$secondary: #6c757d;
// Custom navbar height
$navbar-height: 70px;
// Import base variables for other defaults
@import "shared/scss/variables_project";
Custom Layouts:
Override specific templates by creating them locally:
layouts/
├── _default/
│ └── single.html # Custom single page layout
├── partials/
│ └── navbar.html # Custom navbar
└── shortcodes/
└── callout.html # Custom shortcode
Priority Order:
- Local
layouts/ (highest) - Mounted
shared/layouts/ from my-documents - Docsy theme layouts (lowest)
Shared SEO features are provided via shared/layouts/partials/hooks/head-end.html:
Automatic SEO Tags:
- Open Graph meta tags
- Twitter Card tags
- JSON-LD structured data
- Canonical URLs
- Sitemap generation
Configure per Page:
---
title: "My Guide"
description: "Comprehensive guide to using the tool"
images: ["/images/guide-preview.png"]
---
Site-Wide SEO:
# hugo.yaml
params:
description: Default site description
images: [/images/site-preview.png]
# Social links for structured data
github_repo: https://github.com/user/repo
# Google Analytics (optional)
google_analytics: G-XXXXXXXXXX
Verify SEO:
# Check generated meta tags
hugo server -D
curl http://localhost:1313/page/ | grep -A5 "og:"
Main Menu Configuration:
# hugo.yaml
menu:
main:
- name: Documentation
url: /docs/
weight: 10
- name: About
url: /about/
weight: 20
- name: GitHub
url: https://github.com/user/repo
weight: 30
pre: <i class='fab fa-github'></i>
Per-Page Menu Entry:
---
title: "API Reference"
menu:
main:
name: "API"
weight: 15
parent: "Documentation"
---
Sidebar Menu:
The sidebar menu is automatically generated from content structure. Control it with:
---
title: "Section"
weight: 10 # Order in menu
linkTitle: "Short Name" # Display name (optional)
---
Disable Menu Item:
---
title: "Hidden Page"
menu:
main:
weight: 0
_build:
list: false
render: true
---
13. Contributing
13.1. How to Contribute to Reusable Action
The reusable action is defined in my-documents/.github/workflows/build-site-action.yml.
Contributing Process:
Fork the repository:
gh repo fork fchastanet/my-documents --clone
cd my-documents
Create a feature branch:
git checkout -b feature/improve-action
Make changes:
- Edit
.github/workflows/build-site-action.yml - Update documentation if needed
- Test changes thoroughly
Commit using conventional commits:
git commit -m "feat(workflows): add support for custom Hugo version"
Push and create PR:
git push origin feature/improve-action
gh pr create --title "Add custom Hugo version support"
13.2. Testing Changes
Test Reusable Action Changes:
Push changes to your fork:
git push origin feature/improve-action
Update dependent repository to use your fork:
# .github/workflows/build-site.yml
jobs:
build-deploy:
uses: |-
YOUR-USERNAME/my-documents/.github/workflows/build-site-action.yml@feature/improve-action
Trigger workflow:
git commit --allow-empty -m "Test workflow"
git push
Verify results:
- Check Actions tab for workflow run
- Ensure build and deployment succeed
- Test deployed site
Test Configuration Changes:
# Test base configuration changes
cd my-documents
hugo server -D
# Test site-specific overrides
cd bash-compiler
hugo mod get -u
hugo server -D
Test Shared Resources:
# Add new shared layout
echo '<meta name="test" content="value">' >shared/layouts/partials/test.html
# Rebuild dependent site
cd ../bash-compiler
hugo mod clean
hugo mod get -u
hugo server -D
# Verify partial available
curl http://localhost:1313 | grep 'name="test"'
13.3. Best Practices
Workflow Development:
- Test thoroughly: Changes affect all dependent sites
- Use semantic versioning: Tag stable versions
- Document parameters: Add clear comments
- Handle errors gracefully: Add validation steps
- Maintain backwards compatibility: Don’t break existing sites
Configuration Updates:
- Test locally first: Verify
hugo config output - Check all sites: Test impact on all dependent repositories
- Document changes: Update this documentation
- Use minimal diffs: Only change what’s necessary
- Validate YAML: Use
yamllint before committing
Shared Resources:
- Keep layouts generic: Avoid site-specific code
- Document usage: Add comments to complex partials
- Version carefully: Breaking changes require coordination
- Test across sites: Ensure compatibility with all sites
- Optimize assets: Minimize SCSS and JS files
Communication:
- Open issues: Discuss major changes before implementing
- Tag maintainers: Use
@mentions for review requests - Document breaking changes: Clearly mark in PR description
- Update changelog: Keep CHANGELOG.md up to date
- Announce deployments: Notify dependent site owners
14. CI/CD Workflows Reference
14.1. build-site-action.yml (Reusable)
Location: my-documents/.github/workflows/build-site-action.yml
Purpose: Reusable workflow called by dependent repositories to build and deploy Hugo sites.
Inputs:
inputs:
site-name:
description: Name of the site being built
required: true
type: string
base-url:
description: Base URL for the site
required: true
type: string
checkout-repo:
description: Repository to checkout (owner/repo)
required: true
type: string
hugo-version:
description: Hugo version to use
required: false
type: string
default: latest
go-version:
description: Go version to use
required: false
type: string
default: '1.24'
Steps:
- Checkout repository: Clones the calling repository
- Setup Hugo: Installs Hugo Extended
- Setup Go: Installs Go (required for Hugo modules)
- Download modules: Runs
hugo mod get -u - Build site: Runs
hugo --minify - Upload artifact: Uploads
public/ directory - Deploy to Pages: Uses
actions/deploy-pages
Usage Example:
jobs:
build-deploy:
uses: fchastanet/my-documents/.github/workflows/build-site-action.yml@master
with:
site-name: bash-compiler
base-url: https://bash-compiler.devlab.top
checkout-repo: fchastanet/bash-compiler
14.2. build-site.yml (my-documents Own)
Location: my-documents/.github/workflows/build-site.yml
Purpose: Builds and deploys the my-documents site itself (not a reusable workflow).
Triggers:
on:
push:
branches: [master]
paths:
- content/**
- static/**
- shared/**
- configs/**
- hugo.yaml
- go.mod
workflow_dispatch:
Calls: The same build-site-action.yml reusable workflow
Configuration:
jobs:
build-deploy:
uses: ./.github/workflows/build-site-action.yml
with:
site-name: my-documents
base-url: https://devlab.top
checkout-repo: fchastanet/my-documents
14.3. main.yml
Location: my-documents/.github/workflows/main.yml
Purpose: Runs pre-commit hooks and MegaLinter on the repository and deploy documentation if master branch is
updated.
Triggers:
on:
push:
branches: ['**']
pull_request:
branches: [master]
workflow_dispatch:
Steps:
- Checkout code: Clones repository with full history
- Setup Python: Installs Python for pre-commit
- Install pre-commit: Installs pre-commit tool
- Run pre-commit: Executes all pre-commit hooks
- Run MegaLinter: Runs comprehensive linting
- Upload reports: Saves linter reports as artifacts
- Create auto-fix PR: Optionally creates PR with fixes (if not “skip fix” in commit)
Linters Run:
- Markdown: mdformat, markdownlint
- YAML: yamllint, v8r
- JSON: jsonlint
- Bash: shellcheck, shfmt
- Spelling: cspell, codespell
- Secrets: gitleaks, secretlint
Auto-fix Behavior:
If linters make changes and commit message doesn’t contain “skip fix”, an auto-fix PR is created automatically.
15. Summary
This documentation system uses a modern, reusable GitHub Actions architecture that simplifies deployment and
maintenance:
Key Takeaways:
- No complex authentication: Standard
GITHUB_TOKEN only - Reusable action: One workflow definition, multiple sites
- Hugo modules: Share resources without file copying
- Independent control: Each repo owns its deployment
- Easy testing: Standard Hugo commands work locally
- Fast builds: Parallel execution across repositories
Getting Started:
- Create content structure in your repository
- Add
go.mod, hugo.yaml, and build-site.yml - Configure GitHub Pages to use “GitHub Actions” source
- Push to trigger automatic build and deployment
Next Steps:
For questions or issues, open an issue in the
my-documents repository.
2 - Static Site Generation Migration Analysis
Analysis of migrating from Docsify to an SEO-optimized static site generator
Project: my-documents repository migration and multi-site consolidation
Goal: Migrate from Docsify to an SEO-optimized static site generator while maintaining simplicity and GitHub CI
compatibility
1. Executive Summary
This document evaluates the current Docsify setup and recommends alternative static site generators that provide
superior SEO performance while maintaining the simplicity and ease of deployment that made Docsify attractive.
Current Challenge: Docsify renders content client-side, which severely limits SEO capabilities and page load
performance. This is critical for a documentation site seeking organic search visibility.
2. Current Solution Analysis: Docsify
2.1. Current Configuration
- Type: Client-side SPA (Single Page Application)
- Deployment: Direct to GitHub Pages (no build step)
- Content Format: Markdown
- Theme: Simple Dark (customized)
- Search: Built-in search plugin
- Navigation: Manual sidebar and navbar configuration
2.2. Docsify Pros ✅
| Advantage | Impact |
|---|
| Zero build step required | Instant deployment, minimal CI/CD complexity |
| Simple file structure | Easy to add new documentation files |
| No dependencies to manage | Fewer security concerns, simpler setup |
| Client-side rendering | Works directly with GitHub Pages |
| Lightweight theme system | Easy customization with CSS |
| Good for technical audience | Fast navigation for users familiar with SPAs |
| Markdown-first | Natural for technical documentation |
2.3. Docsify Cons ❌
| Limitation | Impact |
|---|
| Client-side rendering | Poor SEO - Search engines struggle to index content |
| No static HTML | No pre-rendered pages for crawlers |
| JavaScript dependent | Requires JS in browser (security consideration) |
| Limited meta tags control | Difficult to optimize individual pages for SEO |
| Slow initial page load | JavaScript bundle must load first |
| No built-in sitemap | Manual sitemap generation needed |
| No RSS/feed support | Hard to distribute content |
| Search plugin limitations | Site search not indexed by external search engines |
| No static asset optimization | All images referenced as relative paths |
| Outdated dependency stack | Uses Vue 2 (Vue 3 available), jQuery, legacy patterns |
2.4. Docsify SEO Score
Current Estimate: 2/10 ⛔
- ❌ No static pre-rendered HTML
- ❌ Robot.txt and sitemap not automatically generated
- ❌ Limited per-page meta tag control
- ❌ No automatic JSON-LD schema generation
- ❌ Poor mobile-first Core Web Vitals (JS-heavy)
- ⚠️ Possible crawl budget waste
- ⚠️ Delayed indexing (content hidden until JS loads)
3. Recommended Migration Path
3.1. Phase 1: Evaluation (This Phase)
- Compare alternatives against criteria
- Identify best fit for multi-site architecture
- Plan migration strategy
3.2. Phase 2: Pilot
- Set up new solution with one repository
- Migrate content and test
- Validate SEO improvements
3.3. Phase 3: Full Migration
- Migrate remaining repositories
- Set up CI/CD pipeline
- Monitor performance metrics
3.4. Phase 4: Optimization
- Fine-tune SEO settings
- Implement analytics
- Monitor search engine indexing
4. Alternative Solutions Comparison
4.1. Option 1: Hugo ⭐⭐⭐⭐⭐ (RECOMMENDED)
Type: Go-based static site generator Build Time: <1s for most sites Theme System: Flexible with 500+ themes
4.1.1. Pros ✅
- Extremely fast compilation - Processes 1000+ pages in milliseconds
- Excellent for documentation - Purpose-built with documentation sites in mind
- Superior SEO support - Generates static HTML, sitemaps, feeds, schemas
- Simple setup - Single binary, no dependency hell
- Markdown + frontmatter - Natural upgrade from Docsify
- GitHub Actions ready - Hugo orb/actions available for CI/CD
- Responsive themes - Many documentation-specific themes (Docsy, Relearn, Book)
- Built-in features - Search indexes, RSS feeds, JSON-LD support
- Content organization - Hierarchical content structure with archetypes
- Output optimization - Image processing, minification, CSS purging
- Flexible routing - Customize URLs, create custom taxonomies
- Active community - Large ecosystem, frequent updates
- Multi-language support - Built-in i18n capability
4.1.2. Cons ❌
- Learning curve for Go templating (shortcodes, partials)
- Theme customization requires understanding Hugo’s page model
- Configuration in TOML/YAML (minor, but different from Docsify)
- Less visual for live preview compared to Docsify
4.1.3. SEO Score: 9/10 ✅
- ✅ Static HTML pre-rendering
- ✅ Automatic sitemap generation
- ✅ Per-page meta tags and structured data
- ✅ RSS/Atom feeds
- ✅ Canonical URLs
- ✅ Image optimization
- ✅ Performance optimizations (minification, compression)
- ⚠️ JSON-LD not automated (requires theme customization)
4.1.4. GitHub CI/CD Integration
# .github/workflows/deploy.yml example
- uses: peaceiris/actions-hugo@v2
with:
hugo-version: latest
extended: true
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
4.1.5. Migration Effort
- Content: Minimal - Markdown stays same, just add frontmatter
- Structure: Organize into content sections (easy mapping from Docsify)
- Navigation: Automatic from directory structure or config
- Customization: Moderate - Theme customization required
4.1.6. Recommended Themes
- Docsy - Google-created, excellent documentation theme, built-in search
- Relearn - MkDocs-inspired, sidebar navigation like Docsify
- Book - Clean, minimal, perfect for tutorials
- Geek Docs - Modern, fast, developer-friendly
4.1.7. Best For
✅ Technical documentation ✅ Multi-site architecture ✅ SEO-critical sites ✅ GitHub Pages deployment ✅ Content-heavy sites
(1000+ pages)
4.2. Option 2: Astro ⭐⭐⭐⭐
Type: JavaScript/TypeScript-based, island architecture Build Time: <2s typical Theme System:
Component-based
4.2.1. Pros ✅
- Outstanding SEO support - Static HTML generation, built-in meta tag management
- Zero JavaScript by default - Only JS needed for interactive components
- Modern stack - Latest JavaScript patterns, TypeScript support
- Markdown + MDX support - Markdown with embedded React/Vue components
- Component imports - Use React, Vue, Svelte components in Markdown
- Fast performance - Island architecture means minimal JS shipping
- Great for blogs/docs - Built-in content collections API
- Image optimization - Automatic image processing and responsive images
- Built-in integrations - Readily available for analytics, fonts, CSS
- Flexible deployment - Works with any static host or serverless
- TypeScript first - Better tooling and IDE support
- Vite-based - Fast HMR and builds
4.2.2. Cons ❌
- Newer ecosystem (less battle-tested than Hugo)
- Small learning curve with Astro-specific patterns
- Requires Node.js and npm (dependency management)
- Theme ecosystem smaller than Hugo
- MDX adds complexity if not needed
4.2.3. SEO Score: 9/10 ✅
- ✅ Static HTML pre-rendering
- ✅ Fine-grained meta tag control
- ✅ JSON-LD schema support
- ✅ Automatic sitemap generation
- ✅ RSS/feed support
- ✅ Image optimization with AVIF
- ✅ Open Graph and Twitter cards
- ✅ Performance metrics built-in
4.2.4. GitHub CI/CD Integration
# .github/workflows/deploy.yml example
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
4.2.5. Migration Effort
- Content: Minimal - Markdown compatible with optional frontmatter
- Structure: Convert to Astro collections (straightforward)
- Navigation: Can use auto-generated from file structure
- Customization: Moderate - Components offer more flexibility than Hugo
4.2.6. Recommended Themes/Templates
- Starlight - Official Astro docs template, excellent for documentation
- Docs Kit - Tailored for technical documentation
- Astro Paper - Blog-focused, highly customizable
4.2.7. Best For
✅ Modern tech stack preference ✅ Need for interactive components ✅ TypeScript-heavy teams ✅ Blogs + Documentation hybrid
✅ SEO + Performance critical
4.3. Option 3: 11ty (Eleventy) ⭐⭐⭐⭐
Type: JavaScript template engine Build Time: <1s typical Theme System: Template-based
4.3.1. Pros ✅
- Incredibly flexible - Supports multiple template languages (Markdown, Nunjucks, Liquid, etc.)
- Lightweight - Minimal opinion on structure, you decide
- Fast builds - Blazingly fast incremental builds
- JavaScript-based - Easier for Node.js teams than Go
- Markdown-first - Natural Markdown support with plugins
- No locked-in framework - Use vanilla HTML/CSS or any framework
- Great community - Excellent documentation and starter projects
- Simple config -
.eleventy.js is readable JavaScript - Content collections - Flexible ways to organize content
- Image processing - Built-in with popular plugins
- GitHub Pages friendly - Easy integration with GitHub Actions
- Low barrier to entry - Understand JavaScript, you understand Eleventy
4.3.2. Cons ❌
- Less opinionated (requires more configuration)
- Smaller pre-built theme ecosystem
- Requires JavaScript knowledge for customization
- No built-in search (needs separate solution)
- Learning curve steeper if unfamiliar with template languages
4.3.3. SEO Score: 8/10 ✅
- ✅ Static HTML generation
- ✅ Manual sitemap generation (simple plugin)
- ✅ Per-page meta tag control
- ✅ Feed/RSS support (via plugins)
- ✅ Image optimization (via plugins)
- ⚠️ Schema/JSON-LD (requires custom implementation)
4.3.4. GitHub CI/CD Integration
# .github/workflows/deploy.yml example
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./_site
4.3.5. Migration Effort
- Content: Minimal - Markdown files work as-is
- Structure: Very flexible, custom folder organization
- Navigation: Can auto-generate from structure or manually configure
- Customization: High - Maximum control but more work
4.3.6. Recommended Starters
- 11ty Base Blog - Simple starting point
- Eleventy High Performance Blog - Performance-focused
- Slinkity - Hybrid with component support
4.3.7. Best For
✅ Developers who want full control ✅ Simple, focused documentation ✅ JavaScript/Node.js teams ✅ Performance optimization
focus ✅ Unique design requirements
4.4. Option 4: VuePress 2 ⭐⭐⭐
Type: Vue 3-based static site generator Build Time: 1-2s typical Theme System: Vue components
4.4.1. Pros ✅
- Vue ecosystem - Use Vue components directly in Markdown
- Documentation-first - Built specifically for docs
- Markdown extensions - Plugin system for custom Markdown syntax
- Built-in search - Local search with Algolia option
- Plugin ecosystem - Rich ecosystem for docs sites
- Good themes - VuePress Theme Default is solid
- PWA support - Can work offline (if configured)
- Git history - Can show last edited time from git
- i18n built-in - Multi-language support
- Flexible routing - Customizable URL structure
4.4.2. Cons ❌
- Vue knowledge required
- Smaller ecosystem than Hugo
- Heavy JavaScript bundle (not as optimized as Astro)
- Less mature than Hugo
- Configuration can be verbose
- Search indexing still client-side primarily
4.4.3. SEO Score: 6/10 ⚠️
- ✅ Static HTML generation
- ✅ Per-page meta tags
- ✅ Sitemap support (via plugin)
- ⚠️ Search still somewhat client-side
- ⚠️ Performance not optimized (Vue overhead)
- ⚠️ JSON-LD requires manual setup
4.4.4. GitHub CI/CD Integration
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
4.4.5. Migration Effort
- Content: Minimal - Markdown compatible
- Structure: Organized in
.vuepress/config.js - Navigation: Configured in sidebar/navbar config
- Customization: Moderate - Vue components for complex needs
4.4.6. Best For
✅ Vue-centric teams ✅ Need interactive components ✅ Plugin-heavy customization ✅ Smaller documentation sites ✅ Already
using Vue ecosystem
4.5. Option 5: MkDocs ⭐⭐⭐
Type: Python-based documentation generator Build Time: <1s typical Theme System: Python template-based
4.5.1. Pros ✅
- Documentation-optimized - Built by documentation enthusiasts
- Simple configuration -
mkdocs.yml is straightforward - Markdown-native - Pure Markdown with extensions
- Great themes - Material for MkDocs is excellent
- Low overhead - Minimal learning curve
- Python-based - Good for Python-heavy teams
- Fast builds - Quick incremental rebuilds
- Search integration - Good local search, Algolia-ready
- Git integration - Edit on GitHub features
- Active community - Good documentation and examples
4.5.2. Cons ❌
- Python dependency management
- Smaller ecosystem than Hugo
- Theme customization requires Python knowledge
- Less flexibility than some alternatives
- Setup requires Python environment
4.5.3. SEO Score: 7/10 ✅
- ✅ Static HTML generation
- ✅ Per-page meta tags
- ✅ Sitemap support (via plugin)
- ⚠️ Schema/JSON-LD minimal
- ⚠️ Image optimization requires external tools
4.5.4. GitHub CI/CD Integration
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: pip install mkdocs mkdocs-material
- name: Build
run: mkdocs build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site
4.5.5. Migration Effort
- Content: Minimal - Markdown files work directly
- Structure: Configured in
mkdocs.yml - Navigation: Simple hierarchical structure
- Customization: Easy for theming, harder for core customization
4.5.6. Best For
✅ Documentation-only focus ✅ Python-familiar teams ✅ Minimal configuration needed ✅ Material design preference ✅ Rapid
setup priority
4.6. Option 6: Next.js / Vercel ⭐⭐
Type: React meta-framework Build Time: 5-10s typical Theme System: React components
4.6.1. Pros ✅
- Powerful frameworks - React + Node.js backend possibility
- Vercel optimization - Vercel specialist optimization
- React ecosystem - Access to millions of components
- SSR capable - Server-side rendering if needed
- API routes - Can add serverless functions
- Image optimization - Automatic image optimization
- Incremental Static Regeneration - Change content without full rebuild
- TypeScript native - First-class TypeScript support
- Performance monitoring - Web vitals built-in
4.6.2. Cons ❌
- Overkill for static docs - Too much complexity
- Learning curve steep - React + Next.js knowledge required
- Build times longer - Slower than purpose-built SSGs
- More dependencies - Dependency management complexity
- GitHub Pages less ideal - Optimized for Vercel deployment
- Maintenance burden - React team required to maintain
4.6.3. SEO Score: 8/10 ✅
- ✅ Static generation capability
- ✅ Per-page meta tags via next/head
- ✅ Sitemap and robots.txt support
- ✅ Image optimization
- ⚠️ Requires more configuration
- ⚠️ Slower builds than dedicated SSGs
4.6.4. GitHub CI/CD Integration (Docsify level: Complex)
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Static Export
run: npm run export
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
4.6.5. Migration Effort
- Content: Moderate - Convert to Next.js structure
- Structure: Pages directory structure required
- Navigation: Custom component creation
- Customization: High complexity
4.6.6. Best For
✅ React-centric teams ✅ Need dynamic functionality ✅ Willing to deploy on Vercel ✅ Complex sites with interactive
elements ❌ NOT recommended for pure documentation
4.7. Option 7: Gatsby ⭐⭐
Type: React-based static site generator Build Time: 10-30s typical Theme System: React components + theme
shadowing
4.7.1. Pros ✅
- Powerful plugin system - Huge ecosystem
- GraphQL querying - Flexible content queries
- Performance optimization - Good performance features
- React components - Full React power available
- CMS integration - Works with many headless CMS
4.7.2. Cons ❌
- Heavy and slow - Longest build times of alternatives
- High complexity - Steep learning curve
- Dependency bloat - Many dependencies to maintain
- Not ideal for docs - Over-engineered for simple documentation
- GitHub Pages unfriendly - Best with Netlify
- Overkill - Too much power for static docs
4.7.3. SEO Score: 7/10 ✅
- ✅ Static generation
- ✅ Good plugin ecosystem for SEO
- ⚠️ Heavy JavaScript overhead
- ⚠️ Slower builds
4.7.4. Best For
❌ NOT recommended for documentation migration
5. Comparison Matrix
| Criteria | Hugo | Astro | 11ty | VuePress | MkDocs | Next.js | Gatsby |
|---|
| SEO Score | 9/10 | 9/10 | 8/10 | 6/10 | 7/10 | 8/10 | 7/10 |
| Build Speed | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| Learning Curve | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ | ⭐ | ⭐ |
| Customization | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| GitHub Pages | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| Static Output | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Documentation Focus | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐ |
| Theme Ecosystem | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| Community Size | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| GitHub Pages Native | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ | ❌ |
| Multiple Sites | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐ |
6. Improvements for New Solutions
Regardless of which SSG is chosen, implement these SEO improvements:
6.1. Technical SEO Baseline
6.2. Content Structure
6.4. Search and Indexing
6.5. Advanced SEO
6.6. Analytics and Monitoring
6.7. GitHub CI/CD Improvements
7. Hugo-Specific Recommendations
If Hugo is chosen (recommended), implement:
# config.yaml example improvements
params:
description: Collection of my documents on various subjects
keywords: bash,best practices,learn,docker,jenkins
openGraph:
enabled: true
twitterCards:
enabled: true
jsonLD:
enabled: true
outputs:
home:
- HTML
- JSON
- RSS
section:
- HTML
- JSON
- RSS
taxonomies:
category: categories
tag: tags
mediaTypes:
application/json:
suffixes:
- json
outputFormats:
JSON:
isPlainText: true
mediaType: application/json
8. Astro-Specific Recommendations
If Astro is chosen, implement:
// astro.config.mjs example improvements
export default defineConfig({
integrations: [
sitemap(),
robotsTxt(),
react(),
vue(),
],
image: {
remotePatterns: [{
protocol: "https"
}],
},
vite: {
plugins: [
sitemap(),
],
},
});
9. Migration Strategy for Multiple Sites
9.1. With Hugo (Recommended Approach)
github-sites-monorepo/
├── myDocuments/
│ ├── content/
│ ├── themes/
│ └── config.yaml
├── bashToolsFramework/
│ ├── content/
│ ├── themes/
│ └── config.yaml
├── bashTools/
│ ├── content/
│ ├── themes/
│ └── config.yaml
└── bashCompiler/
├── content/
├── themes/
└── config.yaml
CI/CD Strategy:
- Single workflow builds all sites
- Each site has separate output directory
- Deploy to respective GitHub Pages branches
- Shared theme for consistency (git submodule or package)
- Single dependency management file
10. Risk Assessment and Mitigation
| Risk | Hugo | Astro | 11ty | MkDocs | VuePress |
|---|
| Breaking changes | ⚠️ Low | ⚠️ Medium | ✅ Low | ✅ Low | ⚠️ Medium |
| Ecosystem longevity | ✅ Very High | ⚠️ High | ✅ Very High | ✅ High | ⚠️ Medium |
| Theme support | ✅ Excellent | ⚠️ Good | ⚠️ Good | ✅ Good | ⚠️ Good |
| GitHub Pages | ✅ Perfect | ✅ Perfect | ✅ Perfect | ✅ Perfect | ⚠️ Works |
| Team skills | ⚠️ Go required | ⚠️ JS required | ✅ JS (low level) | ✅ Python/Markdown | ⚠️ Vue required |
| Maintenance burden | ✅ Low | ⚠️ Medium | ⚠️ Medium | ✅ Low | ⚠️ Medium |
11. Final Recommendation: Hugo
11.1. Justification
- SEO Excellence - 9/10 score meets all objectives
- Simplicity - Single Go binary, no dependency management
- Performance - <1s builds, scales to thousands of pages
- Documentation-First - Built for exactly this use case
- GitHub Pages Native - Zero friction deployment
- Multi-Site Scalability - Perfect for multiple repositories
- Community - Largest documentation site generator community
- Proven - 1000+ major documentation sites use it
- Themes - Docsy, Relearn excellent for technical docs
- Future-Proof - Stable, active development
11.2. Hugo Implementation Plan
Phase 1: Setup (1-2 weeks)
- Install Hugo and select Docsy or Relearn theme
- Create content structure
- Configure SEO baseline
- Set up GitHub Actions workflow
- Test locally
Phase 2: Migration (2-3 weeks)
- Convert Markdown files (minimal changes)
- Migrate sidebar structure to Hugo config
- Update internal links
- Test all links and navigation
- Performance testing
Phase 3: SEO Optimization (1-2 weeks)
- Implement schema markup
- Configure sitemaps and feeds
- Submit to Google Search Console
- Baseline performance metrics
- Optimize Core Web Vitals
Phase 4: Deployment (1 week)
- Validate all tests pass
- Deploy to production
- Monitor indexing and performance
- Gather feedback
12. Alternative: Astro for Modern Setup
If your team prefers JavaScript/TypeScript and wants maximum flexibility with modern tooling, Astro with Starlight
is the secondary recommendation:
- Excellent SEO (equal to Hugo)
- More flexible for custom components
- Modern JavaScript ecosystem
- Better DX with TypeScript
- Slightly longer build times acceptable
- GitHub Pages deployment straightforward
13. NOT Recommended
- ❌ Docsify - Keep for simple internal documentation only, not public sites
- ❌ Next.js - Overcomplicated for documentation, not ideal for GitHub Pages
- ❌ Gatsby - Slow builds, high complexity, deprecated
14. Conclusion
Migrate to Hugo with Docsy theme for optimal balance of simplicity, SEO performance, and documentation focus. This
will:
- Improve SEO from 2/10 to 9/10
- Reduce page load times significantly
- Provide static pre-rendered pages for crawlers
- Scale to multiple sites easily
- Maintain simplicity in CI/CD
- Future-proof your documentation infrastructure
Next Steps:
- Review this analysis with relevant stakeholders
- Set up pilot Hugo site with one repository
- Validate SEO improvements with Search Console
- Plan full migration timeline
- Document Hugo best practices for team
3 - My Documents - Multi repositories Site Generation
Comprehensive documentation of the Hugo migration for multi-site documentation
Project: Migration from Docsify to Hugo with Docsy theme for multiple documentation repositories
Status: ✅ Completed
Repositories:
fchastanet/my-documents (orchestrator + own documentation)fchastanet/bash-compilerfchastanet/bash-toolsfchastanet/bash-tools-frameworkfchastanet/bash-dev-env
Related Documentation: See
doc/ai/2026-02-18-migrate-repo-from-docsify-to-hugo.md
for detailed migration guide.
1. Technical Solutions Evaluated
1.1. Static Site Generator Solutions
1.1.1. Hugo (SELECTED)
Evaluation: ⭐⭐⭐⭐⭐ Type: Go-based static site generator
Pros:
- Extremely fast compilation (<1s for most documentation sites)
- Excellent for documentation with purpose-built features
- Superior SEO support (static HTML, sitemaps, feeds, schemas) - 9/10 SEO score
- Single binary with no dependency complications
- Markdown + frontmatter support (natural progression from Docsify)
- GitHub Actions ready with official actions
- Large theme ecosystem (500+ themes) including specialized documentation themes
- Built-in features: search indexes, RSS feeds, hierarchical content organization
- Output optimization: image processing, minification, CSS purging
- Active community with frequent updates
- Multi-language support built-in
Cons:
- Learning curve for Go templating (shortcodes, partials)
- Theme customization requires understanding Hugo’s page model
- Configuration in YAML/TOML format
GitHub CI/CD Integration: Native, simple integration with peaceiris/actions-hugo
Best For: Technical documentation, multi-site architecture, SEO-critical sites, GitHub Pages, content-heavy sites
1.1.2. Astro
Evaluation: ⭐⭐⭐⭐ Type: JavaScript/TypeScript-based with island architecture
Pros:
- Outstanding SEO support (static HTML, zero JavaScript by default) - 9/10 SEO score
- Modern JavaScript patterns with TypeScript support
- Markdown + MDX support (embedded React/Vue components in Markdown)
- Island architecture minimizes JavaScript shipping
- Fast performance and build times (<2s)
- Automatic image optimization (AVIF support)
- Vite-based with fast HMR
Cons:
- Newer ecosystem, less battle-tested than Hugo
- Requires Node.js and npm dependency management
- Smaller theme ecosystem
- MDX adds complexity if not needed
Best For: Modern tech stacks, interactive components, TypeScript-heavy teams, blogs + documentation hybrids
1.1.3. 11ty (Eleventy)
Evaluation: ⭐⭐⭐⭐
Type: JavaScript template engine
Pros:
- Incredibly flexible with multiple template language support
- Lightweight and fast builds
- JavaScript-based (easier for Node.js teams)
- Low barrier to entry
- No framework lock-in
Cons:
- Less opinionated, requires more configuration
- Smaller pre-built theme ecosystem
- No built-in search (requires plugins)
- SEO score: 8/10
Best For: Developers wanting full control, JavaScript/Node.js teams, unique design requirements
1.1.4. VuePress 2
Evaluation: ⭐⭐⭐
Type: Vue 3-based static site generator
Pros:
- Documentation-first design
- Built-in search functionality
- Plugin ecosystem for documentation
- Vue component integration in Markdown
Cons:
- Vue.js knowledge required
- Heavy JavaScript bundle (not as optimized as others)
- Smaller ecosystem than Hugo
- SEO score: 6/10
Best For: Vue-centric teams, smaller documentation sites
1.1.5. MkDocs
Evaluation: ⭐⭐⭐
Type: Python-based documentation generator
Pros:
- Documentation-optimized out of the box
- Simple configuration
- Material for MkDocs theme is excellent
- Fast builds
Cons:
- Python dependency management required
- Smaller ecosystem than Hugo
- Limited flexibility
- SEO score: 7/10
Best For: Documentation-only focus, Python-familiar teams, rapid setup
1.1.6. Next.js and Gatsby
Evaluation: ⭐⭐ - Not recommended for static documentation
Reasons:
- Overkill complexity for pure documentation
- Longer build times (5-30s vs <1s for Hugo)
- Heavy JavaScript requirements
- Optimized for different use cases (web apps, not docs)
- Maintenance burden too high for static documentation
1.1.7. Comparison Summary
| Criteria | Hugo | Astro | 11ty | VuePress | MkDocs |
|---|
| SEO Score | 9/10 | 9/10 | 8/10 | 6/10 | 7/10 |
| Build Speed | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Learning Curve | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
| GitHub Pages | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Documentation Focus | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Theme Ecosystem | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| Multi-Site Support | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
1.2. Multi-Site Build Pipeline Solutions
1.2.1. Centralized Orchestrator (my-documents builds all sites) (SELECTED)
Evaluation: ⭐⭐⭐⭐⭐ Architecture:
my-documents (orchestrator)
├── .github/workflows/build-all-sites.yml ← Builds all sites
├── configs/
│ ├── _base.yaml ← Shared config
│ ├── bash-compiler.yaml ← Site overrides
│ ├── bash-tools.yaml
│ └── bash-tools-framework.yaml
├── shared/
│ ├── layouts/ ← Shared templates
│ ├── assets/ ← Shared styles
│ └── archetypes/ ← Content templates
└── content/ ← my-documents own docs
Dependent repos (minimal):
bash-compiler/
├── .github/workflows/trigger-docs.yml ← Triggers my-documents
└── content/en/ ← Documentation only
How It Works:
- Push to
bash-compiler → triggers my-documents via repository_dispatch - my-documents workflow:
- Checks out ALL repos (my-documents, bash-compiler, bash-tools, bash-tools-framework, bash-dev-env)
- Builds each site in parallel using GitHub Actions matrix strategy
- Merges configs (
_base.yaml + site-specific overrides) - Deploys each site to its respective GitHub Pages
Pros:
- ✅ All repos under same owner (fchastanet) simplifies permission management
- ✅ One workflow update fixes all sites immediately
- ✅ Guaranteed consistency across all documentation sites
- ✅ Simpler per-repo setup (2 files: trigger workflow + content)
- ✅ No Hugo modules needed (simpler dependency management)
- ✅ Centralized theme customization with per-site overrides
- ✅ Build all sites in ~60s (parallel matrix execution)
- ✅ Single point of maintenance
Cons:
- ⚠️ Requires authentication setup (GitHub App or deploy keys)
- ⚠️ All sites rebuild together (cannot isolate to single site)
- ⚠️ All-or-nothing failures (one site failure blocks others in same matrix job)
- ⚠️ Slightly more complex initial setup
Best For: Related projects under same organization, shared theme/purpose, centralized maintenance preference
1.2.2. Decentralized with Reusable Workflows + Hugo Modules
Architecture:
my-documents (shared resources hub)
├── .github/workflows/hugo-build-deploy-reusable.yml ← Reusable workflow
├── layouts/ (Hugo module export)
└── assets/ (Hugo module export)
bash-compiler/ (independent)
├── .github/workflows/hugo-build-deploy.yml ← Calls reusable workflow
├── hugo.yaml (imports my-documents module)
├── go.mod
└── content/
How It Works:
- Each dependent repo has its own build workflow
- Workflow calls the reusable workflow from my-documents
- Hugo modules pull shared resources during build
- Each site builds and deploys independently
Pros:
- ✅ Independent deployment (site failures isolated)
- ✅ Automatic updates when reusable workflow changes
- ✅ Version control (can pin to
@v1.0.0 or @master) - ✅ No trigger coordination needed
- ✅ Faster builds for single-site changes (~30s per site)
- ✅ Per-repo flexibility if needed
Cons:
- ⚠️ Hugo modules require Go toolchain
- ⚠️ More files per repository (6 core files vs 2)
- ⚠️ Learning curve for Hugo module system
- ⚠️ Network dependency (modules fetched from GitHub)
- ⚠️ Potential configuration drift if repos don’t update modules
- ⚠️ More complex to enforce consistency
Best For: Fully independent projects, teams wanting flexibility, isolated failure tolerance
1.2.3. True Monorepo with Subdirectories
Architecture: All content in single repo with subdirectories for each project
Pros:
- ✅ Simplest configuration
- ✅ Single build process
- ✅ Guaranteed consistency
Cons:
- ❌ Loses separate GitHub Pages URLs
- ❌ No independent repository control
- ❌ Violates existing repository structure
- ❌ Complicated permission management
Evaluation: Not recommended - Conflicts with requirement to maintain separate repository URLs
1.2.4. Pipeline Solution Comparison
| Criteria | Centralized Orchestrator | Decentralized Reusable | Monorepo |
|---|
| Complexity | Low (minimal per-repo) | Medium (per-repo setup) | Low (single repo) |
| Build Time | ~60s all sites | ~30s per site | ~60s all sites |
| Maintenance | Update once | Update workflow × N | Update once |
| Consistency | ✅ Guaranteed | Can drift | ✅ Guaranteed |
| Failure Isolation | All-or-nothing | ✅ Independent | All-or-nothing |
| Setup Effort | 1 workflow + N configs | 6 files × N repos | Single setup |
| Independent URLs | ✅ Yes | ✅ Yes | ❌ No |
| Hugo Modules | ❌ Not needed | Required | ❌ Not needed |
2. Chosen Solutions & Rationale
2.1. Static Site Generator: Hugo + Docsy Theme
Choice: Hugo with Google’s Docsy theme
Rationale:
SEO Requirements Met:
- Static HTML pre-rendering (search engines can easily index)
- Automatic sitemap and robots.txt generation
- Per-page meta tags and structured data support
- RSS/Atom feeds
- Image optimization
- Performance optimizations (minification, compression)
- SEO improvement: 2/10 (Docsify) → 9/10 (Hugo)
Technical Excellence:
- Extremely fast builds (<1s for typical documentation site)
- Simple deployment (single Go binary, no dependency hell)
- GitHub Pages native support
- Mature, stable, battle-tested (10+ years in production use)
Documentation-Specific Features:
- Docsy theme built by Google specifically for documentation
- Built-in search functionality
- Responsive design
- Navigation auto-generation from content structure
- Version management support
- Multi-language support
Developer Experience:
- Markdown + frontmatter (minimal migration effort from Docsify)
- Good documentation and large community
- Extensive theme ecosystem
- Active development and updates
Multi-Site Architecture Support:
- Excellent support for shared configurations
- Hugo modules for code reuse
- Flexible configuration merging
- Content organization flexibility
Alternatives Considered:
- Astro: Excellent option, but newer ecosystem and Node.js dependency management adds complexity
- 11ty: Good flexibility, but less opinionated structure requires more setup work
- MkDocs: Python dependencies and smaller ecosystem less ideal
- VuePress/Next.js/Gatsby: Too heavy for pure documentation needs
2.2. Multi-Site Pipeline: Centralized Orchestrator
Choice: Centralized build orchestrator in my-documents repository
Rationale:
Project Context Alignment:
- All repositories under same owner (fchastanet)
- All share same purpose (Bash tooling documentation)
- All need consistent look and feel
- Related projects benefit from coordinated updates
Maintenance Efficiency:
- Single workflow update affects all sites immediately
- One place to fix bugs or add features
- Guaranteed consistency across all documentation
- Reduced mental overhead (one system to understand)
Simplified Per-Repository Structure:
- Only 2 essential files per dependent repo:
- Trigger workflow (10 lines)
- Content directory
- No Hugo configuration duplication
- No Go module management per repo
Configuration Management:
- Base configuration shared via
configs/_base.yaml - Site-specific overrides in
configs/{site}.yaml - Automatic merging with
yq tool - No configuration drift possible
Build Efficiency:
- Parallel matrix execution builds all 5 sites simultaneously
- Total time ~60s for all sites (vs 30s × 5 = 150s sequential)
- Resource sharing in CI/CD (single Hugo/Go setup)
Deployment Simplification:
- Authentication centralized in my-documents (GitHub App)
- Single set of deployment credentials
- Easier to audit and manage security
Trade-offs Accepted:
- ⚠️ All sites rebuild together (acceptable for related documentation)
- ⚠️ More complex initial setup (one-time investment)
- ⚠️ All-or-nothing failures (mitigated with
fail-fast: false in matrix)
Alternatives Considered:
- Decentralized Reusable Workflows: Good for truly independent projects, but adds complexity without benefit for our
use case where all sites are related and share theme/purpose
- Monorepo: Would lose independent GitHub Pages URLs, not acceptable
3. Implementation Details
3.1. Repository Architecture
Orchestrator Repository: fchastanet/my-documents
Responsibilities:
- Build all documentation sites (including its own)
- Manage shared configurations and theme customizations
- Deploy to multiple GitHub Pages repositories
- Coordinate builds triggered from dependent repositories
Dependent Repositories:
fchastanet/bash-compilerfchastanet/bash-toolsfchastanet/bash-tools-frameworkfchastanet/bash-dev-env
Responsibilities: Contain documentation content only, trigger builds in orchestrator
3.2. Directory Structure
3.2.1. my-documents (Orchestrator)
/home/wsl/fchastanet/my-documents/
├── .github/workflows/
│ └── build-all-sites.yml ← Orchestrator workflow
├── configs/
│ ├── _base.yaml ← Shared configuration
│ ├── my-documents.yaml ← my-documents overrides
│ ├── bash-compiler.yaml ← bash-compiler overrides
│ ├── bash-tools.yaml
│ ├── bash-tools-framework.yaml
│ └── bash-dev-env.yaml
├── shared/
│ ├── layouts/ ← Shared Hugo templates
│ ├── assets/ ← Shared SCSS, JS
│ └── archetypes/ ← Content templates
├── content/ ← my-documents own content
├── hugo.yaml ← Generated per build
└── go.mod ← Hugo modules (Docsy)
Key Files:
3.2.2. Dependent Repository (Example: bash-compiler)
fchastanet/bash-compiler/
├── .github/workflows/
│ └── trigger-docs.yml ← Triggers orchestrator
└── content/en/ ← Documentation content only
├── _index.md
└── docs/
└── *.md
3.3. Configuration Merging Strategy
Approach: Use yq tool for proper YAML deep-merging
Base Configuration: configs/_base.yaml
Contains:
- Hugo module imports (Docsy theme)
- Common parameters (language, SEO settings)
- Shared markup configuration
- Mount points for shared resources
- Common menu structure
- Default theme parameters
Site-Specific Overrides: Example configs/bash-compiler.yaml
Contains:
- Site title and baseURL
- Repository-specific links
- Site-specific theme colors (
ui.navbar_bg_color) - Custom menu items
- SEO keywords specific to the project
- GitHub repository links
Merging Process:
Implemented in .github/workflows/build-all-sites.yml:
yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' \ configs/_base.yaml
\ configs/bash-compiler.yaml > hugo.yaml
...
Result: Clean, merged hugo.yaml with:
- Base configuration as foundation
- Site-specific overrides applied
- Proper YAML structure preserved (no duplication)
- Deep merge of nested objects
3.4. Build Workflow
Main Workflow: .github/workflows/build-all-sites.yml
Triggers:
workflow_dispatch - Manual triggerrepository_dispatch with type trigger-docs-rebuild - From dependent repospush to master branch affecting:content/**shared/**configs/**.github/workflows/build-all-sites.yml
Strategy: Parallel matrix build
matrix:
site:
- name: my-documents
repo: fchastanet/my-documents
baseURL: https://devlab.top
self: true
- name: bash-compiler
repo: fchastanet/bash-compiler
baseURL: https://bash-compiler.devlab.top
self: false
# ... other sites
Build Steps (Per Site):
- Checkout Orchestrator: Clone my-documents repository
- Checkout Content: Clone dependent repository content (if not self)
- Setup Tools: Install Hugo Extended 0.155.3, Go 1.24, yq
- Prepare Build Directory:
- For my-documents: Use orchestrator directory
- For dependent repos: Create
build-{site} directory
- Merge Configurations: Combine
_base.yaml + {site}.yaml - Copy Shared Resources: Link shared layouts, assets, archetypes
- Copy Content: Link content directory
- Initialize Hugo Modules: Run
hugo mod init and hugo mod get -u - Build Site: Run
hugo --minify - Deploy: Push to respective GitHub Pages
Concurrency: cancel-in-progress: true prevents duplicate builds
Failure Handling: fail-fast: false allows other sites to build even if one fails
3.5. Deployment Approach
Method: GitHub App authentication (migrated from deploy keys)
Authentication Flow:
- Generate App Token: Use
actions/create-github-app-token@v1 - Deploy with Token: Use
peaceiris/actions-gh-pages@v4
Secrets Required (in my-documents):
DOC_APP_ID - GitHub App IDDOC_APP_PRIVATE_KEY - GitHub App private key (PEM format)
Deployment Step Example:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.DOC_APP_ID }}
private-key: ${{ secrets.DOC_APP_PRIVATE_KEY }}
owner: fchastanet
repositories: bash-compiler
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ steps.app-token.outputs.token }}
external_repository: fchastanet/bash-compiler
publish_dir: ./public
publish_branch: gh-pages
Result URLs:
3.6. Trigger Mechanism
Dependent Repository Workflow Example: .github/workflows/trigger-docs.yml
name: Trigger Documentation Rebuild
on:
push:
branches: [master]
paths:
- content/**
- .github/workflows/trigger-docs.yml
jobs:
trigger:
runs-on: ubuntu-latest
steps:
- name: Trigger my-documents build
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.DOCS_TRIGGER_PAT }}
repository: fchastanet/my-documents
event-type: trigger-docs-rebuild
client-payload: |
{
"repository": "${{ github.repository }}",
"ref": "${{ github.ref }}",
"sha": "${{ github.sha }}"
}
Required Secret: DOCS_TRIGGER_PAT - Personal Access Token with repo scope
3.7. Theme Customization
Shared Customizations: shared/
Contains:
- Layouts: Custom Hugo templates override Docsy defaults
- Assets: Custom SCSS variables, additional CSS/JS
- Archetypes: Content templates for new pages
Per-Site Customization: Via configuration overrides in configs/{site}.yaml
Examples:
- Theme colors:
params.ui.navbar_bg_color: '#007bff' (blue for bash-compiler) - Custom links in footer or navbar
- Site-specific SEO keywords and description
- Logo overrides
Mount Strategy: Defined in configs/_base.yaml
module:
mounts:
- {source: shared/layouts, target: layouts}
- {source: shared/assets, target: assets}
- {source: shared/archetypes, target: archetypes}
- {source: content, target: content}
- {source: static, target: static}
Result: Shared resources available to all sites, with per-site override capability
4. Lessons Learned & Future Considerations
4.1. GitHub App Migration from Deploy Keys
Initial Approach: Deploy keys for each repository
- Setup: Generate SSH key pair per repository, store private key in my-documents secrets
- Secrets Required:
DEPLOY_KEY_BASH_COMPILER, DEPLOY_KEY_BASH_TOOLS, etc. (4+ secrets) - Management: Per-repository key addition in Settings → Deploy keys
Problem: Scalability and management overhead
Migration to GitHub Apps:
Advantages:
- ✅ Fine-grained permissions: Only Contents and Pages write access (vs full repo access)
- ✅ Centralized management: One app for all repositories
- ✅ Better security: Automatic token expiration and rotation
- ✅ Audit trail: All actions logged under app identity
- ✅ No SSH management: HTTPS with tokens instead of SSH keys
- ✅ Easily revocable: Instant access revocation without key regeneration
- ✅ Scalable: Add/remove repositories without creating new keys
- ✅ Secrets reduction: 2 secrets (app ID + private key) vs 4+ deploy keys
GitHub Official Recommendation:
“We recommend using GitHub Apps with permissions scoped to specific repositories for enhanced security and more
granular access control.”
Implementation: See doc/ai/2026-02-18-github-app-migration.md
for complete migration guide
Outcome: Significantly improved security posture and simplified credential management
4.2. Trade-offs Discovered
4.2.1. All-Site Rebuild Trade-off
Trade-off: All sites rebuild together when any site content changes
Mitigation Strategies:
- ✅
fail-fast: false in matrix strategy - One site failure doesn’t block others - ✅ Parallel execution - All 5 sites build simultaneously (~60s total)
- ✅ Path-based triggers - Only rebuild when relevant files change
- ✅ Concurrency control - Cancel duplicate builds
Acceptance Rationale:
- Related documentation sites benefit from synchronized updates
- Total build time (60s) acceptable for documentation updates
- Ensures all sites stay consistent with latest shared resources
- Simpler mental model: one build updates everything
4.2.2. Authentication Complexity
Trade-off: Initial setup requires GitHub App creation and secret configuration
Mitigation:
- ✅ One-time setup effort well-documented
- ✅ Improved security worth the complexity
- ✅ Scales better than deploy keys (no per-repo setup needed for new sites)
Outcome: Initial investment pays off with easier ongoing management
4.2.3. Configuration Flexibility vs Consistency
Trade-off: Centralized configuration limits per-site flexibility
Mitigation:
- ✅ Site-specific override files in
configs/{site}.yaml - ✅ Shared base with override capability provides best of both worlds
- ✅ yq deep-merge preserves flexibility where needed
Outcome: Achieved balance between consistency and customization
4.3. Best Practices Identified
4.3.1. Configuration Management
- Use YAML deep-merge:
yq eval-all properly merges nested structures - Separate concerns: Base configuration vs site-specific overrides
- Version control everything: All configs in git
- Document override patterns: Clear examples in base config
4.3.2. Build Optimization
- Parallel matrix builds: Leverage GitHub Actions matrix for speed
- Minimal checkout: Only fetch what’s needed (depth, paths)
- Careful path triggers: Avoid unnecessary builds
- Cancel redundant builds: Use concurrency groups
4.3.3. Dependency Management
- Pin versions: Hugo 0.155.3, Go 1.24 (reproducible builds)
- Cache when possible: Hugo modules could be cached (future optimization)
- Minimal dependencies: yq only additional tool needed
4.3.4. Security
- GitHub Apps over deploy keys: Better security model
- Minimal permissions: Only what’s needed (Contents write, Pages write)
- Secret scoping: Secrets only in orchestrator repo
- Audit logging: GitHub App actions fully logged
4.4. Future Considerations
4.4.1. Potential Optimizations
Hugo Module Caching:
- Current: Hugo modules downloaded fresh each build
- Future: Cache Go modules directory to speed up builds
- Benefit: Reduce build time by 5-10s per site
Conditional Site Builds:
- Current: All sites build on any trigger
- Future: Parse
repository_dispatch payload to build only affected site - Benefit: Faster feedback for single-site changes
- Trade-off: More complex logic, potential consistency issues
Build Artifact Reuse:
- Current: Each site built independently
- Future: Share Hugo module downloads across matrix jobs
- Benefit: Reduced redundant network calls
4.4.2. Scalability Considerations
Adding New Documentation Sites:
- Create new repository with content
- Add trigger workflow (2-minute setup)
- Add site config to
my-documents/configs/{new-site}.yaml - Add site to matrix in
build-all-sites.yml - Install GitHub App on new repository
- Done - automatic builds immediately available
Estimated effort: 15-30 minutes per new site
4.4.3. Alternative Approaches for Future Projects
When Decentralized Makes Sense:
- Truly independent projects (not related documentation)
- Different teams with different update schedules
- Need for isolated failure handling
- Different Hugo/Docsy versions per project
When to Reconsider:
- More than 10 sites (build time may become issue)
- Sites diverge significantly in requirements
- Team structure changes (separate maintainers per site)
- Different deployment targets (not all GitHub Pages)
4.5. Success Metrics
Achieved:
- ✅ SEO Improvement: 2/10 (Docsify) → 9/10 (Hugo with Docsy)
- ✅ Build Time: ~60s for all 5 sites (parallel)
- ✅ Maintenance Reduction: One workflow update vs 5× separate updates
- ✅ Consistency: 100% - All sites use same base configuration
- ✅ Security: GitHub App authentication with fine-grained permissions
- ✅ Deployment: Automatic on content changes
- ✅ Developer Experience: Simplified per-repo structure (2 files vs 6)
- ✅ Independent URLs: All 5 repositories maintain separate GitHub Pages URLs
- ✅ Theme Sharing: Shared Docsy theme customizations across all sites
Continuous Improvement:
- Monitor build times as content grows
- Gather feedback on developer experience
- Iterate on shared vs per-site customizations
- Evaluate caching opportunities
- Consider additional SEO optimization (structured data, etc.)
5. Conclusion
The Hugo migration successfully addressed the SEO limitations of Docsify while establishing a scalable, maintainable
multi-site documentation architecture. The centralized orchestrator approach provides the right balance of consistency
and flexibility for related Bash tooling documentation projects.
Key Success Factors:
- Right tool for the job: Hugo’s documentation focus and SEO capabilities
- Architectural alignment: Centralized approach matches project relationships
- Security improvement: GitHub App migration enhanced security posture
- Maintainability: Single-point updates reduce ongoing effort
- Flexibility preserved: Configuration overrides allow per-site customization
Documentation maintained and current as of: 2026-02-18
Related Resources:
4 - My Documents - Trigger Reusable Workflow Documentation
Overview of the technical architecture and implementation details of the My Documents reusable workflow for triggering documentation builds
1. Overview
The trigger-docs-reusable.yml workflow is a reusable GitHub Actions workflow that enables dependent repositories
(bash-compiler, bash-tools, bash-tools-framework, bash-dev-env) to trigger documentation builds in the centralized
my-documents orchestrator.
Benefits:
- No secrets required in dependent repositories (GitHub handles authentication automatically)
- Centralized configuration - All authentication handled by GitHub App in my-documents
- Configurable - Override defaults for organization, repository, URLs, etc.
- Secure - Uses GitHub App authentication with automatic token expiration
- Simple integration - Just a few lines in dependent repo workflows
2. Quick Start
2.1. Basic Usage
Create .github/workflows/trigger-docs.yml in your dependent repository:
name: Trigger Documentation Build
on:
push:
branches: [master]
paths:
- content/**
- static/**
- go.mod
- go.sum
workflow_dispatch:
jobs:
trigger-docs:
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
secrets: inherit
That’s it! No secrets to configure, no tokens to manage.
3. How It Works
3.1. Architecture
┌─────────────────────────┐
│ Dependent Repository │
│ (e.g., bash-compiler) │
│ │
│ Push to master branch │
│ ├─ content/** │
│ └─ static/** │
└────────────┬────────────┘
│
│ workflow_call
▼
┌─────────────────────────────────────┐
│ my-documents Repository │
│ │
│ .github/workflows/ │
│ trigger-docs-reusable.yml │
│ │
│ ┌────────────────────────────────┐ │
│ │ 1. Generate GitHub App Token │ │
│ │ (using DOC_APP_ID secret) │ │
│ └────────────┬───────────────────┘ │
│ │ │
│ ┌────────────▼───────────────────┐ │
│ │ 2. Trigger repository_dispatch │ │
│ │ event in my-documents │ │
│ └────────────┬───────────────────┘ │
└───────────────┼─────────────────────┘
│
│ repository_dispatch
▼
┌─────────────────────────────────────┐
│ my-documents Repository │
│ │
│ .github/workflows/ │
│ build-all-sites.yml │
│ │
│ Builds all 5 documentation sites │
│ Deploys to GitHub Pages │
└─────────────────────────────────────┘
3.2. Authentication Flow
- Calling workflow runs in dependent repository context
- Reusable workflow executes in my-documents repository context
- GitHub App token generated using my-documents secrets:
DOC_APP_ID - GitHub App IDDOC_APP_PRIVATE_KEY - GitHub App private key
- Token used to trigger
repository_dispatch event - Build workflow starts automatically in my-documents
Security Benefits:
- No PAT tokens needed in dependent repositories
- No secrets management in dependent repos
- Automatic token expiration (1 hour)
- Fine-grained permissions (Contents: write, Pages: write)
- Centralized audit trail
4. Configuration
All inputs are optional with sensible defaults:
| Input | Description | Default |
|---|
target_org | Target organization/user | fchastanet |
target_repo | Target repository name | my-documents |
event_type | Repository dispatch event type | trigger-docs-rebuild |
docs_url_base | Documentation URL base | https://devlab.top/ |
workflow_filename | Workflow filename to monitor | build-all-sites.yml |
source_repo | Source repository | ${{ github.repository }} |
| (auto-detected if not provided) | |
4.2. Advanced Usage Examples
4.2.1. Custom Documentation URL
jobs:
trigger-docs:
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
with:
docs_url_base: https://docs.example.com
secrets: inherit
4.2.2. Different Target Repository
jobs:
trigger-docs:
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
with:
target_org: myOrg
target_repo: my-docs
workflow_filename: build-docs.yml
secrets: inherit
4.2.3. Manual Trigger with Custom Event Type
jobs:
trigger-docs:
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
with:
event_type: custom-docs-rebuild
secrets: inherit
5. Complete Example
Here’s a complete example for a dependent repository:
name: Trigger Documentation Build
on:
# Trigger on content changes
push:
branches: [master]
paths:
- content/** # Hugo content
- static/** # Static assets
- go.mod # Hugo modules
- go.sum # Hugo module checksums
- configs/** # If using custom configs
# Allow manual triggering
workflow_dispatch:
# Trigger on releases
release:
types: [published]
jobs:
trigger-docs:
name: Trigger Documentation Build
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
secrets: inherit
6. Secrets Configuration
6.1. In my-documents Repository
The reusable workflow requires these secrets to be configured in the my-documents repository:
| Secret | Description | How to Get |
|---|
DOC_APP_ID | GitHub App ID | From GitHub App settings |
DOC_APP_PRIVATE_KEY | GitHub App private key (PEM format) | Generated when creating GitHub App |
Setting up secrets:
- Go to https://github.com/fchastanet/my-documents/settings/secrets/actions
- Add
DOC_APP_ID with your GitHub App ID - Add
DOC_APP_PRIVATE_KEY with the private key content
6.2. In Dependent Repositories
No secrets needed! The secrets: inherit directive allows the reusable workflow to access my-documents secrets when
running.
7. Understanding Secrets: Inherit and Access Control
7.1. What is secrets: inherit?
secrets: inherit is a GitHub Actions feature that allows a reusable workflow to access repository secrets from the
calling workflow’s repository when in the same repository context.
Important distinction:
When a dependent repository (like bash-compiler) calls this reusable workflow with secrets: inherit:
jobs:
trigger-docs:
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
secrets: inherit
It means:
“Pass any secrets from bash-compiler repository to the reusable workflow”
NOT:
“Pass secrets from my-documents to bash-compiler”
7.2. How Does It Work for Dependent Repositories?
The key to understanding this is the execution context:
- Workflow file location:
.github/workflows/trigger-docs-reusable.yml lives in my-documents - Calling workflow location:
.github/workflows/trigger-docs.yml lives in bash-compiler (or other dependent
repo) - Execution context: When bash-compiler calls the reusable workflow, the reusable workflow still runs in the
my-documents context
This means:
- The reusable workflow has access to my-documents’ secrets, not bash-compiler’s secrets
secrets: inherit tells the reusable workflow “use my (the calling repo’s) secrets if needed”- But since the workflow runs in my-documents context, it automatically has access to my-documents’ secrets anyway
7.3. Secret Access Hierarchy
GitHub Actions processes reusable workflows within the repository where they’re defined:
┌────────────────────────────────────────────────────────────────────────────────────┐
│ bash-compiler repo │
│ │
│ .github/workflows/ │
│ trigger-docs.yml │
│ │
│ calls: fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master │
│ secrets: inherit │
└───────────────────────────────────────┬────────────────────────────────────────────┘
│
│ workflow_call (context: my-documents)
│
▼
┌─────────────────────────────────┐
│ my-documents repo │
│ (workflow context) │
│ │
│ .github/workflows/ │
│ trigger-docs-reusable.yml │
│ │
│ ✅ Can access: │
│ - DOC_APP_ID │
│ - DOC_APP_PRIVATE_KEY │
│ (my-documents secrets) │
│ │
│ ❌ Cannot directly access: │
│ - bash-compiler secrets │
└─────────────────────────────────┘
7.4. Why This Workflow Can’t Be Used by Others
This workflow is tightly coupled to the my-documents infrastructure:
7.4.1. Reason 1: GitHub App is Organization-Specific
The workflow uses DOC_APP_ID and DOC_APP_PRIVATE_KEY secrets that are:
- Configured only in the my-documents repository
- Created from a GitHub App installed only on:
- fchastanet/my-documents
- fchastanet/bash-compiler
- fchastanet/bash-tools
- fchastanet/bash-tools-framework
- fchastanet/bash-dev-env
If someone from outside this organization tries to use the workflow:
# In their-org/their-repo
jobs:
trigger-docs:
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
secrets: inherit
What happens:
- Workflow starts in their-org/their-repo context (calling workflow)
- Reusable workflow executes in fchastanet/my-documents context
- Reusable workflow tries to access
DOC_APP_ID and DOC_APP_PRIVATE_KEY - These secrets don’t exist in their-repo, so
secrets: inherit doesn’t provide them - The workflow fails with authentication error
Error: The variable has not been set, or it has been set to an empty string.
Evaluating: secrets.DOC_APP_ID
7.4.2. Reason 2: GitHub App Has No Access to Other Organizations
The GitHub App is installed only on specific fchastanet repositories:
- When workflow tries to trigger
repository_dispatch in my-documents using the app token - The token is only valid for repositories where the app is installed
- If someone tries to point it to their own my-documents fork, the app has no permission
Error example:
Error: Resource not accessible by integration
at https://api.github.com/repos/their-org/their-docs/dispatches
7.4.3. Reason 3: Secrets Are Repository-Specific
GitHub Actions secrets are stored at three levels:
| Level | Scope | Accessible By |
|---|
| Repository | Single repository | Workflows in that repository only |
| Environment | Specific deployment environment | Workflows targeting that environment |
| Organization | All repositories in organization | All workflows in the organization |
My-documents secrets are stored at the repository level:
- Only accessible to workflows executing in my-documents context
- Not accessible to workflows in other organizations
- Not inherited by other repositories, even if they call the reusable workflow
7.5. Practical Example: Why It Fails
Scenario: User john forks my-documents to john/my-documents-fork and tries to use the workflow:
# In john/bash-compiler (dependent repo fork)
jobs:
trigger-docs:
uses: |-
john/my-documents-fork/.github/workflows/trigger-docs-reusable.yml@master
secrets: inherit
Execution flow:
1. bash-compiler workflow starts (context: john)
❌ john/my-documents-fork doesn't have DOC_APP_ID or DOC_APP_PRIVATE_KEY secrets
2. Reusable workflow starts (context: john/my-documents-fork)
❌ Tries to access secrets.DOC_APP_ID
❌ Secrets don't exist in john/my-documents-fork
❌ secrets: inherit doesn't help (no secrets in john/bash-compiler either)
3. GitHub App access attempt
❌ GitHub App not installed on john/my-documents-fork
❌ Authentication fails with 403 error
7.6. How Someone Else Could Create Their Own Version
If someone wanted to use this pattern for their own orchestrator:
Create their own GitHub App
- In their organization settings
- With Contents: write and Pages: write permissions
- Install on their repositories
Set up secrets in their my-documents repository
DOC_APP_ID = their-app-id
DOC_APP_PRIVATE_KEY = their-private-key
Create their own reusable workflow
- Copy and adapt the trigger-docs-reusable.yml
- Reference their own secrets
- Change target_org default to their organization
Update dependent repositories
- Point to their reusable workflow
- Use
secrets: inherit in their calls
Example for their-org:
# In their-org/bash-compiler
jobs:
trigger-docs:
uses: |-
their-org/my-docs-orchestrator/.github/workflows/trigger-docs-reusable.yml@master
secrets: inherit
# This now references their-org's secrets, not fchastanet's
7.7. Summary: Why This Workflow is Fchastanet-Only
| Component | Why It’s Fchastanet-Specific | Can Be Generalized? |
|---|
| Workflow logic | Generic, reusable for any workflow | ✅ Yes, with different inputs |
DOC_APP_ID secret | Specific to fchastanet’s GitHub App | ❌ No, organization-specific |
DOC_APP_PRIVATE_KEY secret | Specific to fchastanet’s GitHub App | ❌ No, organization-specific |
| Target repository (default) | Hardcoded to my-documents | ✅ Yes, via target_repo input |
| Target organization (default) | Hardcoded to fchastanet | ✅ Yes, via target_org input |
| GitHub App installation | Only on fchastanet repositories | ❌ No, would need own app |
7.8. Conclusion
The secrets: inherit mechanism is elegant for internal workflows within an organization because:
- For dependent repos in fchastanet: They can call the workflow without managing secrets (works perfectly)
- For external users: They cannot use this workflow as-is because the GitHub App and secrets are
organization-specific
- This is intentional: It provides security and prevents unauthorized access to the build orchestration
This is not a limitation but a security feature - the workflow is designed to work only within the fchastanet
organization where the GitHub App is installed.
8. Workflow Outputs
The workflow provides rich output and summaries:
8.1. Console Output
🔔 Triggering documentation build in fchastanet/my-documents...
✅ Successfully triggered docs build in fchastanet/my-documents
📖 Documentation will be updated at: https://bash-compiler.devlab.top/
ℹ️ Note: Documentation deployment may take 2-5 minutes
8.2. GitHub Actions Summary
The workflow creates a detailed summary visible in the Actions UI:
### 8.3. ✅ Documentation build triggered
**Source Repository:** `fchastanet/bash-compiler`
**Target Repository:** `fchastanet/my-documents`
**Commit:** `abc123def456`
**Triggered by:** `fchastanet`
🔗 [View build status](https://github.com/fchastanet/my-documents/actions/workflows/build-all-sites.yml)
📖 [View documentation](https://bash-compiler.devlab.top/)
9. Troubleshooting
9.1. Build Not Triggered
Symptoms:
- Workflow runs successfully but build doesn’t start
- HTTP 204 response but no activity in my-documents
Possible Causes:
GitHub App not installed on target repository
- Solution: Install the GitHub App on my-documents repository
GitHub App permissions insufficient
- Solution: Ensure app has
Contents: write permission
Event type mismatch
- Solution: Verify
event_type input matches what build-all-sites.yml expects
9.2. Authentication Failures
Symptoms:
- HTTP 401 (Unauthorized) or 403 (Forbidden) errors
- “Resource not accessible by integration” error
Possible Causes:
Secrets not configured in my-documents
- Solution: Add
DOC_APP_ID and DOC_APP_PRIVATE_KEY secrets
GitHub App private key incorrect
- Solution: Regenerate private key in GitHub App settings
GitHub App permissions revoked
- Solution: Reinstall GitHub App on repositories
9.3. Workflow Not Found
Symptoms:
- “Unable to resolve action” error
- “Workflow file not found” error
Possible Causes:
Wrong branch reference
- Solution: Use
@master not @main (my-documents uses master branch)
Workflow file renamed or moved
- Solution: Verify file exists at
.github/workflows/trigger-docs-reusable.yml
9.4. Debug Mode
Enable debug logging in dependent repository:
jobs:
trigger-docs:
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
secrets: inherit
Then enable debug logs in repository settings:
- Go to repository settings → Secrets and variables → Actions
- Add repository variable:
ACTIONS_STEP_DEBUG = true - Add repository variable:
ACTIONS_RUNNER_DEBUG = true
10. Migration Guide
10.1. From Old Trigger Workflow
If you’re migrating from the old PAT-based trigger workflow:
Old approach (deprecated):
jobs:
trigger:
runs-on: ubuntu-latest
steps:
- name: Trigger my-documents build
run: |
curl -X POST \
-H "Authorization: token ${{ secrets.DOCS_BUILD_TOKEN }}" \
...
New approach (recommended):
jobs:
trigger-docs:
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
secrets: inherit
Benefits of migration:
- ✅ Remove
DOCS_BUILD_TOKEN secret from dependent repository - ✅ Simpler workflow (3 lines vs 50+ lines)
- ✅ Centralized authentication
- ✅ Automatic token management
- ✅ Better security (GitHub App vs PAT)
11. Best Practices
11.1. Trigger Paths
Only trigger on content changes to avoid unnecessary builds:
on:
push:
branches: [master]
paths:
- content/** # Documentation content
- static/** # Static assets
- go.mod # Hugo modules (theme updates)
- go.sum
Don’t trigger on:
- Test files
- CI configuration changes
- Source code changes (unless they affect docs)
- README updates (unless it’s documentation content)
11.2. Concurrency Control
Prevent multiple concurrent builds:
jobs:
trigger-docs:
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
secrets: inherit
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
11.3. Conditional Triggers
Only trigger for certain branches:
jobs:
trigger-docs:
if: github.ref == 'refs/heads/master'
uses: |-
fchastanet/my-documents/.github/workflows/trigger-docs-reusable.yml@master
secrets: inherit
12. FAQ
A: No! When using secrets: inherit, the reusable workflow can access secrets from my-documents repository.
12.2. Q: Can I test the workflow before merging to master?
A: Yes, add workflow_dispatch trigger and manually run it from the Actions tab.
12.3. Q: How long does documentation deployment take?
A: Typically 2-5 minutes:
- Trigger: ~5 seconds
- Build (all sites): ~60 seconds
- Deployment: ~1-3 minutes (GitHub Pages propagation)
12.4. Q: Can I use this with my own organization?
A: Yes, override target_org and target_repo inputs. You’ll need to set up your own GitHub App.
12.5. Q: What if the build fails?
A: Check the build status link in the workflow summary. The trigger workflow will still succeed; failures happen in
the build workflow.
12.6. Q: Can I trigger builds for multiple repositories?
A: Yes, create multiple jobs in your workflow, each calling the reusable workflow with different source_repo
values.
14. Support
For issues or questions:
- Check Troubleshooting section
- Review GitHub Actions logs
- Create an issue in my-documents repository
5 - Quick Reference - Hugo Site Development
A quick reference guide for developing and maintaining the Hugo documentation site
1. Local Development
1.1. Start
# Download dependencies (first time only)
hugo mod get -u
# Start development server
hugo server -D
# Open browser
# http://localhost:1313/my-documents/
1.2. Auto-reload
- Edit markdown files
- Browser auto-refreshes
- Press
Ctrl+C to stop
2. Adding Content
2.1. New Page in Existing Section
hugo new docs/bash-scripts/my-page.md
Edit the file with frontmatter:
---
title: My New Page
description: Brief description for SEO
weight: 10
categories: [Bash]
tags: [bash, example]
---
Your content here...
2.2. New Section
Create directory in content/en/docs/ and _index.md:
mkdir -p content/en/docs/new-section
touch content/en/docs/new-section/_index.md
2.3. Frontmatter Fields
---
title: Page Title # Required, shown as H1
description: SEO description # Required, used in meta tags
weight: 10 # Optional, controls ordering (lower = earlier)
categories: [category-name] # Optional, for content organization
tags: [tag1, tag2] # Optional, for tagging
---
3. Content Organization
content/en/docs/
├── bash-scripts/ # Weight: 10 (first)
├── howtos/ # Weight: 20
│ └── howto-write-jenkinsfile/ # Subsection
├── lists/ # Weight: 30
└── other-projects/ # Weight: 40 (last)
Navigation: Automatic based on directory structure + weight frontmatter
4. Images and Assets
Place in static/ directory:
static/
├── howto-write-dockerfile/ # For Dockerfile guide images
├── howto-write-jenkinsfile/ # For Jenkins guide images
└── your-section/ # Create as needed
Reference in markdown:

5. Common Docsy Shortcodes
5.1. Info Box
<div class="pageinfo pageinfo-primary">
This is an informational box.
</div>
5.2. Alert
<div class="alert alert-warning" role="alert"><div class="h4 alert-heading" role="heading">Warning</div>
This is a warning message.
</div>
5.3. Tabbed Content
<ul class="nav nav-tabs" id="tabs-2" role="tablist">
<li class="nav-item">
<button class="nav-link active"
id="tabs-02-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-00" role="tab"
aria-controls="tabs-02-00" aria-selected="true">
Tab 1
</button>
</li><li class="nav-item">
<button class="nav-link"
id="tabs-02-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-02-01" role="tab"
aria-controls="tabs-02-01" aria-selected="false">
Tab 2
</button>
</li>
</ul>
<div class="tab-content" id="tabs-2-content">
<div class="tab-pane fade show active"
id="tabs-02-00" role="tabpanel" aria-labelled-by="tabs-02-00-tab" tabindex="2">
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"><p>Content for tab 1</p></span></span></code></pre></div>
</div>
<div class="tab-pane fade"
id="tabs-02-01" role="tabpanel" aria-labelled-by="tabs-02-01-tab" tabindex="2">
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"><p>Content for tab 2</p></span></span></code></pre></div>
</div>
</div>
See full list: https://www.docsy.dev/docs/reference/shortcodes/
6. Code Blocks
Specify language for syntax highlighting:
```bash
#!/bin/bash
echo "Hello World"
```
```yaml
key: value
nested:
item: value
```
```python
def hello():
print("Hello World")
```
7. Internal Links
Use relative paths:
[Link text](/docs/bash-scripts/page-name/)
[Link text](/docs/section/_index/)
Hugo resolves these automatically.
8. Building for Production
# Build minified site
hugo --minify
# Output goes to public/ directory
# GitHub Actions handles deployment automatically
9. Content Guidelines
- Line length: 120 characters max (enforced by mdformat)
- Headers: Use ATX style (#, ##, ###)
- Lists: 2-space indentation
- Code blocks: Always specify language
- Images: Include alt text
- Links: Use relative paths for internal, full URLs for external
10. Spell Checking
Add technical terms to .cspell/bash.txt:
echo "newWord" >>.cspell/bash.txt
pre-commit run file-contents-sorter # auto-sorts
11. Git Workflow
- Branch: Always use
master - Commit: Detailed message with changes
- Push: Triggers linting and Hugo build
- CI/CD: GitHub Actions handles rest
git add .
git commit -m "Add new documentation on topic"
git push origin master
12. Troubleshooting
12.1. Hugo server won’t start
rm go.sum
hugo mod clean
hugo mod get -u
hugo server -D
12.2. Module not found errors
hugo version # Check it says "extended"
hugo mod get -u
12.3. Build artifacts in way
rm -rf resources/ public/
hugo --minify
12.4. Link errors
- Check relative path is correct
- Verify file exists in expected location
- Internal links should start with
/docs/
13. File Locations
| Item | Path |
|---|
| Site config | hugo.yaml |
| Home page | content/en/_index.html |
| Docs home | content/en/docs/_index.md |
| Bash guides | content/en/docs/bash-scripts/ |
| How-TO guides | content/en/docs/howtos/ |
| Lists | content/en/docs/lists/ |
| Images | static/section-name/ |
| Archetypes | archetypes/*.md |
| Theme config | hugo.yaml params section |
14. SEO Best Practices
- ✅ Use descriptive titles and descriptions
- ✅ Add
weight to control ordering - ✅ Use categories and tags
- ✅ Include proper alt text on images
- ✅ Link to related content
- ✅ Use clear heading hierarchy
- ✅ Keep page descriptions under 160 chars
15. Submitting to Search Engines
- Build site:
hugo --minify (GitHub Actions does this) - GitHub Actions deploys to GitHub Pages
- Submit sitemap to search console:
16. Useful Commands
hugo server -D # Run dev server
hugo --minify # Build for production
hugo --printI18nWarnings # Check for i18n issues
hugo --printPathWarnings # Check path warnings
hugo --printUnusedTemplates # Check unused templates
pre-commit run -a # Run all linters
17. Theme Customization
To override Docsy styles:
- Create
/assets/scss/_custom.scss - Add custom CSS
- Rebuild with
hugo server
For more details: https://www.docsy.dev/docs/
Quick Links: