Release and PyPI¶
Maintainer runbook for versioned releases and PyPI publishing.
Release Checklist¶
- Bump
src/honestroles/__about__.pyto the new version. - Add release notes in
CHANGELOG.md. - Run deterministic coverage gate:
$ PYTHON_BIN=.venv/bin/python bash scripts/run_coverage.sh
- Run docs tests:
$ PYTHONPATH=src:plugin_template/src .venv/bin/python -m pytest tests/docs -q
- Smoke-test operability commands on a sample parquet:
$ honestroles init --input-parquet examples/jobs_sample.parquet --pipeline-config /tmp/pipeline.toml --plugins-manifest /tmp/plugins.toml --force
$ honestroles doctor --pipeline-config /tmp/pipeline.toml --format table
$ honestroles reliability check --pipeline-config /tmp/pipeline.toml --strict --format table
$ honestroles ingest validate --source greenhouse --source-ref stripe --quality-policy ingest_quality.toml --format table
$ honestroles ingest sync --source greenhouse --source-ref stripe --max-pages 1 --max-jobs 50 --quality-policy ingest_quality.toml --strict-quality --merge-policy updated_hash --retain-snapshots 30 --prune-inactive-days 90 --format table
Optional batch smoke (if using ingestion manifests):
$ honestroles ingest sync-all --manifest ingest.toml --format table
- Commit and push
main.
Dedicated Ingestion Smoke Flow¶
Live ATS connector smoke tests run in a separate manual workflow:
- GitHub Actions workflow:
Ingestion Smoke(.github/workflows/ingest-smoke.yml) - Trigger:
workflow_dispatch - Inputs:
greenhouse_ref,lever_ref,ashby_ref,workable_ref
Local equivalent command:
$ export HONESTROLES_SMOKE_GREENHOUSE_REF=stripe
$ export HONESTROLES_SMOKE_LEVER_REF=plaid
$ export HONESTROLES_SMOKE_ASHBY_REF=notion
$ export HONESTROLES_SMOKE_WORKABLE_REF=skroutz
$ PYTHON_BIN=.venv/bin/python bash scripts/run_ingest_smoke.sh
This flow runs only smoke-marked live integration tests and is intentionally isolated from deterministic CI and coverage gates.
Smoke assertions require non-empty outputs per source (rows_written > 0 and parquet
height > 0) and strict quality pass, so keep refs current before triggering the workflow.
Dedicated Neon Smoke Flow¶
Neon publish contract checks run in a separate manual workflow:
- GitHub Actions workflow:
NeonDB Smoke(.github/workflows/neondb-smoke.yml) - Trigger:
workflow_dispatch - Inputs:
schema(defaulthonestroles_api) - Required secret:
NEON_DATABASE_URL
Local equivalent command:
$ export NEON_DATABASE_URL=<postgres-url>
$ PYTHON_BIN=.venv/bin/python DATABASE_URL_ENV=NEON_DATABASE_URL SCHEMA=honestroles_api bash scripts/run_neondb_smoke.sh
This flow validates the complete publish contract:
publish neondb migratepublish neondb sync(from generated sample artifacts)publish neondb verify- Direct
match_jobs_v1(...)query with non-empty assertion and payload-key checks againstcontracts/agent_response.v1.json.
Publish (Manual, API Token)¶
Publishing is manual and token-based.
Preferred local command:
$ bash scripts/publish_pypi.sh
scripts/publish_pypi.sh behavior:
- loads
PYPI_API_KEYfrom current env or.env - falls back to
PYPI_API_TOKENif present - builds sdist/wheel
- runs
twine check - uploads via token auth (
TWINE_USERNAME=__token__)
Optional GitHub Manual Workflow¶
The Release GitHub Action is workflow_dispatch only (manual) and validates the requested version before upload.
If used, configure one repository secret:
PYPI_API_KEY(preferred)PYPI_API_TOKEN(fallback)
Important: local .env values are not visible to GitHub runners.
Post-Release Verification¶
After publish succeeds:
- Install the released version in a clean environment.
- Run
honestroles --helpand confirm commands are present (init,doctor,reliability,ingest,runs). - Run one lineage-writing command (
run,report-quality,adapter infer,eda,reliability check,ingest sync,ingest validate, oringest sync-all) and verify.honestroles/runs/<run_id>/run.jsonis created. - If you ran
reliability check, confirmdist/reliability/latest/gate_result.jsonis written (or your custom--output-file). - If you ran ingestion, confirm latest/snapshot/report artifacts exist under
dist/ingest/...and batch report exists forsync-all.
Common Publish Failures¶
Missing Local API Key¶
Symptom:
Missing PyPI API key. Set PYPI_API_KEY (or PYPI_API_TOKEN) in env or .env.
Fix:
- Add
PYPI_API_KEY=<pypi-token>to.envor shell env. - Re-run:
$ bash scripts/publish_pypi.sh
Missing GitHub Secret (manual workflow path)¶
Symptom:
Missing PyPI token secret. Set PYPI_API_KEY (or PYPI_API_TOKEN) in repository secrets.
Fix:
- Add one secret in
Settings -> Secrets and variables -> Actions.