Skip to content

Commit 68b0213

Browse files
authored
feat: produce publishable distribution archives (bazel-contrib#1019)
* feat: produce publishable distribution archives Fixes bazel-contrib#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.
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy