CI/CD Pipeline¶
pyrig generates and manages a complete three-stage GitHub Actions pipeline.
The workflows are produced as ConfigFile subclasses, so they are kept correct
automatically by the pyrig sync pre-commit hook, just like any other managed file.
Pipeline Overview¶
release.yml is the only workflow triggered by a push to the default branch.
It calls the other two workflows as reusable workflows (workflow_call),
running them as jobs in sequence:
Push to default branch
│
▼
┌───────────────────┐
│ Release │
│ │
│ ┌─────────────┐ │
│ │Health Check │ │ ← called via workflow_call
│ └──────┬──────┘ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Publish │ │ ← tags and publishes a GitHub Release
│ └──────┬──────┘ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Deploy │ │ ← called via workflow_call
│ └─────────────┘ │
└───────────────────┘
Health Check is also independently triggered by manual dispatch, every pull
request, and a nightly schedule, so it supports on-demand diagnostics while
doubling as both a PR gate and a reusable job called from release.yml.
Deploy only runs via workflow_call, invoked by release.yml's deploy job
after publish succeeds; since jobs run in dependency order (needs:), no
if guard is required — deploy never executes unless publish (and,
transitively, health-check) succeeded.
Every job in the deploy workflow gets its own GitHub Actions environment, named after the job's stable ID automatically.
Stage 1 — Health Check¶
File: .github/workflows/health_check.yml
This workflow executes tests and other general health checks. It has four
triggers: manual dispatch, every pull request, a nightly schedule, and
workflow_call (so release.yml can run it as a job). Manual dispatch is
useful for on-demand diagnostics; as a PR gate it blocks merging until it
passes; as a nightly job it catches regressions from automatic dependency
upgrades (see below); and as a reusable workflow it acts as the first job in
the release pipeline, gating publish.
Stage 2 — Release¶
File: .github/workflows/release.yml
Trigger: push to the default branch.
Three jobs run in dependency order:
health-check— callshealth_check.ymlas a reusable workflow.publish— runs only ifhealth-checksucceeds (needs:). Creates a GitHub Release with auto-generated release notes, tagging the current commit in the same call.deploy— runs only ifpublishsucceeds (needs:). Callsdeploy.ymlas a reusable workflow.
Important
The release workflow creates a new tag, which will fail if that tag
already exists. This means you must ensure the version is updated in
pyproject.toml before pushing to the default branch, otherwise the
release workflow will fail on the existing tag. This is a common source
of confusion, so make sure to update the version in pyproject.toml
before creating a new release. This is easily done by running
uv version --bump patch (or minor/major).
Stage 3 — Deploy¶
File: .github/workflows/deploy.yml
Trigger: workflow_call only, invoked by release.yml's deploy job.
Two jobs run in this final stage:
repository— applies repository settings and protection rulesets, and more, all via the GitHub API. Requirescontents: readat the job level; the configuration step itself authenticates separately via theREPO_TOKENsecret.documentation— builds the documentation site and deploys it to GitHub Pages. This job requirescontents: read,pages: write, andid-token: writepermissions at the job level.
Important
If your repository is private, the published docs site is still publicly accessible. Please check how to change the visibility of your GitHub Pages site in the repository settings. Pyrig does not do this for you as it is not free for private repositories.
Tip
Keep your documentation public for users and only document user facing relevant information and avoid exposing internal implementation details.
Automatic Dependency Updates Checks¶
A notable property of the pipeline is that dependency
upgrades happen inside CI in the health check stage. It runs uv lock --upgrade
to pull the latest dependency versions within declared constraints. This ensures
your project catches problems caused by new versions in the dependencies early.
This way the regular nightly health check runs will catch any issues caused by
dependency upgrades automatically.
If you need specific versions of packages you need to pin them in pyproject.toml
to prevent it from being updated by the pipeline.
Customizing the Pipeline¶
All three workflow files are managed ConfigFile instances, so they can be
extended or overridden in the same way as any other managed file in pyrig.
Run pyrig mk subcls and search for the workflow class you want to change
(HealthCheckWorkflowConfigFile, ReleaseWorkflowConfigFile, or
DeployWorkflowConfigFile) to generate a correctly placed subclass skeleton.
Override the methods that need changing — jobs, triggers, steps, permissions,
or environment variables. The WorkflowConfigFile base class provides
composable helpers for common patterns (matrix strategies, step builders,
trigger constructors) so custom workflows stay concise and consistent with
the generated ones.
Run pyrig sync after any change to update or regenerate the workflow files.