Run in CI
This guide sets up a GitHub Actions workflow that installs pz, validates a project, and runs
it on a schedule. Read it once a project is ready to run unattended instead of from your own
machine.
Prerequisites
Section titled “Prerequisites”- A
pzproject committed to the repository, includingpz.lock.jsonifproject.ymldeclares any non-builtinconnectors:. - Any credential the project needs, stored as a GitHub Actions secret.
-
Add a workflow file that installs the .NET 10 SDK, installs
pzas a global tool, and runs the project on a schedule:.github/workflows/pz-run.yml name: pz nightly runon:schedule:- cron: "0 3 * * *"workflow_dispatch:jobs:run:runs-on: ubuntu-latestenv:DB_PASSWORD: ${{ secrets.DB_PASSWORD }}steps:- uses: actions/checkout@v4- uses: actions/setup-dotnet@v4with:dotnet-version: "10.0.x"- run: dotnet tool install --global pz- run: echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"- run: pz restore- run: pz validate- run: pz run --all --log-format json--log-format jsonemits NDJSON, one object per run event, which is easier to grep from a failed job’s log than the interactive tree renderer. See Run events. -
Pass secrets as environment variables, referenced from
connections.ymlwith${VAR}:connections.yml warehouse:connector: sqlserverhost: ${DB_HOST}database: salesuser: ${DB_USER}password: ${DB_PASSWORD}Map each one from a GitHub Actions secret into the job’s
env:, asDB_PASSWORDis above. A variableconnections.ymlreferences but the job never sets fails validation withPZ0103before anything runs. See Secure connection config. -
Run
pz restorewhenproject.ymldeclaresconnectors:. It resolves those packages against the host feeds, materializes them under.pz/packages, and rewritespz.lock.json. Commitpz.lock.jsonto the repository;pz runandpz validaterefuse to start if it no longer matchesproject.yml’s declared connectors.pz restoreis harmless to run even when the project declares no connectors at all. -
Handle the exit code.
pz runexits0on full success,1when at least one node failed,2on a usage or configuration error, and3on a fatal engine error. GitHub Actions fails the step (and the job) on any non-zero exit automatically, so no extra handling is needed to get a red job on failure. See the CLI reference for the full table. -
Decide where state lives.
.pz/is created fresh in the runner’s ephemeral workspace on every job, so watermarks, run results, and staging databases do not survive between runs unless you do something about it. Two options:- Point the project at a remote state store, following Move state off the local disk, so watermarks and run results live outside the runner entirely. This is the only option that also survives a runner OS change or a concurrent job.
- Cache
.pz/state(not.pz/runs, which holds a staging database you don’t want to persist) withactions/cache, keyed on the repository and branch, so watermarks survive between scheduled runs on the same workflow. This only works for one workflow running at a time; two concurrent jobs racing on the same cache key will not merge cleanly.
Verify
Section titled “Verify”Trigger the workflow manually from the Actions tab (workflow_dispatch) and confirm the
pz validate step passes before pz run executes. A green job with pz run --all in its log
means the schedule is ready to run unattended.
Troubleshooting
Section titled “Troubleshooting”| If you see | Do |
|---|---|
pz validate fails with PZ0103 |
A connections.yml variable has no matching env: entry in the workflow. Add the secret to the job’s env: block. |
pz run/pz validate refuses to start over a lock mismatch |
pz.lock.json is out of date. Run pz restore locally and commit the result, rather than adding --no-lock-check. |
The job exits 1 |
At least one node failed at run time. Read the NDJSON log for the failing node’s error, then re-run with pz retry locally or in a follow-up job. |
The job exits 2 |
A configuration or validation error. Nothing ran; fix the file and line the error names. |
| Watermarks reset to the beginning every run | .pz/state isn’t persisted between jobs. Add remote state or an actions/cache step, per step 5 above. |
Related
Section titled “Related”- Move state off the local disk: the durable alternative to a runner’s ephemeral
.pz/for watermarks and run results. - Secure connection config: getting a secret from the environment into
connections.yml. - CLI reference: every flag and exit code used in the workflow.
- Connectors: what
pz restoreandpz.lock.jsondo for non-builtin connectors. - Environment variables: what
CIand every other variable pz reads controls.