8000 feat: produce publishable distribution archives (#1019) · bazel-contrib/rules_python@68b0213 · GitHub
[go: up one dir, main page]

Skip to content

Commit 68b0213

Browse files
authored
feat: produce publishable distribution archives (#1019)
* feat: produce publishable distribution archives Fixes #741 * fix: give unique names to dist/ folders by default
1 parent fa3e2d5 commit 68b0213

File tree

5 files changed

+90
-17
lines changed

5 files changed

+90
-17
lines changed

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ jobs:
1515
- name: Prepare workspace snippet
1616
run: .github/workflows/workspace_snippet.sh > release_notes.txt
1717
- name: Build wheel dist
18-
run: bazel build --stamp --embed_label=${{ env.GITHUB_REF_NAME }} //python/runfiles:wheel
18+
run: bazel build --stamp --embed_label=${{ env.GITHUB_REF_NAME }} //python/runfiles:wheel.dist
1919
- name: Publish runfiles package to PyPI
2020
uses: pypa/gh-action-pypi-publish@release/v1
2121
with:
2222
# Note, the PYPI_API_TOKEN was added on
2323
# https://github.com/bazelbuild/rules_python/settings/secrets/actions
2424
# and currently uses a token which authenticates as https://pypi.org/user/alexeagle/
2525
password: ${{ secrets.PYPI_API_TOKEN }}
26-
packages_dir: bazel-bin/python/runfiles
26+
packages_dir: bazel-bin/python/runfiles/dist
2727
- name: Release
2828
uses: softprops/action-gh-release@v1
2929
with:

docs/packaging.md

Lines changed: 27 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

python/packaging.bzl

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,43 @@ This rule is intended to be used as data dependency to py_wheel rule.
3131
attrs = py_package_lib.attrs,
3232
)
3333

34+
# Based on https://github.com/aspect-build/bazel-lib/tree/main/lib/private/copy_to_directory.bzl
35+
# Avoiding a bazelbuild -> aspect-build dependency :(
36+
def _py_wheel_dist_impl(ctx):
37+
dir = ctx.actions.declare_directory(ctx.attr.out)
38+
name_file = ctx.attr.wheel[PyWheelInfo].name_file
39+
cmds = [
40+
"mkdir -p \"%s\"" % dir.path,
41+
"""cp "{}" "{}/$(cat "{}")" """.format(ctx.files.wheel[0].path, dir.path, name_file.path),
42+
]
43+
ctx.actions.run_shell(
44+
inputs = ctx.files.wheel + [name_file],
45+
outputs = [dir],
46+
command = "\n".join(cmds),
47+
mnemonic = "CopyToDirectory",
48+
progress_message = "Copying files to directory",
49+
use_default_shell_env = True,
50+
)
51+
return [
52+
DefaultInfo(files = depset([dir])),
53+
]
54+
55+
py_wheel_dist = rule(
56+
doc = """\
57+
Prepare a dist/ folder, following Python's packaging standard practice.
58+
59+
See https://packaging.python.org/en/latest/tutorials/packaging-projects/#generating-distribution-archives
60+
which recommends a dist/ folder containing the wheel file(s), source distributions, etc.
61+
62+
This also has the advantage that stamping information is included in the wheel's filename.
63+
""",
64+
implementation = _py_wheel_dist_impl,
65+
attrs = {
66+
"out": attr.string(doc = "name of the resulting directory", mandatory = True),
67+
"wheel": attr.label(doc = "a [py_wheel rule](/docs/packaging.md#py_wheel_rule)", providers = [PyWheelInfo]),
68+
},
69+
)
70+
3471
def py_wheel(name, **kwargs):
3572
"""Builds a Python Wheel.
3673
@@ -80,15 +117,12 @@ def py_wheel(name, **kwargs):
80117
name: A unique name for this target.
81118
**kwargs: other named parameters passed to the underlying [py_wheel rule](#py_wheel_rule)
82119
"""
83-
_py_wheel(name = name, **kwargs)
120+
py_wheel_dist(
121+
name = "{}.dist".format(name),
122+
wheel = name,
123+
out = kwargs.pop("dist_folder", "{}_dist".format(name)),
124+
)
84125

85-
# TODO(alexeagle): produce an executable target like this:
86-
# py_publish_wheel(
87-
# name = "{}.publish".format(name),
88-
# wheel = name,
89-
# # Optional: override the label for a py_binary that runs twine
90-
# # https://twine.readthedocs.io/en/stable/
91-
# twine_bin = "//path/to:twine",
92-
# )
126+
_py_wheel(name = name, **kwargs)
93127

94128
py_wheel_rule = _py_wheel

python/private/py_wheel.bzl

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,23 @@ Stamped targets are not rebuilt unless their dependencies change.
< 8000 /code>
7373
),
7474
"version": attr.string(
7575
mandatory = True,
76-
doc = (
77-
"Version number of the package. Note that this attribute " +
78-
"supports stamp format strings (eg. `1.2.3-{BUILD_TIMESTAMP}`) " +
79-
"as well as 'make variables' (e.g. `1.2.3-$(VERSION)`)."
80-
),
76+
doc = """\
77+
Version number of the package.
78+
79+
Note that this attribute supports stamp format strings as well as 'make variables'.
80+
For example:
81+
- `version = "1.2.3-{BUILD_TIMESTAMP}"`
82+
- `version = "{BUILD_EMBED_LABEL}"`
83+
- `version = "$(VERSION)"`
84+
85+
Note that Bazel's output filename cannot include the stamp information, as outputs must be known
86+
during the analysis phase and the stamp data is available only during the action execution.
87+
88+
The [`py_wheel`](/docs/packaging.md#py_wheel) macro produces a `.dist`-suffix target which creates a
89+
`dist/` folder containing the wheel with the stamped name, suitable for publishing.
90+
91+
See [`py_wheel_dist`](/docs/packaging.md#py_wheel_dist) for more info.
92+
""",
8193
),
8294
"_stamp_flag": attr.label(
8395
doc = "A setting used to determine whether or not the `--stamp` flag is enabled",

python/runfiles/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ py_wheel(
4141
"License :: OSI Approved :: Apache Software License",
4242
],
4343
description_file = "README.md",
44+
dist_folder = "dist",
4445
distribution = "bazel_runfiles",
4546
homepage = "https://github.com/bazelbuild/rules_python",
4647
strip_path_prefixes = ["python"],

0 commit comments

Comments
 (0)
0