Stop hard-coding default Xcode version (#1802)
The script now simply uses the oldest installed Xcode version if no
specific version was requested or if the requested version isn't
installed.
Progress towards
https://github.com/bazelbuild/continuous-integration/issues/1708
diff --git a/buildkite/bazelci.py b/buildkite/bazelci.py
index d74a16e..6612d84 100755
--- a/buildkite/bazelci.py
+++ b/buildkite/bazelci.py
@@ -553,8 +553,6 @@
# release platform for all Linux downstream tests.
LINUX_BINARY_PLATFORM = "centos7_java11_devtoolset10"
-# Maps major MacOS version numbers to the Xcode version that should be activated on that particular OS
-DEFAULT_XCODE_VERSIONS_PER_OS = {12: ["13.0"], 13: ["14.2", "14.3"]}
XCODE_VERSION_REGEX = re.compile(r"^\d+\.\d+(\.\d+)?$")
XCODE_VERSION_OVERRIDES = {"10.2.1": "10.3", "11.2": "11.2.1", "11.3": "11.3.1"}
@@ -1473,52 +1471,28 @@
shutil.rmtree(tmpdir)
-def get_default_xcode_versions():
- # Cannot use platform.mac_ver() since it returns 10.16 on both 12.x and 13.x
- macos = execute_command_and_get_output(["sw_vers", "-productVersion"], print_output=False)
- major = int(macos.split(".")[0])
- return DEFAULT_XCODE_VERSIONS_PER_OS.get(major, ["13.0"]) # we use 13.0 due to legacy reasons
-
-
def activate_xcode(task_config):
- all_default_xcode_versions = get_default_xcode_versions()
supported_versions = sorted(
# Stripping "Xcode" prefix and ".app" suffix from e.g. "Xcode12.0.1.app" leaves just the version number.
[os.path.basename(x)[5:-4] for x in glob("/Applications/Xcode*.app")],
- reverse=True,
)
+ if not supported_versions:
+ raise BuildkiteInfraException("Could not find a valid Xcode installation.")
- default_xcode_version = "13.0"
- for v in all_default_xcode_versions:
- if v in supported_versions:
- default_xcode_version = v
- break
-
- # Get the Xcode version from the config.
- wanted_xcode_version = task_config.get("xcode_version", default_xcode_version)
- print_collapsed_group(":xcode: Activating Xcode {}...".format(wanted_xcode_version))
-
- # Ensure it's a valid version number.
- if not isinstance(wanted_xcode_version, str):
- raise BuildkiteException(
- "Version number '{}' is not a string. Did you forget to put it in quotes?".format(
- wanted_xcode_version
- )
- )
- if not XCODE_VERSION_REGEX.match(wanted_xcode_version):
- raise BuildkiteException(
- "Invalid Xcode version format '{}', must match the format X.Y[.Z].".format(
- wanted_xcode_version
- )
- )
+ # Get the Xcode version from the config. Can be None.
+ wanted_xcode_version = get_requested_xcode_version(task_config)
# This is used to replace e.g. 11.2 with 11.2.1 without having to update all configs.
xcode_version = XCODE_VERSION_OVERRIDES.get(wanted_xcode_version, wanted_xcode_version)
- # This falls back to a default version if the selected version is not available.
+ # Default to the oldest installed version if no version was requested
+ # or the requested version is not installed.
if xcode_version not in supported_versions:
- xcode_version = default_xcode_version
- if xcode_version != wanted_xcode_version:
+ xcode_version = supported_versions[0]
+
+ if not wanted_xcode_version or wanted_xcode_version == xcode_version:
+ print_collapsed_group(":xcode: Activating Xcode {}...".format(xcode_version))
+ else:
print_collapsed_group(
":xcode: Fixed Xcode version: {} -> {}...".format(wanted_xcode_version, xcode_version)
)
@@ -1540,18 +1514,36 @@
]
)
- # Check that the selected Xcode version is actually installed on the host.
- xcode_path = "/Applications/Xcode{}.app".format(xcode_version)
- if not os.path.exists(xcode_path):
- raise BuildkiteException("Xcode not found at '{}'.".format(xcode_path))
-
# Now activate the specified Xcode version and let it install its required components.
# The CI machines have a sudoers config that allows the 'buildkite' user to run exactly
# these two commands, so don't change them without also modifying the file there.
+ xcode_path = "/Applications/Xcode{}.app".format(xcode_version)
execute_command(["/usr/bin/sudo", "/usr/bin/xcode-select", "--switch", xcode_path])
execute_command(["/usr/bin/sudo", "/usr/bin/xcodebuild", "-runFirstLaunch"])
+def get_requested_xcode_version(task_config):
+ wanted_xcode_version = task_config.get("xcode_version")
+ if not wanted_xcode_version:
+ return None
+
+ # Ensure it's a valid version number.
+ if not isinstance(wanted_xcode_version, str):
+ raise BuildkiteException(
+ "Version number '{}' is not a string. Did you forget to put it in quotes?".format(
+ wanted_xcode_version
+ )
+ )
+ if not XCODE_VERSION_REGEX.match(wanted_xcode_version):
+ raise BuildkiteException(
+ "Invalid Xcode version format '{}', must match the format X.Y[.Z].".format(
+ wanted_xcode_version
+ )
+ )
+
+ return wanted_xcode_version
+
+
def get_bazelisk_cache_directory():
# The path relies on the behavior of Go's os.UserCacheDir()
# and of the Go version of Bazelisk.