First public alpha release plan¶
Scheduling: 2026-09-04¶
This release procedure remains valid but is not the active implementation priority. Follow the developer experience execution plan for local product work. Its execution does not authorize release tags, public uploads, or protected-environment changes. Recheck all dated external facts and exact-candidate CI evidence when an operator resumes this procedure.
Objective¶
Publish streamt==0.1.0a1 as the first installable public alpha without
allowing an untested commit, a mismatched tag, or a locally built replacement
artifact to reach PyPI.
The upload is irreversible: Python package versions cannot be replaced after publication. Repository preparation may land before the release, but the tag, GitHub prerelease, trusted-publisher approval, and PyPI upload are one reviewed operator procedure.
Status — 2026-09-03¶
The source tree builds a valid wheel and source distribution, twine check
passes, and the wheel installs into an isolated environment. The installed CLI
reports the package version. Full CI run
33800184842
passed on commit d5f48945c54daec1f7843b282115ec8bd0881ec8, including the
Python matrix, installed-wheel checks, PostgreSQL 14/18, Conduktor Gateway
3.15, and the real DataHub v1.7.0 GMS gate.
Publication is not ready yet. There is no public streamt distribution, tag,
or GitHub release, and the repository has no pypi or testpypi GitHub
environment, immutable v* tag rule, or protected-main rule. The PyPI and
TestPyPI trusted publishers must be configured by an account authorized on
those services. Do not create a release or tag until the preparation and
TestPyPI rehearsal below pass for the exact candidate commit.
Release contract¶
- The first package version is the PEP 440 prerelease
0.1.0a1; the Git tag is exactlyv0.1.0a1, the GitHub release title is exactlyv0.1.0a1, and the GitHub release is marked as a prerelease. pyproject.toml, installed distribution metadata,streamt.__version__,streamt --version, the tag, and the release title all identify the same version.- The release commit is on
mainand the fullCIworkflow has succeeded for that exact commit SHA. Success for an ancestor or a different rebuild is not sufficient. - The package CI job builds and uploads one immutable wheel/sdist pair before exercising that same pair. Release verification and both publish jobs download that exact artifact from the successful exact-SHA CI run; the release workflow never rebuilds it.
- TestPyPI and PyPI use separate protected GitHub environments and separate trusted-publisher registrations. No long-lived package-index token is stored in GitHub.
- Every action in an OIDC-bearing job is pinned to a reviewed immutable commit. Metadata verification and default PyPI attestations remain enabled.
- Uploads never use
skip-existing. A duplicate version is an error, not an idempotent success. - The wheel and source distribution hashes recorded by the release workflow must match the files exposed by the package index and GitHub release.
- Installation documentation changes to the exact PyPI command only in a
follow-up documentation commit after production verification succeeds.
Until then,
maincontinues to describe the repository install as a preview.
External configuration¶
Create pending trusted publishers for the not-yet-created projects with these exact claims:
| Index | Owner | Repository | Workflow | GitHub environment |
|---|---|---|---|---|
| TestPyPI | conduktor |
streamt |
release.yml |
testpypi |
| PyPI | conduktor |
streamt |
release.yml |
pypi |
Create both GitHub environments with deployment restrictions that admit only
the exact release tag pattern. The production pypi environment requires a
human reviewer who did not create the tag. Branch ancestry checks supplement
these controls; they do not replace them.
Create a repository ruleset for refs/tags/v* that blocks tag updates and
deletion, and a protected-main ruleset requiring the complete CI workflow.
The workflow re-resolves annotated or lightweight tags after environment
approval, but only the immutable-tag rule closes the race after that check.
The official procedures are:
- https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/
- https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-pypi
Record no PyPI password, API token, OIDC token, or environment configuration in the repository or workflow evidence artifacts.
Implementation slices¶
Slice 1: package identity¶
- Set the candidate version to
0.1.0a1. - Add an executable version-coherence test covering source metadata, runtime metadata, installed metadata, and CLI output.
- Align Python support metadata with the tested release matrix.
- Add stable Issues and Changelog project URLs and verify the built metadata.
- Keep the Apache-2.0 license and packaged third-party notices in both distributions.
Slice 2: exact-SHA release workflow¶
- Retain isolated build and OIDC publish jobs with least privilege.
- Resolve the release tag to its commit and require a successful completed
CIworkflow whosehead_shais exactly that commit. - Reject a tag/version mismatch, a commit outside
main, missing exact-SHA CI success, or a regular rather than prerelease GitHub release. - Build wheel and sdist once in the package CI job, run
twine check, upload the immutable pair, then install and exercise those same files. - Resolve the successful exact-SHA CI run and download its artifact for release verification and each index upload; never rebuild during release.
- Add a manually triggered TestPyPI rehearsal whose input and workflow ref are the same existing exact tag and that cannot select production publication.
- Pin every action in the OIDC jobs by immutable SHA, reverify the tag after environment approval, and keep production publication restricted to the published GitHub prerelease event.
Slice 3: release documentation¶
- Replace stale numeric test badges and make README links valid on PyPI.
- Consolidate the accumulated unreleased notes under
0.1.0a1. - Make the packaged README safe for the immutable PyPI description before the
tag: show
python -m pip install "streamt==0.1.0a1"plus a clearly labeled pre-publication fallback. After production-index verification, update the live installation guide in a follow-up commit and use the equivalent exactpostgresextra where needed. - Keep the alpha limitations and unsupported deployment boundaries explicit.
- Mark the roadmap item complete only after the production index install has been independently verified.
Rehearsal and publication¶
- Merge the preparation commits and wait for full CI success on the exact candidate SHA.
- Create the signed or annotated
v0.1.0a1tag locally and verify that it resolves to that SHA. Push only that exact tag. - Run the manual TestPyPI workflow at the exact tag, for example
gh workflow run release.yml --ref v0.1.0a1 -f tag=v0.1.0a1. From a new environment, install with--index-url https://test.pypi.org/simple/while allowing dependencies from PyPI, then verify distribution metadata,streamt --version,streamt --help, and one offline example. - Compare TestPyPI hashes and attestations with the workflow evidence.
- Publish the GitHub prerelease for the same tag and approve the protected
pypienvironment after reviewing the exact SHA, version, CI run, and artifact hashes. - Install
streamt==0.1.0a1andstreamt[postgres]==0.1.0a1from production PyPI in separate clean environments. Verify metadata, CLI startup, the packaged schema set, and one offline export. - Attach the verified hashes to the GitHub prerelease and update the roadmap only after those production checks pass.
If TestPyPI or PyPI publication fails before upload, keep the version and tag unchanged while correcting configuration or workflow faults. If any file was accepted by an index, never rebuild or reuse that version; diagnose the published artifact and advance to a new PEP 440 prerelease when a code change is required.
Acceptance criteria¶
- An exact-SHA green CI run is machine-verified before either index receives a distribution.
- TestPyPI rehearsal and production publication use distinct protected OIDC identities and no stored package-index credential.
- Wheel and sdist install independently and expose the same version and CLI.
pip install "streamt==0.1.0a1"succeeds from production PyPI and the installed artifact passes the bounded smoke checks.- The GitHub prerelease, PyPI metadata, documentation, hashes, and attestations all identify the same immutable release.