Skip to content

ci: publish the package to PyPI and attach it to the release - #69

Merged
luomaofu merged 2 commits into
mainfrom
ci/publish-to-pypi
Oct 16, 2026
Merged

luomaofu merged 2 commits into
mainfrom
ci/publish-to-pypi

Conversation

@yang-dong-yd

Copy link
Copy Markdown
Contributor

Summary

The release workflow was still the source-only stub synced from repo-template:
it versioned, tagged and opened a GitHub release, but shipped no package — while
the README has been telling readers the package is not on PyPI yet. This PR adds
the two jobs the template provides for a repository that publishes, so a merge to
main ends with the SDK on PyPI and the same two files on the release.

PyPI has to be told about this repository before this merges — see below.

Before merging

Register a pending publisher at https://pypi.org/manage/account/publishing/:

Field Value
PyPI project name litegrip
Owner nexform-tech
Repository name litegrip-python
Workflow name release.yml
Environment name (leave empty)

Until that exists the publish job is refused and goes red. No secret is needed
and none should be created: the job authenticates with a short-lived OIDC token,
so there is no long-lived credential to leak or rotate.

litegrip is free on PyPI today, and it is the name pyproject.toml and the
README already use. The first release after this merges publishes v1.2.0 or
v1.1.2, whichever the merge prefix earns.

Changes

  • release.yml — new publish job: builds the sdist and wheel, uploads both to
    PyPI through Trusted Publishing.
  • release.yml — new package job: attaches the same two files to the GitHub
    release. It repeats the build instead of sharing it with publish on purpose;
    the template's jobs are independent siblings, and coupling them would mean
    deleting one breaks the other.
  • release.yml — both jobs rewrite the version from the tag in the workspace
    only, then assert the rewrite before building. A sed that matched nothing
    would otherwise build 0.0.0, the placeholder, and publish a version nobody
    chose.
  • ci.yml — build the package on pull requests. This is the second commit and can
    be dropped on its own if you would rather not have it.

litegrip.__version__ needs no second rewrite step, because it reads the installed
distribution metadata rather than repeating the number. The wheel therefore cannot
disagree with itself.

Testing

Replayed against a copy of this tree at HEAD, with a stand-in tag v1.2.0:

Command Result
python3 -m unittest discover -s tests -t tests Ran 466 tests in 11.446s — OK (skipped=12)
the jobs' version rewrite, then python -m build litegrip-1.2.0.tar.gz, litegrip-1.2.0-py3-none-any.whl
install that wheel, then litegrip.__version__ 1.2.0, matching the wheel metadata and the tag

The assertion was exercised on its failure path too: with the version line
removed, the step exits 1 rather than building the placeholder.

Not tested here: the upload itself. It cannot run before the pending publisher
exists, and it cannot run before a tag exists.

Issues

None — no open issue in this repository covers it. README.md line 24 says the
package is not on PyPI yet, which stops being true at the first publish; it is
left alone here because it is accurate until then, and is worth updating in the
pull request that follows the first release.

The release workflow was the source-only stub: it tagged and created the
GitHub release but shipped no package. Add the two jobs the template
provides for a repository that publishes.

`publish` uploads the sdist and the wheel to PyPI through Trusted
Publishing (OIDC), so this repository stores no API token at all.
`package` attaches the same two files to the GitHub release.

Both jobs rewrite the version from the tag inside the workspace, because
semantic-release never commits it back (AGENTS.md §3), and assert the
rewrite before building: a sed that matched nothing would otherwise
build 0.0.0, the placeholder. `litegrip.__version__` needs no equivalent
step, because it reads the installed distribution metadata, so the wheel
cannot disagree with itself.
The release workflow only builds after a merge to the default branch, by
which point semantic-release has already created the tag and the GitHub
release. A build that fails there leaves a version that exists as a tag
and nowhere else, and that number cannot be reused.

Build in the pull request gate as well, so a broken pyproject.toml is
stopped before the merge. The version is deliberately left alone here:
what this checks is that the tree as committed builds.
@luomaofu
luomaofu merged commit 25ecacd into main Oct 16, 2026
1 check passed
@luomaofu
luomaofu deleted the ci/publish-to-pypi branch October 16, 2026 11:41
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