Update mona_lisa_overdrive.md #846
Workflow file for this run
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
| # .github/workflows/jekyll.yml | |
| # | |
| # Runs on every push to every branch: | |
| # 1. `bundle exec rubocop` (lint). | |
| # 2. Ruby tests (`load` every _tests/**/test_*.rb). | |
| # 3. Python script tests in _scripts/ (setup-python + `uv run pytest`). | |
| # 4. `_bin/check_strict.rb` (strict Liquid variables). | |
| # 5. Build, HTML structure validation, feed XML validation, broken-link | |
| # check (only the `test` job's steps run on every branch; `build` and | |
| # `deploy` below only run for main via the `needs:`/`if:` chain). | |
| # | |
| # Test-job concurrency is per-ref and cancels stale runs | |
| # (`test-${{ github.ref }}`); the deploy job's `group: pages` lock is scoped | |
| # to deployment only so it can't starve test runs on other branches. | |
| name: Test and Deploy Jekyll site to Pages | |
| on: | |
| # Runs on pushes to ANY branch | |
| push: | |
| # Allows you to run this workflow manually from the Actions tab | |
| workflow_dispatch: | |
| # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages | |
| permissions: | |
| contents: read | |
| pages: write | |
| id-token: write | |
| jobs: | |
| # Test job - Runs on EVERY branch | |
| test: | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: test-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Setup Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| bundler-cache: true | |
| cache-version: 0 | |
| - name: Run linter | |
| run: bundle exec rubocop | |
| - name: Run tests | |
| run: bundle exec ruby -I _plugins -I _tests -e "require 'test_helper'; Dir.glob('_tests/**/test_*.rb').each { |f| load f }" | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| - name: Run script tests | |
| working-directory: _scripts | |
| run: uv run pytest | |
| - name: Check for strict Liquid errors | |
| run: bundle exec ruby _bin/check_strict.rb | |
| # Build job | |
| build: | |
| runs-on: ubuntu-latest | |
| needs: test | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v7 | |
| - name: Setup Ruby | |
| uses: ruby/setup-ruby@v1 | |
| with: | |
| bundler-cache: true | |
| cache-version: 0 | |
| - name: Setup Pages | |
| id: pages | |
| uses: actions/configure-pages@v6 | |
| - name: Build with Jekyll | |
| run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" | |
| env: | |
| JEKYLL_ENV: production | |
| - name: Validate HTML structure | |
| run: | | |
| echo "Checking for missing DOCTYPE declarations..." | |
| missing_doctype=$(find _site -name '*.html' -exec sh -c 'head -1 "$1" | grep -qv "^<!DOCTYPE" && echo "$1"' _ {} \;) | |
| if [ -n "$missing_doctype" ]; then | |
| echo "ERROR: The following files are missing <!DOCTYPE html>:" | |
| echo "$missing_doctype" | |
| echo "This usually indicates a broken layout chain or corrupted front matter." | |
| exit 1 | |
| fi | |
| echo "Checking for raw front matter in output..." | |
| # Only check for --- at the START of files (actual unprocessed front matter) | |
| # Ignore --- inside code blocks (legitimate content like Jekyll tutorials) | |
| raw_frontmatter=$(find _site -name '*.html' -exec sh -c 'head -1 "$1" | grep -q "^---$" && echo "$1"' _ {} \;) | |
| if [ -n "$raw_frontmatter" ]; then | |
| echo "ERROR: Raw front matter delimiters found at start of HTML files:" | |
| echo "$raw_frontmatter" | |
| exit 1 | |
| fi | |
| echo "All HTML structure checks passed." | |
| - name: Validate feed XML | |
| run: | | |
| bundle exec ruby -rrexml -e ' | |
| feeds = Dir.glob("_site/**/*.xml").select { |f| | |
| content = File.read(f, 512) | |
| content.include?("<feed") || content.include?("<rss") | |
| } | |
| abort "FAILED — no feed XML files found in _site" if feeds.empty? | |
| feeds.each do |path| | |
| print "#{path}: " | |
| raw = File.read(path) | |
| abort "FAILED — starts with raw Liquid/HTML, not XML declaration" unless raw.start_with?("<?xml") | |
| doc = REXML::Document.new(raw) | |
| entries = REXML::XPath.match(doc, "//*[local-name()=\"entry\"]") | |
| abort "FAILED — feed contains no entries" if entries.empty? | |
| puts "OK (#{entries.length} entries)" | |
| end | |
| ' | |
| - name: Check for broken links | |
| run: bundle exec ruby _bin/check_links.rb | |
| - name: Upload artifact | |
| # Only upload if we are on main (where deployment happens) | |
| if: github.ref == 'refs/heads/main' | |
| uses: actions/upload-pages-artifact@v5 | |
| # Deployment job | |
| deploy: | |
| concurrency: | |
| group: "pages" | |
| cancel-in-progress: false | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| runs-on: ubuntu-latest | |
| needs: build | |
| # This matches the condition above, ensuring we only try to deploy if we uploaded | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v5 |