Skip to content

ci: add GitHub Actions deploy workflow for GitHub Pages#199

Open
mmcky wants to merge 2 commits intomainfrom
fix/198-github-actions-deploy
Open

ci: add GitHub Actions deploy workflow for GitHub Pages#199
mmcky wants to merge 2 commits intomainfrom
fix/198-github-actions-deploy

Conversation

@mmcky
Copy link
Copy Markdown
Collaborator

@mmcky mmcky commented May 5, 2026

Summary

Switches production publishing from the legacy "Deploy from a branch" method (which pins to the GitHub Pages gem sandbox / Jekyll 3.10) to a proper GitHub Actions workflow so the Gemfile's Jekyll 4.4 is used in production.

What changed

Added .github/workflows/deploy.yml using the standard GitHub Pages Actions pattern:

  1. ruby/setup-ruby — same Ruby 3.2 + bundler-cache: true config as the existing build.yml
  2. actions/configure-pages — emits the correct base_path for the site URL
  3. bundle exec jekyll build with JEKYLL_ENV=production
  4. actions/upload-pages-artifactactions/deploy-pages

Triggers on push to main and workflow_dispatch. The existing build.yml (PR preview) is left untouched.

Required manual step after merge

Settings → Pages → Source → change from "Deploy from a branch" to "GitHub Actions"
https://github.com/QuantEcon/website/settings/pages

After this lands we can

  • Restore @use / @forward Dart Sass directives in assets/main.scss (currently reverted to @import as a workaround)
  • Use Jekyll 4.x-only Liquid filters safely in templates
  • Drop the github-pages gem dependency entirely

Verification checklist

  • After flipping Pages source: confirm quantecon.org CNAME resolves correctly
  • Confirm redirects in pages/ still work
  • Verify all collections (_posts, _lectures, _team-members, _projects) build identically
  • Check sitemap.xml and feed.xml output

Closes #198

Switch production publishing from the legacy 'Deploy from branch' method
(Jekyll 3.10 sandbox) to a GitHub Actions workflow so the Gemfile's
Jekyll 4.4 version is used in production.

- Add .github/workflows/deploy.yml using the standard Pages pattern:
  actions/configure-pages → jekyll build → upload-pages-artifact → deploy-pages
- Trigger on push to main and workflow_dispatch
- Mirror ruby/setup-ruby config from existing build.yml (Ruby 3.2, bundler-cache)
- Set JEKYLL_ENV=production and pass base_path from configure-pages

After merging, go to Settings → Pages → Source and change from
'Deploy from a branch' to 'GitHub Actions' to activate this workflow.

Closes #198
Copilot AI review requested due to automatic review settings May 5, 2026 03:03
@netlify
Copy link
Copy Markdown

netlify Bot commented May 5, 2026

Deploy Preview for grand-swan-ca5201 ready!

Name Link
🔨 Latest commit a919804
🔍 Latest deploy log https://app.netlify.com/projects/grand-swan-ca5201/deploys/69f969aac7bbcb00087cd3d9
😎 Deploy Preview https://deploy-preview-199--grand-swan-ca5201.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a dedicated GitHub Actions deployment workflow for the QuantEcon Jekyll site so production publishing uses the repository’s configured Jekyll 4.4 toolchain instead of the legacy GitHub Pages branch build.

Changes:

  • Adds a new Pages deployment workflow that builds the site with Ruby 3.2 and Bundler cache.
  • Uses actions/configure-pages, uploads the generated _site artifact, and deploys it via actions/deploy-pages.
  • Keeps the existing PR preview workflow separate from production deployment.

Comment thread .github/workflows/deploy.yml
Comment thread .github/workflows/deploy.yml Outdated
- Scope pages:write and id-token:write to the deploy job only;
  top-level permissions reduced to contents:read so the build job
  (which runs repo code and third-party actions) cannot use deployment
  credentials even if compromised.
- Add if: github.ref == 'refs/heads/main' guard to the deploy job so
  a manual workflow_dispatch triggered from a non-main branch builds
  but never publishes to production.
@mmcky
Copy link
Copy Markdown
Collaborator Author

mmcky commented May 5, 2026

Copilot feedback addressed

Two commits pushed to address the two Copilot security notes:

  1. Permissions scoped to deploy job onlypages: write and id-token: write moved off the top-level block and onto the deploy job. Top-level now carries only contents: read. This means the build job (which checks out repo code and runs third-party actions) cannot use deployment credentials even if a step were compromised.

  2. workflow_dispatch branch guard — Added if: github.ref == 'refs/heads/main' to the deploy job. A manual trigger from a non-main branch will still run the build job (useful for testing the build) but will never push to the production Pages environment.


Why this migration is worth doing

The core problem

The legacy "Deploy from a branch" Pages setup runs builds inside GitHub's gem sandbox, which is pinned to Jekyll 3.10 and LibSass (via jekyll-sass-converter 1.x) regardless of what's in Gemfile. That's a two-major-version gap from what's specified locally.

What Jekyll 4.x unlocks

Feature Jekyll 3.10 (current production) Jekyll 4.4 (after this PR)
where_exp / group_by_exp Liquid filters ✅ — already used in #204 (workshops collection)
Dart Sass (@use / @forward) ❌ LibSass only
@import deprecation warnings None (LibSass ignores them) Shown — pushes toward modern CSS
Incremental build (--incremental) Partial More reliable
Better Liquid error messages

The @use / @forward directives were already written in assets/main.scss as part of the site refresh (#194) but had to be reverted (65163f9) because they fail on the LibSass sandbox in production. Once this PR is merged and Pages is switched to GitHub Actions, those can be restored.

Gemfile control

With the legacy setup, the github-pages gem silently overrides individual gem pins. Every dependency is locked to whatever GitHub chose for their sandbox at build time — meaning a gem update GitHub makes on their end can silently change production behaviour. After this migration we own the full dependency graph via Gemfile.lock.

Reproducibility

Local builds, Netlify preview builds, and production builds all use identical Ruby + Jekyll + gem versions. The "it works locally but fails in production" class of bug goes away.

Summary

This is a small workflow file that removes a large hidden constraint on the tooling we can use. The immediate unblock is Dart Sass @use; longer term it means we can adopt any Jekyll 4.x feature without worrying about the sandbox ceiling.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate GitHub Pages publishing to GitHub Actions workflow

2 participants