npm annoying #40
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: Publish Python SDK | |
| on: | |
| workflow_dispatch: | |
| release: | |
| types: | |
| - published | |
| push: | |
| branches: | |
| - main | |
| jobs: | |
| preflight: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| publish_needed: ${{ steps.pypi_check.outputs.publish_needed }} | |
| version: ${{ steps.meta.outputs.version }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Read package metadata | |
| id: meta | |
| run: | | |
| python - <<'PY' | |
| import os | |
| import tomllib | |
| with open("bindings/python/pyproject.toml", "rb") as f: | |
| project = tomllib.load(f)["project"] | |
| with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as out: | |
| out.write(f"name={project['name']}\n") | |
| out.write(f"version={project['version']}\n") | |
| PY | |
| - name: Check if version is already on PyPI | |
| id: pypi_check | |
| run: | | |
| python - <<'PY' | |
| import json | |
| import os | |
| import tomllib | |
| import urllib.error | |
| import urllib.request | |
| with open("bindings/python/pyproject.toml", "rb") as f: | |
| project = tomllib.load(f)["project"] | |
| name = project["name"] | |
| version = project["version"] | |
| url = f"https://pypi.org/pypi/{name}/json" | |
| publish_needed = True | |
| try: | |
| with urllib.request.urlopen(url, timeout=15) as resp: | |
| payload = json.load(resp) | |
| releases = payload.get("releases", {}) | |
| publish_needed = version not in releases | |
| except urllib.error.HTTPError as e: | |
| if e.code != 404: | |
| raise | |
| print(f"{name} {version} publish_needed={publish_needed}") | |
| with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as out: | |
| out.write(f"publish_needed={'true' if publish_needed else 'false'}\n") | |
| PY | |
| build_native: | |
| needs: preflight | |
| if: needs.preflight.outputs.publish_needed == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-2022 | |
| artifact: win32-x64 | |
| - os: ubuntu-22.04 | |
| artifact: linux-x64 | |
| - os: macos-15-intel | |
| artifact: darwin-x64 | |
| - os: macos-14 | |
| artifact: darwin-arm64 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup MSYS2 (Windows onionrelay toolchain) | |
| if: runner.os == 'Windows' | |
| uses: msys2/setup-msys2@v2 | |
| with: | |
| msystem: MINGW64 | |
| update: true | |
| install: >- | |
| mingw-w64-x86_64-toolchain | |
| mingw-w64-x86_64-openssl | |
| mingw-w64-x86_64-libevent | |
| mingw-w64-x86_64-xz | |
| mingw-w64-x86_64-zstd | |
| mingw-w64-x86_64-zlib | |
| autoconf | |
| automake | |
| libtool | |
| make | |
| pkgconf | |
| gettext | |
| - name: Install Linux dependencies (onionrelay) | |
| if: runner.os == 'Linux' | |
| shell: bash | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| build-essential \ | |
| pkg-config \ | |
| libevent-dev \ | |
| libssl-dev \ | |
| zlib1g-dev \ | |
| liblzma-dev \ | |
| libzstd-dev \ | |
| automake \ | |
| libtool \ | |
| autoconf \ | |
| gettext | |
| - name: Install macOS dependencies (onionrelay) | |
| if: runner.os == 'macOS' | |
| shell: bash | |
| run: | | |
| brew update | |
| brew install \ | |
| pkg-config \ | |
| libevent \ | |
| openssl@3 \ | |
| xz \ | |
| zstd \ | |
| automake \ | |
| libtool \ | |
| autoconf \ | |
| gettext | |
| - name: Build native core (Windows) | |
| if: runner.os == 'Windows' | |
| shell: powershell | |
| run: .\scripts\build_p4_core.ps1 | |
| - name: Build native core (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| chmod +x scripts/build_p4_core_unix.sh | |
| ./scripts/build_p4_core_unix.sh | |
| - name: Build onionrelay (Windows) | |
| if: runner.os == 'Windows' | |
| shell: powershell | |
| env: | |
| MSYS2_ROOT: ${{ runner.temp }}\\msys64 | |
| run: .\build_onionrelay_windows.ps1 | |
| - name: Build onionrelay (Linux/macOS) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| chmod +x scripts/build_onionrelay_unix.sh | |
| ./scripts/build_onionrelay_unix.sh "${GITHUB_WORKSPACE}/dist" onionrelay | |
| - name: Stage bundled payload (Windows) | |
| if: runner.os == 'Windows' | |
| shell: powershell | |
| run: | | |
| New-Item -ItemType Directory -Force -Path out\win32-x64\core | Out-Null | |
| New-Item -ItemType Directory -Force -Path out\win32-x64\onionrelay | Out-Null | |
| Copy-Item dist\p4_core\windows-x64\p4_core.dll out\win32-x64\core\p4_core.dll -Force | |
| Copy-Item onionrelay_src\src\app\onionrelay.exe out\win32-x64\onionrelay\onionrelay.exe -Force | |
| $dlls = Get-ChildItem onionrelay_src\src\app\*.dll -ErrorAction SilentlyContinue | |
| foreach ($dll in $dlls) { | |
| Copy-Item $dll.FullName out\win32-x64\onionrelay\ -Force | |
| } | |
| - name: Stage bundled payload (Linux) | |
| if: runner.os == 'Linux' | |
| shell: bash | |
| run: | | |
| mkdir -p out/linux-x64/core | |
| mkdir -p out/linux-x64/onionrelay | |
| cp -f dist/p4_core/linux-x64/libp4_core.so out/linux-x64/core/libp4_core.so | |
| cp -f dist/onionrelay out/linux-x64/onionrelay/onionrelay | |
| chmod +x out/linux-x64/onionrelay/onionrelay | |
| - name: Stage bundled payload (macOS) | |
| if: runner.os == 'macOS' | |
| shell: bash | |
| run: | | |
| mkdir -p "out/${{ matrix.artifact }}/core" | |
| mkdir -p "out/${{ matrix.artifact }}/onionrelay" | |
| cp -f dist/p4_core/macos/libp4_core.dylib "out/${{ matrix.artifact }}/core/libp4_core.dylib" | |
| cp -f dist/onionrelay "out/${{ matrix.artifact }}/onionrelay/onionrelay" | |
| chmod +x "out/${{ matrix.artifact }}/onionrelay/onionrelay" | |
| - name: Upload native artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: python-native-${{ matrix.artifact }} | |
| path: out/** | |
| publish: | |
| needs: [preflight, build_native] | |
| if: needs.preflight.outputs.publish_needed == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Download native artifact (Windows x64) | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: python-native-win32-x64 | |
| path: tmp_native/win32 | |
| - name: Download native artifact (Linux x64) | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: python-native-linux-x64 | |
| path: tmp_native/linux | |
| - name: Download native artifact (macOS x64) | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: python-native-darwin-x64 | |
| path: tmp_native/darwin-x64 | |
| - name: Download native artifact (macOS arm64) | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: python-native-darwin-arm64 | |
| path: tmp_native/darwin-arm64 | |
| - name: Stage downloaded native payload | |
| shell: bash | |
| run: | | |
| mkdir -p bindings/python/p4_core/native | |
| mkdir -p bindings/python/p4_core/onionrelay | |
| find bindings/python/p4_core/native -mindepth 1 -maxdepth 1 ! -name '__init__.py' ! -name '.gitkeep' -exec rm -rf {} + | |
| find bindings/python/p4_core/onionrelay -mindepth 1 -maxdepth 1 ! -name '.gitkeep' -exec rm -rf {} + | |
| rm -rf bindings/python/p4_core/native/win32-x64 | |
| rm -rf bindings/python/p4_core/native/linux-x64 | |
| rm -rf bindings/python/p4_core/native/darwin-x64 | |
| rm -rf bindings/python/p4_core/native/darwin-arm64 | |
| rm -rf bindings/python/p4_core/onionrelay/win32-x64 | |
| rm -rf bindings/python/p4_core/onionrelay/linux-x64 | |
| rm -rf bindings/python/p4_core/onionrelay/darwin-x64 | |
| rm -rf bindings/python/p4_core/onionrelay/darwin-arm64 | |
| mkdir -p bindings/python/p4_core/native/win32-x64 | |
| mkdir -p bindings/python/p4_core/native/linux-x64 | |
| mkdir -p bindings/python/p4_core/native/darwin-x64 | |
| mkdir -p bindings/python/p4_core/native/darwin-arm64 | |
| mkdir -p bindings/python/p4_core/onionrelay/win32-x64 | |
| mkdir -p bindings/python/p4_core/onionrelay/linux-x64 | |
| mkdir -p bindings/python/p4_core/onionrelay/darwin-x64 | |
| mkdir -p bindings/python/p4_core/onionrelay/darwin-arm64 | |
| WIN_SRC="$(find tmp_native/win32 -type f -path '*core/p4_core.dll' | head -n1)" | |
| LIN_SRC="$(find tmp_native/linux -type f -name 'libp4_core.so' | head -n1)" | |
| DARWIN_X64="$(find tmp_native/darwin-x64 -type f -name 'libp4_core.dylib' | head -n1)" | |
| DARWIN_ARM="$(find tmp_native/darwin-arm64 -type f -name 'libp4_core.dylib' | head -n1)" | |
| WIN_ONION_DIR="$(find tmp_native/win32 -type d -name onionrelay | head -n1)" | |
| LIN_ONION="$(find tmp_native/linux -type f -path '*onionrelay/onionrelay' | head -n1)" | |
| DARWIN_X64_ONION="$(find tmp_native/darwin-x64 -type f -path '*onionrelay/onionrelay' | head -n1)" | |
| DARWIN_ARM_ONION="$(find tmp_native/darwin-arm64 -type f -path '*onionrelay/onionrelay' | head -n1)" | |
| if [ -z "${WIN_SRC}" ] || [ -z "${LIN_SRC}" ] || [ -z "${DARWIN_ARM}" ] || [ -z "${DARWIN_X64}" ] || [ -z "${WIN_ONION_DIR}" ] || [ -z "${LIN_ONION}" ] || [ -z "${DARWIN_X64_ONION}" ] || [ -z "${DARWIN_ARM_ONION}" ]; then | |
| echo "Failed to locate expected native/onionrelay artifacts." | |
| find tmp_native -maxdepth 5 -type f -print | |
| exit 1 | |
| fi | |
| cp -f "${WIN_SRC}" bindings/python/p4_core/native/win32-x64/p4_core.dll | |
| cp -f "${LIN_SRC}" bindings/python/p4_core/native/linux-x64/libp4_core.so | |
| cp -f "${DARWIN_X64}" bindings/python/p4_core/native/darwin-x64/libp4_core.dylib | |
| cp -f "${DARWIN_ARM}" bindings/python/p4_core/native/darwin-arm64/libp4_core.dylib | |
| cp -f "${WIN_ONION_DIR}"/* bindings/python/p4_core/onionrelay/win32-x64/ | |
| cp -f "${LIN_ONION}" bindings/python/p4_core/onionrelay/linux-x64/onionrelay | |
| cp -f "${DARWIN_X64_ONION}" bindings/python/p4_core/onionrelay/darwin-x64/onionrelay | |
| cp -f "${DARWIN_ARM_ONION}" bindings/python/p4_core/onionrelay/darwin-arm64/onionrelay | |
| chmod +x bindings/python/p4_core/onionrelay/linux-x64/onionrelay | |
| chmod +x bindings/python/p4_core/onionrelay/darwin-x64/onionrelay | |
| chmod +x bindings/python/p4_core/onionrelay/darwin-arm64/onionrelay | |
| - name: Build wheel + sdist | |
| run: | | |
| python -m pip install --upgrade pip build twine | |
| python -m build bindings/python | |
| - name: Publish to PyPI | |
| env: | |
| TWINE_USERNAME: __token__ | |
| TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} | |
| run: | | |
| if [ -z "${TWINE_PASSWORD}" ]; then | |
| echo "PYPI_API_TOKEN secret is missing" | |
| exit 1 | |
| fi | |
| twine upload bindings/python/dist/* | |
| skip: | |
| needs: preflight | |
| if: needs.preflight.outputs.publish_needed != 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - run: echo "Version already exists on PyPI; skipping publish." |