You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/craft:site:deploy deploys Quarto/pkgdown/MkDocs sites to GitHub Pages only. Netlify is a common target for the same site types, and the migration path has sharp edges that a command could absorb.
Concretely: GitHub Pages on a private repo depends on plan tier, which is not readable from the CLI (gh api user returns plan: null; the org endpoint needs an admin:org scope a normal token lacks). Netlify sidesteps that entirely — it serves a public site from a private repo on the free tier.
Evidence from a real migration
Migrated Data-Wise/regression (Quarto course site, 126 pages) from Pages to Netlify on 2026-08-12. What bit, in order:
A repo-linked Netlify build reads config from the checked-out branch only.netlify.toml existed locally and on the working branch but not on main. Per Netlify's docs an empty build command means Netlify "skips the build step and deploys files as-is" — so the failure presents as a mysterious no-op deploy, not a config error. Cost the most time of anything here.
Netlify's build image has no Quarto. The build must fetch it. Where _freeze/ is committed, R is not needed and the build stays fast (170s for 126 pages).
netlify.toml overrides the UI. Typing the build command into the dashboard while a toml is present creates two sources of truth that silently disagree.
Double-publish. Leaving deploy.yml in place after linking Netlify publishes every commit to two hosts, which then drift.
Retiring Pages needs a UI action. Deleting the workflow stops Pages updating; the old site keeps serving its last build until the deployment is removed in repo settings.
Proposed
Add a --target argument (pages | netlify), defaulting to pages so nothing changes for existing users.
For --target netlify:
Detect an existing netlify.toml; scaffold one if absent, with a project-type-aware build command (Quarto: fetch Quarto + quarto render; MkDocs: pip install + mkdocs build; pkgdown: pkgdown build) and the right publish dir (_site, site, docs).
Warn when a deploy.yml-style Pages workflow is still active, since that is the double-publish trap.
Pin the toolchain version rather than tracking latest, so an upstream release cannot change a live course/docs site with no commit.
Notes
The official @quarto/netlify-plugin-quarto exists but was last pushed 2023-05-10 (16 stars, not archived). A pinned fetch-and-render build command proved more current and pins the version explicitly, whereas the plugin defaults version to latest. Worth considering, but not obviously the right default.
Netlify's free tier moved to credit-based pricing in Sept 2025 (~300 credits/month, ~15 per production deploy ≈ ~20 deploys). That argues for keeping validation in a local gate rather than hosted CI. Per-deploy credit figure is from third-party trackers, not Netlify docs — worth re-verifying before relying on it.
Problem
/craft:site:deploydeploys Quarto/pkgdown/MkDocs sites to GitHub Pages only. Netlify is a common target for the same site types, and the migration path has sharp edges that a command could absorb.Concretely: GitHub Pages on a private repo depends on plan tier, which is not readable from the CLI (
gh api userreturnsplan: null; the org endpoint needs anadmin:orgscope a normal token lacks). Netlify sidesteps that entirely — it serves a public site from a private repo on the free tier.Evidence from a real migration
Migrated
Data-Wise/regression(Quarto course site, 126 pages) from Pages to Netlify on 2026-08-12. What bit, in order:netlify.tomlexisted locally and on the working branch but not onmain. Per Netlify's docs an empty build command means Netlify "skips the build step and deploys files as-is" — so the failure presents as a mysterious no-op deploy, not a config error. Cost the most time of anything here._freeze/is committed, R is not needed and the build stays fast (170s for 126 pages).netlify.tomloverrides the UI. Typing the build command into the dashboard while a toml is present creates two sources of truth that silently disagree.deploy.ymlin place after linking Netlify publishes every commit to two hosts, which then drift.Proposed
Add a
--targetargument (pages|netlify), defaulting topagesso nothing changes for existing users.For
--target netlify:netlify.toml; scaffold one if absent, with a project-type-aware build command (Quarto: fetch Quarto +quarto render; MkDocs:pip install+mkdocs build; pkgdown: pkgdown build) and the right publish dir (_site,site,docs).netlify.tomlis committed and present on the deploy branch. This is the docs: fix broken links and add CLAUDE.md #1 failure and it is cheap to check.deploy.yml-style Pages workflow is still active, since that is the double-publish trap.latest, so an upstream release cannot change a live course/docs site with no commit.Notes
@quarto/netlify-plugin-quartoexists but was last pushed 2023-05-10 (16 stars, not archived). A pinned fetch-and-render build command proved more current and pins the version explicitly, whereas the plugin defaultsversiontolatest. Worth considering, but not obviously the right default.🤖 Generated with Claude Code