Files
wickra/.github/workflows/bench.yml
T
kingchenc 73415cd2dc ci: zizmor security hardening (#133)
* ci: pass ref context through env in release tag step

zizmor flagged the "Resolve target tag" step in release.yml for
template-injection: github.event_name / github.ref / github.ref_name
were interpolated directly into the shell script. On a tag push the tag
name is attacker-influenceable, so a crafted tag could inject commands.

Move all three context values into the step env and reference them as
shell variables instead. Verified with zizmor 1.16.3: template-injection
findings on release.yml drop from 2 to 0.

* ci: accept release.yml build caches via zizmor config

The release pipeline restores Swatinem/rust-cache and actions/setup-node
caches as a deliberate optimisation. zizmor flags all eight under
cache-poisoning because release.yml publishes to crates.io / PyPI / npm.
The caches are maintainer-controlled and the restore speedup is kept on
purpose, so accept the finding via a zizmor config ignore for release.yml
rather than running cache-free release builds. (Six of the eight are
actions/setup-node, reported at Low confidence.)

Adds .github/zizmor.yml; release.yml now reports 0 high findings.

* ci: drop persisted checkout credentials on read-only jobs

zizmor's artipacked audit flags every actions/checkout that keeps the
default persisted credential: the token is written to the runner's
.git/config, where it can leak if a later step packs .git into an
uploaded artifact, or be read by another step in the same job.

Set persist-credentials: false on the 20 checkouts whose jobs never push
or authenticate to git (build/test/clippy/msrv/coverage/supply-chain/
fuzz/python/wasm/node in ci.yml, plus bench.yml, codeql.yml, the seven
release.yml build/publish jobs, and sync-metadata.yml). The publish and
release jobs authenticate to crates.io / npm / PyPI / the GitHub API with
their own tokens, not persisted git credentials, so this is safe.

sync-about.yml genuinely pushes the indicator-count fix-up to the PR
branch, so it keeps its credential and is accepted via .github/zizmor.yml.
zizmor artipacked for the repo drops to 0 (0 high, 0 medium remaining).
2026-06-02 02:08:40 +02:00

120 lines
4.7 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Cross-library benchmark
# Audit finding R10: previously the cross-library benchmark ran on every push
# and every pull-request to `main`, adding 510 minutes of build + bench time
# per CI run with no consumer of the resulting artefact. The benchmark is now
# scheduled (nightly at 03:00 UTC) and on-demand via `workflow_dispatch`. The
# CI pipeline proper (.github/workflows/ci.yml) still verifies build / tests /
# lints on every push and pull-request.
on:
schedule:
# Nightly at 03:00 UTC. Pick a slot well away from common European /
# American working-hours pushes to keep this off the critical path.
- cron: "0 3 * * *"
workflow_dispatch:
inputs:
size:
description: "Number of bars per indicator (default 20000)"
required: false
default: "20000"
iterations:
description: "Batch iterations per indicator (default 10)"
required: false
default: "10"
# Least-privilege default for the auto-injected GITHUB_TOKEN. The single job
# only builds and uploads an artifact (upload-artifact uses the artifact
# storage API, not the contents scope), so it never needs repo write (OpenSSF
# Scorecard: Token-Permissions).
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
# Network-flake resilience: retry transient registry/DNS failures at the tool
# level so a blip fetching crates.io / PyPI inside any build step (cargo,
# maturin, pip) retries automatically instead of failing the job. Cargo treats
# "couldn't resolve host" / connect / timeout as spurious and retries with
# backoff; 10 attempts ride out a transient DNS blip on a runner.
CARGO_NET_RETRY: "10"
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
npm_config_fetch_retries: "5"
npm_config_fetch_retry_maxtimeout: "120000"
PIP_RETRIES: "5"
PIP_DEFAULT_TIMEOUT: "120"
jobs:
cross-library-bench:
name: Cross-library benchmark report
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable branch, 2026-03-27
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
continue-on-error: true # cache is an optimisation; never block on a stuck/slow restore
timeout-minutes: 6
- name: Set up Python
id: setup_python
continue-on-error: true
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
cache: pip
cache-dependency-path: .github/requirements/bench.txt
- name: Wait before Python retry
if: steps.setup_python.outcome == 'failure'
shell: bash
run: |
echo "::warning::setup-python failed (likely CDN flake), waiting 30s before retry..."
sleep 30
- name: Set up Python (retry)
if: steps.setup_python.outcome == 'failure'
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
cache: pip
cache-dependency-path: .github/requirements/bench.txt
- name: Install Python deps + peer libs
run: |
python -m pip install --upgrade pip
# Hash-locked deps (OpenSSF Scorecard PinnedDependencies). bench.yml
# runs on a single Python version (3.11), so one lock file suffices.
python -m pip install --require-hashes -r .github/requirements/bench.txt
- name: Build Wickra wheel
working-directory: bindings/python
run: maturin build --release --out dist
- name: Install Wickra wheel
working-directory: bindings/python
run: python -m pip install --find-links dist --force-reinstall wickra
- name: Run cross-library benchmark
working-directory: bindings/python
# workflow_dispatch inputs are untrusted; pass them through the
# environment and quote them rather than interpolating into the shell
# command (OpenSSF Scorecard: Dangerous-Workflow).
env:
BENCH_SIZE: ${{ github.event.inputs.size || '20000' }}
BENCH_ITERATIONS: ${{ github.event.inputs.iterations || '10' }}
run: |
python -m benchmarks.compare_libraries \
--size "$BENCH_SIZE" \
--iterations "$BENCH_ITERATIONS" \
--streaming-window 5000 --streaming-iterations 2 \
| tee benchmark.txt
- name: Upload report
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cross-library-bench
path: bindings/python/benchmark.txt