From 559acbca0022f9949fef0b60658078538d1fb789 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 13 Aug 2026 12:05:40 -0400 Subject: [PATCH 1/4] chore: secure CI Pin all GitHub Actions to SHAs, remove default token permissions, and add supply-chain cooldowns. Assisted-by: ClaudeCode:claude-opus-5 --- .github/dependabot.yml | 18 ++++++++-- .github/workflows/cd.yml | 28 ++++++++++----- .github/workflows/ci.yml | 60 +++++++++++++++++++++++---------- .github/workflows/gpu.yml | 8 ++--- .github/workflows/notebooks.yml | 10 ++++-- .pre-commit-config.yaml | 21 ++++++++---- pyproject.toml | 5 +++ 7 files changed, 109 insertions(+), 41 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6c4b3695..f5838975 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,8 +4,22 @@ updates: - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "weekly" + interval: "monthly" groups: - actions: + github-actions: patterns: - "*" + cooldown: + default-days: 7 + + # Maintain pre-commit hooks + - package-ecosystem: "pre-commit" + directory: "/" + schedule: + interval: "monthly" + groups: + pre-commit: + patterns: + - "*" + cooldown: + default-days: 7 diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 90d825e8..4129e17a 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -6,17 +6,26 @@ on: types: - published +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + jobs: dist: + name: Build sdist and wheel runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 + persist-credentials: false - - uses: hynek/build-and-inspect-python-package@v2 + - uses: hynek/build-and-inspect-python-package@2abe76da66d0a6a4a227101f9348ee855797cfa5 # v3.0.1 publish: + name: Publish to PyPI needs: [dist] runs-on: ubuntu-latest if: github.event_name == 'release' && github.event.action == 'published' @@ -24,11 +33,12 @@ jobs: name: pypi url: https://pypi.org/p/vector permissions: - id-token: write - attestations: write + id-token: write # trusted publishing to PyPI + attestations: write # record build provenance for the sdist and the wheel + contents: read # gh attestation verify reads this repository steps: - - uses: actions/download-artifact@v8 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: Packages path: dist @@ -44,13 +54,15 @@ jobs: - name: Verify sdist artifact attestation env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh attestation verify dist/vector-*.tar.gz --repo ${{ github.repository }} + REPOSITORY: ${{ github.repository }} + run: gh attestation verify dist/vector-*.tar.gz --repo "$REPOSITORY" - name: Verify wheel artifact attestation env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh attestation verify dist/vector-*.whl --repo ${{ github.repository }} + REPOSITORY: ${{ github.repository }} + run: gh attestation verify dist/vector-*.whl --repo "$REPOSITORY" - - uses: pypa/gh-action-pypi-publish@release/v1 + - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 with: attestations: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75b08e6c..2cc8a439 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,8 @@ on: - develop workflow_dispatch: +permissions: {} + concurrency: # Skip intermediate builds: always. # Cancel intermediate builds: only if it is a pull request build. @@ -21,19 +23,23 @@ env: jobs: pre-commit: - runs-on: ubuntu-latest name: Check SDist + runs-on: ubuntu-latest + permissions: {} steps: - - uses: actions/checkout@v7 - - uses: actions/setup-python@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: 3.x - - uses: astral-sh/setup-uv@v9.0.0 + - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 - name: PyLint run: uvx nox -s pylint -- --output-format=github check-lite: runs-on: ubuntu-latest + permissions: {} strategy: fail-fast: false matrix: @@ -46,21 +52,26 @@ jobs: - "3.14t" name: Python ${{ matrix.python-version }} - Lite steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - - uses: actions/setup-python@v7 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} allow-prereleases: true - - uses: astral-sh/setup-uv@v9.0.0 + - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 - name: Test lite package - run: uvx nox -s lite-${{ matrix.python-version }} --verbose + run: uvx nox -s lite-$PYTHON --verbose + env: + PYTHON: ${{ matrix.python-version }} check-full: needs: [check-lite] runs-on: ubuntu-latest + permissions: {} strategy: fail-fast: false matrix: @@ -73,45 +84,58 @@ jobs: - "3.14t" name: Python ${{ matrix.python-version }} - Full steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - - uses: actions/setup-python@v7 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} allow-prereleases: true - - uses: astral-sh/setup-uv@v9.0.0 + - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 - name: Install nox run: uv tool install nox - name: Run doctests on Python 3.11 if: matrix.python-version == 3.11 - run: nox -s doctests-${{ matrix.python-version }} --verbose + run: nox -s doctests-$PYTHON --verbose + env: + PYTHON: ${{ matrix.python-version }} - name: Test package and generate coverage report - run: nox -s coverage-${{ matrix.python-version }} --verbose + run: nox -s coverage-$PYTHON --verbose + env: + PYTHON: ${{ matrix.python-version }} - name: Upload coverage report - uses: codecov/codecov-action@v7.0.0 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 with: token: ${{ secrets.CODECOV_TOKEN }} root: - runs-on: ubuntu-latest name: ROOT comparison tests + runs-on: ubuntu-latest + permissions: {} steps: - - uses: actions/checkout@v7 - - uses: prefix-dev/setup-pixi@v0.10.1 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: prefix-dev/setup-pixi@f00437f565399d418b0acc85936d12c1fb668347 # v0.10.1 with: environments: root - name: Run ROOT comparison tests run: pixi run root-tests pass: + name: Pass needs: [pre-commit, check-lite, check-full, root] if: always() runs-on: ubuntu-latest + permissions: {} steps: - name: Decide whether all required jobs succeeded - run: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} + run: $SUCCESS + env: + SUCCESS: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} diff --git a/.github/workflows/gpu.yml b/.github/workflows/gpu.yml index 0c51f55d..d6dd3aaf 100644 --- a/.github/workflows/gpu.yml +++ b/.github/workflows/gpu.yml @@ -8,8 +8,7 @@ on: - main workflow_dispatch: -permissions: - contents: read +permissions: {} concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -23,6 +22,7 @@ jobs: name: CUDA ${{ matrix.cuda-version }} if: github.event_name != 'schedule' || github.repository_owner == 'scikit-hep' runs-on: self-hosted + permissions: {} timeout-minutes: 60 # Required for micromamba to activate conda @@ -43,11 +43,11 @@ jobs: rm -rf * .[!.]* || echo "Nothing to clean" rm -rf ~/micromamba* || echo "Nothing to clean" - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: mamba-org/setup-micromamba@v3 + - uses: mamba-org/setup-micromamba@f457c30a868e4760d3a6fcea5f25dc655b8edf39 # v3.2.1 with: environment-name: test-env init-shell: bash diff --git a/.github/workflows/notebooks.yml b/.github/workflows/notebooks.yml index de496766..98036540 100644 --- a/.github/workflows/notebooks.yml +++ b/.github/workflows/notebooks.yml @@ -7,6 +7,8 @@ on: - develop workflow_dispatch: +permissions: {} + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -18,13 +20,17 @@ env: jobs: test: + name: Test notebooks runs-on: ubuntu-latest + permissions: {} steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Set up Python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.10" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 38a9ff24..2f04b599 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v6.0.0 + rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 hooks: - id: check-added-large-files - id: check-case-conflict @@ -19,14 +19,14 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.15.20" + rev: "c59bba8fb259db0fec2bbb77ad8ba51ea7341b56" # frozen: v0.15.20 hooks: - id: ruff-check args: ["--fix", "--show-fixes"] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v2.1.0 + rev: d2823d321df3af8f878f7ee3414dc94d037145b9 # frozen: v2.1.0 hooks: - id: mypy files: src @@ -40,29 +40,36 @@ repos: - optree - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 + rev: 57b21406f092110c18776e39b0bda50d37c945c8 # frozen: v2.4.3 hooks: - id: codespell - repo: https://github.com/rbubley/mirrors-prettier - rev: "v3.9.4" + rev: "39e2973981e6d2f9b6c543b0086a2d2393abdc89" # frozen: v3.9.4 hooks: - id: prettier types_or: [yaml, markdown, html, css, scss, javascript, json] exclude: assets/js/webapp\.js - repo: https://github.com/adamchainz/blacken-docs - rev: 1.20.0 + rev: fda77690955e9b63c6687d8806bafd56a526e45f # frozen: 1.20.0 hooks: - id: blacken-docs args: ["-E"] additional_dependencies: [black~=26.0] - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.10.0 + rev: 3a6eb0fadf60b3cccfd80bad9dbb6fae7e47b316 # frozen: v1.10.0 hooks: - id: python-check-blanket-type-ignore exclude: ^src/vector/backends/_numba_object.py$ - id: rst-backticks - id: rst-directive-colons - id: rst-inline-touching-normal + + - repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: 451b56af716f9f0d0c2b816503a3fd0cf8b036fa # frozen: v1.29.0 + hooks: + - id: zizmor + files: "^\\.github" + args: [--persona=pedantic] diff --git a/pyproject.toml b/pyproject.toml index 5bacd150..0aaa0bf0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -108,6 +108,10 @@ dev = [ version.source = "vcs" build.hooks.vcs.version-file = "src/vector/_version.py" +# Supply-chain cooldown: ignore releases newer than this +[tool.uv] +exclude-newer = "7 days" + [tool.ruff.lint] extend-select = [ "B", # flake8-bugbear @@ -296,6 +300,7 @@ ignore-regex = "[A-Za-z0-9+/]{100,}" [tool.pixi.workspace] channels = ["conda-forge"] platforms = ["linux-64", "osx-arm64", "osx-64"] +exclude-newer = "7d" [tool.pixi.feature.root.dependencies] python = ">=3.10" From d3937b322c5a6582eeb3b16208545b879b74702a Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 13 Aug 2026 12:33:35 -0400 Subject: [PATCH 2/4] Apply suggestion from @henryiii --- .github/dependabot.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f5838975..1974bcd6 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -11,15 +11,3 @@ updates: - "*" cooldown: default-days: 7 - - # Maintain pre-commit hooks - - package-ecosystem: "pre-commit" - directory: "/" - schedule: - interval: "monthly" - groups: - pre-commit: - patterns: - - "*" - cooldown: - default-days: 7 From 3b0dc7968598f6e510ac4cdd6b44de97df896a44 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Sat, 15 Aug 2026 16:03:21 -0400 Subject: [PATCH 3/4] Update .pre-commit-config.yaml Co-authored-by: Saransh Chopra --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2f04b599..7b9c0165 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "c59bba8fb259db0fec2bbb77ad8ba51ea7341b56" # frozen: v0.15.20 + rev: c59bba8fb259db0fec2bbb77ad8ba51ea7341b56 # frozen: v0.15.20 hooks: - id: ruff-check args: ["--fix", "--show-fixes"] From 4ac5408ec7b29597920c45f9133b9a104a2ecb47 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Sat, 15 Aug 2026 16:25:02 -0400 Subject: [PATCH 4/4] Apply suggestion from @henryiii --- .github/workflows/cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 4129e17a..3d1a0501 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -47,7 +47,7 @@ jobs: run: ls -l dist/ - name: Generate artifact attestation for sdist and wheel - uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 + uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2 with: subject-path: "dist/vector-*"