Skip to content

Commit 1af5a71

Browse files
CavRileyhjmjohnson
authored andcommitted
ENH: Add scripts to publish wheels and cached builds
1 parent e2a8e3b commit 1af5a71

File tree

9 files changed

+1922
-134
lines changed

9 files changed

+1922
-134
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ docs/_build
7373
.idea/*
7474
*.swp
7575
/itkVersion.py
76+
# PyPI credentials
77+
.pypirc
78+
7679
# pixi environments
7780
.pixi/*
7881
!.pixi/config.toml

.pypirc.example

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# .pypirc.example -- DO NOT commit real credentials
2+
# Copy to ~/.pypirc and fill in your token.
3+
#
4+
# Generate a token at: https://pypi.org/manage/account/token/
5+
# For TestPyPI: https://test.pypi.org/manage/account/token/
6+
#
7+
# Alternatively, set environment variables:
8+
# TWINE_USERNAME=__token__
9+
# TWINE_PASSWORD=pypi-<your-token>
10+
11+
[distutils]
12+
index-servers =
13+
pypi
14+
testpypi
15+
16+
[pypi]
17+
username = __token__
18+
password = pypi-YOUR-TOKEN-HERE
19+
20+
[testpypi]
21+
repository = https://test.pypi.org/legacy/
22+
username = __token__
23+
password = pypi-YOUR-TOKEN-HERE

README.md

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# ITK Python Package
22

33
This project configures pyproject.toml files and manages environmental
4-
variables needed to build ITK Python binary wheels on MacOS, Linux, and Windows platforms.
4+
variables needed to build ITK Python binary wheels on macOS, Linux, and Windows platforms.
55
Scripts are available for both [ITK infrastructure](https://github.com/insightSoftwareConsortium/ITK) and
66
ITK external module Python packages.
77

@@ -20,7 +20,7 @@ or at the [ITK GitHub homepage](https://github.com/insightSoftwareConsortium/ITK
2020
## Building Remote Modules with ITKPythonPackage
2121

2222
ITK reusable workflows are available to build and package Python wheels as
23-
part of Continuous Integration (CI) via Github Actions runners.
23+
part of Continuous Integration (CI) via GitHub Actions runners.
2424
Those workflows can handle the overhead of fetching, configuring, and
2525
running ITKPythonPackage build scripts for most ITK external modules.
2626
See [ITKRemoteModuleBuildTestPackageAction](https://github.com/InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction)
@@ -31,7 +31,7 @@ for more information.
3131
3232
For special cases where ITK reusable workflows are not a good fit,
3333
ITKPythonPackage scripts can be directly used to build Python wheels
34-
to target Windows, Linux, and MacOS platforms. See
34+
to target Windows, Linux, and macOS platforms. See
3535
below or the [ITKPythonPackage ReadTheDocs](https://itkpythonpackage.readthedocs.io/en/latest/Build_ITK_Module_Python_packages.html)
3636
documentation for more information on building wheels by hand.
3737

@@ -273,8 +273,43 @@ On Windows systems
273273

274274
To build caches for local use, you can run the `build_wheels.py` script with the `--build-itk-tarball-cache`
275275

276+
#### Publish Tarball Caches
277+
278+
To publish the tarball caches to a GitHub Release, you can run:
279+
280+
> [!NOTE]
281+
> This requires the `GH_TOKEN` environment variable to be set or `gh auth login` to have been run beforehand.
282+
> Tarballs are expected in the parent directory of `--build-dir-root` (POSIX `.tar.zst`) or inside it (Windows `.zip`).
283+
284+
```bash
285+
pixi run -e publish publish-tarball-cache --itk-package-version v6.0b02 --build-dir-root /path/to/build/root
286+
```
287+
288+
Users can also specify the GitHub repository to publish to using `--repo` (defaults to ITKPythonBuilds) and
289+
`--create-release` to create the release if it does not already exist.
290+
276291
</details>
277292

293+
To see how to publish wheels see this section:
294+
295+
<details>
296+
<summary><strong>Publishing Wheels</strong></summary>
297+
This repository contains a script for publishing wheels to PyPI and TestPyPI.
298+
299+
The script can be run with the pixi environment as such:
300+
301+
> [!NOTE]
302+
> This script assumes you have the `TWINE_USERNAME` and `TWINE_PASSWORD` environment variables set or the
303+
> `.pypirc` file configured on your machine. An example `.pypirc` can be seen in the root of this repository
304+
305+
```bash
306+
pixi run -e publish publish-wheels --dist-directory /path/to/dist/
307+
```
308+
309+
You can also optionally pass in `--test` to publish to TestPyPI for validation before uploading to production,
310+
`--repository-url` to specify a custom package index, or `--skip-existing` to skip already-uploaded wheels.
311+
312+
</details>
278313

279314
---
280315
## Frequently Asked Questions

docs/Build_ITK_Module_Python_packages.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,35 @@ Example output::
277277
Uploading to PyPI
278278
=================
279279

280+
Using the Publish Environment
281+
-----------------------------
282+
283+
ITKPythonPackage provides a ``publish`` Pixi environment with ``twine``
284+
pre-configured. Set your PyPI credentials (see ``.pypirc.example`` in the
285+
repository root) and run:
286+
287+
.. code-block:: bash
288+
289+
export TWINE_USERNAME=__token__
290+
export TWINE_PASSWORD=pypi-<your-token>
291+
292+
# Test on TestPyPI first
293+
pixi run -e publish publish-wheels \
294+
--dist-directory /path/to/module/dist \
295+
--test
296+
297+
# Then upload to production PyPI
298+
pixi run -e publish publish-wheels \
299+
--dist-directory /path/to/module/dist
300+
301+
Pass ``--skip-existing`` to skip already-uploaded wheels when re-running after
302+
a partial upload failure.
303+
280304
Manual Upload
281305
-------------
282306

307+
Alternatively, install and use ``twine`` directly.
308+
283309
Test on TestPyPI first::
284310

285311
pip install twine

docs/Build_ITK_Python_packages.rst

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,103 @@ Install and smoke-test a wheel directly from the ``dist/`` directory:
343343
python -c "import itk; print(itk.__version__)"
344344
345345
346+
Publishing
347+
==========
348+
349+
ITKPythonPackage provides a lightweight ``publish`` Pixi environment with
350+
`twine <https://twine.readthedocs.io/>`_ for uploading wheels to PyPI and the
351+
`GitHub CLI <https://cli.github.com/>`_ for uploading tarball caches to GitHub
352+
Releases. Install it with::
353+
354+
pixi install -e publish
355+
356+
357+
Publishing Wheels to PyPI
358+
-------------------------
359+
360+
The ``publish-wheels`` task validates wheel metadata with ``twine check`` and
361+
then uploads all ``.whl`` files from a ``dist/`` directory.
362+
363+
**Authentication** — set environment variables or configure ``~/.pypirc``
364+
(see ``.pypirc.example`` in the repository root):
365+
366+
.. code-block:: bash
367+
368+
export TWINE_USERNAME=__token__
369+
export TWINE_PASSWORD=pypi-<your-token>
370+
371+
Upload to **TestPyPI** first for validation:
372+
373+
.. code-block:: bash
374+
375+
pixi run -e publish publish-wheels \
376+
--dist-directory /path/to/dist \
377+
--test
378+
379+
Then upload to **production PyPI**:
380+
381+
.. code-block:: bash
382+
383+
pixi run -e publish publish-wheels \
384+
--dist-directory /path/to/dist
385+
386+
Additional options:
387+
388+
.. list-table::
389+
:header-rows: 1
390+
:widths: 30 70
391+
392+
* - Option
393+
- Description
394+
* - ``--test``
395+
- Upload to TestPyPI (``https://test.pypi.org/legacy/``)
396+
* - ``--repository-url``
397+
- Custom package index URL (overrides ``--test``)
398+
* - ``--skip-existing``
399+
- Skip already-uploaded wheels instead of failing
400+
401+
402+
Publishing Tarball Caches to GitHub Releases
403+
--------------------------------------------
404+
405+
The ``publish-tarball-cache`` task uploads ``.tar.zst`` (POSIX) and ``.zip``
406+
(Windows) build caches to a GitHub Release on the
407+
`ITKPythonBuilds <https://github.com/InsightSoftwareConsortium/ITKPythonBuilds>`_
408+
repository.
409+
410+
**Authentication** — set the ``GH_TOKEN`` environment variable or run
411+
``gh auth login`` beforehand.
412+
413+
.. code-block:: bash
414+
415+
pixi run -e publish publish-tarball-cache \
416+
--itk-package-version v6.0b02 \
417+
--build-dir-root /path/to/build \
418+
--create-release
419+
420+
Additional options:
421+
422+
.. list-table::
423+
:header-rows: 1
424+
:widths: 30 70
425+
426+
* - Option
427+
- Description
428+
* - ``--itk-package-version``
429+
- **(required)** Release tag name (e.g. ``v6.0b02``)
430+
* - ``--build-dir-root``
431+
- Root of the build directory; tarballs are found in its parent
432+
(POSIX ``.tar.zst``) or inside it (Windows ``.zip``)
433+
* - ``--repo``
434+
- Target GitHub repository (default: ``InsightSoftwareConsortium/ITKPythonBuilds``)
435+
* - ``--create-release``
436+
- Create the GitHub Release if it does not already exist
437+
438+
.. note::
439+
The ``--clobber`` flag is used internally so re-uploading a tarball for the
440+
same platform replaces the existing asset without manual cleanup.
441+
442+
346443
Troubleshooting
347444
===============
348445

0 commit comments

Comments
 (0)