cf-job-logs
A utility for fetching and structuring conda-forge CI logs (Azure Pipelines and GitHub Actions) into clean, agent-readable artifacts.
Installation
This project is managed by pixi. You can install the package in development mode using:
git clone https://github.com/Quantco/cf-job-logs
cd cf-job-logs
pixi run pre-commit-install
pixi run test
CLI Usage
The cf-job-logs CLI provides commands to inspect CI jobs for a conda-forge PR.
Authentication
Unauthenticated GitHub API requests are limited to 60 per hour, which a single PR inspection can exhaust, and GitHub Actions job logs require authentication altogether. By default, the token is therefore resolved in this order:
- the
GITHUB_TOKENenvironment variable, - the token of a logged-in
ghCLI (gh auth token), - no token — requests are sent unauthenticated.
So running gh auth login once is enough to stay clear of the rate limit. Use --gh
to require the gh CLI token (the command fails if gh is missing or logged out), or
--no-gh to never invoke gh and only use GITHUB_TOKEN:
cf-job-logs --gh list-jobs <pr_url>
cf-job-logs --no-gh list-jobs <pr_url>
List jobs
List failed jobs (default) for a PR:
cf-job-logs list-jobs https://github.com/conda-forge/some-feedstock/pull/123
List all jobs (including succeeded):
cf-job-logs list-jobs --all https://github.com/conda-forge/some-feedstock/pull/123
Download a job log
Use a job ID from the list-jobs output to download its log (sanitized by default):
cf-job-logs download-log https://github.com/conda-forge/some-feedstock/pull/123 <job_id>
Use --no-sanitize to get the raw log with timestamps:
cf-job-logs download-log --no-sanitize https://github.com/conda-forge/some-feedstock/pull/123 <job_id>
Output goes to stdout, so you can redirect it to a file:
cf-job-logs download-log <pr_url> <job_id> > build.log
Wait for CI
Wait for all CI checks to complete on a PR, then report which passed or failed:
cf-job-logs wait-for-ci https://github.com/conda-forge/some-feedstock/pull/123
Customize the polling interval and timeout:
cf-job-logs wait-for-ci --interval 60 --timeout 3600 <pr_url>
By default, --fail-fast is enabled: the command returns as soon as any check fails without waiting for the rest. Use --no-fail-fast to wait for all checks to complete.
The command exits with code 0 if all checks pass, or 1 if any check fails or the timeout is reached.
Note: wait-for-ci reports check-run level results (name + pass/fail). To get job IDs for download-log, use list-jobs after wait-for-ci completes.
Recommended agent workflow
# 1. Wait for CI to finish
cf-job-logs wait-for-ci --json <pr_url>
# 2. If something failed, get the job IDs
cf-job-logs list-jobs --json <pr_url>
# 3. Download the log for a specific failed job
cf-job-logs download-log <pr_url> <job_id>
JSON output
All commands that produce tabular output support --json for machine-readable output:
cf-job-logs list-jobs --json <pr_url>
cf-job-logs wait-for-ci --json <pr_url>
Verbose mode
Add -v for debug logging:
cf-job-logs -v list-jobs https://github.com/conda-forge/some-feedstock/pull/123
Running via pixi
All commands can also be run through pixi:
pixi run cf-job-logs list-jobs <pr_url>
Metadata
Release files for cf-job-logs 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cf_job_logs-0.4.0.tar.gz | 1.2 MB | With provenance | Details for cf_job_logs-0.4.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cf_job_logs-0.4.0-py3-none-any.whl | Python 3 | none | any | Details for cf_job_logs-0.4.0-py3-none-any.whl |
Total release size: 1.2 MB
Release files / cf_job_logs-0.4.0.tar.gz
| Download URL | cf_job_logs-0.4.0.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
28e8a45fd480bf8c3967d0b725606a3d84397ef4bd6e642e655916079488f7fe
|
|
BLAKE2b-256 checksum How to use checksums |
45f0ac2feadaca21e570750ab567dbf1e0f707141eb893565131368870ccc7c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logRelease files / cf_job_logs-0.4.0-py3-none-any.whl
| Download URL | cf_job_logs-0.4.0-py3-none-any.whl |
|---|---|
| Size | 21.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
099227e6a34dc69446da1351d6b8d80fff0e2463103f0050112e11b93d32d630
|
|
BLAKE2b-256 checksum How to use checksums |
c9e3a5a5a2485d839fb9a6b452bdf2855c1601429530f395b38efeb8e394cd28
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logSecurity for cf-job-logs 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for cf_job_logs-0.4.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.