diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 625466151e34de..6aa99928278294 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -414,6 +414,29 @@ jobs: - name: Build and test run: ./Android/android.py ci --fast-ci ${{ matrix.arch }}-linux-android + build-ios: + name: iOS + needs: build-context + if: needs.build-context.outputs.run-tests == 'true' + timeout-minutes: 60 + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + # GitHub recommends explicitly selecting the desired Xcode version: + # https://github.com/actions/runner-images/issues/12541#issuecomment-3083850140 + # This became a necessity as a result of + # https://github.com/actions/runner-images/issues/12541 and + # https://github.com/actions/runner-images/issues/12751. + - name: Select Xcode version + run: | + sudo xcode-select --switch /Applications/Xcode_16.4.app + + - name: Build and test + run: python3 Apple ci iOS --fast-ci --simulator 'iPhone 16e,OS=18.5' + build-wasi: name: 'WASI' needs: build-context @@ -723,6 +746,7 @@ jobs: - build-ubuntu-ssltests-awslc - build-ubuntu-ssltests-openssl - build-android + - build-ios - build-wasi - test-hypothesis - build-asan @@ -759,6 +783,7 @@ jobs: build-ubuntu-ssltests-awslc, build-ubuntu-ssltests-openssl, build-android, + build-ios, build-wasi, test-hypothesis, build-asan, diff --git a/Apple/__main__.py b/Apple/__main__.py index 96c2d34fbe0959..34744871f681ea 100644 --- a/Apple/__main__.py +++ b/Apple/__main__.py @@ -823,7 +823,7 @@ def test(context: argparse.Namespace, host: str | None = None) -> None: + [ "--", "test", - "--slow-ci" if context.slow else "--fast-ci", + f"--{context.ci_mode}-ci", "--single-process", "--no-randomize", # Timeout handling requires subprocesses; explicitly setting @@ -836,11 +836,39 @@ def test(context: argparse.Namespace, host: str | None = None) -> None: ) +def apple_sim_host(platform_name: str) -> str: + """Determine the native simulator target for this platform.""" + for _, slice_parts in HOSTS[platform_name].items(): + for host_triple in slice_parts: + parts = host_triple.split('-') + if parts[0] == platform.machine() and parts[-1] == "simulator": + return host_triple + + raise KeyError(platform_name) + + def ci(context: argparse.Namespace) -> None: - """The implementation of the "ci" command.""" + """The implementation of the "ci" command. + + In "Fast" mode, this compiles the build python, and the simulator for the + build machine's architecture; and runs the test suite with `--fast-ci` + configuration. + + In "Slow" mode, it compiles the build python, plus all candidate + architectures (both device and simulator); then runs the test suite with + `--slow-ci` configuration. + """ clean(context, "all") - build(context, host="all") - test(context, host="all") + if context.ci_mode == "slow": + # In slow mode, build and test the full XCframework + build(context, host="all") + test(context, host="all") + else: + # In fast mode, just build the simulator platform. + sim_host = apple_sim_host(context.platform) + build(context, host="build") + build(context, host=sim_host) + test(context, host=sim_host) def parse_args() -> argparse.Namespace: @@ -947,11 +975,13 @@ def parse_args() -> argparse.Namespace: "an ARM64 iPhone 16 Pro simulator running iOS 26.0." ), ) - cmd.add_argument( - "--slow", - action="store_true", - help="Run tests with --slow-ci options.", - ) + group = cmd.add_mutually_exclusive_group() + group.add_argument( + "--fast-ci", action="store_const", dest="ci_mode", const="fast", + help="Add test arguments for GitHub Actions") + group.add_argument( + "--slow-ci", action="store_const", dest="ci_mode", const="slow", + help="Add test arguments for buildbots") for subcommand in [configure_build, configure_host, build, ci]: subcommand.add_argument( @@ -1012,4 +1042,10 @@ def signal_handler(*args): if __name__ == "__main__": + # Under the buildbot, stdout is not a TTY, but we must still flush after + # every line to make sure our output appears in the correct order relative + # to the output of our subprocesses. + for stream in [sys.stdout, sys.stderr]: + stream.reconfigure(line_buffering=True) + main() diff --git a/Apple/testbed/__main__.py b/Apple/testbed/__main__.py index 4a1333380cdb6d..f3407ecdf7e734 100644 --- a/Apple/testbed/__main__.py +++ b/Apple/testbed/__main__.py @@ -412,4 +412,9 @@ def main(): if __name__ == "__main__": + # Under the buildbot, stdout is not a TTY, but we must still flush after + # every line to make sure our output appears in the correct order relative + # to the output of our subprocesses. + for stream in [sys.stdout, sys.stderr]: + stream.reconfigure(line_buffering=True) main() diff --git a/Misc/NEWS.d/next/Build/2025-10-16-11-30-53.gh-issue-140189.YCrUyt.rst b/Misc/NEWS.d/next/Build/2025-10-16-11-30-53.gh-issue-140189.YCrUyt.rst new file mode 100644 index 00000000000000..a1b81659242670 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2025-10-16-11-30-53.gh-issue-140189.YCrUyt.rst @@ -0,0 +1 @@ +iOS builds were added to CI.