Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

How-to: choose which events publish the site

publish.yml fires on every completed CI run — pull requests, pushes to the default branch, and tags alike:

on:
  workflow_run:
    workflows: [CI]
    types: [completed]

Every deploy rebuilds the whole site from durable sources, so this is what makes the site self-healing: any deploy that came out wrong is corrected by the next one, whatever triggered it. Narrowing the trigger trades that away, so narrow it deliberately.

Check the cost first

Publishing is no longer on any PR’s critical path — it runs after CI, on its own run — so “it slows my PRs down” is not a reason to narrow it any more. Deploys do still serialise on the pages concurrency group, and a burst of pushes costs at most one extra deploy: a group holds one pending run, so a third arrival replaces the queued second rather than adding to it. A deploy already in flight is never cancelled — see architecture.

If a deploy takes minutes, the site itself is probably too big rather than the trigger too broad — see keep-the-site-small.

If you still want fewer deploys

Narrow the job’s if: in your publish.yml. To publish only on the default branch and tags, skip the runs whose triggering event was a pull request:

jobs:
  publish:
    if: >-
      github.event_name == 'workflow_dispatch' ||
      (github.event.workflow_run.conclusion == 'success' &&
       github.event.workflow_run.head_repository.full_name == github.repository &&
       github.event.workflow_run.event != 'pull_request')

You keep PR previews either way — any deploy gathers every open PR’s build artifact, so /pr-<n>/ still appears; it just refreshes on the next merge rather than on every push. And you keep self-healing, at merge cadence.

What you must not remove

The two guards in the shipped if: are not style:

Both fail open if removed — the site keeps deploying and nothing looks wrong — so test/workflow-harness/test_shape.py asserts them in this repo. Consider the same if you edit your copy.

Checking what your trigger actually does

publish.yml runs appear under Actions as their own runs, not as checks on the PR. A run that skipped shows the publish job as skipped. When one does deploy, its Gather release artifacts step prints a decision for every release the API listed — gathered, skipped, and why — and the extract step reports the assembled size and version count, so you can see whether a version made it in and what kept it out.