Updates from testing (#155) #94
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ============================================================================= | |
| # MICROSOFT COPILOT STUDIO LABS - UNIFIED BUILD AND DEPLOY WORKFLOW | |
| # ============================================================================= | |
| # This unified workflow: | |
| # 1. Generates PDFs from lab markdown files | |
| # 2. Builds Jekyll site with auto-generated lab pages | |
| # 3. Deploys to GitHub Pages with fresh PDFs included | |
| # ============================================================================= | |
| name: 🚀 Build and Deploy Labs | |
| # ============================================================================= | |
| # CONCURRENCY CONTROL | |
| # ============================================================================= | |
| # Prevents multiple GitHub Pages deployments from running simultaneously | |
| # - Only one deployment per group runs at a time | |
| # - Newer deployments automatically cancel any in-progress older deployments | |
| # - Prevents race conditions and deployment conflicts | |
| # ============================================================================= | |
| concurrency: | |
| group: github-pages-deployment | |
| cancel-in-progress: true | |
| # ============================================================================= | |
| # WORKFLOW TRIGGERS | |
| # ============================================================================= | |
| on: | |
| # Trigger on changes to lab content, configurations, or styling | |
| push: | |
| branches: [main] | |
| paths: | |
| - "labs/**/*.md" # Lab markdown content | |
| - "labs/**/images/**" # Lab images and assets | |
| - "_layouts/**" # Jekyll layouts | |
| - "assets/**" # Jekyll assets and styling | |
| - "_config.yml" # Jekyll configuration | |
| - "scripts/**" # PowerShell generation scripts | |
| - "lab-config.yml" # Lab configuration | |
| - ".github/styles/**" # PDF styling files | |
| - ".github/scripts/**" # PDF generation scripts | |
| - ".github/workflows/build-and-deploy.yml" # This workflow file | |
| - "package.json" # Dependencies | |
| # Allow manual execution for testing | |
| workflow_dispatch: | |
| inputs: | |
| debug: | |
| description: "Enable debug output" | |
| required: false | |
| default: false | |
| type: boolean | |
| # ============================================================================= | |
| # GITHUB PAGES PERMISSIONS | |
| # ============================================================================= | |
| permissions: | |
| contents: read | |
| pages: write | |
| id-token: write | |
| # ============================================================================= | |
| # WORKFLOW JOBS | |
| # ============================================================================= | |
| jobs: | |
| build-and-deploy: | |
| name: 🔨 Build PDFs and Deploy Jekyll Site | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| steps: | |
| # ================================================================= | |
| # STEP 1: REPOSITORY SETUP | |
| # ================================================================= | |
| - name: 📂 Checkout Repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| # ================================================================= | |
| # STEP 2: PDF GENERATION SETUP | |
| # ================================================================= | |
| - name: 📄 Setup Pandoc (Markdown to HTML Converter) | |
| uses: pandoc/actions/setup@v1.1.1 | |
| with: | |
| version: 3.1.3 | |
| - name: 🔧 Setup Node.js and PDF Generation Tools | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "18" | |
| - name: 📄 Install PDF Generation Dependencies | |
| run: | | |
| echo "🔧 Installing PDF generation dependencies..." | |
| npm install | |
| echo "✅ Dependencies installed successfully" | |
| # Install fonts for better PDF rendering | |
| sudo apt-get update -qq | |
| sudo apt-get install -y --no-install-recommends fonts-noto-color-emoji fonts-noto-sans fonts-noto-serif || echo "⚠️ Warning: Could not install some fonts" | |
| echo "✅ Font installation completed" | |
| # Verify installations | |
| echo "🔍 Verifying installations:" | |
| pandoc --version 2>/dev/null | head -2 || echo "Pandoc version check failed" | |
| node --version | |
| npm list puppeteer --depth=0 2>/dev/null || echo "Puppeteer available locally" | |
| timeout-minutes: 8 | |
| # ================================================================= | |
| # STEP 3: GENERATE PDFS FROM LAB MARKDOWN | |
| # ================================================================= | |
| - name: 📄 Generate Lab PDFs | |
| run: | | |
| echo "📄 Starting PDF generation for all labs..." | |
| # Create dist directory structure | |
| mkdir -p dist | |
| # Process each lab directory containing a README.md file | |
| for lab_dir in labs/*/; do | |
| if [ -d "$lab_dir" ] && [ -f "${lab_dir}README.md" ]; then | |
| lab_name=$(basename "$lab_dir") | |
| echo "📝 Processing lab: $lab_name" | |
| # Create output directory for this lab | |
| mkdir -p "dist/$lab_name" | |
| # Enter lab directory to ensure relative image paths work correctly | |
| cd "$lab_dir" | |
| # Preprocess markdown content | |
| echo " 🔄 Preprocessing markdown content..." | |
| cp "README.md" "${lab_name}_processed.md" | |
| # Handle callout blocks (including indented ones) | |
| awk ' | |
| BEGIN { | |
| callout = 0; | |
| callout_type = ""; | |
| indent = ""; | |
| } | |
| match($0, /^([[:space:]]*)> \[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]/, m) { | |
| callout = 1; | |
| indent = m[1]; # Capture leading whitespace | |
| callout_type = tolower(m[2]); | |
| if (callout_type == "note") { class="note"; label="**Note:** "; } | |
| else if (callout_type == "tip") { class="tip"; label="**Tip:** "; } | |
| else { class="warning"; label="**" toupper(callout_type) ":** "; } | |
| sub(/^[[:space:]]* *> \[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]/, indent "> <div class=\"" class "\">" label); | |
| print; | |
| next; | |
| } | |
| callout && /^[[:space:]]*> / { | |
| print; | |
| next; | |
| } | |
| callout && !/^[[:space:]]*> / { | |
| print indent "</div>"; | |
| callout = 0; | |
| callout_type = ""; | |
| indent = ""; | |
| } | |
| { print; } | |
| ' "${lab_name}_processed.md" > "${lab_name}_callouts.md" | |
| mv "${lab_name}_callouts.md" "${lab_name}_processed.md" | |
| # Extract document title | |
| lab_title=$(grep -m 1 '^# ' "${lab_name}_processed.md" | sed 's/^# //' | sed 's/[*_`]//g' | head -1) | |
| if [ -z "$lab_title" ]; then | |
| lab_title="$lab_name - Microsoft Copilot Studio Labs" | |
| fi | |
| echo " 📋 Document title: $lab_title" | |
| # Convert to HTML first | |
| echo " 🔄 Converting to HTML..." | |
| yaml_disabled_format="markdown+auto_identifiers+gfm_auto_identifiers+emoji+header_attributes+raw_html+raw_attribute" | |
| if grep -q '^---$' "${lab_name}_processed.md"; then | |
| first_line=$(head -1 "${lab_name}_processed.md") | |
| second_line=$(sed -n '2p' "${lab_name}_processed.md") | |
| if [ "$first_line" != "---" ] || [ "$second_line" = "---" ]; then | |
| yaml_disabled_format="markdown-yaml_metadata_block+auto_identifiers+gfm_auto_identifiers+emoji+header_attributes+raw_html+raw_attribute" | |
| fi | |
| fi | |
| # Convert to HTML | |
| if pandoc "${lab_name}_processed.md" \ | |
| -o "../../dist/${lab_name}/${lab_name}.html" \ | |
| --standalone \ | |
| --embed-resources \ | |
| --css="../../.github/styles/html.css" \ | |
| --html-q-tags \ | |
| --section-divs \ | |
| --id-prefix="" \ | |
| --metadata title="$lab_title" \ | |
| --metadata lang="en" \ | |
| -f "$yaml_disabled_format" \ | |
| -t html5; then | |
| echo " ✅ HTML conversion successful" | |
| # Post-process HTML | |
| html_output_file="../../dist/${lab_name}/${lab_name}.html" | |
| sed -i '/<header id="title-block-header">/,/<\/header>/d' "$html_output_file" | |
| sed -i 's/id=""//g' "$html_output_file" | |
| sed -i 's/<a href="\(https\?:\/\/[^"]*\)"/<a href="\1" target="_blank" rel="noopener noreferrer"/g' "$html_output_file" | |
| # Convert HTML to PDF | |
| echo " 📄 Converting HTML to PDF..." | |
| pdf_output_file="../../dist/${lab_name}/${lab_name}.pdf" | |
| if node "../../.github/scripts/generate-pdf.js" "$html_output_file" "$pdf_output_file" "$lab_title"; then | |
| echo " ✅ PDF generated successfully" | |
| # Conditionally clean up intermediate HTML file based on debug mode | |
| if [ "${{ inputs.debug }}" != "true" ]; then | |
| rm -f "$html_output_file" | |
| echo " 🧹 Cleaned up intermediate HTML file" | |
| else | |
| echo " 🔍 Debug mode: Keeping HTML file for inspection at $html_output_file" | |
| fi | |
| else | |
| echo " ⚠️ PDF generation failed for $lab_name" | |
| fi | |
| else | |
| echo " ❌ HTML conversion failed for $lab_name" | |
| fi | |
| # Cleanup | |
| rm -f "${lab_name}_processed.md" | |
| cd - > /dev/null | |
| fi | |
| done | |
| echo "📊 Generated PDFs: $(find dist -name "*.pdf" -type f | wc -l 2>/dev/null || echo "0")" | |
| # ================================================================= | |
| # STEP 4: SETUP JEKYLL ENVIRONMENT | |
| # ================================================================= | |
| - name: 💎 Setup Ruby and Jekyll | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| ruby-version: "3.1" | |
| bundler-cache: false | |
| - name: 🔧 Install PowerShell and dependencies | |
| run: | | |
| # Install PowerShell 7.x | |
| wget -q https://github.com/PowerShell/PowerShell/releases/download/v7.4.0/powershell_7.4.0-1.deb_amd64.deb | |
| sudo dpkg -i powershell_7.4.0-1.deb_amd64.deb || sudo apt-get install -f -y | |
| - name: 📦 Install PowerShell YAML module | |
| run: pwsh -Command "Install-Module -Name powershell-yaml -Force -Scope CurrentUser -Repository PSGallery" | |
| # ================================================================= | |
| # STEP 5: GENERATE JEKYLL CONTENT | |
| # ================================================================= | |
| - name: 🏗️ Generate Jekyll lab pages and index files | |
| run: pwsh -File scripts/Generate-Labs.ps1 | |
| - name: 📄 Copy PDFs to Jekyll assets | |
| run: | | |
| # Create assets directory for PDFs | |
| mkdir -p assets/pdfs | |
| # Copy PDFs from dist to Jekyll assets | |
| if [ -d "dist" ]; then | |
| echo "📄 Copying generated PDFs to Jekyll assets..." | |
| find dist -name "*.pdf" -type f | while read pdf_file; do | |
| lab_name=$(basename "$(dirname "$pdf_file")") | |
| cp "$pdf_file" "assets/pdfs/${lab_name}.pdf" | |
| echo " ✅ Copied PDF for lab: $lab_name" | |
| done | |
| echo "📊 Total PDFs copied: $(find assets/pdfs -name "*.pdf" | wc -l)" | |
| else | |
| echo "⚠️ No PDFs found to copy" | |
| fi | |
| - name: 💎 Install Jekyll dependencies | |
| run: | | |
| gem install bundler jekyll | |
| bundle config set --local path 'vendor/bundle' | |
| bundle install --retry 3 --jobs 4 | |
| - name: 🏗️ Build Jekyll site | |
| run: | | |
| bundle exec jekyll build --verbose | |
| env: | |
| JEKYLL_ENV: production | |
| # ================================================================= | |
| # STEP 6: DEPLOY TO GITHUB PAGES | |
| # ================================================================= | |
| - name: ⚙️ Setup GitHub Pages | |
| uses: actions/configure-pages@v4 | |
| - name: 📦 Upload to GitHub Pages | |
| uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: ./_site | |
| - name: 🚀 Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v4 | |
| - name: 🎉 Deployment Summary | |
| run: | | |
| echo "✅ Lab Browser deployed successfully!" | |
| echo "🌐 Site URL: ${{ steps.deployment.outputs.page_url }}" | |
| echo "" | |
| echo "🔄 UNIFIED WORKFLOW COMPLETED:" | |
| echo " 1. ✅ Generated PDFs from lab markdown files" | |
| echo " 2. ✅ Generated Jekyll lab pages with PowerShell" | |
| echo " 3. ✅ Built Jekyll site with PDF download links" | |
| echo " 4. ✅ Deployed to GitHub Pages" | |
| echo "" | |
| echo "🎯 Features deployed:" | |
| echo " - Auto-generated lab pages from README files" | |
| echo " - Fresh PDFs with download buttons" | |
| echo " - Journey-based navigation system" | |
| echo " - Responsive design with section filtering" | |
| echo " - Single workflow for complete build process" |