name: Deploy Jekyll Site to GitHub Pages
on:
push:
branches: ["main"]
workflow_dispatch:
inputs:
deploy_preview:
description: 'Deploy a preview version'
type: boolean
default: false
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.1'
bundler-cache: true
working-directory: website
- name: Setup Pages
id: pages
uses: actions/configure-pages@v4
- name: Sync ADRs to Jekyll collection
run: |
echo "Syncing ADRs from docs/adr/ to website/_adrs/"
# Create _adrs directory if it doesn't exist (matches Jekyll collection name 'adrs')
mkdir -p website/_adrs
# Copy all ADR files
cp docs/adr/*.md website/_adrs/ 2>/dev/null || true
# Verify sync
SOURCE_COUNT=$(ls -1 docs/adr/*.md 2>/dev/null | wc -l)
JEKYLL_COUNT=$(ls -1 website/_adrs/*.md 2>/dev/null | grep -v README.md | wc -l)
echo "Source ADRs: $SOURCE_COUNT"
echo "Jekyll ADRs: $JEKYLL_COUNT"
if [ "$SOURCE_COUNT" -ne "$JEKYLL_COUNT" ]; then
echo "ERROR: ADR count mismatch!"
echo "Expected $SOURCE_COUNT ADRs in website/_adrs/, found $JEKYLL_COUNT"
exit 1
fi
echo "✅ ADR sync completed successfully"
- name: Copy markdown documentation
run: |
# Copy entire docs directory structure to website
if [ -d "docs" ]; then
echo "Copying documentation from /docs to website/docs..."
# Create the target directory if it doesn't exist
mkdir -p website/docs
# Copy all documentation files preserving directory structure
cp -r docs/* website/docs/ 2>/dev/null || true
# Also copy root-level documentation files
cp ARCHITECTURE.md ROADMAP.md SECURITY.md CONTRIBUTING.md website/docs/ 2>/dev/null || true
# Copy README with fixed logo path for Jekyll
cp README.md website/docs/README.md.tmp
# Replace relative logo path with Jekyll-friendly path
sed 's|<img src="logo.svg"|<img src="{{ '"'"'/assets/img/logo.svg'"'"' \| relative_url }}"|g' website/docs/README.md.tmp > website/docs/README.md
rm website/docs/README.md.tmp
fi
# Add Jekyll front matter to all markdown files if not present
find website/docs -name "*.md" | while read -r file; do
if [ -f "$file" ] && ! grep -q "^---" "$file"; then
# Extract title from filename, replacing hyphens with spaces
filename=$(basename "$file" .md)
title=$(echo "$filename" | sed 's/-/ /g' | sed 's/\b\(.\)/\u\1/g')
# Create temp file with front matter
{
echo "---"
echo "layout: documentation"
echo "title: \"${title}\""
echo "---"
echo ""
cat "$file"
} > "${file}.tmp"
mv "${file}.tmp" "$file"
fi
done
echo "Documentation copy completed. Contents of website/docs:"
find website/docs -type f -name "*.md" | sort
- name: Fetch latest release info
id: latest_release
run: |
# Fetch latest release from GitHub API
RELEASE_JSON=$(curl -s https://api.github.com/repos/${{ github.repository }}/releases/latest)
# Check if we got a valid release
if echo "$RELEASE_JSON" | grep -q '"tag_name"'; then
# Extract release information
TAG_NAME=$(echo "$RELEASE_JSON" | jq -r '.tag_name // "v0.0.0"')
RELEASE_NAME=$(echo "$RELEASE_JSON" | jq -r '.name // "Development"')
RELEASE_DATE=$(echo "$RELEASE_JSON" | jq -r '.published_at // ""' | cut -d'T' -f1)
# Get release body - keep as Markdown but make YAML-safe
RELEASE_BODY_RAW=$(echo "$RELEASE_JSON" | jq -r '.body // ""')
# Escape quotes for YAML and limit length
RELEASE_BODY=$(echo "$RELEASE_BODY_RAW" | \
sed 's/"/\\"/g' | \
head -20)
RELEASE_URL=$(echo "$RELEASE_JSON" | jq -r '.html_url // ""')
# Clean version (remove 'v' prefix if present)
VERSION="${TAG_NAME#v}"
# Check if this is a pre-1.0 release
if [[ "$VERSION" == 0.* ]]; then
RELEASE_STATUS="Early Development"
RELEASE_PHASE="Foundation Phase"
else
RELEASE_STATUS="Stable Release"
RELEASE_PHASE="Production Ready"
fi
else
# No releases found, use defaults
VERSION="0.1.0-dev"
TAG_NAME="development"
RELEASE_NAME="Foundation Phase"
RELEASE_DATE=$(date +%Y-%m-%d)
RELEASE_STATUS="Early Development"
RELEASE_PHASE="Foundation Phase"
RELEASE_BODY="Caxton is currently in early development. Core architecture is being implemented with a focus on getting the fundamentals right: WebAssembly isolation, FIPA messaging, and comprehensive observability."
RELEASE_URL="https://github.com/${{ github.repository }}/releases"
fi
# Export for Jekyll
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "RELEASE_TAG=$TAG_NAME" >> $GITHUB_ENV
echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV
echo "RELEASE_DATE=$RELEASE_DATE" >> $GITHUB_ENV
echo "RELEASE_STATUS=$RELEASE_STATUS" >> $GITHUB_ENV
echo "RELEASE_PHASE=$RELEASE_PHASE" >> $GITHUB_ENV
echo "RELEASE_URL=$RELEASE_URL" >> $GITHUB_ENV
# Create release data file for Jekyll
mkdir -p website/_data
# Write YAML file line by line to avoid heredoc issues
echo "version: \"$VERSION\"" > website/_data/release.yml
echo "tag: \"$TAG_NAME\"" >> website/_data/release.yml
echo "name: \"$RELEASE_NAME\"" >> website/_data/release.yml
echo "date: \"$RELEASE_DATE\"" >> website/_data/release.yml
echo "status: \"$RELEASE_STATUS\"" >> website/_data/release.yml
echo "phase: \"$RELEASE_PHASE\"" >> website/_data/release.yml
echo "url: \"$RELEASE_URL\"" >> website/_data/release.yml
echo "description: |" >> website/_data/release.yml
# Ensure release body is properly indented for YAML
if [ -n "$RELEASE_BODY" ]; then
echo "$RELEASE_BODY" | sed 's/^/ /' >> website/_data/release.yml
else
echo " Caxton is currently in early development." >> website/_data/release.yml
fi
# Debug: Show the generated file
echo "Generated release.yml:"
cat website/_data/release.yml
echo "---"
echo "Latest release: $VERSION ($RELEASE_STATUS)"
- name: Build Jekyll site
run: |
cd website
bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
env:
JEKYLL_ENV: production
JEKYLL_VERSION: ${{ env.VERSION }}
JEKYLL_RELEASE_TAG: ${{ env.RELEASE_TAG }}
JEKYLL_RELEASE_NAME: ${{ env.RELEASE_NAME }}
JEKYLL_RELEASE_DATE: ${{ env.RELEASE_DATE }}
JEKYLL_RELEASE_STATUS: ${{ env.RELEASE_STATUS }}
JEKYLL_RELEASE_PHASE: ${{ env.RELEASE_PHASE }}
JEKYLL_RELEASE_URL: ${{ env.RELEASE_URL }}
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: website/_site
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4