CI Pipeline Tests¶
PBI-Scope uses GitHub Actions to automatically build the full Snakemake pipeline and validate the pbi Python package against real data on every pull request and push to main.
Overview¶
| Property | Value |
|---|---|
| Runner | ubuntu-latest |
| Timeout | 120 minutes |
| Triggers | Pull requests to main, pushes to main, manual dispatch |
| Expected runtime | 20-40 minutes (with Buildx cache) |
The CI pipeline performs two jobs in sequence:
- Run the Snakemake pipeline against a reduced subset of PhageScope data (2 of 26 sources).
- Run smoke tests that exercise the
pbiPython package against the database and FASTA files produced by the pipeline.
If the pipeline step fails, the smoke tests still run (they use if: always()), so you can see whether the package works even when upstream data sources are temporarily unavailable.
Workflow Steps¶
1. Checkout and Buildx Setup¶
The repository is checked out and Docker Buildx is initialized. Buildx enables advanced build features, most importantly layer caching (see Docker Buildx Caching below).
2. Build Docker Image¶
- uses: docker/build-push-action@v6
with:
context: .
file: workflow/Dockerfile
tags: pbiscope-ci:latest
load: true
cache-from: type=gha,scope=pbiscope-pipeline
cache-to: type=gha,mode=max,scope=pbiscope-pipeline
The Docker image is built from workflow/Dockerfile. It installs Snakemake, DuckDB, pyfaidx, and all other dependencies via conda. The image is tagged pbiscope-ci:latest and loaded into the local Docker daemon so subsequent steps can use it.
3. Run Pipeline (CI Subset)¶
docker run --rm \
-v ${{ github.workspace }}/data:/data \
snakemake --cores 2 --use-conda \
--snakefile /app/workflow/Snakefile.ci
The Snakemake pipeline runs inside the built container using Snakefile.ci, which loads the full default config and then overrides it with config.ci.yaml. This produces a DuckDB database, indexed FASTA files, and merged CSV outputs under /data/processed/.
4. Run Smoke Tests¶
docker run --rm \
-v ${{ github.workspace }}/tests:/app/tests \
-e DATA_PATH="/data/processed" \
bash -c "pip install -e /app/. pytest && \
python -m pytest /app/tests/test_pbi_ci_smoke.py -v"
A second container mounts the tests/ directory and the pipeline output, installs the pbi package in editable mode, then runs the smoke test suite with pytest.
CI Subset Configuration¶
The CI pipeline uses a reduced configuration to keep runtime under 40 minutes. The full production pipeline downloads from 26 sources; CI uses only 2.
| Setting | Production | CI |
|---|---|---|
| Phage metadata sources | 26 | 2 (RefSeq, PhagesDB) |
| Metadata features | 9 | All 9 included |
| FASTA sources | 26 | 2 (RefSeq, PhagesDB) |
| GFF3 sources | 26 | 2 (RefSeq, PhagesDB) |
| Host genome downloads | Configurable | Enabled (metadata_only_mode: false) |
The CI config lives at workflow/config/config.ci.yaml. The CI Snakefile (workflow/Snakefile.ci) loads the full default config first, then replaces top-level keys with CI overrides.
Smoke Tests¶
The smoke tests live in tests/test_pbi_ci_smoke.py and run inside the Docker container against the real pipeline output. They verify that the pbi package works end-to-end without asserting exact data values.
| Test Class | Tests | What It Validates |
|---|---|---|
| TestConnection | 2 | Database file exists, quick_connect() returns a SequenceRetriever |
| TestMetadataQueries | 4 | Phage metadata, protein metadata, phage-host pairs, structured filters all return results |
| TestFastaAccess | 3 | FASTA files exist, get_phage_sequence() returns a valid string |
| TestPhageGenomeStreaming | 6 | Genome retrieval in all modes (concat, first, list, dict), gap handling, missing phage error |
| TestHostGenomeStreaming | 8 | Host genome retrieval in all modes, genome stats, gap handling, graceful skip when host data unavailable |
| TestPhageHostPairStreaming | 2 | Phage-host pairs with sequences, concat mode |
| TestErrorHandling | 1 | Nonexistent phage ID returns None |
Total: 26 tests
Tests that depend on host genomes use pytest.skip() when host data is not available, so they pass gracefully in both host-enabled and host-disabled CI configurations.
Running Smoke Tests Locally¶
After a local pipeline run:
docker run --rm \
-v $(pwd)/data:/data \
-v $(pwd)/tests:/app/tests \
-e DATA_PATH="/data/processed" \
pbiscope-ci:latest \
bash -c "pip install -e /app/. pytest && \
python -m pytest /app/tests/test_pbi_ci_smoke.py -v"
Docker Buildx Caching¶
The CI workflow uses Docker Buildx with GitHub Actions cache to speed up image builds.
What is Buildx?¶
Buildx is an extended build backend for Docker that supports advanced features like multi-platform builds, build secrets, and build cache backends. The docker/setup-buildx-action GitHub Action installs and configures it automatically.
How the Cache Works¶
type=gha: Uses the GitHub Actions cache backend. Cache layers are stored as GitHub Actions cache entries, scoped to the repository.scope=pbiscope-pipeline: Isolates this workflow's cache from other workflows in the same repository.mode=max: Exports all layers (not just the final image layers) to the cache. This maximizes cache hits for intermediate layers.
Why It Matters¶
The Docker image installs conda environments, which can take 5-10 minutes to resolve and download. With Buildx caching:
- First run: Full build, layers are pushed to cache (~10-15 min).
- Subsequent runs (when only code changes): Docker reuses cached layers for unchanged steps (conda install, system packages). Only the
COPYlayers for modified files are rebuilt (~1-3 min).
The cache is automatically evicted by GitHub after 7 days of inactivity.
Artifacts¶
After each CI run, two artifacts are uploaded:
| Artifact | Contents | Retention |
|---|---|---|
pipeline-logs |
Snakemake logs, reports, and run metadata from /pipeline-logs/ |
7 days |
merged-data |
Merged CSV outputs from data/intermediate/csv/merged/ |
7 days |
These are available for download from the GitHub Actions run summary page.
See Also¶
- Code Structure — project layout and test overview
workflow/config/config.ci.yaml— CI subset configurationtests/test_pbi_ci_smoke.py— smoke test source codeworkflow/Snakefile.ci— CI Snakefile with config override logic