Skip to content

chore: release v1.3.2 #5413

chore: release v1.3.2

chore: release v1.3.2 #5413

Workflow file for this run

# This file is part of the jebel-quant/rhiza repository
# (https://github.com/jebel-quant/rhiza).
#
# Workflow: Continuous Integration
#
# Purpose: Run tests on multiple Python versions, check dependencies, run
# pre-commit hooks, verify documentation coverage, validate the
# project, run security scans, and check license compliance.
#
# Python version matrix source of truth:
# - Generated by hynek/build-and-inspect-python-package
# - Reads `Programming Language :: Python :: 3.x` classifiers from package metadata
# - Adding/removing classifiers updates CI Python coverage automatically
#
# Trigger: On push and pull_request.
name: "(RHIZA) CI"
# Cancel superseded in-progress runs of this workflow for the same ref.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
actions: read
on:
push:
pull_request:
workflow_call:
secrets:
GH_PAT:
required: false
UV_EXTRA_INDEX_URL:
required: false
jobs:
generate-matrix:
# CI budget: ≤5 min (matrix generation/setup). Last measured: 2026-05-28.
timeout-minutes: 5
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.versions-output.outputs.list }}
os_matrix: ${{ steps.os.outputs.list }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
lfs: true
- id: versions
name: Build package metadata and extract supported Python classifiers
uses: hynek/build-and-inspect-python-package@d44ca7d91762de7a7d5436ddae667c6da6d1c3df # v2.18.0
- id: versions-output
run: |
echo "list=${{ steps.versions.outputs.supported_python_classifiers_json_array }}" >> "$GITHUB_OUTPUT"
- name: Debug matrix
run: |
echo "Python versions: ${{ steps.versions-output.outputs.list }}"
- id: os
run: |
OS_MATRIX=$(make -f .rhiza/rhiza.mk -s ci-os-matrix)
echo "list=$OS_MATRIX" >> "$GITHUB_OUTPUT"
- name: Debug OS matrix
run: |
echo "OS versions: ${{ steps.os.outputs.list }}"
test:
# CI budget: ≤20 min (test matrix execution). Last measured: 2026-05-28.
timeout-minutes: 20
needs: generate-matrix
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
os: ${{ fromJson(needs.generate-matrix.outputs.os_matrix) }}
fail-fast: false
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
lfs: true
- name: Install uv
id: install-uv
continue-on-error: true
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
version: "0.11.16"
python-version: ${{ matrix.python-version }}
- name: Retry uv installation
if: steps.install-uv.outcome == 'failure'
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
version: "0.11.16"
python-version: ${{ matrix.python-version }}
- name: Configure git auth for private packages
uses: jebel-quant/actions/configure-git-auth@6d52725ca371d609489c5b50236965ad70bbe528 # v1
with:
token: ${{ secrets.GH_PAT }}
- name: Cache uv artifacts
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: ~/.cache/uv
key: ${{ runner.os }}-uv-${{ hashFiles('uv.lock') }}
restore-keys: |
${{ runner.os }}-uv-
- name: Run tests
env:
UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
shell: bash
run: |
make test
- name: Verify clean working tree
if: matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest'
shell: bash
run: |
status="$(git status --porcelain)"
if [[ -n "$status" ]]; then
echo "Working tree is dirty after make test:"
printf '%s\n' "$status"
git diff --exit-code || true
exit 1
fi
- name: Upload coverage report
if: matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-report
path: _tests/coverage.xml
if-no-files-found: ignore
lowest-deps:
name: Lowest-direct dependency compatibility
# CI budget: ≤20 min (dependency compatibility test run). Last measured: 2026-05-28.
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
version: "0.11.16"
- name: Configure git auth for private packages
uses: jebel-quant/actions/configure-git-auth@6d52725ca371d609489c5b50236965ad70bbe528 # v1
with:
token: ${{ secrets.GH_PAT }}
- name: Install project with lowest-direct resolution
env:
UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
run: uv sync --all-extras --all-groups --resolution lowest-direct
- name: Run tests with lowest-direct resolution
env:
UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
run: uv run --all-extras --all-groups --resolution lowest-direct pytest tests -q --ignore=tests/stress --ignore=tests/benchmarks
typecheck:
name: Type checking (Python ${{ matrix.python-version }})
# CI budget: ≤5 min (lint/typecheck quality gate). Last measured: 2026-05-28.
timeout-minutes: 5
needs: generate-matrix
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
fail-fast: false
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
version: "0.11.16"
python-version: ${{ matrix.python-version }}
- name: Configure git auth for private packages
uses: jebel-quant/actions/configure-git-auth@6d52725ca371d609489c5b50236965ad70bbe528 # v1
with:
token: ${{ secrets.GH_PAT }}
- name: Run ty and mypy type checkers (make typecheck)
# Runs `uv run ty check src/` and `uv run mypy --strict src/`
# as defined in .rhiza/make.d/test.mk. Set TYPECHECKER=ty or
# TYPECHECKER=mypy to run only one of the two checkers.
env:
UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
run: make typecheck
deptry:
name: Check dependencies with deptry
# CI budget: ≤5 min (lint/dependency hygiene check). Last measured: 2026-05-28.
timeout-minutes: 5
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
version: "0.11.16"
- name: Configure git auth for private packages
uses: jebel-quant/actions/configure-git-auth@6d52725ca371d609489c5b50236965ad70bbe528 # v1
with:
token: ${{ secrets.GH_PAT }}
- name: Run deptry
run: make deps
pre-commit:
name: Pre-commit hooks
# CI budget: ≤5 min (lint/format hooks). Last measured: 2026-05-28.
timeout-minutes: 5
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Configure git auth for private packages
uses: jebel-quant/actions/configure-git-auth@6d52725ca371d609489c5b50236965ad70bbe528 # v1
with:
token: ${{ secrets.GH_PAT }}
- name: Cache prek environments
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: ~/.cache/prek
key: ${{ runner.os }}-prek-${{ hashFiles('.pre-commit-config.yaml') }}
restore-keys: |
${{ runner.os }}-prek-
- name: Run prek
run: |
make fmt
docs-coverage:
# CI budget: ≤10 min (docs quality check). Last measured: 2026-05-28.
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
version: "0.11.16"
- name: Configure git auth for private packages
uses: jebel-quant/actions/configure-git-auth@6d52725ca371d609489c5b50236965ad70bbe528 # v1
with:
token: ${{ secrets.GH_PAT }}
- name: Check docs coverage
env:
UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
run: |
make docs-coverage
security:
name: Security scanning
# CI budget: ≤10 min (security scanning and suppression audit). Last measured: 2026-05-28.
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
version: "0.11.16"
- name: Configure git auth for private packages
uses: jebel-quant/actions/configure-git-auth@6d52725ca371d609489c5b50236965ad70bbe528 # v1
with:
token: ${{ secrets.GH_PAT }}
- name: Run security scans
env:
UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
run: make security
license:
name: License compliance scan
# CI budget: ≤10 min (license and artifact generation). Last measured: 2026-05-28.
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
version: "0.11.16"
- name: Configure git auth for private packages
uses: jebel-quant/actions/configure-git-auth@6d52725ca371d609489c5b50236965ad70bbe528 # v1
with:
token: ${{ secrets.GH_PAT }}
- name: Run license check
env:
UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
run: make license
- name: Generate LICENSES.md
env:
UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
run: |
uv run --with pip-licenses pip-licenses --format markdown --output-file LICENSES.md
- name: Upload LICENSES.md
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: LICENSES.md
path: LICENSES.md
if-no-files-found: ignore
ci-gate:
name: CI gate
# Roll-up gate: a single required status check that aggregates the test,
# typecheck, and lowest-deps jobs. Branch protection requires this context
# instead of every per-leg name, so the matrix can change without editing
# the ruleset.
# CI budget: ≤5 min (result aggregation only). Last measured: 2026-06-27.
timeout-minutes: 5
if: always()
needs: [test, typecheck, lowest-deps]
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Verify test, typecheck, and lowest-deps succeeded
run: |
echo "test result: ${{ needs.test.result }}"
echo "typecheck result: ${{ needs.typecheck.result }}"
echo "lowest-deps result: ${{ needs.lowest-deps.result }}"
# Accept "success" or "cancelled" (transient runner cancellation).
# Reject "failure" (real failure) and "skipped" (job never ran).
if [[ "${{ needs.test.result }}" != "success" && "${{ needs.test.result }}" != "cancelled" \
|| "${{ needs.typecheck.result }}" != "success" && "${{ needs.typecheck.result }}" != "cancelled" \
|| "${{ needs.lowest-deps.result }}" != "success" && "${{ needs.lowest-deps.result }}" != "cancelled" ]]; then
echo "::error::test, typecheck, and/or lowest-deps did not succeed; failing the CI gate."
exit 1
fi
echo "All required CI jobs succeeded."