Skip to content

Commit ecf5a5b

Browse files
committed
Merge branch 'main' into fix/lockfile-inconsistency
2 parents cf76913 + 6babe59 commit ecf5a5b

File tree

8 files changed

+246
-10
lines changed

8 files changed

+246
-10
lines changed

CHANGELOG.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ A brief description of the categories of changes:
5252

5353
{#v0-0-0-fixed}
5454
### Fixed
55-
* (rules) Setting `--incompatible_python_disallow_native_rules` no longer
56-
causes rules_python rules to fail.
57-
([#2326](https://github.com/bazelbuild/rules_python/issues/2326).
55+
- Nothing yet
5856

5957
{#v0-0-0-added}
6058
### Added
@@ -64,6 +62,17 @@ A brief description of the categories of changes:
6462
### Removed
6563
- Nothing yet
6664

65+
{#v0-37-1}
66+
## [0.37.1] - 2024-10-22
67+
68+
[0.37.1]: https://github.com/bazelbuild/rules_python/releases/tag/0.37.1
69+
70+
{#v0-37-1-fixed}
71+
### Fixed
72+
* (rules) Setting `--incompatible_python_disallow_native_rules` no longer
73+
causes rules_python rules to fail
74+
([#2326](https://github.com/bazelbuild/rules_python/issues/2326)).
75+
6776
{#v0-37-0}
6877
## [0.37.0] - 2024-10-18
6978

python/private/local_runtime_repo_setup.bzl

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,26 @@ def define_local_runtime_toolchain_impl(
6161
cc_library(
6262
name = "_python_headers",
6363
# NOTE: Keep in sync with watch_tree() called in local_runtime_repo
64-
srcs = native.glob(["include/**/*.h"]),
64+
srcs = native.glob(
65+
["include/**/*.h"],
66+
# A Python install may not have C headers
67+
allow_empty = True,
68+
),
6569
includes = ["include"],
6670
)
6771

6872
cc_library(
6973
name = "_libpython",
7074
# Don't use a recursive glob because the lib/ directory usually contains
7175
# a subdirectory of the stdlib -- lots of unrelated files
72-
srcs = native.glob([
73-
"lib/*{}".format(lib_ext), # Match libpython*.so
74-
"lib/*{}*".format(lib_ext), # Also match libpython*.so.1.0
75-
]),
76+
srcs = native.glob(
77+
[
78+
"lib/*{}".format(lib_ext), # Match libpython*.so
79+
"lib/*{}*".format(lib_ext), # Also match libpython*.so.1.0
80+
],
81+
# A Python install may not have shared libraries.
82+
allow_empty = True,
83+
),
7684
hdrs = [":_python_headers"],
7785
)
7886

sphinxdocs/docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ is agnostic as to what is being documented.
1717
1818
starlark-docgen
1919
sphinx-bzl
20+
readthedocs
2021
```

sphinxdocs/docs/readthedocs.md

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
:::{default-domain} bzl
2+
:::
3+
4+
# Read the Docs integration
5+
6+
The {obj}`readthedocs_install` rule provides support for making it easy
7+
to build for, and deploy to, Read the Docs. It does this by having Bazel do
8+
all the work of building, and then the outputs are copied to where Read the Docs
9+
expects served content to be placed. By having Bazel do the majority of work,
10+
you have more certainty that the docs you generate locally will match what
11+
is created in the Read the Docs build environment.
12+
13+
Setting this up is conceptually simple: make the Read the Docs build call `bazel
14+
run` with the appropriate args. To do this, it requires gluing a couple things
15+
together, most of which can be copy/pasted from the examples below.
16+
17+
## `.readthedocs.yaml` config
18+
19+
In order for Read the Docs to call our custom commands, we have to use the
20+
advanced `build.commands` setting of the config file. This needs to do two key
21+
things:
22+
1. Install Bazel
23+
2. Call `bazel run` with the appropriate args.
24+
25+
In the example below, `npm` is used to install Bazelisk and a helper shell
26+
script, `readthedocs_build.sh` is used to construct the Bazel invocation.
27+
28+
The key purpose of the shell script it to set the
29+
`--@rules_python//sphinxdocs:extra_env` and
30+
`--@rules_python//sphinxdocs:extra_defines` flags. These are used to communicate
31+
`READTHEDOCS*` environment variables and settings to the Bazel invocation.
32+
33+
## BUILD config
34+
35+
In your build file, the {obj}`readthedocs_install` rule handles building the
36+
docs and copying the output to the Read the Docs output directory
37+
(`$READTHEDOCS_OUTPUT` environment variable). As input, it takes a `sphinx_docs`
38+
target (the generated docs).
39+
40+
## conf.py config
41+
42+
Normally, readthedocs will inject extra content into your `conf.py` file
43+
to make certain integration available (e.g. the version selection flyout).
44+
However, because our yaml config uses the advanced `build.commands` feature,
45+
those config injections are disabled and we have to manually re-enable them.
46+
47+
To do this, we modify `conf.py` to detect `READTHEDOCS=True` in the environment
48+
and perform some additional logic. See the example code below for the
49+
modifications.
50+
51+
Depending on your theme, you may have to tweak the conf.py; the example is
52+
based on using the sphinx_rtd_theme.
53+
54+
## Example
55+
56+
```
57+
# File: .readthedocs.yaml
58+
version: 2
59+
60+
build:
61+
os: "ubuntu-22.04"
62+
tools:
63+
nodejs: "19"
64+
commands:
65+
- env
66+
- npm install -g @bazel/bazelisk
67+
- bazel version
68+
# Put the actual action behind a shell script because it's
69+
# easier to modify than the yaml config.
70+
- docs/readthedocs_build.sh
71+
```
72+
73+
```
74+
# File: docs/BUILD
75+
76+
load("@rules_python//sphinxdocs:readthedocs.bzl.bzl", "readthedocs_install")
77+
readthedocs_install(
78+
name = "readthedocs_install",
79+
docs = [":docs"],
80+
)
81+
```
82+
83+
```
84+
# File: docs/readthedocs_build.sh
85+
86+
#!/bin/bash
87+
88+
set -eou pipefail
89+
90+
declare -a extra_env
91+
while IFS='=' read -r -d '' name value; do
92+
if [[ "$name" == READTHEDOCS* ]]; then
93+
extra_env+=("--@rules_python//sphinxdocs:extra_env=$name=$value")
94+
fi
95+
done < <(env -0)
96+
97+
# In order to get the build number, we extract it from the host name
98+
extra_env+=("--@rules_python//sphinxdocs:extra_env=HOSTNAME=$HOSTNAME")
99+
100+
set -x
101+
bazel run \
102+
--stamp \
103+
"--@rules_python//sphinxdocs:extra_defines=version=$READTHEDOCS_VERSION" \
104+
"${extra_env[@]}" \
105+
//docs:readthedocs_install
106+
```
107+
108+
```
109+
# File: docs/conf.py
110+
111+
# Adapted from the template code:
112+
# https://github.com/readthedocs/readthedocs.org/blob/main/readthedocs/doc_builder/templates/doc_builder/conf.py.tmpl
113+
if os.environ.get("READTHEDOCS") == "True":
114+
# Must come first because it can interfere with other extensions, according
115+
# to the original conf.py template comments
116+
extensions.insert(0, "readthedocs_ext.readthedocs")
117+
118+
if os.environ.get("READTHEDOCS_VERSION_TYPE") == "external":
119+
# Insert after the main extension
120+
extensions.insert(1, "readthedocs_ext.external_version_warning")
121+
readthedocs_vcs_url = (
122+
"http://github.com/bazelbuild/rules_python/pull/{}".format(
123+
os.environ.get("READTHEDOCS_VERSION", "")
124+
)
125+
)
126+
# The build id isn't directly available, but it appears to be encoded
127+
# into the host name, so we can parse it from that. The format appears
128+
# to be `build-X-project-Y-Z`, where:
129+
# * X is an integer build id
130+
# * Y is an integer project id
131+
# * Z is the project name
132+
_build_id = os.environ.get("HOSTNAME", "build-0-project-0-rules-python")
133+
_build_id = _build_id.split("-")[1]
134+
readthedocs_build_url = (
135+
f"https://readthedocs.org/projects/rules-python/builds/{_build_id}"
136+
)
137+
138+
html_context = {
139+
# This controls whether the flyout menu is shown. It is always false
140+
# because:
141+
# * For local builds, the flyout menu is empty and doesn't show in the
142+
# same place as for RTD builds. No point in showing it locally.
143+
# * For RTD builds, the flyout menu is always automatically injected,
144+
# so having it be True makes the flyout show up twice.
145+
"READTHEDOCS": False,
146+
"github_version": os.environ.get("READTHEDOCS_GIT_IDENTIFIER", ""),
147+
# For local builds, the github link won't work. Disabling it replaces
148+
# it with a "view source" link to view the source Sphinx saw, which
149+
# is useful for local development.
150+
"display_github": os.environ.get("READTHEDOCS") == "True",
151+
"commit": os.environ.get("READTHEDOCS_GIT_COMMIT_HASH", "unknown commit"),
152+
# Used by readthedocs_ext.external_version_warning extension
153+
# This is the PR number being built
154+
"current_version": os.environ.get("READTHEDOCS_VERSION", ""),
155+
}
156+
```

tests/integration/compile_pip_requirements/WORKSPACE

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2+
3+
http_archive(
4+
name = "protobuf",
5+
sha256 = "da288bf1daa6c04d03a9051781caa52aceb9163586bff9aa6cfb12f69b9395aa",
6+
strip_prefix = "protobuf-27.0",
7+
url = "https://github.com/protocolbuffers/protobuf/releases/download/v27.0/protobuf-27.0.tar.gz",
8+
)
9+
10+
http_archive(
11+
name = "rules_cc",
12+
sha256 = "d9bdd3ec66b6871456ec9c965809f43a0901e692d754885e89293807762d3d80",
13+
strip_prefix = "rules_cc-0.0.13",
14+
urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.13/rules_cc-0.0.13.tar.gz"],
15+
)
16+
117
local_repository(
218
name = "rules_python",
319
path = "../../..",

tests/integration/ignore_root_user_error/WORKSPACE

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2+
3+
http_archive(
4+
name = "protobuf",
5+
sha256 = "da288bf1daa6c04d03a9051781caa52aceb9163586bff9aa6cfb12f69b9395aa",
6+
strip_prefix = "protobuf-27.0",
7+
url = "https://github.com/protocolbuffers/protobuf/releases/download/v27.0/protobuf-27.0.tar.gz",
8+
)
9+
10+
http_archive(
11+
name = "rules_cc",
12+
sha256 = "d9bdd3ec66b6871456ec9c965809f43a0901e692d754885e89293807762d3d80",
13+
strip_prefix = "rules_cc-0.0.13",
14+
urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.13/rules_cc-0.0.13.tar.gz"],
15+
)
16+
117
local_repository(
218
name = "rules_python",
319
path = "../../..",
@@ -13,8 +29,6 @@ python_register_toolchains(
1329
python_version = "3.9",
1430
)
1531

16-
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
17-
1832
http_archive(
1933
name = "bazel_skylib",
2034
sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d",

tests/integration/pip_parse/WORKSPACE

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2+
3+
http_archive(
4+
name = "protobuf",
5+
sha256 = "da288bf1daa6c04d03a9051781caa52aceb9163586bff9aa6cfb12f69b9395aa",
6+
strip_prefix = "protobuf-27.0",
7+
url = "https://github.com/protocolbuffers/protobuf/releases/download/v27.0/protobuf-27.0.tar.gz",
8+
)
9+
10+
http_archive(
11+
name = "rules_cc",
12+
sha256 = "d9bdd3ec66b6871456ec9c965809f43a0901e692d754885e89293807762d3d80",
13+
strip_prefix = "rules_cc-0.0.13",
14+
urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.13/rules_cc-0.0.13.tar.gz"],
15+
)
16+
117
local_repository(
218
name = "rules_python",
319
path = "../../..",

tests/integration/py_cc_toolchain_registered/WORKSPACE

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2+
3+
http_archive(
4+
name = "protobuf",
5+
sha256 = "da288bf1daa6c04d03a9051781caa52aceb9163586bff9aa6cfb12f69b9395aa",
6+
strip_prefix = "protobuf-27.0",
7+
url = "https://github.com/protocolbuffers/protobuf/releases/download/v27.0/protobuf-27.0.tar.gz",
8+
)
9+
10+
http_archive(
11+
name = "rules_cc",
12+
sha256 = "d9bdd3ec66b6871456ec9c965809f43a0901e692d754885e89293807762d3d80",
13+
strip_prefix = "rules_cc-0.0.13",
14+
urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.13/rules_cc-0.0.13.tar.gz"],
15+
)
16+
117
local_repository(
218
name = "rules_python",
319
path = "../../..",

0 commit comments

Comments
 (0)