diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 9a8ba396..ab2c7ae8 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -53,6 +53,7 @@ jobs: outputs: build-docs: ${{ steps.select-jobs.outputs.docs }} build-android: ${{ steps.select-jobs.outputs.android }} + build-ios: ${{ steps.select-jobs.outputs.ios }} steps: - name: "Workflow run information" run: | @@ -260,11 +261,45 @@ jobs: repository: "${{ env.GIT_REMOTE }}/cpython" ref: "v${{ env.CPYTHON_RELEASE }}" + # Python 3.15 moved the build tools to the Platforms directory. Add a + # compatibility shim to simplify execution. Can be removed when 3.14 + # reaches EOL + - name: Set up compatibility symlink + run: | + if [ ! -e Platforms/Android ]; then + mkdir -p Platforms + ln -s ../Android Platforms/Android + ln -s ./android.py Android/__main__.py + fi + - name: Build and test - run: ./Android/android.py ci --fast-ci "$triplet" + run: python3 Platforms/Android ci --fast-ci "$triplet" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: ${{ env.triplet }} path: cross-build/${{ env.triplet }}/dist/* if-no-files-found: error + + build-ios: + name: build-iOS + needs: + - verify-input + if: fromJSON(needs.verify-input.outputs.build-ios) + runs-on: macos-14 + timeout-minutes: 60 + steps: + - name: "Checkout ${{ env.GIT_REMOTE }}/cpython" + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + repository: "${{ env.GIT_REMOTE }}/cpython" + ref: "v${{ env.CPYTHON_RELEASE }}" + + - name: Build and test + run: python3 Platforms/Apple build ci --slow-ci + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + path: cross-build/dist/* + if-no-files-found: error diff --git a/add_to_pydotorg.py b/add_to_pydotorg.py index 92c95f47..e5a30a8f 100755 --- a/add_to_pydotorg.py +++ b/add_to_pydotorg.py @@ -150,13 +150,17 @@ def get_file_descriptions( ), ), ( - rx(r"aarch64-linux-android.tar.gz$"), + rx(r"-aarch64-linux-android.tar.gz$"), ("Android embeddable package (aarch64)", "android", False, ""), ), ( - rx(r"x86_64-linux-android.tar.gz$"), + rx(r"-x86_64-linux-android.tar.gz$"), ("Android embeddable package (x86_64)", "android", False, ""), ), + ( + rx(r"-iOS-XCframework.tar.gz$"), + ("iOS XCframework", "ios", False, ""), + ), ] diff --git a/select_jobs.py b/select_jobs.py index 513b97b4..db2130b7 100755 --- a/select_jobs.py +++ b/select_jobs.py @@ -21,6 +21,9 @@ def main() -> None: # Android binary releases began in Python 3.14. output("android", version.as_tuple() >= (3, 14)) + # iOS binary releases began in Python 3.15. + output("ios", version.as_tuple() >= (3, 15)) + if __name__ == "__main__": main() diff --git a/tests/fake-ftp-files.txt b/tests/fake-ftp-files.txt index d3db468e..e2c6183e 100644 --- a/tests/fake-ftp-files.txt +++ b/tests/fake-ftp-files.txt @@ -522,6 +522,7 @@ python-3.14.0b2t-amd64.zip python-3.14.0b2t-arm64.zip python-3.14.0b2t-win32.zip python-3.14.0b3-aarch64-linux-android.tar.gz +Python-3.14.0b3-iOS-XCframework.tar.gz python-3.14.0b3-amd64.exe python-3.14.0b3-amd64.exe.crt python-3.14.0b3-amd64.exe.sig diff --git a/tests/test_add_to_pydotorg.py b/tests/test_add_to_pydotorg.py index 02e4d7df..237db485 100644 --- a/tests/test_add_to_pydotorg.py +++ b/tests/test_add_to_pydotorg.py @@ -161,6 +161,13 @@ def test_list_files(fs: FakeFilesystem) -> None: # Assert assert files == [ + ( + "Python-3.14.0b3-iOS-XCframework.tar.gz", + "iOS XCframework", + "ios", + False, + "", + ), ("Python-3.14.0b3.tar.xz", "XZ compressed source tarball", "source", True, ""), ("Python-3.14.0b3.tgz", "Gzipped source tarball", "source", False, ""), ( diff --git a/tests/test_select_jobs.py b/tests/test_select_jobs.py index 6d649172..7b3148bc 100644 --- a/tests/test_select_jobs.py +++ b/tests/test_select_jobs.py @@ -7,24 +7,25 @@ @pytest.mark.parametrize( - ("version", "docs", "android"), + ("version", "docs", "android", "ios"), [ - ("3.13.0a1", "false", "false"), - ("3.13.0rc1", "true", "false"), - ("3.13.0", "true", "false"), - ("3.13.1", "true", "false"), - ("3.14.0b2", "false", "true"), - ("3.14.0rc1", "true", "true"), - ("3.14.0", "true", "true"), - ("3.14.1", "true", "true"), - ("3.15.0a1", "false", "true"), - ("3.15.0", "true", "true"), + ("3.13.0a1", "false", "false", "false"), + ("3.13.0rc1", "true", "false", "false"), + ("3.13.0", "true", "false", "false"), + ("3.13.1", "true", "false", "false"), + ("3.14.0b2", "false", "true", "false"), + ("3.14.0rc1", "true", "true", "false"), + ("3.14.0", "true", "true", "false"), + ("3.14.1", "true", "true", "false"), + ("3.15.0a1", "false", "true", "true"), + ("3.15.0", "true", "true", "true"), ], ) def test_select_jobs( version: str, docs: str, android: str, + ios: str, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], ) -> None: @@ -34,5 +35,6 @@ def test_select_jobs( f"""\ docs={docs} android={android} + ios={ios} """ )