Audit docs, drop dead code, add snippet linter (#65) #470
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| test: | |
| name: OTP ${{ matrix.otp }} / Python ${{ matrix.python }} / ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Linux with different OTP/Python combinations | |
| - os: ubuntu-24.04 | |
| otp: "27.0" | |
| python: "3.12" | |
| - os: ubuntu-24.04 | |
| otp: "27.0" | |
| python: "3.13" | |
| - os: ubuntu-24.04 | |
| otp: "27.0" | |
| python: "3.14" | |
| # macOS | |
| - os: macos-15 | |
| otp: "27" | |
| python: "3.12" | |
| - os: macos-15 | |
| otp: "27" | |
| python: "3.13" | |
| - os: macos-15 | |
| otp: "27" | |
| python: "3.14" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python }} | |
| - name: Set up Erlang (Ubuntu) | |
| if: startsWith(matrix.os, 'ubuntu') | |
| uses: erlef/setup-beam@v1 | |
| with: | |
| otp-version: ${{ matrix.otp }} | |
| rebar3-version: "3.24" | |
| - name: Set up Erlang (macOS) | |
| if: startsWith(matrix.os, 'macos') | |
| run: | | |
| brew install erlang rebar3 | |
| - name: Install numpy (for ML thread-affinity tests) | |
| run: | | |
| python3 -m pip install --upgrade pip | |
| python3 -m pip install numpy | |
| - name: Verify versions | |
| run: | | |
| echo "Erlang/OTP version:" | |
| erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().' -noshell | |
| echo "Python version:" | |
| python3 --version | |
| echo "Python config:" | |
| python3-config --cflags | head -c 100 | |
| echo "..." | |
| - name: Set Python library path (Ubuntu) | |
| if: startsWith(matrix.os, 'ubuntu') | |
| run: | | |
| PYTHON_LIB=$(python3 -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))") | |
| echo "LD_LIBRARY_PATH=${PYTHON_LIB}:${LD_LIBRARY_PATH}" >> $GITHUB_ENV | |
| - name: Clean and compile | |
| run: | | |
| rm -rf _build | |
| rebar3 compile | |
| - name: Run tests | |
| run: rebar3 ct --readable=compact | |
| - name: Run dialyzer | |
| run: rebar3 dialyzer | |
| - name: Run xref | |
| run: rebar3 xref | |
| - name: Lint docs | |
| run: escript scripts/lint_doc_snippets.escript | |
| # FreeBSD test using cross-platform action | |
| test-freebsd: | |
| name: FreeBSD 14 / Python ${{ matrix.python }} | |
| runs-on: ubuntu-24.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - python: "3.11" | |
| python_pkg: "python311" | |
| - python: "3.12" | |
| python_pkg: "python312" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Test on FreeBSD | |
| uses: vmactions/freebsd-vm@v1 | |
| with: | |
| release: "14.1" | |
| usesh: true | |
| prepare: | | |
| pkg install -y erlang ${{ matrix.python_pkg }} cmake | |
| # numpy package follows the py<noDot>-numpy convention. | |
| # Non-fatal: not every FreeBSD pkg snapshot ships numpy for | |
| # every Python flavor; the ML SUITE self-skips when numpy | |
| # is missing, which is the right behavior here. | |
| NUMPY_PKG="$(echo '${{ matrix.python_pkg }}' | sed 's/^python/py/')-numpy" | |
| pkg install -y "$NUMPY_PKG" || \ | |
| echo "WARN: $NUMPY_PKG unavailable; ML cases will skip" | |
| run: | | |
| # Set up environment | |
| export PYTHON_CONFIG=python${{ matrix.python }}-config | |
| export PATH="/usr/local/bin:$PATH" | |
| # Verify versions | |
| echo "Erlang version:" | |
| erl -eval 'io:format("~s~n", [erlang:system_info(otp_release)]), halt().' -noshell | |
| echo "Python version:" | |
| python${{ matrix.python }} --version | |
| # Build with rebar3 | |
| fetch https://github.com/erlang/rebar3/releases/download/3.24.0/rebar3 -o rebar3 | |
| chmod +x rebar3 | |
| # Compile and test (uses CMake-based build) | |
| ./rebar3 compile | |
| ./rebar3 ct --readable=compact | |
| ./rebar3 dialyzer | |
| ./rebar3 xref | |
| # Test with free-threaded Python (experimental, no GIL) | |
| test-free-threaded: | |
| name: Free-threaded Python 3.13t | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Erlang | |
| uses: erlef/setup-beam@v1 | |
| with: | |
| otp-version: "27.0" | |
| rebar3-version: "3.24" | |
| - name: Set up free-threaded Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13t" | |
| - name: Verify free-threading is enabled | |
| run: | | |
| python3 --version | |
| python3 -c "import sys; print('GIL enabled:', sys._is_gil_enabled())" | |
| python3 -c "import sysconfig; print('Py_GIL_DISABLED:', sysconfig.get_config_var('Py_GIL_DISABLED'))" | |
| - name: Install numpy (for ML thread-affinity tests) | |
| run: | | |
| python3 -m pip install --upgrade pip | |
| python3 -m pip install numpy | |
| - name: Set Python library path | |
| run: | | |
| PYTHON_LIB=$(python3 -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))") | |
| echo "LD_LIBRARY_PATH=${PYTHON_LIB}:${LD_LIBRARY_PATH}" >> $GITHUB_ENV | |
| - name: Clean and compile | |
| env: | |
| PYTHON_GIL: "0" | |
| run: | | |
| rm -rf _build | |
| rebar3 compile | |
| - name: Run tests | |
| env: | |
| PYTHON_GIL: "0" | |
| run: rebar3 ct --readable=compact | |
| - name: Verify execution mode | |
| env: | |
| PYTHON_GIL: "0" | |
| run: | | |
| erl -pa _build/default/lib/erlang_python/ebin -noshell -eval ' | |
| application:ensure_all_started(erlang_python), | |
| Mode = py:execution_mode(), | |
| io:format("Execution mode: ~p~n", [Mode]), | |
| case Mode of | |
| free_threaded -> io:format("SUCCESS: Running in free-threaded mode~n"); | |
| _ -> io:format("NOTE: Running in ~p mode~n", [Mode]) | |
| end, | |
| halt(). | |
| ' | |
| continue-on-error: true # Free-threading is experimental | |
| # ASan builds for detecting memory issues | |
| test-asan: | |
| name: ASan / Python ${{ matrix.python }} | |
| runs-on: ubuntu-24.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python: ["3.12", "3.13", "3.14"] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python }} | |
| - name: Set up Erlang | |
| uses: erlef/setup-beam@v1 | |
| with: | |
| otp-version: "27.0" | |
| rebar3-version: "3.24" | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake | |
| - name: Install numpy (for ML thread-affinity tests) | |
| run: | | |
| python3 -m pip install --upgrade pip | |
| python3 -m pip install numpy | |
| - name: Set Python library path | |
| run: | | |
| PYTHON_LIB=$(python3 -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))") | |
| echo "LD_LIBRARY_PATH=${PYTHON_LIB}:${LD_LIBRARY_PATH}" >> $GITHUB_ENV | |
| - name: Clean and compile with ASan | |
| run: | | |
| rm -rf _build | |
| mkdir -p _build/cmake | |
| cd _build/cmake | |
| cmake ../../c_src -DENABLE_ASAN=ON -DENABLE_UBSAN=ON | |
| cmake --build . -- -j $(nproc) | |
| cd ../.. | |
| rebar3 compile | |
| - name: Run tests with ASan | |
| env: | |
| ASAN_OPTIONS: detect_leaks=0:abort_on_error=1 | |
| run: | | |
| export LD_PRELOAD=$(gcc -print-file-name=libasan.so) | |
| rebar3 ct --readable=compact | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Erlang | |
| uses: erlef/setup-beam@v1 | |
| with: | |
| otp-version: "27.0" | |
| rebar3-version: "3.24" | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Set Python library path | |
| run: | | |
| PYTHON_LIB=$(python3 -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))") | |
| echo "LD_LIBRARY_PATH=${PYTHON_LIB}:${LD_LIBRARY_PATH}" >> $GITHUB_ENV | |
| - name: Compile | |
| run: rebar3 compile | |
| - name: Run xref | |
| run: rebar3 xref | |
| - name: Run dialyzer | |
| run: rebar3 dialyzer | |
| docs: | |
| name: Documentation | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Erlang | |
| uses: erlef/setup-beam@v1 | |
| with: | |
| otp-version: "27.0" | |
| rebar3-version: "3.24" | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Set Python library path | |
| run: | | |
| PYTHON_LIB=$(python3 -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))") | |
| echo "LD_LIBRARY_PATH=${PYTHON_LIB}:${LD_LIBRARY_PATH}" >> $GITHUB_ENV | |
| - name: Compile | |
| run: rebar3 compile | |
| - name: Build documentation | |
| run: rebar3 ex_doc | |
| - name: Verify doc artifacts | |
| run: | | |
| test -d doc || (echo "doc directory not created" && exit 1) | |
| test -f doc/index.html || (echo "doc/index.html not found" && exit 1) | |
| echo "Documentation built successfully" | |
| ls -la doc/ |