Repository navigation
Release: merge release into main #73
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: TypedPython CI | |
| # The TypedPython gate and compiler are Python (python-multiplatform-ksp/src/{main,test}/python). | |
| # Gradle does not run them; this workflow does. | |
| on: | |
| push: | |
| branches: [ "develop", "main" ] | |
| paths: [ "python-multiplatform-ksp/**", "python-multiplatform-ksp/fixtures/app/**", ".github/workflows/typedpython.yml" ] | |
| pull_request: | |
| branches: [ "develop", "main" ] | |
| paths: [ "python-multiplatform-ksp/**", "python-multiplatform-ksp/fixtures/app/**", ".github/workflows/typedpython.yml" ] | |
| concurrency: | |
| # A newer push to the same ref supersedes this run; frees the shared macOS runners. | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| test: | |
| name: TypedPython tests (${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| defaults: | |
| run: | |
| working-directory: python-multiplatform-ksp | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: astral-sh/setup-uv@v5 | |
| - name: Create the environment | |
| # pyrefly is pinned exactly: the gate reads its versioned type-report format. | |
| run: | | |
| uv venv .venv --python 3.13 | |
| uv pip install --python .venv/bin/python "pyrefly==1.3.2" pytest | |
| - name: Behaviour tests | |
| run: .venv/bin/python -m pytest -q -m "not measurement" | |
| - name: Measurements (recorded, sanity bounds only) | |
| # A shared runner is not an idle machine (AGENTS.md §8): read ratios, not absolute times. | |
| run: .venv/bin/python -m pytest -q -s -m measurement | |
| sanitizers: | |
| # SPEC N-8: ASan/UBSan runs are the safety net outside the proof. Every extension TypedPython | |
| # builds in these tests is compiled with -fsanitize=address,undefined (TP_SANITIZE=1, see | |
| # conftest.py) and the interpreter runs with the ASan runtime preloaded; any report fails the run. | |
| # Linux only: macOS refuses to load the ASan runtime into the framework Python (the cgen | |
| # sanitizer test has a launcher-based macOS path of its own). | |
| name: TypedPython tests under ASan + UBSan (ubuntu-latest) | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: python-multiplatform-ksp | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: astral-sh/setup-uv@v5 | |
| - name: Create the environment | |
| run: | | |
| uv venv .venv --python 3.13 | |
| uv pip install --python .venv/bin/python "pyrefly==1.3.2" pytest | |
| - name: Relax ASLR entropy (ASan shadow mapping on newer kernels) | |
| run: sudo sysctl -w vm.mmap_rnd_bits=28 || true | |
| - name: Self-check, the sanitizers must catch planted faults | |
| # Builds a deliberately faulty extension (heap out-of-bounds read, signed overflow) and | |
| # REQUIRES both reports. If this step passes, the setup below can detect faults. | |
| run: .venv/bin/python tools/sanitizers.py selfcheck | |
| - name: cgen, runtime and pipeline tests, sanitized | |
| # detect_leaks=0: CPython itself leaks at exit. LD_PRELOAD is applied to this one command | |
| # only (tools/sanitizers.py env prints it); the gate's pyrefly runs without it. | |
| run: | | |
| env $(.venv/bin/python tools/sanitizers.py env) \ | |
| .venv/bin/python -m pytest -q -m "not measurement" \ | |
| src/test/python/test_cgen.py src/test/python/test_runtime.py src/test/python/test_pipeline.py | |
| app-fixture: | |
| # #45: a TypedPython-compiled module calling Kotlin through the upcall table, in the app | |
| # fixture's desktop JVM. buildTypedPythonBridge needs a host Python with pyrefly; without one the | |
| # four TypedPythonKotlinCallTest tests skip. Locally that is allowed; here a skip fails the job. | |
| # macOS only: elsewhere the JVM does not load libpython with global symbols, so the | |
| # dynamic_lookup extension cannot resolve the C API (python-multiplatform-ksp/fixtures/app/build.gradle.kts). | |
| name: TypedPython from Kotlin, app fixture (macos-latest) | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-java@v4 | |
| with: | |
| java-version: '21' | |
| distribution: 'zulu' | |
| cache: 'gradle' | |
| - uses: astral-sh/setup-uv@v5 | |
| - name: Create the TypedPython host environment | |
| working-directory: python-multiplatform-ksp | |
| run: | | |
| uv venv .venv --python 3.13 | |
| uv pip install --python .venv/bin/python "pyrefly==1.3.2" pytest | |
| - name: App fixture tests | |
| run: | | |
| rm -rf python-multiplatform-ksp/fixtures/app/build/test-results/desktopTest | |
| ./gradlew :python-multiplatform-ksp:fixtures:app:desktopTest --rerun --console=plain \ | |
| -PtypedpythonPython="$PWD/python-multiplatform-ksp/.venv/bin/python" | |
| - name: The TypedPython tests ran (none skipped) | |
| run: | | |
| python3 - <<'PY' | |
| import glob, sys, xml.etree.ElementTree as ET | |
| cases = [c for p in glob.glob("python-multiplatform-ksp/fixtures/app/build/test-results/desktopTest/*.xml") | |
| for c in ET.parse(p).getroot().iter("testcase") | |
| if c.get("classname") == "fixture.app.TypedPythonKotlinCallTest"] | |
| skipped = [c.get("name") for c in cases if c.find("skipped") is not None] | |
| print(f"TypedPythonKotlinCallTest: {len(cases)} test(s), {len(skipped)} skipped") | |
| if not cases or skipped: | |
| print("skipped: " + ", ".join(skipped) if skipped else "no TypedPythonKotlinCallTest results") | |
| sys.exit(1) | |
| PY |