From 385b4ee1fefc2bffff98195218a7d2b0bd852295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Desgroppes?= Date: Wed, 21 Jan 2026 15:29:04 +0100 Subject: [PATCH] fix(test): make `packaging_test` work with Bazel 9 Bazel 9 flipped `--incompatible_strict_action_env` to `true` by default (bazelbuild/bazel#27670), which means tests no longer inherit `PATH` from the host environment. This breaks subprocess calls that rely on `PATH` lookup: ``` ==================== Test output for //distro:packaging_test: E. ====================================================================== ERROR: testBuild (__main__.PackagingTest.testBuild) ---------------------------------------------------------------------- Traceback (most recent call last): [...] build_result = subprocess.check_output(['bazel', 'build', '--enable_workspace', ':dummy_tar']) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [...] FileNotFoundError: [Errno 2] No such file or directory: 'bazel' ``` This change therefore adds `env_inherit = ["PATH"]` to that very test, which matches the behavior of earlier Bazel versions and is consistent with the presence of a "noci" tag. Additionally, Bazel 9 removed `WORKSPACE` support entirely (bazelbuild/bazel#26131), requiring `bzlmod` with `MODULE.bazel`: ``` ==================== Test output for //distro:packaging_test: [...] WARNING: --enable_bzlmod is set, but no MODULE.bazel file was found at the workspace root. Bazel will create an empty MODULE.bazel file. Please consider migrating your external dependencies from WORKSPACE to MODULE.bazel. For more details, please refer to https://github.com/bazelbuild/bazel/issues/18958. [...] ERROR: error loading package '': Unable to find package for @@[unknown repo 'not_named_rules_pkg' requested from @@]//pkg:tar.bzl: The repository '@@[unknown repo 'not_named_rules_pkg' requested from @@]' could not be resolved: No repository visible as '@not_named_rules_pkg' from main repository. [...] ERROR: Build did NOT complete successfully E. ====================================================================== ERROR: testBuild (__main__.PackagingTest.testBuild) ---------------------------------------------------------------------- [...] build_result = subprocess.check_output(['bazel', 'build'] + bazel_flags + [':dummy_tar']) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [...] subprocess.CalledProcessError: Command '['bazel', 'build', '--enable_workspace', ':dummy_tar']' returned non-zero exit status 1. ``` The test now detects the Bazel version at runtime and generates the appropriate setup: - Bazel 9+: `MODULE.bazel`, with `bazel_dep` and `archive_override`, - earlier versions, as before: `WORKSPACE`, with `http_archive` and `--enable_workspace` flag. For good measure, the change also addresses a leftover TODO by replacing the `tar` subprocess invocation with pure Python code (as otherwise done in the repo). --- distro/BUILD | 1 + distro/packaging_test.py | 53 +++++++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/distro/BUILD b/distro/BUILD index 5d3cc43c..d105f560 100644 --- a/distro/BUILD +++ b/distro/BUILD @@ -98,6 +98,7 @@ py_test( ":small_module", "//:standard_package", ], + env_inherit = ["PATH"], imports = [".."], local = True, python_version = "PY3", diff --git a/distro/packaging_test.py b/distro/packaging_test.py index 61f796d5..f1146256 100644 --- a/distro/packaging_test.py +++ b/distro/packaging_test.py @@ -17,6 +17,7 @@ import os import re import subprocess +import tarfile import unittest from python.runfiles import runfiles @@ -57,7 +58,8 @@ def testBuild(self): tempdir = os.path.join(os.environ['TEST_TMPDIR'], 'build') if not os.path.exists(tempdir): os.makedirs(tempdir) - with open(os.path.join(tempdir, 'WORKSPACE'), 'w') as workspace: + filename, setup_lines, bazel_flags = self._select_bazel_supported_setup() + with open(os.path.join(tempdir, filename), 'w') as setup: file_name = release_tools.package_basename(self.source_repo, self.version) # The code looks wrong, but here is why it is correct. # - Rlocation requires '/' as path separators, not os.path.sep. @@ -65,18 +67,11 @@ def testBuild(self): local_path = self.data_files.Rlocation( 'rules_pkg/distro/' + file_name).replace('/', os.path.sep) sha256 = release_tools.get_package_sha256(local_path) - workspace_content = '\n'.join(( - 'workspace(name = "test_rules_pkg_packaging")', - release_tools.workspace_content( - 'file://%s' % local_path, self.source_repo, sha256, - rename_repo=self.dest_repo, - deps_method='rules_pkg_dependencies' - ) - )) - workspace.write(workspace_content) + setup_content = '\n'.join(setup_lines(local_path, sha256)) + setup.write(setup_content) if _VERBOSE: - print('=== WORKSPACE ===') - print(workspace_content) + print(f'=== {filename} ===') + print(setup_content) # We do a little dance of renaming *.tpl to *, mostly so that we do not # have a BUILD file in testdata, which would create a package boundary. @@ -91,15 +86,39 @@ def CopyTestFile(source_name, dest_name): CopyTestFile('BUILD.tpl', 'BUILD') os.chdir(tempdir) - build_result = subprocess.check_output(['bazel', 'build', '--enable_workspace', ':dummy_tar']) + build_result = subprocess.check_output(['bazel', 'build'] + bazel_flags + [':dummy_tar']) if _VERBOSE: print('=== Build Result ===') print(build_result) - # TODO(aiuto): Find tar in a disciplined way - content = subprocess.check_output( - ['tar', 'tzf', 'bazel-bin/dummy_tar.tar.gz']) - self.assertEqual(b'etc/\netc/BUILD\n', content) + with tarfile.open('bazel-bin/dummy_tar.tar.gz', 'r') as tar: + self.assertEqual(['etc', 'etc/BUILD'], tar.getnames()) + + def _select_bazel_supported_setup(self): + output = subprocess.check_output(['bazel', 'version'], text=True) + major_version = re.search(r'Build label:\s+(\d+)', output) + if major_version and int(major_version.group(1)) >= 9: + return 'MODULE.bazel', self._module_bazel_lines, [] + return 'WORKSPACE', self._workspace_lines, ['--enable_workspace'] + + def _module_bazel_lines(self, local_path, sha256): + return ( + 'module(name = "test_rules_pkg_packaging")', + f'bazel_dep(name = "{self.source_repo}", version = "{self.version}", repo_name = "{self.dest_repo}")', + f'archive_override(module_name = "{self.source_repo}", sha256 = "{sha256}", url = "file://{local_path}")', + ) + + def _workspace_lines(self, local_path, sha256): + return ( + 'workspace(name = "test_rules_pkg_packaging")', + release_tools.workspace_content( + url=f'file://{local_path}', + repo=self.source_repo, + sha256=sha256, + rename_repo=self.dest_repo, + deps_method='rules_pkg_dependencies', + ), + ) if __name__ == '__main__':