Add opt-in mimalloc memory allocator #3761
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: build-v2 | |
| # Build & publish wheels for the *v2* Python package living under the | |
| # `python/` directory. These wheels are uploaded to the dedicated | |
| # v2 package index at: | |
| # https://packages.nautechsystems.io/v2/simple/nautilus-trader/ | |
| permissions: | |
| # Principle of least privilege | |
| contents: read | |
| actions: read | |
| on: | |
| push: | |
| branches: | |
| - test-ci | |
| - test-ci-v2 | |
| - develop | |
| - nightly | |
| - master | |
| env: | |
| PACKAGE_DIR: python | |
| jobs: | |
| plan: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| run-tests: ${{ steps.plan.outputs.run_tests }} | |
| run-rust-tests: ${{ steps.plan.outputs.run_rust_tests }} | |
| steps: | |
| # https://github.com/step-security/harden-runner | |
| - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: ${{ vars.STEP_SECURITY_EGRESS_POLICY || 'block' }} | |
| allowed-endpoints: >- | |
| ${{ vars.COMMON_ALLOWED_ENDPOINTS }} | |
| ${{ vars.CI_ALLOWED_ENDPOINTS }} | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Plan | |
| id: plan | |
| shell: bash | |
| env: | |
| EVENT_NAME: ${{ github.event_name }} | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| BEFORE_SHA: ${{ github.event.before }} | |
| run: bash scripts/ci/plan.sh | |
| pre-commit: | |
| # Fork PRs stay on GitHub-hosted runners. | |
| runs-on: >- | |
| ${{ github.event.pull_request.head.repo.fork | |
| && 'ubuntu-22.04' | |
| || fromJson('["self-hosted", "Linux", "X64", "build-v2"]') }} | |
| env: | |
| # Self-hosted keeps Rust artifacts outside the workspace. | |
| CARGO_TARGET_DIR: >- | |
| ${{ github.event.pull_request.head.repo.fork | |
| && format('{0}/target', github.workspace) | |
| || '/home/runner/.cache/cargo-target/pre-commit' }} | |
| CARGO_CI_PROFILE: >- | |
| ${{ github.event.pull_request.head.repo.fork && 'ci-pr' || 'nextest' }} | |
| # Scopes incremental clippy/doc checks; empty for non-PR/push events. | |
| CHANGED_BASE_SHA: >- | |
| ${{ github.event.pull_request.base.sha || github.event.before }} | |
| steps: | |
| - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: ${{ vars.STEP_SECURITY_EGRESS_POLICY || 'block' }} | |
| allowed-endpoints: >- | |
| ${{ vars.COMMON_ALLOWED_ENDPOINTS }} | |
| ${{ vars.CI_ALLOWED_ENDPOINTS }} | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false | |
| # Full history so changed-file scripts can resolve CHANGED_BASE_SHA. | |
| fetch-depth: 0 | |
| # Temporary: fail fast on rare runner worktree corruption while we isolate the root cause | |
| - name: Verify immutable CI inputs (post-checkout) | |
| run: bash scripts/ci/verify-ci-inputs.sh post-checkout | |
| - name: Common setup | |
| uses: ./.github/actions/common-setup | |
| with: | |
| python-version: "3.13" | |
| # free-disk-space auto-skips on the nautilus-ci-runner-* pool. | |
| free-disk-space: "true" | |
| build-type: "pre-commit" | |
| rust-cache-enabled: ${{ github.event.pull_request.head.repo.fork && 'true' || 'false' }} | |
| - name: Limit Cargo build jobs on fork PR runners | |
| if: github.event.pull_request.head.repo.fork | |
| run: echo "CARGO_BUILD_JOBS=2" >> "$GITHUB_ENV" | |
| - name: Run pre-commit | |
| run: prek run --all-files | |
| build: | |
| if: needs.plan.outputs.run-tests == 'true' | |
| needs: | |
| - plan | |
| - pre-commit | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: | |
| - "3.12" | |
| - "3.13" | |
| - "3.14" | |
| runs-on: [self-hosted, Linux, X64, build-v2] | |
| defaults: | |
| run: | |
| shell: bash | |
| env: | |
| BUILD_MODE: release | |
| CARGO_CI_PROFILE: nextest | |
| RUST_BACKTRACE: 1 | |
| # Outside the workspace so it survives actions/checkout's git clean -ffdx, | |
| # giving us persistent on-disk Rust artifact reuse between runs. | |
| CARGO_TARGET_DIR: /home/runner/.cache/cargo-target/py${{ matrix.python-version }} | |
| # yamllint disable rule:line-length | |
| services: | |
| redis: | |
| image: public.ecr.aws/docker/library/redis:7.4.5-alpine3.21@sha256:bb186d083732f669da90be8b0f975a37812b15e913465bb14d845db72a4e3e08 | |
| ports: | |
| - 6379:6379 | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| postgres: | |
| image: public.ecr.aws/docker/library/postgres:16.4-alpine@sha256:5660c2cbfea50c7a9127d17dc4e48543eedd3d7a41a595a2dfa572471e37e64c | |
| env: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: pass | |
| POSTGRES_DB: nautilus | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd "pg_isready -U postgres -d nautilus" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| # yamllint enable rule:line-length | |
| steps: | |
| - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: ${{ vars.STEP_SECURITY_EGRESS_POLICY || 'block' }} | |
| allowed-endpoints: >- | |
| ${{ vars.COMMON_ALLOWED_ENDPOINTS }} | |
| ${{ vars.CI_ALLOWED_ENDPOINTS }} | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false | |
| # Temporary: fail fast on rare runner worktree corruption while we isolate the root cause | |
| - name: Verify immutable CI inputs (post-checkout) | |
| run: bash scripts/ci/verify-ci-inputs.sh post-checkout | |
| - name: Common setup | |
| uses: ./.github/actions/common-setup | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| # free-disk-space auto-skips on the nautilus-ci-runner-* pool. | |
| free-disk-space: "true" | |
| # Persistent CARGO_TARGET_DIR replaces Swatinem/rust-cache here. | |
| rust-cache-enabled: "false" | |
| - name: Install Nautilus CLI | |
| if: needs.plan.outputs.run-rust-tests == 'true' | |
| env: | |
| NAUTILUS_CLI_FORCE_SOURCE: ${{ github.ref == 'refs/heads/nightly' && '1' || '0' }} | |
| run: bash scripts/ci/install-nautilus-cli.sh | |
| - name: Init postgres schema | |
| if: needs.plan.outputs.run-rust-tests == 'true' | |
| run: nautilus database init --schema ${{ github.workspace }}/schema/sql | |
| env: | |
| POSTGRES_HOST: localhost | |
| POSTGRES_PORT: 5432 | |
| POSTGRES_USERNAME: postgres | |
| POSTGRES_PASSWORD: pass | |
| POSTGRES_DATABASE: nautilus | |
| - name: Cached test data | |
| if: needs.plan.outputs.run-rust-tests == 'true' | |
| uses: ./.github/actions/common-test-data | |
| - name: Run Rust tests (core) | |
| if: needs.plan.outputs.run-rust-tests == 'true' | |
| run: make cargo-test-core HYPERSYNC=true NEXTEST_PROFILE=ci | |
| - name: Run Rust tests (adapters) | |
| if: needs.plan.outputs.run-rust-tests == 'true' | |
| run: make cargo-test-adapters HYPERSYNC=true NEXTEST_PROFILE=ci | |
| - name: Clean Rust test artifacts | |
| if: needs.plan.outputs.run-rust-tests == 'true' | |
| run: | | |
| rm -rf "${CARGO_TARGET_DIR}/nextest" | |
| rm -rf "${CARGO_TARGET_DIR}/${CARGO_CI_PROFILE:-nextest}" | |
| df -h . | |
| # Update version for dev/nightly branches | |
| - name: Update version in pyproject.toml | |
| if: ${{ github.ref != 'refs/heads/master' }} | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: | | |
| bash ../scripts/ci/update-pyproject-version.sh | |
| # Temporary: fail fast on rare runner worktree corruption while we isolate the root cause | |
| - name: Verify immutable CI inputs (pre-wheel build) | |
| run: bash scripts/ci/verify-ci-inputs.sh pre-wheel-build | |
| # Build the wheel for v2 under python/ using maturin | |
| - name: Build wheel (v2) | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: | | |
| MATURIN_VERSION="$(bash ../scripts/maturin-version.bash)" | |
| uv run --no-project --no-build --with "maturin==${MATURIN_VERSION}" -- \ | |
| maturin build --release --out ../dist | |
| - name: Run v2 Python tests | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: | | |
| uv sync --group test --no-install-package nautilus-trader | |
| # Install the built wheel with the visualization extra so plotly/kaleido tests run | |
| wheel=$(echo ../dist/*.whl) | |
| uv pip install "${wheel}[visualization]" | |
| # Pin pandas test deps here until v2 runtime deps are settled | |
| uv pip install --only-binary :all: \ | |
| "numpy==2.4.6" \ | |
| "pandas==3.0.3" \ | |
| "python-dateutil==2.9.0.post0" \ | |
| "six==1.17.0" | |
| cd /tmp && uv run --project "$GITHUB_WORKSPACE/${{ env.PACKAGE_DIR }}" --no-sync pytest \ | |
| --import-mode=importlib \ | |
| --rootdir="$GITHUB_WORKSPACE/${{ env.PACKAGE_DIR }}" \ | |
| "$GITHUB_WORKSPACE/${{ env.PACKAGE_DIR }}/tests/" -v | |
| # Temporary: show whether v2 stub or docstring generation dirtied tracked files while we isolate CI drift | |
| - name: Report generated v2 file drift | |
| if: always() | |
| run: | | |
| targets=( | |
| python/generate_docstrings.py | |
| python/generate_stubs.py | |
| crates/pyo3 | |
| ':(glob)python/nautilus_trader/**/*.pyi' | |
| ':(glob)crates/**/src/python/**/*.rs' | |
| ) | |
| changes="$(git status --short --untracked-files=all -- "${targets[@]}")" | |
| if [ -z "$changes" ]; then | |
| echo "No generated v2 file drift detected" | |
| exit 0 | |
| fi | |
| echo "::warning::Tracked or untracked v2 build files changed during the job" | |
| printf '%s\n' "$changes" | |
| echo | |
| git diff --stat HEAD -- "${targets[@]}" || true | |
| - name: Upload wheel artifact | |
| uses: ./.github/actions/upload-artifact-wheel | |
| # Linux ARM64, macOS ARM64, and Windows x86_64 wheels build only on nightly (and the | |
| # test-ci-v2 branch for validation), keeping develop fast as Linux x86_64 only. | |
| build-linux-arm: | |
| if: > | |
| needs.plan.outputs.run-tests == 'true' && | |
| (github.ref_name == 'nightly' || github.ref_name == 'test-ci-v2' || github.ref_name == 'master') | |
| needs: | |
| - plan | |
| - pre-commit | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: | |
| - "3.12" | |
| - "3.13" | |
| - "3.14" | |
| runs-on: depot-ubuntu-22.04-arm-8 | |
| defaults: | |
| run: | |
| shell: bash | |
| env: | |
| BUILD_MODE: release | |
| RUST_BACKTRACE: 1 | |
| CARGO_TARGET_DIR: ${{ github.workspace }}/target/build-v2-linux-arm | |
| steps: | |
| - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: ${{ vars.STEP_SECURITY_EGRESS_POLICY || 'block' }} | |
| allowed-endpoints: >- | |
| ${{ vars.COMMON_ALLOWED_ENDPOINTS }} | |
| ${{ vars.CI_ALLOWED_ENDPOINTS }} | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false | |
| - name: Common setup | |
| uses: ./.github/actions/common-setup | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| free-disk-space: "true" | |
| rust-cache-key: build-v2-linux-arm | |
| rust-cache-workspaces: . -> target/build-v2-linux-arm | |
| rust-cache-save-if: ${{ github.event_name == 'push' }} | |
| - name: Update version in pyproject.toml | |
| if: ${{ github.ref != 'refs/heads/master' }} | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: bash ../scripts/ci/update-pyproject-version.sh | |
| - name: Build wheel (v2) | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: | | |
| MATURIN_VERSION="$(bash ../scripts/maturin-version.bash)" | |
| uv run --no-project --no-build --with "maturin==${MATURIN_VERSION}" -- \ | |
| maturin build --release --out ../dist | |
| - name: Smoke test wheel | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: bash ../scripts/ci/smoke-test-v2-wheel.sh | |
| - name: Upload wheel artifact | |
| uses: ./.github/actions/upload-artifact-wheel | |
| build-macos: | |
| if: > | |
| needs.plan.outputs.run-tests == 'true' && | |
| (github.ref_name == 'nightly' || github.ref_name == 'test-ci-v2' || github.ref_name == 'master') | |
| needs: | |
| - plan | |
| - pre-commit | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: | |
| - "3.12" | |
| - "3.13" | |
| - "3.14" | |
| runs-on: macos-latest | |
| defaults: | |
| run: | |
| shell: bash | |
| env: | |
| BUILD_MODE: release | |
| RUST_BACKTRACE: 1 | |
| CARGO_TARGET_DIR: ${{ github.workspace }}/target/build-v2-macos | |
| steps: | |
| - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: ${{ vars.STEP_SECURITY_EGRESS_POLICY || 'block' }} | |
| allowed-endpoints: >- | |
| ${{ vars.COMMON_ALLOWED_ENDPOINTS }} | |
| ${{ vars.CI_ALLOWED_ENDPOINTS }} | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false | |
| - name: Common setup | |
| uses: ./.github/actions/common-setup | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| free-disk-space: "true" | |
| rust-cache-key: build-v2-macos | |
| rust-cache-workspaces: . -> target/build-v2-macos | |
| rust-cache-save-if: ${{ github.event_name == 'push' }} | |
| - name: Update version in pyproject.toml | |
| if: ${{ github.ref != 'refs/heads/master' }} | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: bash ../scripts/ci/update-pyproject-version.sh | |
| - name: Build wheel (v2) | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: | | |
| MATURIN_VERSION="$(bash ../scripts/maturin-version.bash)" | |
| uv run --no-project --no-build --with "maturin==${MATURIN_VERSION}" -- \ | |
| maturin build --release --out ../dist | |
| - name: Smoke test wheel | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: bash ../scripts/ci/smoke-test-v2-wheel.sh | |
| - name: Upload wheel artifact | |
| uses: ./.github/actions/upload-artifact-wheel | |
| build-windows: | |
| if: > | |
| needs.plan.outputs.run-tests == 'true' && | |
| (github.ref_name == 'nightly' || github.ref_name == 'test-ci-v2' || github.ref_name == 'master') | |
| needs: | |
| - plan | |
| - pre-commit | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: | |
| - "3.12" | |
| - "3.13" | |
| - "3.14" | |
| runs-on: depot-windows-2022-8 | |
| defaults: | |
| run: | |
| shell: bash | |
| env: | |
| BUILD_MODE: release | |
| RUST_BACKTRACE: 1 | |
| CARGO_TARGET_DIR: ${{ github.workspace }}/target/build-v2-windows | |
| steps: | |
| # Harden-Runner skips its agent on Depot Windows, and its post step assumes | |
| # C:\agent exists. Keep this job out until upstream fixes cleanup. | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false | |
| - name: Common setup | |
| uses: ./.github/actions/common-setup | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| free-disk-space: "true" | |
| rust-cache-key: build-v2-windows | |
| rust-cache-workspaces: . -> target/build-v2-windows | |
| rust-cache-save-if: ${{ github.event_name == 'push' }} | |
| - name: Update version in pyproject.toml | |
| if: ${{ github.ref != 'refs/heads/master' }} | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: bash ../scripts/ci/update-pyproject-version.sh | |
| - name: Build wheel (v2) | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: | | |
| MATURIN_VERSION="$(bash ../scripts/maturin-version.bash)" | |
| uv run --no-project --no-build --with "maturin==${MATURIN_VERSION}" -- \ | |
| maturin build --release --out ../dist | |
| - name: Smoke test wheel | |
| working-directory: ${{ env.PACKAGE_DIR }} | |
| run: bash ../scripts/ci/smoke-test-v2-wheel.sh | |
| - name: Upload wheel artifact | |
| uses: ./.github/actions/upload-artifact-wheel | |
| publish: | |
| needs: | |
| - build | |
| - build-linux-arm | |
| - build-macos | |
| - build-windows | |
| runs-on: ubuntu-latest | |
| # Publish dev/nightly wheels to the R2 v2 index. The platform jobs are skipped on develop | |
| # (Linux x86_64 only there), so guard on results rather than success: require the Linux | |
| # build and tolerate skipped (but not failed) platform jobs. master publishes to PyPI via | |
| # publish-pypi instead, so it is intentionally excluded here. | |
| if: > | |
| !cancelled() && | |
| needs.build.result == 'success' && | |
| needs.build-linux-arm.result != 'failure' && | |
| needs.build-macos.result != 'failure' && | |
| needs.build-windows.result != 'failure' && | |
| (github.ref_name == 'develop' || | |
| github.ref_name == 'nightly') | |
| environment: r2-${{ github.ref_name }} | |
| permissions: | |
| actions: write # Required for deleting artifacts | |
| contents: read | |
| id-token: write # Required for attestations | |
| attestations: write # Required for attestations | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| CLOUDFLARE_R2_URL: ${{ secrets.CLOUDFLARE_R2_URL }} | |
| CLOUDFLARE_R2_REGION: "auto" | |
| CLOUDFLARE_R2_BUCKET_NAME: "packages" | |
| CLOUDFLARE_R2_PREFIX: "v2/simple/nautilus-trader" | |
| steps: | |
| - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: ${{ vars.STEP_SECURITY_EGRESS_POLICY || 'block' }} | |
| allowed-endpoints: >- | |
| ${{ vars.COMMON_ALLOWED_ENDPOINTS }} | |
| ${{ vars.CI_ALLOWED_ENDPOINTS }} | |
| tuf-repo-cdn.sigstore.dev:443 | |
| ${{ secrets.CLOUDFLARE_R2_ALLOWED_HOST }}:443 | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false | |
| - name: Block develop publish after failed security audit | |
| if: github.ref_name == 'develop' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: bash scripts/ci/check-security-audit-result.sh | |
| - name: Download built wheels | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| path: dist | |
| pattern: "nautilus_trader-*.whl" | |
| merge-multiple: true | |
| # https://github.com/actions/attest-build-provenance | |
| - name: Attest wheel provenance | |
| uses: ./.github/actions/attest-build-provenance-retry | |
| with: | |
| subject-path: "dist/nautilus_trader-*.whl" | |
| - name: Verify wheel attestations | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| ATTESTATION_IDENTITY: ${{ github.server_url }}/${{ github.workflow_ref }} | |
| ATTESTATION_ISSUER: https://token.actions.githubusercontent.com | |
| run: bash ./scripts/ci/verify-gh-attestations.bash dist/nautilus_trader-*.whl | |
| - name: Publish wheels to Cloudflare R2 (v2 bucket) | |
| uses: ./.github/actions/publish-wheels | |
| - name: Fetch and delete artifacts for current run | |
| shell: bash | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: |- | |
| bash ./scripts/ci/publish-wheels-delete-artifacts.sh | |
| # Dependency license, advisory, and ban checks (master only - gates the v2 PyPI release). | |
| # Mirrors build.yml so the v2 publish respects the same supply-chain gate as the v1 release. | |
| cargo-deny: | |
| if: github.ref == 'refs/heads/master' | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: ${{ vars.STEP_SECURITY_EGRESS_POLICY || 'block' }} | |
| allowed-endpoints: >- | |
| ${{ vars.COMMON_ALLOWED_ENDPOINTS }} | |
| ${{ vars.CI_ALLOWED_ENDPOINTS }} | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false | |
| - name: Install cargo-deny | |
| uses: ./.github/actions/cargo-tool-install | |
| with: | |
| tool-name: cargo-deny | |
| - name: Run cargo-deny (advisories, licenses, sources, bans) | |
| run: | | |
| cargo deny --all-features check advisories licenses sources bans | |
| cargo deny --manifest-path crates/adapters/lighter/fuzz/Cargo.toml \ | |
| --locked --all-features check --config .cargo/deny-fuzz.toml \ | |
| advisories licenses sources bans | |
| cargo deny --manifest-path crates/adapters/derive/fuzz/Cargo.toml \ | |
| --locked --all-features check --config .cargo/deny-fuzz.toml \ | |
| advisories licenses sources bans | |
| # Supply chain security auditing (master only - gates the v2 PyPI release). | |
| cargo-vet: | |
| if: github.ref == 'refs/heads/master' | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: ${{ vars.STEP_SECURITY_EGRESS_POLICY || 'block' }} | |
| allowed-endpoints: >- | |
| ${{ vars.COMMON_ALLOWED_ENDPOINTS }} | |
| ${{ vars.CI_ALLOWED_ENDPOINTS }} | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false | |
| - name: Install cargo-vet | |
| uses: ./.github/actions/cargo-tool-install | |
| with: | |
| tool-name: cargo-vet | |
| - name: Run cargo-vet | |
| run: | | |
| cargo vet --locked | |
| cargo vet --locked --manifest-path crates/adapters/lighter/fuzz/Cargo.toml \ | |
| --store-path .supply-chain | |
| cargo vet --locked --manifest-path crates/adapters/derive/fuzz/Cargo.toml \ | |
| --store-path .supply-chain | |
| publish-pypi: | |
| needs: | |
| - build | |
| - build-linux-arm | |
| - build-macos | |
| - build-windows | |
| - cargo-deny | |
| - cargo-vet | |
| runs-on: ubuntu-latest | |
| # Publish the v2 wheels to PyPI on master only. The platform builds plus the cargo-deny and | |
| # cargo-vet supply-chain gates must all succeed (none are skipped on master), giving the same | |
| # all-or-nothing release gating as build.yml's v1 PyPI publish. crates.io stays in build.yml; | |
| # this job publishes only the python/ package. PyPI Trusted Publishing requires environment | |
| # `release` (registered as a trusted publisher for build-v2.yml on the nautilus-trader project). | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| environment: release | |
| permissions: | |
| actions: read # Required for downloading build artifacts | |
| contents: read | |
| id-token: write # Required for PyPI Trusted Publishing and publish attestations | |
| attestations: write # Required for GitHub artifact attestations | |
| steps: | |
| - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 | |
| with: | |
| egress-policy: ${{ vars.STEP_SECURITY_EGRESS_POLICY || 'block' }} | |
| allowed-endpoints: >- | |
| ${{ vars.COMMON_ALLOWED_ENDPOINTS }} | |
| ${{ vars.CI_ALLOWED_ENDPOINTS }} | |
| tuf-repo-cdn.sigstore.dev:443 | |
| pypi.org:443 | |
| files.pythonhosted.org:443 | |
| upload.pypi.org:443 | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false | |
| - name: Get release Python tool versions | |
| shell: bash | |
| run: | | |
| echo "UV_VERSION=$(bash scripts/uv-version.sh)" >> "$GITHUB_ENV" | |
| echo "PYPI_ATTESTATIONS_VERSION=$(bash scripts/tool-version.sh pypi-attestations)" >> "$GITHUB_ENV" | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 | |
| with: | |
| version: ${{ env.UV_VERSION }} | |
| enable-cache: false | |
| - name: Download built wheel artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| path: dist | |
| pattern: "nautilus_trader-*.whl" | |
| merge-multiple: true | |
| - name: Generate PyPI publish attestations | |
| run: bash ./scripts/ci/sign-pypi-attestations.bash dist/nautilus_trader-*.whl | |
| # https://github.com/actions/attest-build-provenance | |
| - name: Attest wheel provenance | |
| uses: ./.github/actions/attest-build-provenance-retry | |
| with: | |
| subject-path: "dist/nautilus_trader-*.whl" | |
| - name: Verify wheel attestations | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| ATTESTATION_IDENTITY: ${{ github.server_url }}/${{ github.workflow_ref }} | |
| ATTESTATION_ISSUER: https://token.actions.githubusercontent.com | |
| run: bash ./scripts/ci/verify-gh-attestations.bash dist/nautilus_trader-*.whl | |
| - name: Publish wheels to PyPI | |
| if: success() | |
| run: bash ./scripts/ci/publish-pypi-trusted.bash wheels |