Skip to content

Version packages from git tags and publish with trusted publishing - #8

Merged
bruno-f-cruz merged 2 commits into
refactor-unified-apifrom
packaging-and-release-ci
Jul 24, 2026
Merged

Version packages from git tags and publish with trusted publishing#8
bruno-f-cruz merged 2 commits into
refactor-unified-apifrom
packaging-and-release-ci

Conversation

@glopesdev

Copy link
Copy Markdown
Contributor

This branch picks up the four packaging and release items left from the first review round, so that versions come from git tags rather than being written into files, and a release publishes without any commit back to the default branch.

uv stays the resolver, locker, workspace manager, and build frontend. Only the build backend changes.

Versioning from git tags

All six workspace packages now build with the setuptools backend and take their version from setuptools-scm. Each sub-package sets root to ../../.. so all of them resolve the same repository root, which means one tag versions the whole set in lockstep. A build of this branch reports 0.1.dev286+g9a71d40c2 for all six, replacing the previous static 0.0.0, 0.4.0, and 0.1.0 values that had drifted apart.

No version_file is generated, so anything needing the version at runtime should read it through importlib.metadata.

The setuptools floor is >=77 rather than the more usual >=64. Release 77 is the first with PEP 639 support, and both harp and harp-protocol already set license to the SPDX expression MIT, with license-files declared on the umbrella. An older setuptools would not produce that metadata as declared. The built umbrella wheel carries metadata version 2.4, a License-Expression of MIT, and LICENSE under dist-info/licenses/.

Type checking

pyright replaces ty in the dev group and in CI, keeping the same scope as before, which is the four package source trees with tests excluded, on Python 3.11.

typeCheckingMode is standard. Fifteen of the individual rule escalations used in aeon_api are adopted alongside it and all pass with no source changes. Two escalations from that repo are left out. reportPrivateUsage reports 57 errors, because the payload, register, and device code deliberately reaches across private members within the package family, and reportUnnecessaryComparison flags two intentional runtime guards against callers passing enum=None in defiance of the annotation. Two non-escalation settings are also left out, reportMissingImports set to none and useLibraryCodeForTypes set to false, so that missing imports stay reported and inlined dependency types stay in use.

Standard mode reports five errors on the tree as it stands, all at three sites that already carry ty: ignore comments. Those three become pyright: ignore[reportArgumentType]. Three further ty: ignore comments are removed outright, since pyright accepts the expressions they covered.

Release workflow

The prepare-release job is gone, together with the version-setting loop, the commit back to master, and the force-move of the release tag. With the version coming from the tag there is nothing left to write back.

build-release replaces it. The build passes the release tag to setuptools-scm through SETUPTOOLS_SCM_PRETEND_VERSION, so the published version is the tag by construction rather than inferred from history and then validated. Tag spellings normalize on the way through, with v1.0.0-rc1 arriving as 1.0.0rc1, and the one variable covers all six packages. Nothing is written back to the tree, so this replaces the version rewriting rather than reinstating a lighter form of it.

Checkout stays at its default depth, matching aeon_api. Setting the version explicitly is what makes that unconditionally correct, instead of resting on the fact that a release event happens to check out a tag.

One failure mode still warrants a check. Were a pyproject.toml to lose its tool.setuptools_scm table, setuptools-scm would not engage, the variable would be ignored, and the build would fall back to 0.0.0, a valid version that PyPI accepts without complaint. A single glob over dist catches that.

publish-to-pypi uses PyPI trusted publishing through a pypi environment instead of the PYPI_TOKEN secret. Declaring permissions on a job replaces the default set rather than adding to it, so the job requests contents: write alongside id-token: write, the former being what action-gh-release needs to attach the distributions to the release.

The docs job now deploys the tagged commit rather than master, so a release publishes documentation matching the released code. It is also the one job that sets fetch-depth to 0, because the git-authors plugin walks history to attribute pages and at the default depth of a single commit that attribution comes out empty.

The workflow file is renamed from pyharp.yml to harp.yml and its name from pyharp test suite to harp, matching the distribution it builds and the naming already applied elsewhere. Nothing referenced the old file name, and the job names are unchanged, so required status checks still match. The rename belongs with this change because a trusted publisher is bound to the workflow file name, and doing it now avoids configuring the five publishers twice.

Verification

Run locally on Windows against Python 3.13. codespell, ruff format --check, ruff check, and pyright are clean, 166 tests pass, and uv build --all-packages produces all 12 artifacts. Every wheel carries its py.typed without needing a package-data entry, because include-package-data defaults to true under pyproject configuration and the setuptools-scm file finder picks up tracked files. twine check passes on all distributions. Driving the build the way build-release does confirms both directions. A v0.5.0 tag yields 0.5.0 for all six packages and v1.0.0-rc1 yields 1.0.0rc1, while removing a tool.setuptools_scm table falls back to 0.0.0 and trips the check.

Before the first release

  • Trusted publishers configured on PyPI for organization harp-tech, repository pyharp, workflow harp.yml, environment pypi. Three of the five need pending publishers, since harp, harp-device, and harp-data do not exist on PyPI yet. harp-protocol and harp-serial are already published and can be configured directly.
  • If the repository is renamed, configure the publishers after the rename rather than before. A trusted publisher matches the repository and workflow file by literal name and does not follow a GitHub rename, so publishing would fail until each of the five is updated by hand.
  • A first tag of 0.5.0 or higher, since harp-protocol and harp-serial are already published at 0.4.0.
  • Removal of the PYPI_TOKEN secret, once a release has published successfully.

All six workspace packages build with the setuptools backend and take
their version from setuptools-scm, each pointing at the repository root
so one tag versions them in lockstep. The setuptools floor is 77, the
first release supporting the PEP 639 license expression that harp and
harp-protocol already declare. No version file is written, so runtime
lookups go through importlib.metadata.

The release job no longer sets versions in the tree, commits back to
master, or force-moves the release tag. It passes the release tag to
setuptools-scm through SETUPTOOLS_SCM_PRETEND_VERSION, fails if any
distribution falls back to 0.0.0, and publishes through PyPI trusted
publishing in a pypi environment rather than a token secret. The docs
job deploys from the tag and fetches full history for git-authors
attribution. The workflow is renamed to harp.yml after the distribution
it builds.

pyright replaces ty in the dev group and in CI, in standard mode, with
three ty suppressions in harp-protocol translated to pyright and three
more dropped.
@glopesdev
glopesdev requested a review from bruno-f-cruz July 24, 2026 23:23
Follows the default branch rename. Pushes to the default branch trigger
the workflow again; without this the branch filter matches nothing.

@bruno-f-cruz bruno-f-cruz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense!

@bruno-f-cruz
bruno-f-cruz merged commit fa95371 into refactor-unified-api Jul 24, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants