Skip to content

Workflows and actions

quartobot ships two reusable GitHub Actions workflows and three composite actions. Most users don’t need to wire them by hand — quartobot use github-ci scaffolds a thin consumer workflow that calls one of the reusable workflows. This page is the reference for when you need to override an input, compose your own pipeline, or understand exactly what the CI is doing.

render-reusable-lean.yml (default in v0.3+)render-reusable.yml (manubot pattern)
Latest at /
PR preview at /pr/<n>/
Sticky PR comment
/versions/ page✓ (planned in this workflow too)
Per-commit /v/<sha>/ permalinks
Snapshot retention
HTML version banner
Scaffolded by quartobot use github-ci(default)--with-versioned-snapshots

If you’re starting a new project, use lean. Opt into the versioned-snapshots workflow when you actually need per-commit permalinks — preprint reviewers citing a specific commit’s rendering, the manubot-pattern in full.

The lean default. Setup quartobot → install Quarto → run quarto render → stage outputs (latest + PR preview) → update /versions/ page → deploy to gh-pages → sticky PR comment.

Minimum consumer workflow:

.github/workflows/render.yml
name: Render
on:
push: { branches: [main] }
pull_request: { branches: [main] }
workflow_dispatch:
jobs:
render:
uses: seandavi/quartobot/.github/workflows/render-reusable-lean.yml@main
permissions:
contents: write
pull-requests: write

Inputs (all optional):

InputDefaultDescription
formatshtml,pdf,docxComma-separated render formats. html, html,pdf, html,pdf,docx, etc.
project-typemanuscriptmanuscript (per-format file copy from project root) or book (copy the whole _book/ site recursively).
manuscript-namemanuscriptBase name for the PDF/DOCX alias under / and /pr/<n>/ — the PR sticky comment links to it. Ignored when project-type: book.
book-output-dir_bookOutput directory Quarto books write to. Only used when project-type: book.
python-version3.12Python version for the quartobot install.
quartobot-specquartobotPip spec for the quartobot CLI. Defaults to the published PyPI package; pin a tag (quartobot==0.3.0), point at a fork, or use a workspace path for in-tree testing.
quarto-versionreleaserelease for latest stable; pre-release is also recognized. Pass a specific version like "1.5.57" for reproducible CI.
tinytex"true"Install TinyTeX (required for PDF render). Set "false" to skip if HTML-only.
project.Directory holding _quarto.yml. Defaults to the repo root.
project-title"" (repository name)Title for the /versions/ page. Defaults to the repository name; pass an explicit value for a friendlier display.

Overriding inputs:

jobs:
render:
uses: seandavi/quartobot/.github/workflows/render-reusable-lean.yml@main
permissions:
contents: write
pull-requests: write
with:
formats: "html,pdf"
quarto-version: "1.5.57"
project-title: "My Paper"

The v0.1 / manubot-pattern workflow. Everything the lean workflow does, plus a per-commit /v/<sha>/ deploy on every push, snapshot retention pruning before each deploy, and a sed-substituted HTML version banner included into the rendered HTML.

When to use: preprint workflows where readers need to cite a specific commit’s rendering (“we used the version at /v/<commit-sha>/”). Otherwise, prefer the lean workflow — the versioned pattern has substantially more moving parts (banner template, retention policy config, the _version-banner.html include in _quarto.yml).

Minimum consumer workflow: identical shape to the lean one, just pointing at the other file:

jobs:
render:
uses: seandavi/quartobot/.github/workflows/render-reusable.yml@main
permissions:
contents: write
pull-requests: write

Additional inputs over the lean workflow:

InputDefaultDescription
banner-template_version-banner.html.templatePath to the placeholder-containing banner template (sed substitution input).
banner-output_version-banner.htmlPath the substituted banner is written to. The _quarto.yml format.html.include-before-body: should reference this same path.

All the lean workflow’s inputs apply here too.

Retention policy is configured per-project under quartobot.snapshots in _quarto.yml:

quartobot:
snapshots:
latest: keep # / is always the most recent build
tagged: keep # any v/<sha> whose commit has a git tag survives
recent: 10 # rolling window: last N untagged builds
pruned_behavior: redirect # `redirect` (default) or `delete`
size_budget_mb: 800 # 80% of the 1 GB GitHub Pages soft limit
on_over_budget: fail # `fail` (default) or `warn`

See Differences from manubot for the full design rationale on the retention model.

The three composite actions are the building blocks the reusable workflows are built from. You can also use them directly — useful when neither reusable workflow fits your pipeline (custom deploy target, multi-stage build, integration with non-Quarto steps).

Installs Python, the quartobot CLI on PATH (so the Quarto pre-render hook subprocess can invoke it), pandoc, Quarto, and TinyTeX. Used as the first step in both reusable workflows.

Path: seandavi/quartobot/actions/setup-quartobot@main

InputDefaultDescription
python-version3.12Python to install.
quartobot-specquartobotPip spec — PyPI package by default; override with a git ref, a fork, or a workspace path for in-tree testing.
quarto-versionreleaserelease / pre-release / specific version like "1.5.57".
tinytex"true"Install TinyTeX. Skip for HTML-only renders.
project.Directory holding _quarto.yml.

Why pandoc? Quarto bundles its own pandoc, but manubot.cite shells out to a standalone pandoc via shutil.which("pandoc") to convert biblatex (.bib) entries to CSL JSON. Without a system pandoc, manubot silently returns an empty bibliography and .bib keys are treated as unresolved. This action installs one.

Renders a Quarto project to one or more formats with heartbeat output during long PDF renders. Optionally uploads render logs as a workflow artifact.

Path: seandavi/quartobot/actions/render-manuscript@main

InputDefaultDescription
project.Path to the Quarto project directory.
formatshtml,pdf,docxComma-separated formats.
upload-logs"true"Upload render-<fmt>.log files as the render-logs artifact. Set "false" to skip.
log-artifact-namerender-logsArtifact name when upload-logs: true.

Heartbeat output: PDF renders under TinyTeX can be slow. The action emits a [heartbeat] line every 30 seconds during the PDF step so the workflow log doesn’t look hung.

Applies the project’s snapshot retention policy to the gh-pages branch. Only used by render-reusable.yml (versioned-snapshots); the lean workflow doesn’t deploy per-commit snapshots and so doesn’t need pruning.

Path: seandavi/quartobot/actions/prune-snapshots@main

InputDefaultDescription
modeapplyapply prunes + pushes the result. echo runs read-only (inventory + decision logged, no mutations). Use echo on PR builds.
project.Directory holding _quarto.yml (used to load quartobot.snapshots config).
gh-pages-branchgh-pagesName of the gh-pages branch.
latest-sha"" (auto)Full SHA of the build currently being deployed. Defaults to head SHA on PRs, github.sha otherwise.

Outputs:

OutputDescription
pruned-countNumber of v/<sha>/ directories pruned.
over-budget"true" if projected post-prune size still exceeds size_budget_mb.

The examples above use @main. In production, pin to a tag. Tags are immutable; main moves with every commit. The release flow ships tags like v0.3.0:

uses: seandavi/quartobot/.github/workflows/render-reusable-lean.yml@v0.3.0

The reusable workflows internally also reference the actions via @main while the project is pre-1.0; once a tagged release is declared stable, those internal references will be swept to the matching tag in a release commit.

If neither reusable workflow fits — custom deploy target (Netlify, Quarto Pub, Vercel), multi-stage build, integration with non-Quarto steps — the composite actions compose into a workflow you fully control:

name: Custom render
on:
push: { branches: [main] }
jobs:
render:
runs-on: ubuntu-latest
permissions: { contents: write }
steps:
- uses: actions/checkout@v4
- uses: seandavi/quartobot/actions/setup-quartobot@main
- uses: seandavi/quartobot/actions/render-manuscript@main
with:
formats: "html,pdf"
# ... your own deploy / publish steps here

The pre-render hook for citation resolution fires inside quarto rendersetup-quartobot puts quartobot on PATH so it can be invoked by Quarto without further configuration.