feat: wheel publishing (#1015)
feat: add a .publish target to py_wheel macro
diff --git a/docs/packaging.md b/docs/packaging.md
index a7a65ab..b244b42 100755
--- a/docs/packaging.md
+++ b/docs/packaging.md
@@ -121,7 +121,7 @@
## py_wheel
<pre>
-py_wheel(<a href="#py_wheel-name">name</a>, <a href="#py_wheel-kwargs">kwargs</a>)
+py_wheel(<a href="#py_wheel-name">name</a>, <a href="#py_wheel-twine">twine</a>, <a href="#py_wheel-kwargs">kwargs</a>)
</pre>
Builds a Python Wheel.
@@ -168,6 +168,31 @@
)
```
+To publish the wheel to Pypi, the twine package is required.
+rules_python doesn't provide twine itself, see https://github.com/bazelbuild/rules_python/issues/1016
+However you can install it with pip_parse, just like we do in the WORKSPACE file in rules_python.
+
+Once you've installed twine, you can pass its label to the `twine` attribute of this macro,
+to get a "[name].publish" target.
+
+Example:
+
+```python
+py_wheel(
+ name = "my_wheel",
+ twine = "@publish_deps_twine//:pkg",
+ ...
+)
+```
+
+Now you can run a command like the following, which publishes to https://test.pypi.org/
+
+```sh
+% TWINE_USERNAME=__token__ TWINE_PASSWORD=pypi-*** \
+ bazel run --stamp --embed_label=1.2.4 -- \
+ //path/to:my_wheel.publish --repository testpypi
+```
+
**PARAMETERS**
@@ -175,6 +200,7 @@
| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="py_wheel-name"></a>name | A unique name for this target. | none |
+| <a id="py_wheel-twine"></a>twine | A label of the external location of the py_library target for twine | <code>None</code> |
| <a id="py_wheel-kwargs"></a>kwargs | other named parameters passed to the underlying [py_wheel rule](#py_wheel_rule) | none |
diff --git a/python/packaging.bzl b/python/packaging.bzl
index 9274579..1984eb7 100644
--- a/python/packaging.bzl
+++ b/python/packaging.bzl
@@ -68,7 +68,7 @@
},
)
-def py_wheel(name, **kwargs):
+def py_wheel(name, twine = None, **kwargs):
"""Builds a Python Wheel.
Wheels are Python distribution format defined in https://www.python.org/dev/peps/pep-0427/.
@@ -113,16 +113,63 @@
)
```
+ To publish the wheel to Pypi, the twine package is required.
+ rules_python doesn't provide twine itself, see https://github.com/bazelbuild/rules_python/issues/1016
+ However you can install it with pip_parse, just like we do in the WORKSPACE file in rules_python.
+
+ Once you've installed twine, you can pass its label to the `twine` attribute of this macro,
+ to get a "[name].publish" target.
+
+ Example:
+
+ ```python
+ py_wheel(
+ name = "my_wheel",
+ twine = "@publish_deps_twine//:pkg",
+ ...
+ )
+ ```
+
+ Now you can run a command like the following, which publishes to https://test.pypi.org/
+
+ ```sh
+ % TWINE_USERNAME=__token__ TWINE_PASSWORD=pypi-*** \\
+ bazel run --stamp --embed_label=1.2.4 -- \\
+ //path/to:my_wheel.publish --repository testpypi
+ ```
+
Args:
name: A unique name for this target.
+ twine: A label of the external location of the py_library target for twine
**kwargs: other named parameters passed to the underlying [py_wheel rule](#py_wheel_rule)
"""
+ _dist_target = "{}.dist".format(name)
py_wheel_dist(
- name = "{}.dist".format(name),
+ name = _dist_target,
wheel = name,
out = kwargs.pop("dist_folder", "{}_dist".format(name)),
)
_py_wheel(name = name, **kwargs)
+ if twine:
+ if not twine.endswith(":pkg"):
+ fail("twine label should look like @my_twine_repo//:pkg")
+ twine_main = twine.replace(":pkg", ":rules_python_wheel_entry_point_twine.py")
+
+ # TODO: use py_binary from //python:defs.bzl after our stardoc setup is less brittle
+ # buildifier: disable=native-py
+ native.py_binary(
+ name = "{}.publish".format(name),
+ srcs = [twine_main],
+ args = [
+ "upload",
+ "$(rootpath :{})/*".format(_dist_target),
+ ],
+ data = [_dist_target],
+ imports = ["."],
+ main = twine_main,
+ deps = [twine],
+ )
+
py_wheel_rule = _py_wheel
diff --git a/python/runfiles/BUILD.bazel b/python/runfiles/BUILD.bazel
index 19d7804..3a93d40 100644
--- a/python/runfiles/BUILD.bazel
+++ b/python/runfiles/BUILD.bazel
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("//python:defs.bzl", "py_binary", "py_library")
+load("//python:defs.bzl", "py_library")
load("//python:packaging.bzl", "py_wheel")
filegroup(
@@ -45,26 +45,9 @@
distribution = "bazel_runfiles",
homepage = "https://github.com/bazelbuild/rules_python",
strip_path_prefixes = ["python"],
+ twine = "@publish_deps_twine//:pkg",
# this can be replaced by building with --stamp --embed_label=1.2.3
version = "{BUILD_EMBED_LABEL}",
visibility = ["//visibility:public"],
deps = [":runfiles"],
)
-
-# TODO(alexeagle): carry forward #1015 to make this part of the py_wheel macro
-# Typical command-line to run this:
-# TWINE_USERNAME=__token__ TWINE_PASSWORD=pypi-*** \
-# bazel run --stamp --embed_label=1.2.4 -- \
-# //python/runfiles:wheel.publish --repository testpypi
-py_binary(
- name = "wheel.publish",
- srcs = ["@publish_deps_twine//:rules_python_wheel_entry_point_twine.py"],
- args = [
- "upload",
- "$(rootpath :wheel.dist)/*",
- ],
- data = [":wheel.dist"],
- imports = ["."],
- main = "@publish_deps_twine//:rules_python_wheel_entry_point_twine.py",
- deps = ["@publish_deps_twine//:pkg"],
-)