Skip to content

DevOps-Cheatsheet: fix(ci): Resolve PDF Generation Image Issues #20

DevOps-Cheatsheet: fix(ci): Resolve PDF Generation Image Issues

DevOps-Cheatsheet: fix(ci): Resolve PDF Generation Image Issues #20

Workflow file for this run

name: DevOps Cheatsheet PDF Generator
on:
push:
branches: [ main, master ]
paths:
- '**/*.md'
- '**/*.png'
- '**/*.jpg'
- '**/*.jpeg'
- '.github/workflows/generate-pdf.yml'
pull_request:
branches: [ main, master ]
paths:
- '**/*.md'
workflow_dispatch:
inputs:
specific_category:
description: 'Generate PDFs for specific category (leave empty for all)'
required: false
type: string
jobs:
generate-pdfs:
name: Generate Cheatsheet PDFs
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y pandoc texlive-xetex texlive-fonts-recommended texlive-fonts-extra \
imagemagick webp librsvg2-bin
- name: Configure ImageMagick Policy
run: |
sudo sed -i 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml
sudo sed -i 's/rights="none" pattern="LABEL"/rights="read|write" pattern="LABEL"/' /etc/ImageMagick-6/policy.xml
- name: Cache PDF Generation
uses: actions/cache@v3
with:
path: |
.pdf-cache
.image-cache
key: ${{ runner.os }}-pdf-${{ hashFiles('**/*.md', '**/*.png', '**/*.jpg', '**/*.jpeg', '**/*.webp') }}
restore-keys: |
${{ runner.os }}-pdf-
- name: Setup Directories
run: |
mkdir -p pdfs
mkdir -p .pdf-cache
mkdir -p .image-cache
- name: Process Images
run: |
# Function to process images
process_image() {
local input_file="$1"
local output_file="$2"
# Convert WebP to PNG
if [[ "${input_file,,}" == *.webp ]]; then
convert "$input_file" "${output_file%.webp}.png"
echo "${output_file%.webp}.png"
else
# For other formats, optimize and copy
convert "$input_file" -quality 90 "$output_file"
echo "$output_file"
fi
}
# Process all images in markdown files
find . -type f -name "*.md" -exec grep -l '!\[.*\](' {} \; | while read mdfile; do
dir=$(dirname "$mdfile")
mkdir -p ".image-cache/$dir"
# Extract and process images
grep -o '!\[.*\]([^)]*)' "$mdfile" | sed 's/!\[.*\](\(.*\))/\1/' | while read img; do
if [[ "$img" =~ ^https?:// ]]; then
# Skip external images
continue
fi
img_path="$dir/$img"
if [ -f "$img_path" ]; then
cache_path=".image-cache/${img_path#./}"
mkdir -p "$(dirname "$cache_path")"
if [ ! -f "$cache_path" ] || [ "$img_path" -nt "$cache_path" ]; then
echo "Processing image: $img_path"
processed_img=$(process_image "$img_path" "$cache_path")
# Update markdown to use processed image
sed -i "s|$img|$processed_img|g" "$mdfile"
fi
fi
done
done
- name: Generate PDFs
run: |
# Function to generate PDF with custom styling
generate_pdf() {
local input_file="$1"
local output_file="$2"
local category="$(dirname "$input_file" | sed 's/.\///')"
local title="$(basename "$input_file" .md)"
# Create header with metadata
cat > header.yaml <<EOF
---
title: "${title//-/ } Cheatsheet"
author: "DevOps Cheatsheet Hub"
date: "$(date +'%B %d, %Y')"
geometry: margin=2cm
colorlinks: true
linkcolor: blue
urlcolor: blue
toccolor: blue
toc: true
toc-depth: 2
category: "${category}"
header-includes:
- \usepackage{fancyhdr}
- \usepackage{graphicx}
- \usepackage{float}
- \pagestyle{fancy}
- \fancyhead[L]{DevOps Cheatsheet Hub}
- \fancyhead[R]{${category}}
- \fancyfoot[C]{\thepage}
---
EOF
# Combine header with content and generate PDF
cat header.yaml "$input_file" | pandoc \
-f markdown \
-t pdf \
--pdf-engine=xelatex \
--highlight-style=tango \
-o "$output_file" \
--toc \
--toc-depth=2 \
--variable=geometry:margin=2cm \
--wrap=preserve \
--number-sections \
--verbose
}
# Process files based on input
if [ -n "${{ github.event.inputs.specific_category }}" ]; then
category="${{ github.event.inputs.specific_category }}"
echo "Generating PDFs for category: $category"
for file in "$category"/*.md; do
if [ -f "$file" ]; then
output_file="pdfs/$(basename "${file%.md}.pdf")"
if [ ! -f ".pdf-cache/$(basename "$output_file")" ] || [ "$file" -nt ".pdf-cache/$(basename "$output_file")" ]; then
echo "Generating PDF for $file"
generate_pdf "$file" "$output_file"
cp "$output_file" ".pdf-cache/"
else
echo "Using cached version for $file"
cp ".pdf-cache/$(basename "$output_file")" "$output_file"
fi
fi
done
else
echo "Generating PDFs for all categories"
for file in */*.md; do
if [ -f "$file" ]; then
output_file="pdfs/$(dirname "$file")-$(basename "${file%.md}.pdf")"
if [ ! -f ".pdf-cache/$(basename "$output_file")" ] || [ "$file" -nt ".pdf-cache/$(basename "$output_file")" ]; then
echo "Generating PDF for $file"
generate_pdf "$file" "$output_file"
cp "$output_file" ".pdf-cache/"
else
echo "Using cached version for $file"
cp ".pdf-cache/$(basename "$output_file")" "$output_file"
fi
fi
done
fi
- name: Create PDF Index
run: |
echo "# DevOps Cheatsheet PDFs" > pdfs/index.md
echo "Generated on: $(date +'%B %d, %Y')" >> pdfs/index.md
echo "" >> pdfs/index.md
for category in */; do
if [ -d "$category" ]; then
echo "## ${category%/}" >> pdfs/index.md
for pdf in pdfs/${category%/}*.pdf; do
if [ -f "$pdf" ]; then
name=$(basename "$pdf" .pdf | sed 's/-/ /g')
echo "- [$name]($pdf)" >> pdfs/index.md
fi
done
echo "" >> pdfs/index.md
fi
done
- name: Upload Individual PDFs
uses: actions/upload-artifact@v4
with:
name: cheatsheet-pdfs
path: pdfs/*.pdf
retention-days: 30
- name: Create Release
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
run: |
# Zip all PDFs
cd pdfs
zip -r ../cheatsheets.zip *.pdf
cd ..
# Create release tag
TAG="v$(date +'%Y.%m.%d-%H%M')"
gh release create "$TAG" \
--title "DevOps Cheatsheets $TAG" \
--notes-file pdfs/index.md \
cheatsheets.zip
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
- name: Update Documentation
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
run: |
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
# Update README with latest PDF links
sed -i '/## Available PDFs/q' README.md
echo "" >> README.md
cat pdfs/index.md >> README.md
# Commit and push if there are changes
git add README.md
git diff --quiet && git diff --staged --quiet || (git commit -m "docs: Update PDF links [skip ci]" && git push)
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}