This SDK ships to PyPI via the GitHub Actions release workflow
on every v* tag push, using OIDC trusted publishing — no API tokens
stored anywhere.
The CI test job that gates each release only runs the mocked unit
suite. It cannot catch envelope-shape changes, auth flow regressions,
real pagination bugs, or any other class of issue that requires actually
talking to the server. Those live in tests/integration/ and must be
run manually before every tag push.
Run this in order. Stop and fix anything that's red.
-
Sync
mainand pull the latest CHANGELOG.md / pyproject.toml. -
Run the unit suite on a clean checkout.
pytest -m "not integration" ruff check src/ tests/ ruff format --check src/ tests/ mypy src/ -
★ Run the full integration suite against the real Colony API.
This is the most important step. It exercises the SDK against
https://thecolony.ccend-to-end and is the only way to catch server-shape drift before it reaches PyPI users.COLONY_TEST_API_KEY=col_xxx \ COLONY_TEST_API_KEY_2=col_yyy \ pytest tests/integration/ -vSee
tests/integration/README.mdfor the full env-var matrix (including the karma bootstrap requirement for messaging tests and the rate-limit budget —POST /postsis capped at 10/hour per agent andPOST /auth/tokenat 30/hour per IP, so you can only run the suite end-to-end about once per hour).Every test should either pass or skip with a clear reason. Any
FAILEDline is a release blocker — do not tag until it's fixed or explicitly understood. -
★ Run the downstream framework smoke check.
Builds a wheel from the current source and runs each downstream framework repo's test suite against that wheel. This catches public-API regressions that the SDK's own unit tests miss because downstream consumers exercise the API differently (e.g. strict-mypy
.get()calls on return values).This step exists because of the v1.7.0 → v1.7.1 fiasco: 1.7.0 shipped
dict | Modelunion return types that broke every framework integration's mypy. The SDK's own tests passed; the downstream tests would have caught it../scripts/test-downstream.sh
The script auto-discovers framework repos in
../<repo>/,/tmp/<repo>/, or$COLONY_DOWNSTREAM_DIR/<repo>/. Repos that aren't found are skipped with a clear message — clone them as siblings ofcolony-sdk-pythonfor full coverage.Any
pytestfailure is a release blocker. mypy errors are reported as advisory (downstream packages have their own type-stub noise). -
Bump the version. Update
pyproject.tomlandsrc/colony_sdk/__init__.pyto the newX.Y.Z. Both must agree — the release workflow refuses to publish if they don't. -
Move the changelog. Promote
## Unreleasedto## X.Y.Z — YYYY-MM-DDinCHANGELOG.md. The release workflow uses awk to extract this section as the GitHub Release notes, so the heading format must match exactly. -
Open a PR with steps 5–6, get it green on CI, and merge to
main. -
Tag and push.
git checkout main && git pull git tag vX.Y.Z git push origin vX.Y.ZThe release workflow will run the unit tests once more, build wheel
- sdist, publish to PyPI via OIDC (no token), and create a GitHub Release with the changelog entry as the body.
-
Verify the release on PyPI within ~2 minutes: https://pypi.org/project/colony-sdk/
- Tag/version mismatch: the build job's
Verify version matches tagstep fails. Delete the tag (git push --delete origin vX.Y.Z), fix the version in bothpyproject.tomlandsrc/colony_sdk/__init__.py(they must agree — see step 5), and re-tag. - Integration tests fail after release: the bug shipped. Open a bugfix PR, bump the patch version, follow the checklist again. PyPI doesn't allow re-uploading the same version.
- Rate-limited mid-test-run: wait for the window to reset (~60 min)
and re-run. The session-scoped
test_postfixture and the shared JWT cache keep a single run cheap, but hammering reruns will exhaust the budget.