⏱️ Estimated reading time: 22 min

Series Overview

Part 4 of the macOS GitHub CLI Complete Automation Series covers complete automation of wiki management, the foundation of development documentation. We will build an expert-level system that automatically reflects code changes in the wiki, synchronizes API documentation, and supports multiple languages.

Building a Modular Script System

1. Script Directory Structure

# Create an organized script structure
mkdir -p ~/scripts/github-cli/{wiki,core,utils,config}

# Create config file
cat > ~/scripts/github-cli/config/wiki-config.sh << 'EOF'
#!/bin/bash

# Wiki automation configuration
export WIKI_CONFIG_VERSION="1.0"
export WIKI_BASE_DIR="$HOME/Documents/wikis"
export WIKI_TEMPLATES_DIR="$HOME/scripts/github-cli/wiki/templates"
export WIKI_CACHE_DIR="$HOME/.cache/github-wikis"
export WIKI_BACKUP_DIR="$HOME/Documents/wiki-backups"

# Multilingual configuration
export SUPPORTED_LANGUAGES="ko,en,ja,zh"
export DEFAULT_LANGUAGE="en"

# API docs configuration
export API_DOCS_FORMAT="markdown"
export API_DOCS_AUTO_UPDATE="true"

# Quality validation configuration
export SPELL_CHECK_ENABLED="true"
export LINK_CHECK_ENABLED="true"
export TOC_AUTO_GENERATE="true"

echo "Wiki configuration loaded."
EOF

chmod +x ~/scripts/github-cli/config/wiki-config.sh

2. Core Wiki Functions

# Core wiki functions
cat > ~/scripts/github-cli/wiki/wiki-core.sh << 'EOF'
#!/bin/bash

# Wiki repository management
function wiki_init() {
    local repo_url="$1"
    local wiki_name="${2:-$(basename "$repo_url" .git)}"
    
    if [[ -z "$repo_url" ]]; then
        echo "Usage: wiki_init <repository URL> [wiki name]"
        return 1
    fi
    
    # Create wiki directory
    local wiki_dir="$WIKI_BASE_DIR/$wiki_name"
    mkdir -p "$wiki_dir"
    cd "$wiki_dir"
    
    # Clone/initialize wiki repository
    if [[ "$repo_url" == *".wiki.git" ]]; then
        git clone "$repo_url" .
    else
        # Extract wiki URL from main repository
        local wiki_url="${repo_url%.git}.wiki.git"
        git clone "$wiki_url" . 2>/dev/null || {
            # Create wiki if it doesn't exist
            echo "Creating new wiki..."
            git init .
            create_wiki_structure
        }
    fi
    
    echo "OK: Wiki '$wiki_name' initialized at: $wiki_dir"
}

# Create wiki structure
function create_wiki_structure() {
    # Home page
    cat > Home.md << 'HOMEEOF'
# Project Wiki

Welcome! This wiki is automatically generated and maintained.

## Documentation Structure

- [API Documentation](API-Documentation)
- [Installation Guide](Installation-Guide)
- [Development Guide](Development-Guide)
- [FAQ](FAQ)
- [Changelog](Changelog)

## Multilingual Support

- [English](Home) (current)
- [Korean](Home-KO)
- [Japanese](Home-JA)
- [Chinese](Home-ZH)

---
*This document was automatically generated. Last updated: $(date)*
HOMEEOF

    # Create default pages
    create_api_documentation_template
    create_installation_guide_template
    create_development_guide_template
    create_faq_template
    
    # Initial commit
    git add .
    git commit -m "Initial wiki structure created automatically"
    
    echo "OK: Default wiki structure created."
}

# API documentation template
function create_api_documentation_template() {
    cat > API-Documentation.md << 'APIEOF'
# API Documentation

This page is automatically generated and updated.

## Authentication

```bash
curl -H "Authorization: Bearer YOUR_TOKEN" \
     https://api.example.com/v1/endpoint

Endpoints

Overview

  • Base URL: https://api.example.com/v1
  • API Version: v1
  • Response Format: JSON

API documentation is auto-generated from code. APIEOF }

Automatic wiki update

function wiki_auto_update() { local repo_path=”${1:-.}” local wiki_path=”$2”

if [[ -z "$wiki_path" ]]; then
    # Auto-detect wiki path for current repository
    local repo_name=$(basename "$(git -C "$repo_path" remote get-url origin)" .git)
    wiki_path="$WIKI_BASE_DIR/$repo_name"
fi

if [[ ! -d "$wiki_path" ]]; then
    echo "FAIL: Wiki directory not found: $wiki_path"
    return 1
fi

echo "Starting automatic wiki update..."

# Sync README.md to Home.md
if [[ -f "$repo_path/README.md" ]]; then
    echo "Syncing README.md to Home.md"
    sync_readme_to_wiki "$repo_path/README.md" "$wiki_path/Home.md"
fi

# Sync API documentation
if [[ -f "$repo_path/docs/api.md" ]] || [[ -d "$repo_path/docs/api" ]]; then
    echo "Syncing API documentation"
    generate_api_docs "$repo_path" "$wiki_path"
fi

# Update changelog
echo "Updating changelog"
update_changelog "$repo_path" "$wiki_path"

# Commit and push wiki
cd "$wiki_path"
if git diff --quiet; then
    echo "No changes found."
else
    git add .
    git commit -m "Auto-update wiki from $(date '+%Y-%m-%d %H:%M')"
    git push origin master 2>/dev/null || git push origin main
    echo "OK: Wiki updated."
fi }

Sync README to wiki

function sync_readme_to_wiki() { local readme_file=”$1” local wiki_file=”$2”

# Convert README content to wiki format
{
    echo "# $(basename "$(dirname "$readme_file")" | tr '[:lower:]' '[:upper:]') Project"
    echo
    cat "$readme_file" | sed 's/^#/##/g'  # Adjust header levels
    echo
    echo "---"
    echo "*This page is automatically synced from README.md.*"
    echo "*Last updated: $(date)*"
} > "$wiki_file" } EOF

chmod +x ~/scripts/github-cli/wiki/wiki-core.sh


### 3. Automatic API Documentation Generation

```bash
# API documentation auto-generation system
cat > ~/scripts/github-cli/wiki/api-generator.sh << 'EOF'
#!/bin/bash

# Automatic API documentation generation
function generate_api_docs() {
    local repo_path="$1"
    local wiki_path="$2"
    
    echo "Generating API documentation..."
    
    # Detect OpenAPI/Swagger file
    local openapi_file=""
    for file in "$repo_path"/{swagger.yaml,openapi.yaml,docs/swagger.yaml,docs/openapi.yaml,api.yaml}; do
        if [[ -f "$file" ]]; then
            openapi_file="$file"
            break
        fi
    done
    
    if [[ -n "$openapi_file" ]]; then
        echo "OpenAPI spec found: $openapi_file"
        generate_from_openapi "$openapi_file" "$wiki_path/API-Documentation.md"
    else
        # Extract API endpoints from code
        echo "Extracting API endpoints from code..."
        extract_api_from_code "$repo_path" "$wiki_path/API-Documentation.md"
    fi
}

# Generate Markdown from OpenAPI
function generate_from_openapi() {
    local openapi_file="$1"
    local output_file="$2"
    
    # Parse OpenAPI using Python (simplified version)
    python3 -c "
import yaml
import json
import sys
from datetime import datetime

def parse_openapi(file_path):
    with open(file_path, 'r') as f:
        if file_path.endswith('.yaml') or file_path.endswith('.yml'):
            spec = yaml.safe_load(f)
        else:
            spec = json.load(f)
    
    # Generate Markdown
    md = []
    md.append('# API Documentation')
    md.append('')
    md.append(f'**Generated**: {datetime.now().strftime(\"%Y-%m-%d %H:%M\")}')
    md.append('')
    
    # Basic info
    info = spec.get('info', {})
    md.append(f'**Version**: {info.get(\"version\", \"N/A\")}')
    md.append(f'**Description**: {info.get(\"description\", \"API Documentation\")}')
    md.append('')
    
    # Server info
    servers = spec.get('servers', [])
    if servers:
        md.append('## Servers')
        for server in servers:
            md.append(f'- **{server.get(\"description\", \"Default server\")}**: \`{server.get(\"url\")}\`')
        md.append('')
    
    # Endpoints
    paths = spec.get('paths', {})
    if paths:
        md.append('## Endpoints')
        for path, methods in paths.items():
            md.append(f'### {path}')
            for method, details in methods.items():
                if isinstance(details, dict):
                    summary = details.get('summary', method.upper())
                    md.append(f'#### {method.upper()} - {summary}')
                    if 'description' in details:
                        md.append(f'{details[\"description\"]}')
                    md.append('')
    
    return '\\n'.join(md)

try:
    content = parse_openapi('$openapi_file')
    with open('$output_file', 'w') as f:
        f.write(content)
    print('OK: OpenAPI documentation generated.')
except Exception as e:
    print(f'FAIL: OpenAPI parse error: {e}')
" 2>/dev/null || {
        echo "Python OpenAPI parser unavailable. Using default template."
        create_api_documentation_template > "$output_file"
    }
}

# Extract API from code
function extract_api_from_code() {
    local repo_path="$1" 
    local output_file="$2"
    
    {
        echo "# API Documentation"
        echo
        echo "**Auto-generated**: $(date '+%Y-%m-%d %H:%M')"
        echo
        
        # Extract Express.js routes
        if find "$repo_path" -name "*.js" -o -name "*.ts" | head -1 >/dev/null; then
            echo "## Extracted Endpoints"
            echo
            
            # Find GET, POST, PUT, DELETE patterns
            find "$repo_path" -name "*.js" -o -name "*.ts" | xargs grep -h -E "(app\.|router\.|route\.)(get|post|put|delete|patch)" | \
                sed 's/.*\.\(get\|post\|put\|delete\|patch\)\s*(\s*['\''\"]\([^'\''\"]*\)['\''\"]/### \U\1\E \2/' | \
                sort -u | head -20
            echo
        fi
        
        # Extract FastAPI routes
        if find "$repo_path" -name "*.py" | head -1 >/dev/null; then
            echo "## Python API Endpoints"
            echo
            
            find "$repo_path" -name "*.py" | xargs grep -h -E "@app\.(get|post|put|delete|patch)" | \
                sed 's/.*@app\.\([^(]*\)(\s*['\''\"]\([^'\''\"]*\)['\''\"]/### \U\1\E \2/' | \
                sort -u | head -20
            echo
        fi
        
        echo "---"
        echo "*This document was auto-extracted from code.*"
        
    } > "$output_file"
}

# API documentation quality validation
function validate_api_docs() {
    local wiki_path="$1"
    local api_file="$wiki_path/API-Documentation.md"
    
    if [[ ! -f "$api_file" ]]; then
        echo "FAIL: API documentation not found: $api_file"
        return 1
    fi
    
    echo "Validating API documentation quality..."
    
    local issues=0
    
    # Check required sections
    local required_sections=("# API Documentation" "## Endpoints")
    for section in "${required_sections[@]}"; do
        if ! grep -q "$section" "$api_file"; then
            echo "WARNING: Required section missing: $section"
            issues=$((issues + 1))
        fi
    done
    
    # Check for external links
    if grep -q "http" "$api_file"; then
        echo "External links found - validation recommended"
    fi
    
    # Validate code blocks
    local code_blocks=$(grep -c '```' "$api_file")
    if [[ $((code_blocks % 2)) -ne 0 ]]; then
        echo "WARNING: Code block is not properly closed."
        issues=$((issues + 1))
    fi
    
    if [[ $issues -eq 0 ]]; then
        echo "OK: API documentation quality check passed"
    else
        echo "WARNING: $issues issue(s) found."
    fi
    
    return $issues
}
EOF

chmod +x ~/scripts/github-cli/wiki/api-generator.sh

4. Multilingual Wiki Management

# Multilingual wiki management system
cat > ~/scripts/github-cli/wiki/multilingual.sh << 'EOF'
#!/bin/bash

# Generate multilingual wiki
function wiki_translate() {
    local source_file="$1"
    local target_lang="$2"
    local wiki_path="${3:-.}"
    
    if [[ -z "$source_file" || -z "$target_lang" ]]; then
        echo "Usage: wiki_translate <source file> <target language> [wiki path]"
        echo "Supported languages: $SUPPORTED_LANGUAGES"
        return 1
    fi
    
    if [[ ! -f "$wiki_path/$source_file" ]]; then
        echo "FAIL: Source file not found: $wiki_path/$source_file"
        return 1
    fi
    
    local base_name=$(basename "$source_file" .md)
    local target_file="$base_name-${target_lang^^}.md"
    
    echo "Translating $source_file to $target_file..."
    
    # Generate translation template (actual translation via manual or external service)
    {
        echo "# $(get_page_title "$wiki_path/$source_file") ($target_lang)"
        echo
        echo "> **Translation status**: In progress"
        echo "> **Created**: $(date '+%Y-%m-%d')"
        echo "> **Original**: [$base_name]($base_name)"
        echo
        echo "---"
        echo
        
        # Include original content as comment (translation reference)
        echo "<!-- Original content (translation reference):"
        cat "$wiki_path/$source_file"
        echo "-->"
        echo
        echo "## Content Awaiting Translation"
        echo
        echo "This page has not been translated yet."
        echo "To contribute a translation, [create an issue](../../issues/new)."
        echo
        echo "---"
        echo "*This page was automatically generated.*"
        
    } > "$wiki_path/$target_file"
    
    echo "OK: Translation template created: $target_file"
}

# Generate multilingual navigation
function create_multilingual_nav() {
    local wiki_path="${1:-.}"
    local page_name="$2"
    
    local languages=(en ko ja zh)
    local language_names=("English" "Korean" "Japanese" "Chinese")
    
    echo "## Multilingual Support"
    echo
    
    for i in "${!languages[@]}"; do
        local lang="${languages[$i]}"
        local lang_name="${language_names[$i]}"
        
        if [[ "$lang" == "en" ]]; then
            local file_suffix=""
        else
            local file_suffix="-${lang^^}"
        fi
        
        local target_file="$page_name$file_suffix"
        
        if [[ -f "$wiki_path/$target_file.md" ]]; then
            echo "- OK [$lang_name]($target_file)"
        else
            echo "- Pending: $lang_name (translation planned)"
        fi
    done
    echo
}

# Extract page title
function get_page_title() {
    local file="$1"
    local title=$(head -1 "$file" | sed 's/^# //')
    echo "${title:-Untitled}"
}

# Translation status tracking
function translation_status() {
    local wiki_path="${1:-.}"
    
    echo "Translation Status Report"
    echo "========================="
    echo
    
    local base_files=($(find "$wiki_path" -name "*.md" ! -name "*-EN.md" ! -name "*-JA.md" ! -name "*-ZH.md" ! -name "*-KO.md" -exec basename {} .md \;))
    
    for base_file in "${base_files[@]}"; do
        echo "$base_file:"
        
        for lang in KO JA ZH; do
            local trans_file="$base_file-$lang.md"
            if [[ -f "$wiki_path/$trans_file" ]]; then
                local lines=$(wc -l < "$wiki_path/$trans_file")
                if [[ $lines -gt 20 ]]; then
                    echo "  OK: $lang (complete, ${lines} lines)"
                else
                    echo "  PENDING: $lang (in progress, ${lines} lines)"
                fi
            else
                echo "  MISSING: $lang (not translated)"
            fi
        done
        echo
    done
}
EOF

chmod +x ~/scripts/github-cli/wiki/multilingual.sh

5. zshrc Integration

# Integrate wiki system into zshrc
cat >> ~/.zshrc << 'EOF'

# ===============================================
# GitHub Wiki Automation System
# ===============================================

# Load wiki scripts
if [[ -d "$HOME/scripts/github-cli/wiki" ]]; then
    # Load config
    source "$HOME/scripts/github-cli/config/wiki-config.sh"
    
    # Load core functions
    source "$HOME/scripts/github-cli/wiki/wiki-core.sh"
    source "$HOME/scripts/github-cli/wiki/api-generator.sh"
    source "$HOME/scripts/github-cli/wiki/multilingual.sh"
    
    echo "GitHub Wiki Automation System loaded."
fi

# Wiki-related aliases
alias wiki-init="wiki_init"
alias wiki-update="wiki_auto_update"
alias wiki-translate="wiki_translate"
alias wiki-status="translation_status"
alias api-docs="generate_api_docs"

# Integrated wiki management function
function wiki() {
    local command="$1"
    shift
    
    case "$command" in
        "init") wiki_init "$@" ;;
        "update") wiki_auto_update "$@" ;;
        "translate") wiki_translate "$@" ;;
        "status") translation_status "$@" ;;
        "api") generate_api_docs "$@" ;;
        "validate") validate_api_docs "$@" ;;
        *)
            echo "GitHub Wiki Automation System"
            echo "Usage: wiki <command> [options]"
            echo
            echo "Commands:"
            echo "  init <url>           - Initialize wiki"
            echo "  update [repo]        - Auto-update wiki"
            echo "  translate <file> <lang> - Create translation template"
            echo "  status               - Check translation status"
            echo "  api <repo> <wiki>    - Generate API documentation"
            echo "  validate <wiki>      - Validate documentation quality"
            ;;
    esac
}
EOF

source ~/.zshrc

Practical Usage Scenarios

Scenario 1: Initial Wiki Setup for New Project

# 1. Initialize wiki
wiki init https://github.com/yourusername/your-project.git

# 2. Generate API documentation
wiki api /path/to/project ~/Documents/wikis/your-project

# 3. Start multilingual support
wiki translate Home.md KO ~/Documents/wikis/your-project
wiki translate Home.md JA ~/Documents/wikis/your-project

# 4. Check translation status
wiki status ~/Documents/wikis/your-project

Scenario 2: CI/CD Integration

# .github/workflows/wiki-update.yml
name: Auto-update Wiki

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'
      - 'README.md'
      - '*.yaml'
      - '*.yml'

jobs:
  update-wiki:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup GitHub CLI
        run: gh auth setup-git
        env:
          GITHUB_TOKEN: $
      
      - name: Clone Wiki
        run: |
          git clone $/$.wiki.git wiki
      
      - name: Update Wiki
        run: |
          # Run wiki auto-update scripts
          bash scripts/wiki-update.sh
        env:
          WIKI_PATH: ./wiki
          REPO_PATH: .
      
      - name: Push Wiki Changes
        run: |
          cd wiki
          git config user.email "github-actions@github.com"
          git config user.name "GitHub Actions"
          git add .
          git diff --staged --quiet || git commit -m "Auto-update wiki from $"
          git push

Scenario 3: Large-Scale Documentation Management

# Sync documentation for multiple projects
function bulk_wiki_update() {
    local projects_dir="${1:-$HOME/projects}"
    
    echo "Starting bulk wiki update..."
    echo
    
    find "$projects_dir" -name ".git" -type d -maxdepth 3 | while read git_dir; do
        local project_dir=$(dirname "$git_dir")
        local project_name=$(basename "$project_dir")
        
        echo "Processing: $project_name"
        
        # Auto-update wiki
        wiki update "$project_dir" "$WIKI_BASE_DIR/$project_name" 2>/dev/null && \
            echo "  OK: $project_name wiki updated" || \
            echo "  SKIP: $project_name (no wiki)"
    done
    
    echo
    echo "Bulk wiki update complete."
}

Documentation Quality Management

Automatic Quality Checks

# Documentation quality gate
function wiki_quality_gate() {
    local wiki_path="${1:-.}"
    local min_quality_score="${2:-70}"
    
    echo "Running documentation quality check..."
    echo
    
    local total_score=0
    local check_count=0
    
    # 1. Check for required pages
    local required_pages=("Home.md" "API-Documentation.md" "README.md")
    for page in "${required_pages[@]}"; do
        if [[ -f "$wiki_path/$page" ]]; then
            echo "OK: $page exists"
            total_score=$((total_score + 10))
        else
            echo "MISSING: $page"
        fi
        check_count=$((check_count + 1))
    done
    
    # 2. Check recent update
    local last_commit_days=$(( ($(date +%s) - $(git -C "$wiki_path" log -1 --format=%ct)) / 86400 ))
    if [[ $last_commit_days -lt 7 ]]; then
        echo "OK: Recently updated ($last_commit_days days ago)"
        total_score=$((total_score + 20))
    else
        echo "WARNING: Last update was $last_commit_days days ago"
    fi
    
    # 3. Check multilingual support
    local home_translations=$(find "$wiki_path" -name "Home-*.md" | wc -l)
    if [[ $home_translations -gt 0 ]]; then
        echo "OK: $home_translations languages supported"
        total_score=$((total_score + $((home_translations * 5))))
    else
        echo "INFO: No multilingual support yet"
    fi
    
    # 4. Check code examples
    local code_blocks=$(grep -r '```' "$wiki_path" --include="*.md" | wc -l)
    if [[ $code_blocks -gt 10 ]]; then
        echo "OK: $code_blocks code examples"
        total_score=$((total_score + 15))
    fi
    
    echo
    echo "Quality Score: $total_score"
    
    if [[ $total_score -ge $min_quality_score ]]; then
        echo "PASS: Documentation quality meets the standard"
        return 0
    else
        echo "FAIL: Documentation quality is below the standard (minimum: $min_quality_score)"
        return 1
    fi
}

Preview of the Next Part

The final installment, Advanced Workflows and Real-World Application, covers:

  • Full system integration
  • CI/CD pipeline connectivity
  • Team onboarding automation
  • Performance optimization and monitoring
  • Complete production-ready system