Skip to content

Instantly share code, notes, and snippets.

@SolomonHD
Last active July 21, 2025 02:14
Show Gist options
  • Save SolomonHD/1391d973b86c0aeb3e901cceeb34650f to your computer and use it in GitHub Desktop.
Save SolomonHD/1391d973b86c0aeb3e901cceeb34650f to your computer and use it in GitHub Desktop.
Jekyll GitHub Pages Tools README

Jekyll GitHub Pages Tools

A collection of command-line utilities for streamlined Jekyll GitHub Pages deployment on GitHub Enterprise Server (GHES) and GitHub.com. These tools simplify the process of setting up and deploying Jekyll sites to GitHub Pages using the gh-pages branch with a /docs folder structure.

πŸ“‹ Overview

These tools solve common GitHub Pages deployment challenges:

  • Automated branch setup with proper folder structure
  • API-driven configuration to avoid manual settings
  • Force rebuild capability to fix 503 errors and deployment issues
  • Local Jekyll building with remote deployment
  • Multiple authentication methods for different environments

πŸš€ Quick Installation

One-Line Installation

curl -sSL https://gist.githubusercontent.com/SolomonHD/dcd3cf9587cef4751a96a80967b5d598/raw/jekyll-ghpages-installer.sh | bash

Alternative Installation Methods

# Install to user directory (~/.local/bin)
curl -sSL https://gist.githubusercontent.com/SolomonHD/dcd3cf9587cef4751a96a80967b5d598/raw/jekyll-ghpages-installer.sh | bash -s -- --user

# Install to custom directory
curl -sSL https://gist.githubusercontent.com/SolomonHD/dcd3cf9587cef4751a96a80967b5d598/raw/jekyll-ghpages-installer.sh | bash -s -- --dir /opt/bin

# Force reinstall/update
curl -sSL https://gist.githubusercontent.com/SolomonHD/dcd3cf9587cef4751a96a80967b5d598/raw/jekyll-ghpages-installer.sh | bash -s -- --force

πŸ“¦ What Gets Installed

jekyll-ghpages-setup

One-time repository setup utility that creates the initial gh-pages branch with proper structure.

jekyll-ghpages-deploy

Build and deployment automation with force rebuild capability for ongoing deployments.

πŸ“‹ Prerequisites

  • Git repository with remote configured
  • Jekyll installed (gem install jekyll bundler)
  • Ruby with Bundler support (Ruby 3.3+ recommended)
  • Curl (for installation script)

Authentication for API Features

For automatic GitHub Pages rebuild functionality and API configuration:

Option 1: GitHub CLI (Recommended)

# Authenticate with your GitHub instance
gh auth login --hostname your-ghes-instance.com

# For GitHub.com
gh auth login

Option 2: Personal Access Token

Create a Personal Access Token with these permissions:

Required Scopes:

  • repo (Full control of private repositories)
  • pages (Read and write GitHub Pages settings)

For fine-grained tokens, grant these repository permissions:

  • Pages: Read and write
  • Contents: Read and write
  • Metadata: Read
  • Pull requests: Read (if using PR-based workflows)

Set environment variable:

# Add to your ~/.bashrc, ~/.zshrc, or ~/.profile
export GITHUB_TOKEN="your_personal_access_token_here"

# Or use GH_TOKEN
export GH_TOKEN="your_personal_access_token_here"

πŸ› οΈ Tool Documentation

jekyll-ghpages-setup

Purpose: Creates the initial gh-pages branch with proper structure for GitHub Pages deployment.

What it does:

  • Checks if gh-pages branch exists on remote
  • Creates orphan gh-pages branch (clean history)
  • Sets up /docs folder structure with starter content
  • Automatically configures GitHub Pages via API to use /docs folder
  • Pushes branch to remote repository
  • Returns you to your original working branch

Usage:

cd /path/to/your/jekyll-repository
jekyll-ghpages-setup

Options:

  • --help - Show usage information
  • Prompts before overwriting existing gh-pages branch

jekyll-ghpages-deploy

Purpose: Builds your Jekyll site locally and deploys it to the gh-pages/docs/ folder with optional force rebuild.

What it does:

  • Validates prerequisites (Jekyll, Bundler, project structure)
  • Installs dependencies with bundle install
  • Builds Jekyll site from src/ to _site/
  • Uses Git worktree to deploy to gh-pages branch
  • Copies built files to /docs folder
  • Commits with descriptive message including timestamp
  • Pushes to remote automatically
  • Forces GitHub Pages rebuild via API to fix 503 errors
  • Cleans up temporary files

Usage:

cd /path/to/your/jekyll-repository
jekyll-ghpages-deploy

Options:

  • --force / -f - Skip uncommitted changes warning
  • --skip-checks - Skip prerequisite validation (faster for repeated use)
  • --rebuild - Force GitHub Pages rebuild after deployment
  • --help / -h - Show usage information

Build Process:

  1. Source: src/ directory (Jekyll files)
  2. Build: _site/ directory (temporary)
  3. Deploy: gh-pages/docs/ directory (GitHub Pages source)

πŸ”„ Typical Workflow

First Time Setup

# 1. Setup repository structure
jekyll-ghpages-setup

# 2. GitHub Pages is automatically configured via API
# 3. Deploy your site
jekyll-ghpages-deploy

Regular Development

# Make changes to files in src/
# Test locally: cd src && bundle exec jekyll serve

# Deploy changes
jekyll-ghpages-deploy

Quick Repeated Deployments

# Skip checks for faster deployment
jekyll-ghpages-deploy --skip-checks

# Deploy and force Pages rebuild (fixes 503 errors)
jekyll-ghpages-deploy --rebuild

# Force deployment with uncommitted changes and rebuild
jekyll-ghpages-deploy --force --rebuild

πŸ“ Repository Structure

Recommended Layout

your-jekyll-repo/
β”œβ”€β”€ src/                    # Jekyll source files
β”‚   β”œβ”€β”€ _config.yml         # Jekyll configuration
β”‚   β”œβ”€β”€ Gemfile             # Ruby dependencies
β”‚   β”œβ”€β”€ index.md            # Homepage
β”‚   β”œβ”€β”€ _layouts/           # Page templates
β”‚   β”œβ”€β”€ _includes/          # Reusable components
β”‚   β”œβ”€β”€ _posts/             # Blog posts
β”‚   β”œβ”€β”€ _sass/              # Sass stylesheets
β”‚   └── assets/             # Images, CSS, JS
β”œβ”€β”€ README.md               # Project documentation
└── .gitignore              # Git ignore rules

After Setup (Git Branches)

main branch:                # Source code and development
β”œβ”€β”€ src/                    # Jekyll source
β”œβ”€β”€ README.md
└── .gitignore

gh-pages branch:            # Deployment branch
β”œβ”€β”€ docs/                   # Built site (GitHub Pages source)
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ assets/
β”‚   └── (generated files)
β”œβ”€β”€ README.md               # Branch documentation
└── .gitignore

🎯 Advanced Features

Automatic API Configuration

  • GitHub CLI support - Uses gh command if available and authenticated
  • Token-based authentication - Falls back to GITHUB_TOKEN or GH_TOKEN environment variables
  • Smart URL parsing - Works with both GitHub.com and GHES instances
  • Graceful fallbacks - Shows manual instructions if API config fails

Force Rebuild Capability

The deploy script can force GitHub Pages to rebuild, which fixes common issues:

  • 503 Service Unavailable errors
  • Stale deployments that won't update
  • Caching issues after configuration changes

Rebuild Methods (in order of preference):

  1. GitHub CLI API - gh api repos/owner/repo/pages/builds --method POST
  2. curl with token - Direct API call with authentication
  3. Empty commit - Fallback method that always works

Rebuild Confirmation: After triggering a rebuild, the script now:

  • Checks the latest build status via API
  • Reports build status (queued, building, built, errored)
  • Displays your Pages URL
  • Provides instructions to verify rebuild completion

Force Rebuild Integration

# Deploy with automatic rebuild
jekyll-ghpages-deploy --rebuild

# The script will try multiple methods:
# 1. GitHub CLI API (preferred)
# 2. curl + Personal Access Token  
# 3. Empty commit (fallback)

# Manually trigger a Pages rebuild without deploying
# For GitHub.com:
gh api repos/{owner}/{repo}/pages/builds --method POST

# For GHES:
gh api repos/{owner}/{repo}/pages/builds --method POST --hostname your-ghes-instance.com

Smart Commit Messages

Deployment commits include detailed information:

Deploy: 2025-07-16 14:30:22 (from main@a1b2c3d)

Error Handling

  • Graceful cleanup on interruption
  • Detailed error messages with suggestions
  • Prerequisite validation before operations
  • Working directory safety checks
  • Automatic retry mechanisms for API calls

πŸ”§ Configuration Options

GitHub Pages API Configuration

The tools can automatically configure GitHub Pages settings via API:

Supported settings:

  • Source branch: gh-pages
  • Source folder: /docs
  • Custom domains (via API)

Authentication methods:

  1. GitHub CLI: gh auth login --hostname your-ghes-instance.com
  2. Environment token: export GITHUB_TOKEN="token_here"
  3. Manual fallback: Instructions provided if API fails

Jekyll Configuration (src/_config.yml)

# Site settings
title: Your Site Title
description: Site description
baseurl: "/your-repo-name"  # Important for GitHub Pages
url: "https://your-ghes-instance.com"  # Your GHES URL

# Build settings
markdown: kramdown
kramdown:
  footnote_nr: 1
  footnote_backlink: "↩"
  input: GFM
  syntax_highlighter: rouge

# Plugins
plugins:
  - jekyll-feed
  - jekyll-sitemap

# Exclude from build
exclude:
  - README.md
  - Gemfile
  - Gemfile.lock
  - .ruby-version

Ruby Version Management

# Recommended Ruby version (matches GitHub Pages)
echo "3.3.3" > src/.ruby-version

# With rbenv
rbenv install 3.3.3
rbenv local 3.3.3

# With asdf
asdf install ruby 3.3.3
asdf local ruby 3.3.3

Personal Access Token Permissions

Classic tokens need these scopes:

  • βœ… repo (Full control of private repositories)
  • βœ… pages (GitHub Pages settings)

Fine-grained tokens need these repository permissions:

  • βœ… Pages: Read and write
  • βœ… Contents: Read and write
  • βœ… Metadata: Read
  • βœ… Actions: Read (if using GitHub Actions)

To create a token:

  1. Go to Settings β†’ Developer settings β†’ Personal access tokens
  2. Generate new token (classic or fine-grained)
  3. Select required scopes/permissions above
  4. Set expiration and create token
  5. Add to environment: export GITHUB_TOKEN="your_token"

🚨 Troubleshooting

Common Issues

"Jekyll is not installed"

gem install jekyll bundler

"Source directory 'src' not found"

  • Ensure Jekyll files are in src/ directory
  • Check _config.yml exists in src/

"Branch 'gh-pages' does not exist on remote"

jekyll-ghpages-setup  # Run setup first

"No changes detected"

  • Site is already up to date
  • Check if you made changes to source files

"503 Service Unavailable" on Pages site

# Force rebuild to fix caching issues
jekyll-ghpages-deploy --rebuild

If rebuild doesn't fix the 503:

  • Check Settings β†’ Pages to see if there are build errors
  • Verify the /docs folder contains an index.html file
  • Check if the gh-pages branch exists and has content
  • Try visiting a specific file like /docs/index.html directly
  • Check the build status: gh api repos/{owner}/{repo}/pages/builds?per_page=5
  • Look for Jekyll build errors in the Pages build logs
  • Ensure no .nojekyll file exists if using Jekyll
  • Check for CNAME conflicts or custom domain issues

"API rebuild failed"

  • Check GitHub CLI authentication: gh auth status
  • For GHES, ensure you're authenticated to the correct host: gh auth status --hostname your-ghes-instance.com
  • Verify token permissions (needs repo and pages scopes)
  • Token may be expired or invalid
  • The script will show the actual error message to help diagnose issues

"Failed to create worktree"

  • Check if gh-pages branch exists: git branch -r | grep gh-pages
  • Run setup script first: jekyll-ghpages-setup

Permission denied on installation

# Try user installation
curl -sSL https://gist.githubusercontent.com/SolomonHD/dcd3cf9587cef4751a96a80967b5d598/raw/jekyll-ghpages-installer.sh | bash -s -- --user

# Or use sudo
sudo curl -sSL https://gist.githubusercontent.com/SolomonHD/dcd3cf9587cef4751a96a80967b5d598/raw/jekyll-ghpages-installer.sh | bash

# Force reinstall over existing scripts
curl -sSL https://gist.githubusercontent.com/SolomonHD/dcd3cf9587cef4751a96a80967b5d598/raw/jekyll-ghpages-installer.sh | bash -s -- --force

Getting Help

jekyll-ghpages-setup --help
jekyll-ghpages-deploy --help

🌐 GitHub Enterprise Server (GHES)

These tools work with both GitHub.com and GitHub Enterprise Server instances. For GHES:

  1. Ensure GitHub Pages is enabled on your GHES instance
  2. Use the same workflow - tools auto-detect the environment
  3. Pages URL will be: https://your-ghes-instance.com/pages/user/repo

GHES-Specific Features:

  • Automatic detection of GHES host from git remote URL
  • GitHub CLI commands use --hostname flag automatically
  • API endpoints correctly use /api/v3 path
  • Rebuild confirmation works with GHES instances

πŸ”’ Proxy and Firewall Requirements

If your GHES instance is behind a web proxy, Pages builds may timeout trying to fetch dependencies.

Essential domains to whitelist:

# Ruby and gem dependencies
rubygems.org
*.rubygems.org
rubygems.global.ssl.fastly.net

# GitHub resources
github.com
raw.githubusercontent.com
codeload.github.com
api.github.com

# Optional (if used in your Jekyll site)
cdn.jsdelivr.net
cdnjs.cloudflare.com
fonts.googleapis.com

Diagnosing proxy issues:

  • Build timeouts lasting exactly 11 minutes (660 seconds)
  • Multiple consecutive build failures with "Page build timed out"
  • No specific error messages about missing files

Solution: Contact your GHES administrator to whitelist the required domains or configure the HTTP proxy settings for the Pages build environment.

🀝 CI/CD Integration

While these tools are designed for local development, you can integrate them with CI/CD systems:

Jenkins Example

pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                sh 'jekyll-ghpages-deploy --skip-checks'
            }
        }
    }
}

GitHub Actions Alternative

For repositories with GitHub Actions enabled, consider the official actions/deploy-pages action instead.

πŸ”„ Updates

To update the tools:

# Re-run the installer with force flag
curl -sSL https://gist.githubusercontent.com/SolomonHD/dcd3cf9587cef4751a96a80967b5d598/raw/jekyll-ghpages-installer.sh | bash -s -- --force

πŸ“š Related Resources

πŸ“„ License

These tools are provided as-is for community use. Feel free to fork, modify, and share!


Created by: SolomonHD
Gist Collection: Jekyll GitHub Pages Tools
Last Updated: July 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment