Add zstd support to View::to_arrow
#1891
Workflow file for this run
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
| # ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ | |
| # ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃ | |
| # ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃ | |
| # ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃ | |
| # ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃ | |
| # ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ | |
| # ┃ Copyright (c) 2017, the Perspective Authors. ┃ | |
| # ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃ | |
| # ┃ This file is part of the Perspective library, distributed under the terms ┃ | |
| # ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ | |
| # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ | |
| name: Build Status | |
| on: | |
| push: | |
| branches: | |
| - master | |
| tags: | |
| - v* | |
| paths-ignore: | |
| - AUTHORS | |
| - CHANGELOG.md | |
| - CONTRIBUTING.md | |
| - LICENSE | |
| - README.md | |
| - binder/ | |
| - docs/ | |
| - examples/ | |
| - rust/perspective-python/README.md | |
| pull_request: | |
| branches: | |
| - master | |
| workflow_dispatch: | |
| inputs: | |
| ci-full: | |
| description: "Run Full CI" | |
| required: false | |
| type: boolean | |
| default: false | |
| ci-skip-cache: | |
| description: "Omit Cache from CI run" | |
| required: false | |
| type: boolean | |
| default: false | |
| ci-skip-python: | |
| description: "Skip Python components of CI" | |
| required: false | |
| type: boolean | |
| default: false | |
| ci-include-windows: | |
| description: "Include Windows (Python) components of CI" | |
| required: false | |
| type: boolean | |
| default: false | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| jobs: | |
| # , . . .-,--. | |
| # ) . ,-. |- ,-. ,-. ,-| ' | \ ,-. ,-. ,-. | |
| # / | | | | ,-| | | | | , | / | | | `-. | |
| # `--' ' ' ' `' `-^ ' ' `-^ `-^--' `-' `-' `-' | |
| # | |
| lint_and_docs: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| python-version: | |
| - 3.11 | |
| node-version: [22.x] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - name: Initialize Build | |
| id: init-step | |
| uses: ./.github/actions/install-deps | |
| with: | |
| cargo_cache: "false" | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| # Caches dependency-crate artifacts (workspace crates are pruned | |
| # on save); this job heads the critical path so its ~4min of | |
| # cold dep compilation is pure wall-clock. | |
| - name: Setup rust cache | |
| if: ${{ steps.config-step.outputs.SKIP_CACHE != 'true' }} | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| # rust-cache doesn't read `.cargo/config.toml`'s | |
| # `target-dir = "rust/target"` redirect | |
| workspaces: ". -> rust/target" | |
| save-if: ${{ steps.config-step.outputs.SAVE_CACHE == 'true' }} | |
| - name: Metadata Build | |
| run: pnpm run build --ci | |
| env: | |
| PACKAGE: "metadata" | |
| - name: Lint | |
| run: pnpm run lint --nightly | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: perspective-metadata | |
| path: | | |
| rust/perspective-server/cpp/ | |
| rust/perspective-server/cmake/ | |
| rust/perspective-client/src/ | |
| rust/perspective-client/docs/ | |
| rust/perspective-js/src/ts/ | |
| rust/perspective-viewer/src/ts/ | |
| rust/perspective-python/LICENSE_THIRDPARTY_cargo.yml | |
| # ,-,---. . . ,-_/ .---. . | |
| # '|___/ . . . | ,-| ' | ,-. . , ,-. \___ ,-. ,-. . ,-. |- | |
| # ,| \ | | | | | | | ,-| | / ,-| \ | | | | | | | |
| # `-^---' `-^ ' `' `-^ | `-^ `' `-^ `---' `-' ' ' |-' `' | |
| # /` | | | |
| # `--' ' | |
| build_js: | |
| runs-on: ${{ matrix.os }} | |
| needs: [lint_and_docs] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| python-version: | |
| - 3.11 | |
| node-version: [22.x] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-metadata | |
| path: rust/ | |
| # `clean: "true"` (~2-4min) dropped 2026-08: runners now start | |
| # with ~88G free and no job in the workflow peaks near that; the | |
| # `df -h` probe below is the canary if disk pressure returns. | |
| - name: Initialize Build | |
| id: init-step | |
| uses: ./.github/actions/install-deps | |
| with: | |
| python: "false" | |
| playwright: "true" | |
| ccache: "emscripten-wasm32" | |
| emsdk_cache: "wasm32" | |
| cache_save: ${{ steps.config-step.outputs.SAVE_CACHE }} | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - name: WebAssembly Build | |
| run: pnpm run build --ci | |
| env: | |
| PACKAGE: "server,client,viewer,viewer-datagrid,viewer-charts,react,anywidget" | |
| PSP_USE_CCACHE: "1" | |
| - name: Run df -h | |
| run: df -h | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: perspective-js-dist | |
| path: | | |
| rust/perspective-js/dist | |
| rust/perspective-js/src | |
| rust/perspective-server/dist | |
| rust/perspective-viewer/dist | |
| rust/perspective-viewer/src | |
| packages/viewer-charts/dist | |
| packages/viewer-datagrid/dist | |
| packages/react/dist | |
| # The `PerspectiveWidget` anywidget JS/CSS bundle, needed by any | |
| # job which imports `perspective.widget` from the source tree | |
| # (the `build_python` wheel is built in parallel with this job and | |
| # can't include it; `repack_wheel.mjs` injects it into the wheel). | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: perspective-anywidget-dist | |
| path: | | |
| rust/perspective-python/perspective/widget/static/perspective-anywidget.js | |
| rust/perspective-python/perspective/widget/static/perspective-anywidget.css | |
| # The Memory64 engine recompiles the entire C++ dependency chain under | |
| # `-sMEMORY64` (no object sharing with wasm32 is possible), so it builds | |
| # on its own runner in parallel with `build_js` rather than doubling that | |
| # job's wall clock. Downstream jobs merge this single-file artifact into | |
| # `rust/perspective-server/dist/wasm/`. | |
| build_js_wasm64: | |
| runs-on: ${{ matrix.os }} | |
| needs: [lint_and_docs] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| node-version: [22.x] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-metadata | |
| path: rust/ | |
| # `clean: "true"` dropped 2026-08 — see `build_js`. | |
| - name: Initialize Build | |
| id: init-step | |
| uses: ./.github/actions/install-deps | |
| with: | |
| python: "false" | |
| playwright: "true" | |
| ccache: "emscripten-wasm64" | |
| emsdk_cache: "wasm64" | |
| cache_save: ${{ steps.config-step.outputs.SAVE_CACHE }} | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - name: WebAssembly Build (Memory64) | |
| run: pnpm run build --ci | |
| env: | |
| PACKAGE: "server" | |
| PSP_WASM64: "only" | |
| PSP_USE_CCACHE: "1" | |
| - name: Run df -h | |
| run: df -h | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: perspective-server-wasm64-dist | |
| path: rust/perspective-server/dist/wasm/perspective-server.memory64.wasm | |
| # ,-,---. . . .-,--. . . | |
| # '|___/ . . . | ,-| '|__/ . . |- |-. ,-. ,-. | |
| # ,| \ | | | | | | ,| | | | | | | | | | | |
| # `-^---' `-^ ' `' `-^ `' `-| `' ' ' `-' ' ' | |
| # /| | |
| # `-' | |
| build_python: | |
| runs-on: ${{ matrix.os }} | |
| needs: [lint_and_docs] | |
| container: ${{ matrix.container }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| - ubuntu-22.04-arm | |
| - macos-14 | |
| - windows-2025 | |
| arch: | |
| - aarch64 | |
| - x86_64 | |
| python-version: | |
| - 3.11 | |
| node-version: [22.x] | |
| include: | |
| - os: ubuntu-22.04 | |
| arch: x86_64 | |
| python-version: 3.11 | |
| container: quay.io/pypa/manylinux_2_28_x86_64 | |
| - os: ubuntu-22.04-arm | |
| arch: aarch64 | |
| python-version: 3.11 | |
| container: quay.io/pypa/manylinux_2_28_aarch64 | |
| is-release: | |
| - ${{ startsWith(github.ref, 'refs/tags/v') || github.ref_name == 'master' || github.event.inputs.ci-full }} | |
| exclude: | |
| - os: windows-2025 | |
| arch: aarch64 | |
| - os: macos-14 | |
| is-release: false | |
| - os: macos-14 | |
| arch: x86_64 | |
| - os: windows-2025 | |
| is-release: false | |
| - os: ubuntu-22.04 | |
| arch: aarch64 | |
| - os: ubuntu-22.04-arm | |
| arch: x86_64 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-metadata | |
| path: rust/ | |
| # The C++ engine (the `perspective-server` build-script cmake | |
| # step) dominates this job and caches at ~100MB/platform; | |
| # `CMakeLists.txt` picks up the launcher via `PSP_USE_CCACHE`. | |
| - name: Initialize Build | |
| id: init-step | |
| uses: ./.github/actions/install-deps | |
| with: | |
| javascript: "false" | |
| arch: ${{ matrix.arch }} | |
| manylinux: ${{ matrix.container && 'true' || 'false' }} | |
| ccache: native-${{ matrix.os }}-${{ matrix.arch }} | |
| ccache_variant: ${{ contains(matrix.os, 'windows') && 'sccache' || 'ccache' }} | |
| cache_save: ${{ steps.config-step.outputs.SAVE_CACHE }} | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - name: Run df -h | |
| if: ${{ runner.os == 'Linux' }} | |
| run: df -h | |
| - name: Python Build | |
| run: pnpm run build | |
| if: ${{ runner.os != 'Windows' }} | |
| env: | |
| PACKAGE: "python" | |
| PSP_ARCH: ${{ matrix.arch }} | |
| PSP_ROOT_DIR: ${{ github.workspace }} | |
| PSP_BUILD_WHEEL: 1 | |
| PSP_USE_CCACHE: "1" | |
| # sccache instead of ccache on Windows: stable with MSVC, and | |
| # `RUSTC_WRAPPER` additionally caches the rust dependency graph | |
| # (rust-cache can't follow the `D:\psp-rust` redirect here). | |
| - name: Python Build (Windows) | |
| run: | | |
| New-Item -ItemType Directory -Path $env:CARGO_TARGET_DIR -Force | |
| pnpm run build | |
| if: ${{ runner.os == 'Windows' }} | |
| env: | |
| CARGO_TARGET_DIR: D:\psp-rust | |
| PSP_CPP_BUILD_DIR: D:\psp-build | |
| PSP_ROOT_DIR: ${{ github.workspace }} | |
| PACKAGE: "python" | |
| PSP_ARCH: ${{ matrix.arch }} | |
| PSP_BUILD_WHEEL: 1 | |
| PSP_USE_CCACHE: "1" | |
| PSP_CCACHE_BINARY: sccache | |
| RUSTC_WRAPPER: sccache | |
| - name: Run df -h | |
| if: ${{ runner.os == 'Linux' }} | |
| run: df -h | |
| # Windows sucks lol | |
| - uses: actions/upload-artifact@v4 | |
| if: ${{ runner.os == 'Windows' }} | |
| with: | |
| name: perspective-python-dist-${{ matrix.arch}}-${{ matrix.os }}-${{ matrix.python-version }} | |
| path: D:\psp-rust\wheels\*.whl | |
| - uses: actions/upload-artifact@v4 | |
| # if: ${{ runner.os != 'Windows' }} | |
| with: | |
| name: perspective-python-dist-${{ matrix.arch}}-${{ matrix.os }}-${{ matrix.python-version }} | |
| path: rust/target/wheels/*.whl | |
| # ,-,---. . . . ,--,--' . | |
| # '|___/ . . . | ,-| ,-. ,-. ,-| `- | ,-. ,-. |- | |
| # ,| \ | | | | | | ,-| | | | | , | |-' `-. | | |
| # `-^---' `-^ ' `' `-^ `-^ ' ' `-^ `-' `-' `-' `' | |
| # | |
| # .-,--. . | |
| # `|__/ . . ,-. |- | |
| # )| \ | | `-. | | |
| # `' ` `-^ `-' `' | |
| # | |
| build_and_test_rust: | |
| runs-on: ${{ matrix.os }} | |
| needs: [lint_and_docs] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| - windows-2025 | |
| arch: | |
| - x86_64 | |
| node-version: [22.x] | |
| is-release: | |
| - ${{ startsWith(github.ref, 'refs/tags/v') || github.ref_name == 'master' || github.event.inputs.ci-full }} | |
| exclude: | |
| - os: windows-2025 | |
| is-release: false | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-metadata | |
| path: rust/ | |
| - name: Initialize Build | |
| id: init-step | |
| uses: ./.github/actions/install-deps | |
| with: | |
| javascript: "false" | |
| arch: ${{ matrix.arch }} | |
| manylinux: "false" | |
| ccache: native-rust-${{ matrix.os }}-${{ matrix.arch }} | |
| ccache_variant: ${{ contains(matrix.os, 'windows') && 'sccache' || 'ccache' }} | |
| cargo_cache: ${{ contains(matrix.os, 'windows') && 'true' || 'false' }} | |
| cache_save: ${{ steps.config-step.outputs.SAVE_CACHE }} | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| # Linux only: rust-cache cannot follow the Windows job's | |
| # `CARGO_TARGET_DIR: D:\psp-rust` redirect (its `workspaces` | |
| # input path-joins, mangling absolute targets) — Windows relies | |
| # on ccache above, which covers its dominant C++ cost. | |
| - name: Setup rust cache | |
| if: ${{ !contains(matrix.os, 'windows') && steps.config-step.outputs.SKIP_CACHE != 'true' }} | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| # rust-cache doesn't read `.cargo/config.toml`'s | |
| # `target-dir = "rust/target"` redirect | |
| workspaces: ". -> rust/target" | |
| save-if: ${{ steps.config-step.outputs.SAVE_CACHE == 'true' }} | |
| - name: Rust Build | |
| run: pnpm run build | |
| if: ${{ !contains(matrix.os, 'windows') }} | |
| env: | |
| PACKAGE: "rust" | |
| PSP_ROOT_DIR: ${{ github.workspace }} | |
| PSP_USE_CCACHE: "1" | |
| # sccache on Windows — see `build_python`'s Windows build step. | |
| - name: Rust Build (Windows) | |
| run: | | |
| New-Item -ItemType Directory -Path $env:CARGO_TARGET_DIR -Force | |
| pnpm run build | |
| if: ${{ contains(matrix.os, 'windows') }} | |
| env: | |
| CARGO_TARGET_DIR: D:\psp-rust | |
| PSP_ROOT_DIR: ${{ github.workspace }} | |
| PACKAGE: "rust" | |
| PSP_USE_CCACHE: "1" | |
| PSP_CCACHE_BINARY: sccache | |
| RUSTC_WRAPPER: sccache | |
| - name: Rust Test | |
| if: ${{ !contains(matrix.os, 'windows') }} | |
| run: pnpm run test | |
| env: | |
| PACKAGE: "rust" | |
| PSP_ROOT_DIR: ${{ github.workspace }} | |
| PSP_USE_CCACHE: "1" | |
| - name: Rust Test (Windows) | |
| run: | | |
| New-Item -ItemType Directory -Path $env:CARGO_TARGET_DIR -Force | |
| pnpm run test | |
| if: ${{ contains(matrix.os, 'windows') }} | |
| env: | |
| CARGO_TARGET_DIR: D:\psp-rust | |
| PSP_ROOT_DIR: ${{ github.workspace }} | |
| PACKAGE: "rust" | |
| PSP_USE_CCACHE: "1" | |
| PSP_CCACHE_BINARY: sccache | |
| RUSTC_WRAPPER: sccache | |
| # ,-,---. . . .-,--. . . | |
| # '|___/ . . . | ,-| '|__/ . . ,-. ,-| . ,-| ,-. | |
| # ,| \ | | | | | | .| | | | | | | | | | |-' | |
| # `-^---' `-' ' `' `-' `' `-| `-' `-' ' `-' `-' | |
| # /| | |
| # `-' | |
| build_emscripten_wheel: | |
| runs-on: ${{ matrix.os }} | |
| # `build_js` for the `perspective-anywidget-dist` artifact, so that | |
| # maturin's `include` packages the widget bundle into the wheel | |
| # (jupyterlite has no repack step, unlike the native wheels). | |
| needs: [lint_and_docs, build_js] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| arch: | |
| - x86_64 | |
| python-version: | |
| - "3.13" | |
| node-version: [22.x] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-metadata | |
| path: rust/ | |
| # Shares the `emscripten-wasm32` ccache prefix and `wasm32` | |
| # emsdk sysroot with `build_js` — same toolchain, same target. | |
| - name: Initialize Build | |
| id: init-step | |
| uses: ./.github/actions/install-deps | |
| with: | |
| javascript: "false" | |
| arch: ${{ matrix.arch }} | |
| manylinux: "false" | |
| ccache: "emscripten-wasm32" | |
| emsdk_cache: "wasm32" | |
| cargo_cache: "false" | |
| cache_save: ${{ steps.config-step.outputs.SAVE_CACHE }} | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - name: Setup rust cache | |
| if: ${{ steps.config-step.outputs.SKIP_CACHE != 'true' }} | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| # rust-cache doesn't read `.cargo/config.toml`'s | |
| # `target-dir = "rust/target"` redirect | |
| workspaces: ". -> rust/target" | |
| save-if: ${{ steps.config-step.outputs.SAVE_CACHE == 'true' }} | |
| # Place the anywidget bundle in-tree _before_ maturin runs, so the | |
| # pyproject.toml `include` rules package it into the wheel — | |
| # without it `import perspective.widget` fails under jupyterlite. | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-anywidget-dist | |
| path: rust/perspective-python/perspective/widget/static | |
| - name: Python Build Pyodide | |
| run: pnpm install && pnpm run build | |
| env: | |
| PSP_PYODIDE: 1 | |
| PACKAGE: "python" | |
| CI: 1 | |
| PSP_USE_CCACHE: "1" | |
| - name: Verify wheel is PyPI-compatible (PEP 783) | |
| shell: bash | |
| run: | | |
| python -m pip install --quiet --upgrade twine "packaging>=24.2" | |
| shopt -s nullglob | |
| wheels=(rust/target/wheels/*.whl) | |
| if [ ${#wheels[@]} -eq 0 ]; then | |
| echo "::error::no emscripten wheel was produced"; exit 1 | |
| fi | |
| for w in "${wheels[@]}"; do | |
| echo "checking $w" | |
| case "$w" in | |
| *pyemscripten_2025_0_wasm32.whl) ;; | |
| *) echo "::error::$w is not tagged pyemscripten_2025_0_wasm32"; exit 1 ;; | |
| esac | |
| unzip -l "$w" | grep 'perspective/widget/static/perspective-anywidget.js' \ | |
| || { echo "::error::$w is missing the anywidget JS bundle"; exit 1; } | |
| unzip -l "$w" | grep 'perspective/widget/static/perspective-anywidget.css' \ | |
| || { echo "::error::$w is missing the anywidget CSS bundle"; exit 1; } | |
| done | |
| python -m twine check rust/target/wheels/*.whl | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: perspective-python-dist-wasm32-emscripten-${{ matrix.python-version }} | |
| path: rust/target/wheels/*.whl | |
| # ~*~ Test pyodide ~*~ | |
| test_emscripten_wheel: | |
| runs-on: ${{ matrix.os }} | |
| needs: [build_emscripten_wheel] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| arch: | |
| - x86_64 | |
| python-version: | |
| - "3.13" | |
| node-version: [22.x] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - name: Initialize Build | |
| uses: ./.github/actions/install-deps | |
| with: | |
| javascript: "false" | |
| arch: ${{ matrix.arch }} | |
| manylinux: "false" | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-python-dist-wasm32-emscripten-${{ matrix.python-version }} | |
| path: rust/target/wheels/ | |
| - name: Install Python Pyodide dependencies | |
| shell: bash | |
| run: python -m pip install -r rust/perspective-python/requirements-pyodide.txt | |
| - name: Install Pyodide distribution | |
| shell: bash | |
| run: pnpm run install_pyodide | |
| - name: Install Python Playwright browsers | |
| shell: bash | |
| run: python -m playwright install | |
| - name: "Test Pyodide" | |
| run: pnpm run test | |
| env: | |
| PSP_PYODIDE: 1 | |
| PACKAGE: "python" | |
| CI: 1 | |
| # ,-,---. . . . ,--,--' . | |
| # '|___/ . . . | ,-| ,-. ,-. ,-| `- | ,-. ,-. |- | |
| # ,| \ | | | | | | ,-| | | | | , | |-' `-. | | |
| # `-^---' `-^ ' `' `-^ `-^ ' ' `-^ `-' `-' `-' `' | |
| # | |
| # ,-_/ . . . | |
| # ' | . . ,-. . . |- ,-. ,-. | ,-. |-. | |
| # | | | | | | | | |-' | | ,-| | | | |
| # | `-^ |-' `-| `' `-' ' `' `-^ ^-' | |
| # /` | | /| | |
| # `--' ' `-' | |
| # | |
| build_python_sdist: | |
| needs: [build_js] | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| python-version: | |
| - 3.11 | |
| node-version: [22.x] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - name: Initialize Build | |
| id: init-step | |
| uses: ./.github/actions/install-deps | |
| with: | |
| playwright: "true" | |
| cpp: "false" | |
| emsdk_cache: "wasm32" | |
| cache_save: ${{ steps.config-step.outputs.SAVE_CACHE }} | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-js-dist | |
| path: . | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-metadata | |
| path: rust/ | |
| - name: Build extension | |
| run: pnpm run build | |
| env: | |
| # `anywidget` builds the widget bundle into the python static | |
| # dir; `jupyterlab` builds the labextension into the maturin | |
| # `data` dir the sdist packages. Order matters. | |
| PACKAGE: "anywidget,jupyterlab" | |
| - name: Python Build sdist | |
| run: pnpm run build | |
| env: | |
| PACKAGE: "python" | |
| PSP_BUILD_SDIST: 1 | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: perspective-python-sdist | |
| path: rust/target/wheels/*.tar.gz | |
| - name: Package | |
| if: ${{ steps.config-step.outputs.FULL_RUN }} | |
| run: cargo package --config .cargo/release.toml --no-verify --allow-dirty -p perspective -p perspective-viewer -p perspective-js -p perspective-client -p perspective-server -p perspective-python | |
| - uses: actions/upload-artifact@v4 | |
| if: ${{ steps.config-step.outputs.FULL_RUN }} | |
| with: | |
| name: perspective-rust | |
| path: rust/target/package/*.crate | |
| # A single Linux job: the injected labextension + anywidget assets are | |
| # platform-independent and `repack_wheel.mjs` is a zip rewrite, so this | |
| # job repacks EVERY platform's wheel (the old per-platform matrix burned | |
| # 2 extra runners on it — 8.8min of pure setup on Windows — and never | |
| # repacked the linux-aarch64 wheel at all, publishing it without the | |
| # labextension). Repacked wheels ship as one `-repacked` artifact | |
| # consumed by `publish`; the per-platform artifacts keep the original | |
| # un-repacked wheels for `test_python`/`benchmark_python`. | |
| build_and_test_jupyterlab: | |
| needs: [build_js, build_python] | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| python-version: | |
| - 3.11 | |
| node-version: [22.x] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - name: Initialize Build | |
| id: init-step | |
| uses: ./.github/actions/install-deps | |
| with: | |
| rust: "false" | |
| playwright: "true" | |
| cpp: "false" | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-js-dist | |
| path: . | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-metadata | |
| path: rust/ | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-python-dist-x86_64-ubuntu-22.04-${{ matrix.python-version }} | |
| path: . | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-python-dist-aarch64-ubuntu-22.04-arm-${{ matrix.python-version }} | |
| path: . | |
| # The win/mac wheels only exist on release-shaped runs — this | |
| # condition must mirror `build_python`'s `is-release` matrix. | |
| - uses: actions/download-artifact@v4 | |
| if: ${{ startsWith(github.ref, 'refs/tags/v') || github.ref_name == 'master' || github.event.inputs.ci-full == 'true' }} | |
| with: | |
| name: perspective-python-dist-aarch64-macos-14-${{ matrix.python-version }} | |
| path: . | |
| - uses: actions/download-artifact@v4 | |
| if: ${{ startsWith(github.ref, 'refs/tags/v') || github.ref_name == 'master' || github.event.inputs.ci-full == 'true' }} | |
| with: | |
| name: perspective-python-dist-x86_64-windows-2025-${{ matrix.python-version }} | |
| path: . | |
| - name: Build extension | |
| run: pnpm run build | |
| env: | |
| # `anywidget` builds the widget bundle into the python static | |
| # dir; `jupyterlab` builds the renderers labextension. Order | |
| # matters: anywidget first so the static bundle exists. | |
| PACKAGE: "anywidget,jupyterlab" | |
| - run: node tools/scripts/repack_wheel.mjs | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: perspective-python-dist-repacked | |
| path: "*.whl" | |
| # Only the Linux x86_64 wheel is installable on this runner — | |
| # the other platforms' wheels share the working directory. | |
| - uses: ./.github/actions/install-wheel | |
| with: | |
| glob: "*manylinux*x86_64.whl" | |
| - uses: ./.github/actions/install-wheel | |
| with: | |
| inplace: "false" | |
| glob: "*manylinux*x86_64.whl" | |
| # jlab_start.ts passes an explicit `--config`, so no | |
| # `jupyter lab --generate-config` is needed. | |
| - name: Run Jupyter Tests | |
| run: pnpm run test --jupyter | |
| env: | |
| PACKAGE: "jupyterlab" | |
| # ,--,--' . ,-_/ .---. . | |
| # `- | ,-. ,-. |- ' | ,-. . , ,-. \___ ,-. ,-. . ,-. |- | |
| # , | |-' `-. | | ,-| | / ,-| \ | | | | | | | |
| # `-' `-' `-' `' | `-^ `' `-^ `---' `-' ' ' |-' `' | |
| # /` | | | |
| # `--' ' | |
| test_js: | |
| needs: [build_js, build_js_wasm64] | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| python-version: | |
| - 3.11 | |
| node-version: [22.x, 26.x] | |
| is-release: | |
| - ${{ startsWith(github.ref, 'refs/tags/v') || github.ref_name == 'master' || github.event.inputs.ci-full }} | |
| exclude: | |
| - node-version: 26.x | |
| is-release: false | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - name: Initialize Build | |
| uses: ./.github/actions/install-deps | |
| with: | |
| python: "false" | |
| rust: "false" | |
| cpp: "false" | |
| playwright: "true" | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-js-dist | |
| path: . | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-server-wasm64-dist | |
| path: rust/perspective-server/dist/wasm | |
| - name: Run Tests | |
| id: run_tests | |
| run: pnpm run test -- --fetch-snapshots | |
| env: | |
| PACKAGE: "server,client,viewer,viewer-datagrid,viewer-charts,react" | |
| PSP_SNAPSHOT_REPO: ${{ vars.PSP_SNAPSHOT_REPO }} | |
| PSP_SNAPSHOT_TOKEN: ${{ secrets.PSP_SNAPSHOT_TOKEN }} | |
| PSP_SNAPSHOT_REF: ${{ github.head_ref || github.ref_name }} | |
| # PSP_USE_CCACHE: 1 | |
| - name: Upload Test Failures | |
| if: ${{ failure() && steps.run_tests.outcome == 'failure' }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: perspective-js-test-results-node${{ matrix.node-version }} | |
| path: tools/test/dist/results | |
| if-no-files-found: ignore | |
| overwrite: true | |
| # ,--,--' . .-,--. . . | |
| # `- | ,-. ,-. |- '|__/ . . |- |-. ,-. ,-. | |
| # , | |-' `-. | ,| | | | | | | | | | | |
| # `-' `-' `-' `' `' `-| `' ' ' `-' ' ' | |
| # /| | |
| # `-' | |
| test_python: | |
| needs: [build_python, build_js] | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| - ubuntu-22.04-arm | |
| - macos-14 | |
| - windows-2025 | |
| arch: | |
| - x86_64 | |
| - aarch64 | |
| python-version: | |
| - 3.11 | |
| # - 3.11 | |
| node-version: [22.x] | |
| is-release: | |
| - ${{ startsWith(github.ref, 'refs/tags/v') || github.ref_name == 'master' || github.event.inputs.ci-full }} | |
| exclude: | |
| - os: macos-14 | |
| is-release: false | |
| - os: macos-14 | |
| is-release: false | |
| - os: windows-2025 | |
| is-release: false | |
| - os: macos-14 | |
| arch: aarch64 | |
| - os: macos-14 | |
| arch: x86_64 | |
| - os: windows-2025 | |
| arch: aarch64 | |
| - os: ubuntu-22.04 | |
| arch: aarch64 | |
| - os: ubuntu-22.04-arm | |
| arch: x86_64 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - name: Initialize Build | |
| uses: ./.github/actions/install-deps | |
| with: | |
| rust: "false" | |
| cpp: "false" | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-python-dist-${{ matrix.arch }}-${{ matrix.os }}-${{ matrix.python-version }} | |
| - uses: ./.github/actions/install-wheel | |
| # `pytest` imports `perspective` from the source tree (the wheel | |
| # replaces it wholesale via `install-wheel`'s `pip install | |
| # --target`, hence _after_ that step), and `perspective.widget` | |
| # requires the anywidget bundle at import time. The wheel itself | |
| # only gains these assets when repacked in | |
| # `build_and_test_jupyterlab`, which runs in parallel. | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-anywidget-dist | |
| path: rust/perspective-python/perspective/widget/static | |
| - name: Run Tests | |
| run: pnpm run test | |
| env: | |
| PACKAGE: "python" | |
| # PSP_USE_CCACHE: 1 | |
| test_python_sdist: | |
| if: startsWith(github.ref, 'refs/tags/v') || github.ref_name == 'master' || github.event.inputs.ci-full | |
| needs: [build_python_sdist] | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: | |
| - ubuntu-22.04 | |
| arch: | |
| - x86_64 | |
| python-version: | |
| - 3.11 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| # sccache rather than ccache: pip unpacks the sdist into a | |
| # randomized temp dir each run, and `RUSTC_WRAPPER` also covers | |
| # the rust dependency compile inside the pip build. | |
| - name: Initialize Build | |
| uses: ./.github/actions/install-deps | |
| with: | |
| rust: "true" | |
| cpp: "true" | |
| python: "true" | |
| javascript: "false" | |
| ccache: "sdist-python" | |
| ccache_variant: "sccache" | |
| cache_save: ${{ steps.config-step.outputs.SAVE_CACHE }} | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-rust | |
| path: crates/ | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-python-sdist | |
| # The sdist depends on perspective-{client,server} crates published to | |
| # crates.io. Patch the build to instead use .crate artifacts built | |
| # previously in the workflow | |
| - name: Set up path overrides for perspective .crate contents | |
| shell: bash | |
| run: | | |
| (cd crates && tar xvf perspective-client-*.crate && tar xvf perspective-server-*.crate) | |
| CLIENT_CRATE_ROOT=$(ls -d "$PWD"/crates/perspective-client-*/ | head -n 1) | |
| SERVER_CRATE_ROOT=$(ls -d "$PWD"/crates/perspective-server-*/ | head -n 1) | |
| mkdir -p $HOME/.cargo | |
| cat > $HOME/.cargo/config.toml <<EOF | |
| [patch.crates-io] | |
| perspective-client = { path = "$CLIENT_CRATE_ROOT" } | |
| perspective-server = { path = "$SERVER_CRATE_ROOT" } | |
| EOF | |
| - name: Install perspective-python sdist | |
| shell: bash | |
| run: python -m pip install -vv ./perspective*.tar.gz | |
| env: | |
| PSP_USE_CCACHE: "1" | |
| PSP_CCACHE_BINARY: sccache | |
| RUSTC_WRAPPER: sccache | |
| - name: Verify licenses are installed | |
| shell: bash | |
| run: | | |
| pip show -f perspective-python | tee wheel_installed_files.txt | |
| # Maturin got this wrong: the packages should be in .dist-info/licenses/ | |
| # Newer versions of Maturin will fix it, so search for either location. | |
| # https://github.com/PyO3/maturin/pull/862 https://github.com/PyO3/maturin/pull/2181 | |
| grep -E '.dist-info/(licenses|license|license_files)/LICENSE.md' wheel_installed_files.txt | |
| grep -E '.dist-info/(licenses|license|license_files)/LICENSE_THIRDPARTY_cargo.yml' wheel_installed_files.txt | |
| - name: Verify labextension | |
| shell: bash | |
| run: | | |
| jupyter labextension list --debug | |
| jupyter labextension list 2>&1 | grep '@perspective-dev/jupyterlab' | |
| - name: Run import test | |
| run: python -c 'import perspective' | |
| - name: Run pytests | |
| run: pytest -v --pyargs 'perspective.tests' --timeout=300 | |
| # ,-,---. . . | |
| # '|___/ ,-. ,-. ,-. |-. ,-,-. ,-. ,-. | , | |
| # ,| \ |-' | | | | | | | | ,-| | |< | |
| # `-^---' `-' ' ' `-' ' ' ' ' ' `-^ ' ' ` | |
| # | |
| # .-,--. . . | |
| # '|__/ . . |- |-. ,-. ,-. | |
| # ,| | | | | | | | | | | |
| # `' `-| `' ' ' `-' ' ' | |
| # /| | |
| # `-' | |
| benchmark_python: | |
| needs: [build_python, build_js] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-22.04] | |
| python-version: [3.11] | |
| node-version: [22.x] | |
| arch: [x86_64] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - name: Initialize Build | |
| uses: ./.github/actions/install-deps | |
| with: | |
| rust: "false" | |
| cpp: "false" | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-js-dist | |
| path: . | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-python-dist-${{ matrix.arch }}-${{ matrix.os }}-${{ matrix.python-version }} | |
| - uses: ./.github/actions/install-wheel | |
| with: | |
| inplace: "false" | |
| - name: Benchmarks | |
| run: pnpm run bench | |
| env: | |
| PACKAGE: "python" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: perspective-python-benchmarks | |
| path: tools/bench/dist/benchmark-python.arrow | |
| # ,-,---. . . | |
| # '|___/ ,-. ,-. ,-. |-. ,-,-. ,-. ,-. | , | |
| # ,| \ |-' | | | | | | | | ,-| | |< | |
| # `-^---' `-' ' ' `-' ' ' ' ' ' `-^ ' ' ` | |
| # | |
| # ,-_/ .---. . | |
| # ' | ,-. . , ,-. \___ ,-. ,-. . ,-. |- | |
| # | ,-| | / ,-| \ | | | | | | | |
| # | `-^ `' `-^ `---' `-' ' ' |-' `' | |
| # /` | | | |
| # `--' ' | |
| benchmark_js: | |
| needs: [build_js] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| strategy: | |
| matrix: | |
| os: [ubuntu-22.04] | |
| node-version: [22.x] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - name: Initialize Build | |
| uses: ./.github/actions/install-deps | |
| with: | |
| rust: "false" | |
| cpp: "false" | |
| python: "false" | |
| javascript: "false" | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-js-dist | |
| path: . | |
| - name: Benchmarks | |
| run: pnpm run bench | |
| env: | |
| PACKAGE: "client" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: perspective-js-benchmarks | |
| path: tools/bench/dist/benchmark-js.arrow | |
| # .-,--. . . . | |
| # '|__/ . . |-. | . ,-. |-. | |
| # ,| | | | | | | `-. | | | |
| # `' `-^ ^-' `' ' `-' ' ' | |
| # | |
| publish: | |
| needs: | |
| [ | |
| build_and_test_jupyterlab, | |
| build_js_wasm64, | |
| test_python, | |
| test_python_sdist, | |
| test_js, | |
| benchmark_js, | |
| benchmark_python, | |
| build_emscripten_wheel, | |
| test_emscripten_wheel, | |
| build_and_test_rust, | |
| lint_and_docs, | |
| ] | |
| if: startsWith(github.ref, 'refs/tags/v') || github.ref_name == 'master' || github.event.inputs.ci-full | |
| strategy: | |
| matrix: | |
| os: [ubuntu-22.04] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v2 | |
| - name: Config | |
| id: config-step | |
| uses: ./.github/actions/config | |
| - name: Initialize Build | |
| uses: ./.github/actions/install-deps | |
| with: | |
| rust: "false" | |
| cpp: "false" | |
| python: "false" | |
| javascript: "false" | |
| skip_cache: ${{ steps.config-step.outputs.SKIP_CACHE }} | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-js-dist | |
| path: . | |
| # All native-platform wheels, with the labextension + anywidget | |
| # assets injected by `build_and_test_jupyterlab`. The per-platform | |
| # `perspective-python-dist-*` artifacts hold the un-repacked | |
| # originals and must not be published. | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-python-dist-repacked | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-python-dist-wasm32-emscripten-3.13 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-python-sdist | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-js-benchmarks | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-python-benchmarks | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-rust | |
| - run: pnpm pack --pack-destination=../.. | |
| working-directory: ./rust/perspective-js | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: perspective-server-wasm64-dist | |
| path: rust/perspective-server/dist/wasm | |
| # `files` globs don't fail on absence, so a silently-skipped | |
| # memory64 build would otherwise publish a wasm32-only package. | |
| - name: Assert wasm64 engine asset | |
| run: test -f rust/perspective-server/dist/wasm/perspective-server.memory64.wasm | |
| - run: pnpm pack --pack-destination=../.. | |
| working-directory: ./rust/perspective-server | |
| - run: pnpm pack --pack-destination=../.. | |
| working-directory: ./rust/perspective-viewer | |
| - run: pnpm pack --pack-destination=../.. | |
| working-directory: ./packages/viewer-datagrid | |
| - run: pnpm pack --pack-destination=../.. | |
| working-directory: ./packages/viewer-charts | |
| - run: pnpm pack --pack-destination=../.. | |
| working-directory: ./packages/react | |
| - run: pnpm pack --pack-destination=../.. | |
| working-directory: ./packages/cli | |
| - run: pnpm pack --pack-destination=../.. | |
| working-directory: ./packages/jupyterlab | |
| - name: Upload nightly artifacts | |
| uses: actions/upload-artifact@v4 | |
| if: ${{ steps.config-step.outputs.PUBLISH_RELEASE == 'false' }} | |
| with: | |
| name: nightly | |
| path: | | |
| *.whl | |
| *.tar.gz | |
| *.tgz | |
| *.arrow | |
| *.crate | |
| - name: Publish assets | |
| uses: softprops/action-gh-release@v2 | |
| if: ${{ steps.config-step.outputs.PUBLISH_RELEASE == 'true' }} | |
| with: | |
| draft: true | |
| generate_release_notes: true | |
| files: | | |
| *.whl | |
| *.tar.gz | |
| *.tgz | |
| *.arrow | |
| *.crate | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |