Skip to content

Restructure CI/CD pipeline and fix PyPI publishing#667

Draft
anth-volk wants to merge 10 commits intomainfrom
fix/fix-us-data-pypi
Draft

Restructure CI/CD pipeline and fix PyPI publishing#667
anth-volk wants to merge 10 commits intomainfrom
fix/fix-us-data-pypi

Conversation

@anth-volk
Copy link
Copy Markdown
Collaborator

Fixes #666
Fixes #638

Summary

  • Migrate versioning workflow from expired PAT to GitHub App token for reliable PyPI publishing
  • Reorganize tests into unit/ (270 tests, fast) and integration/ (53 tests, require datasets)
  • Consolidate 9 workflow files into 4: pr.yaml, push.yaml, pipeline.yaml, versioning.yaml
  • Add queue-based Modal architecture with scope filtering (all/national/state/congressional/local/test)
  • Add Codecov integration (informational, non-blocking) and per-step build timing summaries
  • Update CLAUDE.md with test organization and CI/CD structure

Test plan

  • PR workflow (pr.yaml): verify unit tests, lint, changelog check, smoke test all pass
  • Verify Codecov posts coverage comment on PR
  • After merge: verify versioning workflow commits "Update package version" with App token
  • After merge: verify push.yaml publish job uploads to PyPI
  • Manual dispatch: pipeline.yaml with scope=test builds only national + NY + NV-01
  • Create pipeline-approval GitHub environment before merge
  • Add CODECOV_TOKEN secret before merge

🤖 Generated with Claude Code

anth-volk and others added 5 commits March 30, 2026 22:04
Fixes #638. The versioning workflow used a PAT (POLICYENGINE_GITHUB)
to push the "Update package version" commit, which broke when the
token expired. Switch to a GitHub App token via
actions/create-github-app-token@v1, matching the pattern used in
policyengine-api-v2-alpha.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Split tests into unit/ (self-contained, synthetic data, mocks) and
integration/ (requires built H5 datasets). Unit sub-folders use no
test_ prefix (datasets/, calibration/) to avoid confusion with
integration tests.

- Move 30+ unit test files to tests/unit/ with calibration/ and
  datasets/ sub-directories
- Move 11 integration test files to tests/integration/
- Merge test_dataset_sanity.py into per-dataset integration files
  (test_cps.py, test_enhanced_cps.py, test_sparse_enhanced_cps.py)
- Rename calibration integration tests to match dataset names
  (test_source_imputed_cps_masking.py, _consistency.py)
- Move top-level tests/ files into appropriate unit/ or integration/
- Add integration conftest.py with skip logic and shared fixtures
- Update pyproject.toml testpaths and add pytest-cov dependency
- Update modal_app/data_build.py TEST_MODULES
- Add make test-unit and make test-integration targets
- Fix Path(__file__) references in moved test files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New queue-based H5 build system that replaces the partition-based
N-worker model with one-container-per-item processing.

- generate_work_items(scope, db_path): auto-generates work item lists
  filtered by scope (all/national/state/congressional/local/test).
  Test scope builds national + NY + NV-01 only.
- build_single_area(): Modal function (1 CPU, 16GB) that processes
  exactly one work item per container via worker_script.py
- queue_coordinator(): spawns up to 50 single-item workers, collects
  results. No multi-threading, no chunking.
- main_queue entrypoint for CLI access
- Wire scope parameter from pipeline.yaml through run_pipeline()
- Fall back to legacy coordinate_publish for scope=all

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add testing standards: unit vs integration placement rules, per-dataset
naming convention, make test-unit/test-integration commands. Add CI/CD
overview documenting the four workflow files and their triggers. Update
Python version from 3.11 to 3.12-3.13.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@anth-volk anth-volk force-pushed the fix/fix-us-data-pypi branch from 48abbd4 to e12990b Compare March 30, 2026 20:21
anth-volk and others added 4 commits March 30, 2026 22:23
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Delete 7 deprecated/redundant workflow files and replace with 3
consolidated workflows matching the policyengine-api-v2-alpha pattern.

pr.yaml: fork check, lint, uv.lock, changelog, unit tests with
Codecov (informational), smoke test. Runs in ~2-3 minutes.

push.yaml: two paths — version bump commits publish to PyPI; all
other commits run per-dataset Modal builds with integration tests
after each stage, then manual approval gate, then pipeline dispatch.

Also adds:
- .codecov.yml with informational-only coverage reporting
- --script mode to data_build.py for per-dataset Modal execution
- SCRIPT_SHORT_NAMES mapping for human-friendly script names
- run_single_script() Modal function for single-dataset builds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Pass HUGGING_FACE_TOKEN to unit test step in pr.yaml so tests that
  transitively import huggingface.py can collect without crashing
- Fix test_etl_national_targets.py: remove nonexistent
  TAX_EXPENDITURE_REFORM_ID import, use reform_id > 0 filter instead
  (mirrors fix from unmerged PR #664)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove test_reproducibility.py: imports modules that never existed
  (enhanced_cps.imputation, enhanced_cps.reweight, scripts). Broken
  since PR #117 (July 2025), never caught because old testpaths
  didn't include top-level tests/.
- Fix test_legacy_target_overview_without_reform_id: create builder
  before installing legacy view so __init__'s create_or_replace_views
  doesn't overwrite it. Clear column cache so builder re-detects
  missing reform_id. Mirrors fix from unmerged PR #665.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
download_private_prerequisites.py downloads files (puf_2015.csv,
demographics_2015.csv, soi.csv, np2023_d5_mid.csv, policy_data.db)
to the local filesystem, which vanishes when the container exits.
In --script mode, each script runs in a separate container, so
subsequent scripts couldn't find the prerequisites.

Fix: save prerequisite files to the checkpoint volume after download,
and restore them before running any other script.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant