This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

My Documents

Articles about this repository, its structure, and how to use it effectively

Dedicated section for articles about this repository, its structure, and how to use it effectively.

1. Available Guides

  • My Documents static site generation - Analysis of migrating from Docsify to an SEO-optimized static site generator
  • My Documents Multi repositories Site Generation - Analysis of generating a documentation site from multiple repositories using Hugo and GitHub Pages
  • My Documents Technical Architecture - Overview of the technical architecture of this documentation site, including the use of Hugo, GitHub Pages, and CI/CD pipelines
  • My Documents Trigger Workflow - Guide on how to trigger the documentation build workflow using GitHub Actions

2. Getting Started

Select a documentation topic from the sidebar to begin.

Articles in this section

TitleDescriptionUpdated
Quick Reference - Hugo Site DevelopmentA quick reference guide for developing and maintaining the Hugo documentation site2026-03-04
Technical ArchitectureComplete technical architecture guide for the Hugo documentation system with reusable GitHub Actions2026-02-22
Static Site Generation Migration AnalysisAnalysis of migrating from Docsify to an SEO-optimized static site generator2026-02-22
My Documents - Trigger Reusable Workflow DocumentationOverview of the technical architecture and implementation details of the My Documents reusable workflow for triggering documentation builds2026-02-21
My Documents - Multi repositories Site GenerationComprehensive documentation of the Hugo migration for multi-site documentation2026-02-18

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

SiteRepositoryLive URL
My Documentsfchastanet/my-documentshttps://devlab.top/
Bash Compilerfchastanet/bash-compilerhttps://bash-compiler.devlab.top/
Bash Toolsfchastanet/bash-toolshttps://bash-tools.devlab.top/
Bash Tools Frameworkfchastanet/bash-tools-frameworkhttps://bash-tools-framework.devlab.top/
Bash Dev Envfchastanet/bash-dev-envhttps://bash-dev-env.devlab.top/

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:

  1. Developer pushes content to a documentation repository (e.g., bash-compiler)
  2. GitHub Actions triggers the build-site.yml workflow in that repository
  3. Workflow calls my-documents/.github/workflows/build-site-action.yml (reusable action)
  4. Hugo downloads modules including my-documents for shared resources
  5. Hugo builds site using merged configuration (base + site-specific overrides)
  6. 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:

  • Admin access to create a new repository or use existing repository
  • Basic understanding of Hugo and Markdown
  • Hugo Extended and Go installed locally for testing

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 username
  • YOUR-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 username
  • YOUR-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:

  1. Navigate to SettingsPages
  2. Under Source, select GitHub Actions
  3. Click Save

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:

  1. Go to Actions tab in your repository
  2. Watch the “Build and Deploy Documentation” workflow
  3. 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:

  • Hugo builds locally without errors (hugo --minify)
  • Development server runs (hugo server -D)
  • All pages render correctly
  • Navigation menu shows correct structure
  • Search works (if enabled)
  • GitHub Actions workflow completes successfully
  • Site deploys to GitHub Pages
  • All links work on live site
  • Mobile view looks correct
  • Theme colors match expectations

5. GitHub Configuration

5.1. GitHub Pages Settings

Required Configuration:

  1. Source: GitHub Actions (NOT a branch)
  2. Custom Domain: Optional
  3. 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:

  1. Base configuration (_base.yaml from my-documents)
  2. 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:

on:
  workflow_dispatch:

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:

  1. Local layouts/ directory (highest priority)
  2. Mounted shared/layouts/ from my-documents
  3. 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:

  1. Check file paths in trigger:

    on:
      push:
        paths:
          - content/**
          - static/**
          - hugo.yaml
    

    Ensure changed files match these patterns.

  2. Verify branch name:

    on:
      push:
        branches: [master]  # Check your default branch name
    
  3. Check workflow syntax:

    # Validate YAML syntax
    yamllint .github/workflows/build-site.yml
    
  4. 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:

  1. Clean module cache:

    hugo mod clean
    hugo mod get -u
    
  2. Verify module versions:

    # Show dependency graph
    hugo mod graph
    
    # Check go.sum for versions
    cat go.sum
    
  3. Force module update:

    # Remove go.sum and rebuild
    rm go.sum
    hugo mod get -u
    hugo mod tidy
    
  4. 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:

  1. Check Pages source:

    • Settings → Pages → Source must be “GitHub Actions”
  2. Verify permissions:

    permissions:
      contents: read
      pages: write
      id-token: write
    
  3. Check deployment logs:

    • Actions tab → Click workflow run → Expand “Deploy to GitHub Pages” step
  4. 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
    
  5. Artifact upload size:

    # Check public/ directory size
    du -sh public/
    
    # GitHub has 10GB limit per artifact
    # Optimize images and remove unnecessary files
    

Problem: Broken links or missing pages

Solutions:

  1. Check relative links:

    <!-- Correct -->
    [Guide](/docs/guide/)
    
    <!-- Incorrect -->
    [Guide](docs/guide/)  <!-- Missing leading slash -->
    
  2. Verify baseURL:

    # Must match deployment URL exactly
    baseURL: https://username.github.io/repo-name
    
  3. Check content organization:

    content/
    └── en/
        ├── _index.md
        └── docs/
            ├── _index.md
            └── guide.md
    
  4. Front matter issues:

    ---
    title: "Guide"
    # Check for typos in keys
    linkTitle: "User Guide"
    weight: 10
    ---
    
  5. Test links locally:

    hugo server -D
    # Check all links work at http://localhost:1313
    

11.6. Debugging Checklist

When troubleshooting, work through this checklist:

  • Local build succeeds: hugo --minify completes without errors
  • Modules downloaded: hugo mod graph shows correct dependencies
  • Configuration valid: hugo config outputs without errors
  • Workflow syntax valid: YAML linter passes
  • Permissions correct: Workflow has pages: write permission
  • Pages source configured: GitHub Pages source is “GitHub Actions”
  • Actions enabled: Repository allows GitHub Actions
  • Branch correct: Workflow triggers on correct branch
  • Paths correct: Changed files match workflow path filters
  • Artifacts created: Workflow creates and uploads artifact
  • Deployment job runs: Separate deployment job executes
  • Content accessible: Files in content/ directory render
  • Links work: Internal navigation functions correctly

Verbose Build Output:

# Local debugging with verbose output
hugo --minify --verbose --debug

# Check Hugo environment
hugo env

Check GitHub Actions Logs:

  1. Go to repository → Actions tab
  2. Click failing workflow run
  3. Expand each step to see detailed output
  4. 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:

  1. Local layouts/ (highest)
  2. Mounted shared/layouts/ from my-documents
  3. Docsy theme layouts (lowest)

12.2. SEO Metadata

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:"

12.3. Menu Customization

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:

  1. Fork the repository:

    gh repo fork fchastanet/my-documents --clone
    cd my-documents
    
  2. Create a feature branch:

    git checkout -b feature/improve-action
    
  3. Make changes:

    • Edit .github/workflows/build-site-action.yml
    • Update documentation if needed
    • Test changes thoroughly
  4. Commit using conventional commits:

    git commit -m "feat(workflows): add support for custom Hugo version"
    
  5. 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:

  1. Push changes to your fork:

    git push origin feature/improve-action
    
  2. 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
    
  3. Trigger workflow:

    git commit --allow-empty -m "Test workflow"
    git push
    
  4. 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:

  1. Checkout repository: Clones the calling repository
  2. Setup Hugo: Installs Hugo Extended
  3. Setup Go: Installs Go (required for Hugo modules)
  4. Download modules: Runs hugo mod get -u
  5. Build site: Runs hugo --minify
  6. Upload artifact: Uploads public/ directory
  7. 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:

  1. Checkout code: Clones repository with full history
  2. Setup Python: Installs Python for pre-commit
  3. Install pre-commit: Installs pre-commit tool
  4. Run pre-commit: Executes all pre-commit hooks
  5. Run MegaLinter: Runs comprehensive linting
  6. Upload reports: Saves linter reports as artifacts
  7. 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:

  1. Create content structure in your repository
  2. Add go.mod, hugo.yaml, and build-site.yml
  3. Configure GitHub Pages to use “GitHub Actions” source
  4. 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 ✅

AdvantageImpact
Zero build step requiredInstant deployment, minimal CI/CD complexity
Simple file structureEasy to add new documentation files
No dependencies to manageFewer security concerns, simpler setup
Client-side renderingWorks directly with GitHub Pages
Lightweight theme systemEasy customization with CSS
Good for technical audienceFast navigation for users familiar with SPAs
Markdown-firstNatural for technical documentation

2.3. Docsify Cons ❌

LimitationImpact
Client-side renderingPoor SEO - Search engines struggle to index content
No static HTMLNo pre-rendered pages for crawlers
JavaScript dependentRequires JS in browser (security consideration)
Limited meta tags controlDifficult to optimize individual pages for SEO
Slow initial page loadJavaScript bundle must load first
No built-in sitemapManual sitemap generation needed
No RSS/feed supportHard to distribute content
Search plugin limitationsSite search not indexed by external search engines
No static asset optimizationAll images referenced as relative paths
Outdated dependency stackUses 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.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

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
  1. Docsy - Google-created, excellent documentation theme, built-in search
  2. Relearn - MkDocs-inspired, sidebar navigation like Docsify
  3. Book - Clean, minimal, perfect for tutorials
  4. 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
  1. Starlight - Official Astro docs template, excellent for documentation
  2. Docs Kit - Tailored for technical documentation
  3. 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
  1. 11ty Base Blog - Simple starting point
  2. Eleventy High Performance Blog - Performance-focused
  3. 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

CriteriaHugoAstro11tyVuePressMkDocsNext.jsGatsby
SEO Score9/109/108/106/107/108/107/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

  • Generate robots.txt automatically
  • Generate XML sitemap automatically
  • Implement per-page meta tags (title, description)
  • Add canonical URLs to prevent duplication
  • Implement JSON-LD schema (Article, BreadcrumbList, Organization)
  • Open Graph and Twitter card meta tags
  • Mobile-first responsive design
  • Fast page load (Core Web Vitals: LCP, CLS, FID)
  • Image optimization and lazy loading
  • Minify and compress assets

6.2. Content Structure

  • Implement breadcrumb navigation (visual + schema)
  • Hierarchical heading structure (H1, H2, H3)
  • Internal linking strategy
  • Related content suggestions
  • Table of contents for long articles
  • Reading time estimates
  • Last updated timestamps

6.3. Performance Optimizations

  • Code splitting and lazy loading
  • Image optimization (WebP, AVIF formats)
  • CSS/JS minification
  • Critical CSS inline
  • Service worker for offline access
  • Asset caching strategies
  • Compression (gzip/brotli)
  • CDN integration

6.4. Search and Indexing

  • Submit sitemap to Google Search Console
  • Monitor indexing status
  • Fix crawl errors
  • Optimize Core Web Vitals
  • Monitor search appearance (ratings, rich results)
  • Use Google Search Console to identify improvements

6.5. Advanced SEO

  • Implement full-text search with ranking
  • Add RSS/Atom feeds for content discovery
  • Implement structured data for articles
  • Add FAQ schema for common questions
  • Breadcrumb schema implementation
  • Organization/website schema
  • Add “edit on GitHub” links for engagement signals

6.6. Analytics and Monitoring

  • Google Analytics 4 integration
  • Search Console monitoring
  • Core Web Vitals tracking
  • Error tracking (Sentry/similar)
  • Performance monitoring dashboard
  • Keyword ranking tracking
  • Traffic Analysis

6.7. GitHub CI/CD Improvements

  • Semantic versioning for releases
  • Link checker in CI pipeline
  • SEO audit in CI (Lighthouse, lighthouse-ci)
  • Spell checker (already implemented)
  • Broken internal link detection
  • Mobile-first testing
  • Accessibility testing (a11y)
  • Build time monitoring
  • Automated lighthouse reports

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

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

RiskHugoAstro11tyMkDocsVuePress
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

  1. SEO Excellence - 9/10 score meets all objectives
  2. Simplicity - Single Go binary, no dependency management
  3. Performance - <1s builds, scales to thousands of pages
  4. Documentation-First - Built for exactly this use case
  5. GitHub Pages Native - Zero friction deployment
  6. Multi-Site Scalability - Perfect for multiple repositories
  7. Community - Largest documentation site generator community
  8. Proven - 1000+ major documentation sites use it
  9. Themes - Docsy, Relearn excellent for technical docs
  10. 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
  • 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:

  1. Review this analysis with relevant stakeholders
  2. Set up pilot Hugo site with one repository
  3. Validate SEO improvements with Search Console
  4. Plan full migration timeline
  5. 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-compiler
  • fchastanet/bash-tools
  • fchastanet/bash-tools-framework
  • fchastanet/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

CriteriaHugoAstro11tyVuePressMkDocs
SEO Score9/109/108/106/107/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:

  1. Push to bash-compiler → triggers my-documents via repository_dispatch
  2. 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:

  1. Each dependent repo has its own build workflow
  2. Workflow calls the reusable workflow from my-documents
  3. Hugo modules pull shared resources during build
  4. 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

CriteriaCentralized OrchestratorDecentralized ReusableMonorepo
ComplexityLow (minimal per-repo)Medium (per-repo setup)Low (single repo)
Build Time~60s all sites~30s per site~60s all sites
MaintenanceUpdate onceUpdate workflow × NUpdate once
Consistency✅ GuaranteedCan drift✅ Guaranteed
Failure IsolationAll-or-nothing✅ IndependentAll-or-nothing
Setup Effort1 workflow + N configs6 files × N reposSingle setup
Independent URLs✅ Yes✅ Yes❌ No
Hugo Modules❌ Not neededRequired❌ Not needed

2. Chosen Solutions & Rationale

2.1. Static Site Generator: Hugo + Docsy Theme

Choice: Hugo with Google’s Docsy theme

Rationale:

  1. 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)
  2. 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)
  3. 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
  4. Developer Experience:

    • Markdown + frontmatter (minimal migration effort from Docsify)
    • Good documentation and large community
    • Extensive theme ecosystem
    • Active development and updates
  5. 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:

  1. 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
  2. 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)
  3. 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
  4. 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
  5. 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)
  6. 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-compiler
  • fchastanet/bash-tools
  • fchastanet/bash-tools-framework
  • fchastanet/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 trigger
  • repository_dispatch with type trigger-docs-rebuild - From dependent repos
  • push 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):

  1. Checkout Orchestrator: Clone my-documents repository
  2. Checkout Content: Clone dependent repository content (if not self)
  3. Setup Tools: Install Hugo Extended 0.155.3, Go 1.24, yq
  4. Prepare Build Directory:
    • For my-documents: Use orchestrator directory
    • For dependent repos: Create build-{site} directory
  5. Merge Configurations: Combine _base.yaml + {site}.yaml
  6. Copy Shared Resources: Link shared layouts, assets, archetypes
  7. Copy Content: Link content directory
  8. Initialize Hugo Modules: Run hugo mod init and hugo mod get -u
  9. Build Site: Run hugo --minify
  10. 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:

  1. Generate App Token: Use actions/create-github-app-token@v1
  2. Deploy with Token: Use peaceiris/actions-gh-pages@v4

Secrets Required (in my-documents):

  • DOC_APP_ID - GitHub App ID
  • DOC_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:

  1. Create new repository with content
  2. Add trigger workflow (2-minute setup)
  3. Add site config to my-documents/configs/{new-site}.yaml
  4. Add site to matrix in build-all-sites.yml
  5. Install GitHub App on new repository
  6. 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:

  1. Right tool for the job: Hugo’s documentation focus and SEO capabilities
  2. Architectural alignment: Centralized approach matches project relationships
  3. Security improvement: GitHub App migration enhanced security posture
  4. Maintainability: Single-point updates reduce ongoing effort
  5. 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

  1. Calling workflow runs in dependent repository context
  2. Reusable workflow executes in my-documents repository context
  3. GitHub App token generated using my-documents secrets:
    • DOC_APP_ID - GitHub App ID
    • DOC_APP_PRIVATE_KEY - GitHub App private key
  4. Token used to trigger repository_dispatch event
  5. 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

4.1. Input Parameters

All inputs are optional with sensible defaults:

InputDescriptionDefault
target_orgTarget organization/userfchastanet
target_repoTarget repository namemy-documents
event_typeRepository dispatch event typetrigger-docs-rebuild
docs_url_baseDocumentation URL basehttps://devlab.top/
workflow_filenameWorkflow filename to monitorbuild-all-sites.yml
source_repoSource 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:

SecretDescriptionHow to Get
DOC_APP_IDGitHub App IDFrom GitHub App settings
DOC_APP_PRIVATE_KEYGitHub App private key (PEM format)Generated when creating GitHub App

Setting up secrets:

  1. Go to https://github.com/fchastanet/my-documents/settings/secrets/actions
  2. Add DOC_APP_ID with your GitHub App ID
  3. 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:

  1. Workflow file location: .github/workflows/trigger-docs-reusable.yml lives in my-documents
  2. Calling workflow location: .github/workflows/trigger-docs.yml lives in bash-compiler (or other dependent repo)
  3. 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:

  1. Workflow starts in their-org/their-repo context (calling workflow)
  2. Reusable workflow executes in fchastanet/my-documents context
  3. Reusable workflow tries to access DOC_APP_ID and DOC_APP_PRIVATE_KEY
  4. These secrets don’t exist in their-repo, so secrets: inherit doesn’t provide them
  5. 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:

LevelScopeAccessible By
RepositorySingle repositoryWorkflows in that repository only
EnvironmentSpecific deployment environmentWorkflows targeting that environment
OrganizationAll repositories in organizationAll 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:

  1. Create their own GitHub App

    • In their organization settings
    • With Contents: write and Pages: write permissions
    • Install on their repositories
  2. Set up secrets in their my-documents repository

    DOC_APP_ID = their-app-id
    DOC_APP_PRIVATE_KEY = their-private-key
    
  3. Create their own reusable workflow

    • Copy and adapt the trigger-docs-reusable.yml
    • Reference their own secrets
    • Change target_org default to their organization
  4. 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

ComponentWhy It’s Fchastanet-SpecificCan Be Generalized?
Workflow logicGeneric, reusable for any workflow✅ Yes, with different inputs
DOC_APP_ID secretSpecific to fchastanet’s GitHub App❌ No, organization-specific
DOC_APP_PRIVATE_KEY secretSpecific 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 installationOnly 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:

  1. GitHub App not installed on target repository

    • Solution: Install the GitHub App on my-documents repository
  2. GitHub App permissions insufficient

    • Solution: Ensure app has Contents: write permission
  3. 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:

  1. Secrets not configured in my-documents

    • Solution: Add DOC_APP_ID and DOC_APP_PRIVATE_KEY secrets
  2. GitHub App private key incorrect

    • Solution: Regenerate private key in GitHub App settings
  3. 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:

  1. Wrong branch reference

    • Solution: Use @master not @main (my-documents uses master branch)
  2. 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:

  1. Go to repository settings → Secrets and variables → Actions
  2. Add repository variable: ACTIONS_STEP_DEBUG = true
  3. 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

12.1. Q: Do I need to configure secrets in my dependent repository?

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:

  1. Check Troubleshooting section
  2. Review GitHub Actions logs
  3. 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:

![Alt text](/howto-write-dockerfile/image-name.png)

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">&lt;p&gt;Content for tab 1&lt;/p&gt;</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">&lt;p&gt;Content for tab 2&lt;/p&gt;</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")
```

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

  1. Branch: Always use master
  2. Commit: Detailed message with changes
  3. Push: Triggers linting and Hugo build
  4. 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
  • Check relative path is correct
  • Verify file exists in expected location
  • Internal links should start with /docs/

13. File Locations

ItemPath
Site confighugo.yaml
Home pagecontent/en/_index.html
Docs homecontent/en/docs/_index.md
Bash guidescontent/en/docs/bash-scripts/
How-TO guidescontent/en/docs/howtos/
Listscontent/en/docs/lists/
Imagesstatic/section-name/
Archetypesarchetypes/*.md
Theme confighugo.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

  1. Build site: hugo --minify (GitHub Actions does this)
  2. GitHub Actions deploys to GitHub Pages
  3. 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:

  1. Create /assets/scss/_custom.scss
  2. Add custom CSS
  3. Rebuild with hugo server

For more details: https://www.docsy.dev/docs/


Quick Links: