Skip to content

Commit 9ac1b47

Browse files
miss-islingtonfreakboy3742hugovk
committed
[3.10] pythongh-140189: Add CI job to test iOS builds. (pythonGH-140190) (python#140696)
Adds a CI configuration to test iOS builds on every build. (cherry picked from commit f4e6370) Co-authored-by: Russell Keith-Magee <russell@keith-magee.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
1 parent 6a7130f commit 9ac1b47

4 files changed

Lines changed: 158 additions & 14 deletions

File tree

.github/workflows/build.yml

Lines changed: 107 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,60 @@ jobs:
251251
- name: Tests
252252
run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu"
253253

254-
build_ubuntu_ssltests:
255-
name: 'Ubuntu SSL tests with OpenSSL'
256-
runs-on: ubuntu-24.04
254+
build-android:
255+
name: Android (${{ matrix.arch }})
256+
needs: build-context
257+
if: needs.build-context.outputs.run-tests == 'true'
258+
timeout-minutes: 60
259+
strategy:
260+
fail-fast: false
261+
matrix:
262+
include:
263+
- arch: aarch64
264+
runs-on: macos-14
265+
- arch: x86_64
266+
runs-on: ubuntu-24.04
267+
268+
runs-on: ${{ matrix.runs-on }}
269+
steps:
270+
- uses: actions/checkout@v4
271+
with:
272+
persist-credentials: false
273+
- name: Build and test
274+
run: ./Android/android.py ci --fast-ci ${{ matrix.arch }}-linux-android
275+
276+
build-ios:
277+
name: iOS
278+
needs: build-context
279+
if: needs.build-context.outputs.run-tests == 'true'
280+
timeout-minutes: 60
281+
runs-on: macos-15
282+
steps:
283+
- uses: actions/checkout@v4
284+
with:
285+
persist-credentials: false
286+
287+
# GitHub recommends explicitly selecting the desired Xcode version:
288+
# https://github.com/actions/runner-images/issues/12541#issuecomment-3083850140
289+
# This became a necessity as a result of
290+
# https://github.com/actions/runner-images/issues/12541 and
291+
# https://github.com/actions/runner-images/issues/12751.
292+
- name: Select Xcode version
293+
run: |
294+
sudo xcode-select --switch /Applications/Xcode_16.4.app
295+
296+
- name: Build and test
297+
run: python3 Apple ci iOS --fast-ci --simulator 'iPhone 16e,OS=18.5'
298+
299+
build-wasi:
300+
name: 'WASI'
301+
needs: build-context
302+
if: needs.build-context.outputs.run-tests == 'true'
303+
uses: ./.github/workflows/reusable-wasi.yml
304+
305+
build_asan:
306+
name: 'Address sanitizer'
307+
runs-on: ubuntu-22.04
257308
timeout-minutes: 60
258309
needs: check_source
259310
if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_ssl_tests == 'true'
@@ -299,5 +350,56 @@ jobs:
299350
run: make -j4
300351
- name: Display build info
301352
run: make pythoninfo
302-
- name: SSL tests
303-
run: ./python Lib/test/ssltests.py
353+
- name: Tests
354+
run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu"
355+
356+
all-required-green: # This job does nothing and is only used for the branch protection
357+
name: All required checks pass
358+
if: always()
359+
360+
needs:
361+
- check_source # Transitive dependency, needed to access `run_tests` value
362+
- check-docs
363+
- check_generated_files
364+
- build_macos
365+
- build_ubuntu
366+
- build_ubuntu_ssltests
367+
- build-android
368+
- build-ios
369+
- build-wasi
370+
- build_windows
371+
- build_asan
372+
373+
runs-on: ubuntu-latest
374+
375+
steps:
376+
- name: Check whether the needed jobs succeeded or failed
377+
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe
378+
with:
379+
allowed-failures: >-
380+
build_macos,
381+
build_ubuntu_ssltests,
382+
allowed-skips: >-
383+
${{
384+
!fromJSON(needs.check_source.outputs.run-docs)
385+
&& '
386+
check-docs,
387+
'
388+
|| ''
389+
}}
390+
${{
391+
needs.check_source.outputs.run_tests != 'true'
392+
&& '
393+
check_generated_files,
394+
build_macos,
395+
build_ubuntu,
396+
build_ubuntu_ssltests,
397+
build-android,
398+
build-ios,
399+
build-wasi,
400+
build_windows,
401+
build_asan,
402+
'
403+
|| ''
404+
}}
405+
jobs: ${{ toJSON(needs) }}

Apple/__main__.py

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ def test(context: argparse.Namespace, host: str | None = None) -> None:
823823
+ [
824824
"--",
825825
"test",
826-
"--slow-ci" if context.slow else "--fast-ci",
826+
f"--{context.ci_mode}-ci",
827827
"--single-process",
828828
"--no-randomize",
829829
# Timeout handling requires subprocesses; explicitly setting
@@ -836,11 +836,39 @@ def test(context: argparse.Namespace, host: str | None = None) -> None:
836836
)
837837

838838

839+
def apple_sim_host(platform_name: str) -> str:
840+
"""Determine the native simulator target for this platform."""
841+
for _, slice_parts in HOSTS[platform_name].items():
842+
for host_triple in slice_parts:
843+
parts = host_triple.split('-')
844+
if parts[0] == platform.machine() and parts[-1] == "simulator":
845+
return host_triple
846+
847+
raise KeyError(platform_name)
848+
849+
839850
def ci(context: argparse.Namespace) -> None:
840-
"""The implementation of the "ci" command."""
851+
"""The implementation of the "ci" command.
852+
853+
In "Fast" mode, this compiles the build python, and the simulator for the
854+
build machine's architecture; and runs the test suite with `--fast-ci`
855+
configuration.
856+
857+
In "Slow" mode, it compiles the build python, plus all candidate
858+
architectures (both device and simulator); then runs the test suite with
859+
`--slow-ci` configuration.
860+
"""
841861
clean(context, "all")
842-
build(context, host="all")
843-
test(context, host="all")
862+
if context.ci_mode == "slow":
863+
# In slow mode, build and test the full XCframework
864+
build(context, host="all")
865+
test(context, host="all")
866+
else:
867+
# In fast mode, just build the simulator platform.
868+
sim_host = apple_sim_host(context.platform)
869+
build(context, host="build")
870+
build(context, host=sim_host)
871+
test(context, host=sim_host)
844872

845873

846874
def parse_args() -> argparse.Namespace:
@@ -947,11 +975,13 @@ def parse_args() -> argparse.Namespace:
947975
"an ARM64 iPhone 16 Pro simulator running iOS 26.0."
948976
),
949977
)
950-
cmd.add_argument(
951-
"--slow",
952-
action="store_true",
953-
help="Run tests with --slow-ci options.",
954-
)
978+
group = cmd.add_mutually_exclusive_group()
979+
group.add_argument(
980+
"--fast-ci", action="store_const", dest="ci_mode", const="fast",
981+
help="Add test arguments for GitHub Actions")
982+
group.add_argument(
983+
"--slow-ci", action="store_const", dest="ci_mode", const="slow",
984+
help="Add test arguments for buildbots")
955985

956986
for subcommand in [configure_build, configure_host, build, ci]:
957987
subcommand.add_argument(
@@ -1012,4 +1042,10 @@ def signal_handler(*args):
10121042

10131043

10141044
if __name__ == "__main__":
1045+
# Under the buildbot, stdout is not a TTY, but we must still flush after
1046+
# every line to make sure our output appears in the correct order relative
1047+
# to the output of our subprocesses.
1048+
for stream in [sys.stdout, sys.stderr]:
1049+
stream.reconfigure(line_buffering=True)
1050+
10151051
main()

Apple/testbed/__main__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,4 +424,9 @@ def main():
424424

425425

426426
if __name__ == "__main__":
427+
# Under the buildbot, stdout is not a TTY, but we must still flush after
428+
# every line to make sure our output appears in the correct order relative
429+
# to the output of our subprocesses.
430+
for stream in [sys.stdout, sys.stderr]:
431+
stream.reconfigure(line_buffering=True)
427432
main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
iOS builds were added to CI.

0 commit comments

Comments
 (0)