Skip to content

Commit b6beaa8

Browse files
committed
pipeline: Convert build-using-self to python
In preparation for a Windows self-host pipeline, convert the build-using-self from a bash script to a python script to make it platform agnostic.
1 parent 314a274 commit b6beaa8

File tree

3 files changed

+174
-65
lines changed

3 files changed

+174
-65
lines changed

Utilities/build-using-self

+166-60
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,168 @@
1-
#!/bin/bash
2-
##===----------------------------------------------------------------------===##
3-
##
4-
## This source file is part of the Swift open source project
5-
##
6-
## Copyright (c) 2014-2022 Apple Inc. and the Swift project authors
7-
## Licensed under Apache License v2.0 with Runtime Library Exception
8-
##
9-
## See http://swift.org/LICENSE.txt for license information
10-
## See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
11-
##
12-
##===----------------------------------------------------------------------===##
13-
14-
set -eu
15-
16-
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
17-
root_dir="$(cd ${__dir}/.. && pwd)"
18-
19-
cd "${root_dir}/"
20-
echo "Current directory is ${PWD}"
21-
22-
CONFIGURATION=debug
23-
export SWIFTCI_IS_SELF_HOSTED=1
24-
25-
# Ensure SDKROOT is configured
26-
host=$(uname)
27-
if [ "${host}" == "Darwin" ]; then
28-
export SDKROOT=$(xcrun --show-sdk-path --sdk macosx)
29-
fi
30-
31-
set -x
32-
33-
env | sort
34-
35-
# Display toolchain version
36-
swift --version
37-
38-
# Perform package update in order to get the latest commits for the dependencies.
39-
swift package update
40-
swift build -c $CONFIGURATION
41-
swift test -c $CONFIGURATION --parallel
42-
43-
# Run the integration tests with just built SwiftPM.
44-
export SWIFTPM_BIN_DIR=$(swift build -c $CONFIGURATION --show-bin-path)
45-
(
46-
cd ${root_dir}/IntegrationTests
47-
# Perform package update in order to get the latest commits for the dependencies.
48-
swift package update
49-
$SWIFTPM_BIN_DIR/swift-test --parallel
1+
#!/usr/bin/env python3
2+
# ===----------------------------------------------------------------------===##
3+
#
4+
# This source file is part of the Swift open source project
5+
#
6+
# Copyright (c) 2025 Apple Inc. and the Swift project authors
7+
# Licensed under Apache License v2.0 with Runtime Library Exception
8+
#
9+
# See http://swift.org/LICENSE.txt for license information
10+
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
11+
#
12+
# ===----------------------------------------------------------------------===##
13+
14+
import argparse
15+
import enum
16+
import logging
17+
import os
18+
import pathlib
19+
import platform
20+
import sys
21+
22+
from helpers import call, call_output
23+
24+
logging.basicConfig(
25+
format=" | ".join(
26+
[
27+
# Prefix script name to the log in an attempt to avoid confusion when parsing logs
28+
f"{pathlib.Path(sys.argv[0]).name}",
29+
"%(asctime)s",
30+
"%(levelname)-8s",
31+
"%(module)s",
32+
"%(funcName)s",
33+
"Line:%(lineno)d",
34+
"%(message)s",
35+
]
36+
),
37+
level=logging.INFO,
5038
)
5139

52-
if [ "${host}" == "Darwin" ]; then
53-
echo "Current working directory is ${PWD}"
54-
echo "Bootstrapping with the XCBuild codepath..."
55-
${root_dir}/Utilities/bootstrap \
56-
build \
57-
--release \
58-
--verbose \
59-
--cross-compile-hosts macosx-arm64 \
60-
--skip-cmake-bootstrap \
61-
--swift-build-path "${SWIFTPM_BIN_DIR}/swift-build"
62-
fi
40+
41+
REPO_ROOT_PATH = pathlib.Path(__file__).parent.parent.resolve()
42+
43+
44+
class Configuration(str, enum.Enum):
45+
DEBUG = "debug"
46+
RELEASE = "release"
47+
48+
49+
def get_arguments() -> argparse.Namespace:
50+
parser = argparse.ArgumentParser(
51+
formatter_class=argparse.ArgumentDefaultsHelpFormatter
52+
)
53+
54+
parser.add_argument(
55+
"-v",
56+
"--verbose",
57+
dest="is_verbose",
58+
action="store_true",
59+
help="When set, prints verbose information.",
60+
)
61+
parser.add_argument(
62+
"-c",
63+
"--configuration",
64+
type=Configuration,
65+
dest="config",
66+
default="debug",
67+
choices=[e.value for e in Configuration],
68+
help="The configuraiton to use.",
69+
)
70+
71+
args = parser.parse_args()
72+
return args
73+
74+
75+
def log_environment() -> None:
76+
logging.info("Environment Variables")
77+
for key, value in sorted(os.environ.items()):
78+
logging.info(" --> %s=%r", key, value)
79+
80+
81+
def get_swiftpm_bin_dir(config: Configuration) -> pathlib.Path:
82+
swiftpm_bin_dir = pathlib.Path(
83+
call_output(["swift", "build", "--configuration", config, "--show-bin-path"])
84+
)
85+
logging.info("SwiftPM BIN DIR: %s", swiftpm_bin_dir)
86+
return swiftpm_bin_dir
87+
88+
89+
def is_on_darwin() -> bool:
90+
return platform.uname().system == "Darwin"
91+
92+
93+
def set_environment(*, config: Configuration) -> None:
94+
os.environ["SWIFTCI_IS_SELF_HOSTED"] = "1"
95+
96+
# Set the SWIFTPM_BIN_DIR path
97+
os.environ["SWIFTPM_BIN_DIR"] = str(get_swiftpm_bin_dir(config=config))
98+
99+
# Ensure SDKROOT is configure
100+
if is_on_darwin():
101+
sdk_root = call_output(["xcrun", "--show-sdk-path", "--sdk", "macosx"])
102+
logging.debug("macos sdk root = %r", sdk_root)
103+
os.environ["SDKROOT"] = sdk_root
104+
log_environment()
105+
106+
107+
def run_bootstrap(swiftpm_bin_dir: pathlib.Path) -> None:
108+
if is_on_darwin():
109+
logging.info("Current working directory is %s", pathlib.Path.cwd())
110+
logging.info("Bootstrapping with the XCBuild codepath...")
111+
call(
112+
[
113+
REPO_ROOT_PATH / "Utilities" / "bootstrap",
114+
"build",
115+
"--release",
116+
"--verbose",
117+
"--cross-compile-hosts",
118+
"macosx-arm64",
119+
"--skip-cmake-bootstrap",
120+
"--swift-build-path",
121+
(swiftpm_bin_dir / "swift-build").resolve(),
122+
]
123+
)
124+
125+
126+
def main() -> None:
127+
args = get_arguments()
128+
logging.getLogger().setLevel(logging.DEBUG if args.is_verbose else logging.INFO)
129+
logging.debug("Args: %r", args)
130+
131+
logging.info("Curent directory is %s", pathlib.Path.cwd())
132+
set_environment(config=args.config)
133+
134+
call(
135+
["swift", "--version"],
136+
cwd=REPO_ROOT_PATH,
137+
)
138+
call(
139+
["swift", "package", "update"],
140+
cwd=REPO_ROOT_PATH,
141+
)
142+
call(
143+
["swift", "build", "--configuration", args.config],
144+
cwd=REPO_ROOT_PATH,
145+
)
146+
call(
147+
["swift", "test", "--configuration", args.config, "--parallel"],
148+
cwd=REPO_ROOT_PATH,
149+
)
150+
151+
swiftpm_bin_dir = get_swiftpm_bin_dir(config=args.config)
152+
call(
153+
["swift", "package", "update"],
154+
cwd=(REPO_ROOT_PATH / "IntegrationTests"),
155+
)
156+
call(
157+
[
158+
str(swiftpm_bin_dir / "swift-test"),
159+
"--parallel",
160+
],
161+
cwd=REPO_ROOT_PATH / "IntegrationTests",
162+
)
163+
164+
run_bootstrap(swiftpm_bin_dir=swiftpm_bin_dir)
165+
166+
167+
if __name__ == "__main__":
168+
main()

Utilities/helpers.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,20 @@ def mkdir_p(path):
3737

3838
def call(cmd, cwd=None, verbose=False):
3939
"""Calls a subprocess."""
40-
logging.info("executing command >>> %s", ' '.join(cmd))
40+
logging.info("executing command >>> %r with cwd %s", ' '.join(cmd), cwd)
4141
try:
4242
subprocess.check_call(cmd, cwd=cwd)
4343
except subprocess.CalledProcessError as cpe:
44-
logging.debug("executing command >>> %s", ' '.join(cmd))
44+
logging.debug("executing command >>> %r with cwd %s", ' '.join(cmd), cwd)
4545
logging.error("Process failure: %s", str(cpe))
4646
raise cpe
4747

4848
def call_output(cmd, cwd=None, stderr=False, verbose=False):
4949
"""Calls a subprocess for its return data."""
50-
logging.info(' '.join(cmd))
50+
logging.info("executing command >>> %r with cwd %s", ' '.join(cmd), cwd)
5151
try:
5252
return subprocess.check_output(cmd, cwd=cwd, stderr=stderr, universal_newlines=True).strip()
5353
except subprocess.CalledProcessError as cpe:
54-
logging.debug(' '.join(cmd))
55-
logging.error(str(cpe))
54+
logging.debug("executing command >>> %r with cwd %s", ' '.join(cmd), cwd)
55+
logging.error("Process failure: %s", str(cpe))
5656
raise cpe

Utilities/python/requirements.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
black==24.10.0
2+
flake8==7.1.1
3+
mypy==1.14.1

0 commit comments

Comments
 (0)