This repository publishes two packages, each from a directory named after its distribution:
- configdirector-server-sdk, the server SDK, imported as
configdirector. - configdirector-openfeature-server-provider, the
OpenFeature provider built on it, imported as
configdirector_openfeature.
They are members of one uv workspace, so they share a lockfile and a virtual environment, and the provider always develops against the SDK in this working tree. Each has its own version, changelog, and release, and the provider's published metadata depends on a version range of the SDK from PyPI, not on this repository.
samples/ and profiling/ are deliberately not workspace members. They install the packages the way an application does.
make install # uv sync, every package
make hooks # pre-push hook that runs make check-all
make check # lint, typecheck, test: the fast loop
make check-all # everything CI runsTargets that run per package take PACKAGES, so make test PACKAGES=configdirector-server-sdk
runs one suite.
The checks live in the Makefile. CI and the pre-push hook only call make targets,
so add new checks there rather than in either of them.
The SDK reports an SDK name and version in the User-Agent header and in telemetry. A package
built on the SDK reports its own, without the SDK accepting an identity from its caller:
configdirector._wrappers.Wrapper is a closed list of the packages allowed to, each mapped to the
distribution whose installed version the SDK reads for itself. Adding a wrapper package means
adding a member there, releasing the SDK, and adding the new name to deprecated-sdk-versions.ts
in the core API.
Each package is released on its own, and the steps are the same for both. The version lives in exactly one place per package, which Hatch reads the package version from:
| Package | Version | Changelog | Workflow |
|---|---|---|---|
| configdirector-server-sdk | _version.py |
CHANGELOG.md | Release configdirector-server-sdk |
| configdirector-openfeature-server-provider | _version.py |
CHANGELOG.md | Release configdirector-openfeature-server-provider |
- In the package's changelog, rename
## [Unreleased]to## [X.Y.Z] - YYYY-MM-DDand open a fresh, empty## [Unreleased]above it. - Bump
__version__to match and merge both tomain. - Run the package's release workflow against
main. It is manual (workflow_dispatch) by design, and releases whatever versionmaincurrently declares. It builds the distributions withmake release-check, publishes this package's to TestPyPI, and then to PyPI, using trusted publishing rather than stored tokens. When TestPyPI is down, clearpublish-to-testpypito skip it and publish straight to PyPI.
The workflow tags the released commit <package>-vX.Y.Z, for example
configdirector-server-sdk-v1.2.0, only after the upload to PyPI succeeds, and refuses to run
when that tag already exists. PyPI never accepts the same version twice, so bump the version and
go again instead. SDK releases up to 1.1.0 predate this and are tagged vX.Y.Z.
Trusted publishing is configured per package and per workflow file name, on both PyPI and TestPyPI. Renaming a release workflow means updating the publisher there first.
The provider's pyproject.toml names the oldest SDK version it works with. When the provider
starts using something new in the SDK, raise that floor and release the SDK first:
make release-check installs the provider's wheel from PyPI alone, and fails while the SDK
version it needs is not published.
The samples pin a released package from PyPI, so they pick up a new release on their own. Raise a floor only when a sample starts using an API the older release lacks, and only once that release resolves on PyPI.
make samples only checks the sample groups listed in RELEASED_SAMPLE_GROUPS in the Makefile.
Add a package's group there once its first release resolves on PyPI; until then
make samples-local is what checks its samples.