Skip to content

Commit

Permalink
feat: add a .publish target to py_wheel macro
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeagle committed Feb 13, 2023
1 parent aef1abf commit 2adab61
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 24 deletions.
28 changes: 27 additions & 1 deletion docs/packaging.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 49 additions & 3 deletions python/packaging.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Public API for for building wheels."""

load("//python/private:py_package.bzl", "py_package_lib")
Expand Down Expand Up @@ -68,7 +67,7 @@ This also has the advantage that stamping information is included in the wheel's
},
)

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/.
Expand Down Expand Up @@ -113,16 +112,63 @@ def py_wheel(name, **kwargs):
)
```
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
21 changes: 20 additions & 1 deletion python/private/py_wheel.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

"Implementation of py_wheel rule"

load("@assemblyai//assemblyai:py_wheel.bzl", "deps_collector_aspect", "get_pip_dependencies")
load("@assemblyai//assemblyai:requirements.bzl", "get_packages")
load("//python/private:stamp.bzl", "is_stamping_enabled")
load(":py_package.bzl", "py_package_lib")

Expand Down Expand Up @@ -272,7 +274,12 @@ def _py_wheel_impl(ctx):

if ctx.attr.python_requires:
metadata_contents.append("Requires-Python: %s" % ctx.attr.python_requires)
for requirement in ctx.attr.requires:
if ctx.attr.auto_add_dependencies:
pip_dependencies = get_pip_dependencies(ctx)
else:
pip_dependencies = ctx.attr.requires

for requirement in pip_dependencies:
metadata_contents.append("Requires-Dist: %s" % requirement)

for option, option_requirements in sorted(ctx.attr.extra_requires.items()):
Expand Down Expand Up @@ -359,7 +366,15 @@ py_wheel_lib = struct(
implementation = _py_wheel_impl,
attrs = _concat_dicts(
{
"auto_add_dependencies": attr.bool(
doc = "Automatically add dependencies to the wheel.",
default = False,
),
"dep_blacklist": attr.string_list(
doc = "Dep path root blacklist; only keep deps that do not start with these roots.",
),
"deps": attr.label_list(
aspects = [deps_collector_aspect],
doc = """\
Targets to be included in the distribution.
Expand All @@ -371,6 +386,10 @@ Note it's usually better to package `py_library` targets and use
tries to locate `.runfiles` directory which is not packaged in the wheel.
""",
),
"packages_mapping": attr.string_dict(
doc = "Mapping of package names to their corresponding targets.",
default = get_packages(),
),
"_wheelmaker": attr.label(
executable = True,
cfg = "exec",
Expand Down
21 changes: 2 additions & 19 deletions python/runfiles/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -45,26 +45,9 @@ py_wheel(
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"],
)

0 comments on commit 2adab61

Please sign in to comment.