Skip to content

Fix SHAPE_PLANE initialization (#84) #641

Fix SHAPE_PLANE initialization (#84)

Fix SHAPE_PLANE initialization (#84) #641

Workflow file for this run

# DO NOT CHANGE ANY SINGLE VERSION. DEPENDABOT HANDLES EVERYTHING.
name: Build Culverin Wheels
on:
push:
branches: [ master ]
tags: [ 'v*' ]
pull_request:
branches: [ master ]
workflow_dispatch: #
jobs:
# build Jolt once per platform
build_jolt:
name: Build Jolt (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
outputs:
jolt-hash: ${{ steps.jolt_hash.outputs.hash }}
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- name: Get submodule hash
id: jolt_hash
shell: bash
run: echo "hash=$(git rev-parse HEAD:extern/JoltPhysics)" >> $GITHUB_OUTPUT
- name: Cache Jolt static lib
id: cache
uses: actions/cache@v5
with:
path: jolt-install
key: jolt-${{ matrix.os }}-${{ steps.jolt_hash.outputs.hash }}-v12
- name: Install deps (Linux)
if: steps.cache.outputs.cache-hit != 'true' && runner.os == 'Linux'
run: sudo apt-get install -y clang lld ninja-build
- name: Install LLVM (macOS)
if: steps.cache.outputs.cache-hit != 'true' && runner.os == 'macOS'
run: brew install llvm ninja
- name: Install ninja (Windows)
if: steps.cache.outputs.cache-hit != 'true' && runner.os == 'Windows'
run: choco install ninja
- name: Build Jolt
if: steps.cache.outputs.cache-hit != 'true'
shell: bash
run: |
# 1. Physically patch Jolt's hardcoded flags out of existence
python - << 'EOF'
import os
path = 'extern/JoltPhysics/Build/CMakeLists.txt'
with open(path, 'r') as f: text = f.read()
# Force RTTI enabled natively
text = text.replace('-fno-rtti', '-frtti')
text = text.replace('/GR-', '/GR')
# Force MSVC Dynamic Runtime (DLL)
text = text.replace('MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"', 'MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL"')
with open(path, 'w') as f: f.write(text)
EOF
# 2. Configure CMake normally
COMMON_CMAKE_ARGS=(
"-G" "Ninja"
"-DCMAKE_BUILD_TYPE=Release"
"-DDOUBLE_PRECISION=ON"
"-DDEBUG_RENDERER_IN_DEBUG_AND_RELEASE=ON"
"-DCMAKE_CXX_STANDARD=23"
"-DCMAKE_INSTALL_PREFIX=$PWD/jolt-install"
"-DBUILD_SHARED_LIBS=OFF"
"-DTARGET_UNIT_TESTS=OFF"
"-DTARGET_PERFORMANCE_TEST=OFF"
"-DTARGET_SAMPLES=OFF"
"-DTARGET_VIEWER=OFF"
)
if [ "$RUNNER_OS" == "Windows" ]; then
cmake -S extern/JoltPhysics/Build -B jolt-build \
"${COMMON_CMAKE_ARGS[@]}" \
-DCMAKE_C_COMPILER="clang-cl" \
-DCMAKE_CXX_COMPILER="clang-cl" \
-DCMAKE_CXX_FLAGS="/arch:AVX2 /fp:fast -DJPH_OBJECT_LAYER_BITS=32"
elif [ "$RUNNER_OS" == "macOS" ]; then
export MACOSX_DEPLOYMENT_TARGET=13.3
cmake -S extern/JoltPhysics/Build -B jolt-build \
"${COMMON_CMAKE_ARGS[@]}" \
-DCMAKE_C_COMPILER="/opt/homebrew/opt/llvm/bin/clang" \
-DCMAKE_CXX_COMPILER="/opt/homebrew/opt/llvm/bin/clang++" \
-DCMAKE_CXX_FLAGS="-mcpu=apple-m1 -mmacosx-version-min=13.0 -DJPH_OBJECT_LAYER_BITS=32"
else
cmake -S extern/JoltPhysics/Build -B jolt-build \
"${COMMON_CMAKE_ARGS[@]}" \
-DCMAKE_C_COMPILER="clang" \
-DCMAKE_CXX_COMPILER="clang++" \
-DCMAKE_C_FLAGS="-fPIC" \
-DCMAKE_CXX_FLAGS="-march=x86-64-v3 -ffast-math -fomit-frame-pointer -fPIC -DJPH_OBJECT_LAYER_BITS=32"
fi
cmake --build jolt-build --parallel
cmake --install jolt-build
- name: Upload Jolt artifact
uses: actions/upload-artifact@v7
with:
name: jolt-prebuilt-${{ matrix.os }}
path: jolt-install/
retention-days: 3
# ===========================================================================
# JOB 1: PRODUCTION RELEASE (Clean Binaries)
# ===========================================================================
build_wheels:
name: Release Build (${{ matrix.os }})
needs: [build_jolt]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: recursive
- name: Set up uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install LLVM (macOS)
if: runner.os == 'macOS'
run: brew install llvm
- name: Download prebuilt Jolt
uses: actions/download-artifact@v8
with:
name: jolt-prebuilt-${{ matrix.os }}
path: jolt-install
- name: Set Jolt CMake dir
shell: bash
run: echo "JOLT_CMAKE_DIR=$(pwd)/jolt-install/lib/cmake/Jolt" >> $GITHUB_ENV
- name: Set Jolt CMake dir (Windows override)
if: runner.os == 'Windows'
shell: pwsh
run: |
$dir = (Resolve-Path "jolt-install/lib/cmake/Jolt").Path.Replace('\', '/')
echo "JOLT_CMAKE_DIR=$dir" >> $env:GITHUB_ENV
- name: Build Wheels
uses: pypa/cibuildwheel@v4.0.0
env:
CIBW_SKIP: "*-musllinux_* *-win32 *_i686"
# Removed cp313t-* to ensure compatibility with v4 architecture
CIBW_BUILD: "cp312-* cp313-* cp314-* cp314t-*"
# Stripped out CIBW_ENABLE completely to avoid "Unknown enable group" errors on v4
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
CIBW_BUILD_FRONTEND: "uv"
CIBW_ENVIRONMENT_PASS: JOLT_CMAKE_DIR
CIBW_ENVIRONMENT_LINUX: >
CC=clang
CXX=clang++
CMAKE_GENERATOR=Ninja
CMAKE_ARGS="-DENABLE_SANITIZER=OFF -DCMAKE_BUILD_TYPE=Release -DDOUBLE_PRECISION=ON -DJOLT_PREBUILT_DIR=/project/jolt-install/lib/cmake/Jolt"
CIBW_ENVIRONMENT_MACOS: >
CC=/opt/homebrew/opt/llvm/bin/clang
CXX=/opt/homebrew/opt/llvm/bin/clang++
CMAKE_GENERATOR=Ninja MACOSX_DEPLOYMENT_TARGET=13.3
CMAKE_ARGS="-DENABLE_SANITIZER=OFF -DCMAKE_BUILD_TYPE=Release -DDOUBLE_PRECISION=ON -DJOLT_PREBUILT_DIR=$JOLT_CMAKE_DIR"
CIBW_ENVIRONMENT_WINDOWS: >
CC=clang-cl
CXX=clang-cl
CMAKE_GENERATOR=Ninja
CMAKE_ARGS="-DENABLE_SANITIZER=OFF -DCMAKE_BUILD_TYPE=Release -DDOUBLE_PRECISION=ON -DJOLT_PREBUILT_DIR=$JOLT_CMAKE_DIR"
CIBW_BEFORE_ALL_LINUX: >
(dnf install -y clang llvm || yum install -y clang llvm || apk add --no-cache clang llvm-dev) &&
pip install ninja
CIBW_TEST_REQUIRES: numpy psutil pytest
CIBW_TEST_COMMAND: |
pytest {project}/tests/
echo "All tests completed!"
- name: Build Experimental Wheels (3.15)
shell: bash
run: |
# 1. Setup Platform-Specific Compilers to match Jolt Build
if [[ "${{ runner.os }}" == "Linux" ]]; then
echo "Configuring LLVM 22 for Linux..."
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 22
export CC=clang-22
export CXX=clang++-22
export LDFLAGS="-fuse-ld=lld-22"
elif [[ "${{ runner.os }}" == "macOS" ]]; then
echo "Configuring Homebrew LLVM for macOS..."
# Match the paths used in the build_jolt job exactly
export CC="/opt/homebrew/opt/llvm/bin/clang"
export CXX="/opt/homebrew/opt/llvm/bin/clang++"
export LDFLAGS="-L/opt/homebrew/opt/llvm/lib"
export CPPFLAGS="-I/opt/homebrew/opt/llvm/include"
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
else
echo "Configuring clang-cl for Windows..."
export CC=clang-cl
export CXX=clang-cl
fi
# 2. Install the alpha versions
uv python install 3.15 3.15t
# 3. Build Arguments (Using the Jolt Cache)
# We use the $JOLT_CMAKE_DIR established in the "Set Jolt CMake dir" step
CMAKE_FLAGS="-GNinja;-DENABLE_SANITIZER=OFF;-DCMAKE_BUILD_TYPE=Release;-DDOUBLE_PRECISION=ON;-DJOLT_PREBUILT_DIR=${JOLT_CMAKE_DIR}"
CXX_FLAGS="-Wno-overriding-option"
# 4. Build Standard 3.15
uv build --wheel --python 3.15 --out-dir wheelhouse/ \
--config-setting=cmake.args="$CMAKE_FLAGS" \
--config-setting=cmake.define.CMAKE_CXX_FLAGS="$CXX_FLAGS"
# 5. Build Free-Threaded 3.15t
uv build --wheel --python 3.15t --out-dir wheelhouse/ \
--config-setting=cmake.args="$CMAKE_FLAGS" \
--config-setting=cmake.define.CMAKE_CXX_FLAGS="$CXX_FLAGS"
# 6. Repair and Tag Linux Wheels for PyPI
if [[ "${{ runner.os }}" == "Linux" ]]; then
echo "Installing patchelf for auditwheel..."
sudo apt-get update -y && sudo apt-get install -y patchelf
echo "Repairing Linux wheels..."
mkdir -p wheelhouse/repaired
# Find only the newly built linux wheels
for whl in wheelhouse/*linux_x86_64.whl; do
if [ -f "$whl" ]; then
echo "Repairing $whl..."
# Use --plat auto to avoid string mismatch errors
uvx auditwheel repair "$whl" --plat auto -w wheelhouse/repaired/
fi
done
# Replace raw linux_x86_64 wheels with manylinux compliant ones
if [ "$(ls -A wheelhouse/repaired/)" ]; then
rm wheelhouse/*linux_x86_64.whl
mv wheelhouse/repaired/*.whl wheelhouse/
fi
rmdir wheelhouse/repaired/
fi
- name: Upload Artifacts
uses: actions/upload-artifact@v7
with:
name: culverin-release-${{ matrix.os }}
path: ./wheelhouse/*.whl
# ===========================================================================
# JOB 2 & 3: SANITIZER VALIDATION (ASan/UBSan/TSan Check)
# ===========================================================================
check_sanitizers:
name: Sanitizer Validation (Ubuntu)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: recursive
- name: Install LLVM 22
run: |
sudo apt-get update
sudo apt-get install -y wget lsb-release software-properties-common gnupg
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 22
# Ensure the specific sanitizer runtimes are present
sudo apt-get install -y clang-22 lld-22 libclang-rt-22-dev ninja-build
- name: Set up uv
uses: astral-sh/setup-uv@v7
- name: Build Wheels with Sanitizers
run: |
export CC=clang-22
export CXX=clang++-22
export CFLAGS="-fno-sanitize=alignment"
export CXXFLAGS="-fno-sanitize=alignment"
export LDFLAGS="-fuse-ld=lld-22"
# Force uv to use Python 3.14
uv build --wheel --python 3.14 \
--config-setting=cmake.args="-DENABLE_SANITIZER=ON;-DCMAKE_BUILD_TYPE=RelWithDebInfo;-DDOUBLE_PRECISION=ON"
- name: Install and Test
run: |
uv venv --python 3.14
# Install the wheel AND the test dependencies
uv pip install dist/*.whl numpy psutil pytest
ASAN_RT=$(find /usr/lib/llvm-22 -name "libclang_rt.asan-x86_64.so" | head -n 1)
echo "ASan Runtime: ${ASAN_RT}"
export ASAN_OPTIONS="detect_leaks=0:detect_odr_violation=0:halt_on_error=1"
export UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1"
if [ -n "$ASAN_RT" ]; then export LD_PRELOAD="$ASAN_RT"; fi
# Use --no-project so it doesn't try to re-build that editable install
uv run --no-project tests/test_core.py
uv run --no-project tests/benchmark.py --leak
# Thread sanitizer
linux_tsan:
name: TSan (${{ matrix.python-version }}${{ matrix.gil_flag }})
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
# Testing the full spectrum:
# 3.12 (Legacy GIL), 3.13t (Current Stable Free-Threaded), 3.14t (Bleeding Edge)
python-version: ["3.12", "3.13", "3.14"]
include:
- python-version: "3.12"
gil_flag: "" # Standard GIL only
- python-version: "3.13"
gil_flag: "t" # Free-threaded
- python-version: "3.14"
gil_flag: "t" # Experimental Free-threaded
- python-version: "3.15"
gil_flag: "t" # The subject to test with!
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- name: Install LLVM 22
run: |
sudo apt-get update
sudo apt-get install -y wget lsb-release software-properties-common gnupg
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 22
- uses: astral-sh/setup-uv@v7
with:
# Dynamically resolve version (e.g., 3.14t)
python-version: "${{ matrix.python-version }}${{ matrix.gil_flag }}"
- name: Build and Scan with TSan
env:
CC: "/usr/bin/clang-22"
CXX: "/usr/bin/clang++-22"
# -O1 is the TSan sweet spot: enough optimization to be fast,
# but keeps the stack traces readable.
CFLAGS: "-fsanitize=thread -g -O1 -fno-omit-frame-pointer"
CXXFLAGS: "-fsanitize=thread -g -O1 -fno-omit-frame-pointer -DENABLE_SANITIZER -D__SANITIZE_THREAD__"
LDFLAGS: "-fsanitize=thread"
CMAKE_ARGS: "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_STANDARD=23 -DENABLE_THREAD_SANITIZER=ON"
PYTEST_ADDOPTS: "-s"
run: |
# Use uv to handle the venv creation for the specific matrix version
uv venv --python "${{ matrix.python-version }}${{ matrix.gil_flag }}" --clear
# Install deps into the version-specific venv
uv pip install scikit-build-core numpy psutil pytest
uv pip install -e . --no-build-isolation
# Locate the specific TSan runtime for LLVM 22
export TSAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-22
TSAN_LIB=$(find /usr/lib/llvm-22 -name "libclang_rt.tsan-x86_64.so" | head -n 1)
# Execution environment
export LD_PRELOAD=$TSAN_LIB
export TSAN_OPTIONS="suppressions=${{ github.workspace }}/tsan.supp second_deadlock_stack=1 halt_on_error=1 symbolize=1"
# Run stress benchmark followed by unit tests
source .venv/bin/activate
python tests/benchmark.py --stress
python -m pytest tests/test_core.py
# ===========================================================================
# JOB 3.2: GCC DEEP VALIDATION (Full Source Build)
# ===========================================================================
linux_gcc_validation:
name: GCC 14 Deep Validation (Ubuntu)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: recursive
- name: Install GCC 14 and Ninja
run: |
sudo apt-get update
sudo apt-get install -y gcc-14 g++-14 lld ninja-build
# Set GCC 14 as the default system compiler
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 100
- name: Patch Jolt Source (Force RTTI)
shell: bash
run: |
python3 - << 'EOF'
import os
path = 'extern/JoltPhysics/Build/CMakeLists.txt'
if os.path.exists(path):
with open(path, 'r') as f: text = f.read()
text = text.replace('-fno-rtti', '-frtti')
text = text.replace('/GR-', '/GR')
with open(path, 'w') as f: f.write(text)
print("Jolt patched successfully.")
EOF
- name: Set up uv
uses: astral-sh/setup-uv@v7
- name: Deep Build with GCC (Jolt + Extension)
env:
CC: gcc
CXX: g++
# Use LLD for speed, but now it's linking GCC objects against GCC objects
LDFLAGS: "-fuse-ld=lld"
# NOTE: JOLT_PREBUILT_DIR is NOT defined.
# This triggers 'add_subdirectory' in your CMakeLists.txt
CMAKE_ARGS: >-
-DENABLE_SANITIZER=OFF
-DCMAKE_BUILD_TYPE=Release
-DDOUBLE_PRECISION=ON
-DJPH_OBJECT_LAYER_BITS=32
run: |
# Build using 3.14t to ensure thread-safety and C23 compliance
uv build --wheel --python 3.14t --out-dir dist/ \
--config-setting=cmake.define.CMAKE_C_COMPILER=gcc \
--config-setting=cmake.define.CMAKE_CXX_COMPILER=g++ \
--config-setting=cmake.verbose=true
- name: Smoke Test GCC Wheel
run: |
# 1. Setup environment
uv venv --python 3.14t
# 2. Force install ONLY the wheel we built, plus dependencies
# --no-index ensures it doesn't try to look at the local source folder
uv pip install dist/*.whl numpy
# 3. CRITICAL: Move to a directory that has NO pyproject.toml or src/
# This ensures 'import culverin' loads from site-packages, not the current folder.
mkdir test_jail
cd test_jail
# 4. Run tests using 'uv run --no-project'
VERSION_INFO=$(uv run --no-project python -c "import culverin; print(culverin.__version__)")
echo "Built version: $VERSION_INFO"
if [[ "$VERSION_INFO" != *"GCC"* ]]; then
echo "Error: Metadata check failed. Expected GCC in version string."
exit 1
fi
uv run --no-project python -c "import culverin; w=culverin.PhysicsWorld(); print('World created safely')"
# ===========================================================================
# JOB 3.5: SANITY CHECKS
# ===========================================================================
pre_flight_sanity_check:
name: Final Artifact Validation
needs: [build_wheels]
runs-on: ubuntu-latest
steps:
- name: "Checkout code with Full History & Tags"
uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true # Ensure we can verify tag reachability
- name: "Download All Built Wheels"
uses: actions/download-artifact@v8
with:
path: dist
pattern: culverin-release-*
merge-multiple: true
- name: "1. Check for Leaked Debug Symbols (.pdb)"
shell: bash
run: |
echo "Searching for hidden .pdb files in wheels..."
for wheel in dist/*.whl; do
if unzip -l "$wheel" | grep -iq "\.pdb$"; then
echo "::error::Found .pdb in $wheel! Check your scikit-build-core excludes."
exit 1
fi
done
- name: "2. Verify Wheel Count (Expected: 18)"
shell: bash
run: |
EXPECTED=18
ACTUAL=$(find dist -name '*.whl' | wc -l)
if [ "$ACTUAL" -ne "$EXPECTED" ]; then
echo "::error::Wheel count mismatch! Expected $EXPECTED, found $ACTUAL."
find dist -name '*.whl'
exit 1
fi
- name: "3. Robust Version Sync (tomllib)"
if: startsWith(github.ref, 'refs/tags/v')
shell: bash
run: |
# Use Python's native tomllib to avoid grep fragility
PY_VER=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
TAG_VER=${GITHUB_REF_NAME#v}
echo "Tag: $TAG_VER, pyproject.toml: $PY_VER"
if [ "$TAG_VER" != "$PY_VER" ]; then
echo "::error::Metadata Mismatch: Tag ($TAG_VER) != pyproject.toml ($PY_VER)"
exit 1
fi
- name: "4. Branch Reachability Check"
if: startsWith(github.ref, 'refs/tags/v')
run: |
# Verify the tag exists on the master branch history
if ! git branch -r --contains ${{ github.ref }} | grep -q "origin/master"; then
echo "::error::The tag ${{ github.ref_name }} is not reachable from origin/master."
echo "Aborting: You are trying to release a commit that isn't on the main line."
exit 1
fi
# ===========================================================================
# JOB 4: PERFORMANCE REGRESSION
# ===========================================================================
performance_regression:
name: Performance Regression Benchmarks
needs: [build_wheels]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: recursive
- name: Set up uv
uses: astral-sh/setup-uv@v7
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Download Artifacts
uses: actions/download-artifact@v8
with:
pattern: culverin-release-ubuntu-latest
path: dist
merge-multiple: true
- name: Install dependencies and Pre-built Wheel
run: |
uv pip install --system numpy psutil
WHEEL=$(ls dist/culverin-*cp313-cp313-manylinux*.whl | head -n 1)
uv pip install --system "$WHEEL"
- name: CPU Feature Audit
run: |
echo "### Runner CPU Info" >> $GITHUB_STEP_SUMMARY
# Check for v3 requirements (AVX2, BMI2, FMA)
grep -E "avx2|bmi2|fma" /proc/cpuinfo > /dev/null \
&& echo "✅ Hardware supports x86-64-v3" >> $GITHUB_STEP_SUMMARY \
|| echo "❌ ERROR: Ancient CPU detected (Missing v3 features)" >> $GITHUB_STEP_SUMMARY
# List all flags for deep dive
echo '```' >> $GITHUB_STEP_SUMMARY
lscpu >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
- name: Run Performance Suite
shell: bash
run: |
echo "## Performance Benchmark Results" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
# Fix: Explicitly point to the tests/ directory
echo "Running test_perf.py..."
python tests/test_perf.py >> $GITHUB_STEP_SUMMARY
echo -e "\nRunning benchmark.py..."
python tests/benchmark.py --leak >> $GITHUB_STEP_SUMMARY
python tests/benchmark.py --churn >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
continue-on-error: false
# ===========================================================================
# JOB 5: PUBLISH
# ===========================================================================
github-release:
name: Create GitHub Release
needs: [build_wheels, check_sanitizers, linux_tsan, pre_flight_sanity_check, performance_regression]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download Artifacts
uses: actions/download-artifact@v8
with:
path: wheelhouse
pattern: culverin-release-*
merge-multiple: true
- name: Upload to GitHub Release
uses: softprops/action-gh-release@v3
with:
files: wheelhouse/*.whl
body: |
Culverin Physics Release ${{ github.ref_name }}
Standard Release Binaries (Sanitizer validated)
prerelease: true
pypi-publish:
name: Upload to PyPI
needs: [build_wheels, check_sanitizers, linux_tsan, pre_flight_sanity_check, performance_regression]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write
steps:
- name: Download Artifacts
uses: actions/download-artifact@v8
with:
path: dist
pattern: culverin-release-*
merge-multiple: true
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
skip-existing: true