From cbd63aaab59062c43d2be94e674ad081fa59c7c3 Mon Sep 17 00:00:00 2001 From: aconite33 Date: Mon, 30 Mar 2026 14:17:48 -0600 Subject: [PATCH 01/21] ci: add CLA workflow --- .github/workflows/cla.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/cla.yml diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 0000000..05a0594 --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,39 @@ +name: "CLA Assistant" +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened, closed, synchronize] + +permissions: + actions: write + contents: write + pull-requests: write + statuses: write + +jobs: + CLAAssistant: + runs-on: ubuntu-latest + steps: + - name: Generate token from GitHub App + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + owner: blacklanternsecurity + repositories: CLA + + - name: "CLA Assistant" + if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' + uses: contributor-assistant/github-action@v2.6.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PERSONAL_ACCESS_TOKEN: ${{ steps.app-token.outputs.token }} + with: + path-to-signatures: "signatures/version1/cla.json" + path-to-document: "https://github.com/blacklanternsecurity/CLA/blob/main/ICLA.md" + branch: "main" + allowlist: "dependabot[bot],github-actions[bot],renovate[bot]" + remote-organization-name: "blacklanternsecurity" + remote-repository-name: "CLA" From ff0ac17a8550cab7d9208206471d9a55f96b06a1 Mon Sep 17 00:00:00 2001 From: aconite33 Date: Mon, 30 Mar 2026 16:39:08 -0600 Subject: [PATCH 02/21] ci: add org members to CLA allowlist --- .github/workflows/cla.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 05a0594..825a076 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -34,6 +34,6 @@ jobs: path-to-signatures: "signatures/version1/cla.json" path-to-document: "https://github.com/blacklanternsecurity/CLA/blob/main/ICLA.md" branch: "main" - allowlist: "dependabot[bot],github-actions[bot],renovate[bot]" + allowlist: "dependabot[bot],github-actions[bot],renovate[bot],aconite33,adeemm,ausmaster,bbot-deploy,blsaccess,blscode,en0f,GabKodes,holsick,jackpas23,kerrymilan,kevinoriley,liquidsec,lunarcowboy,MarcusAmes,Mercury0,MrBlackout20,Nasaltron,oversiemulated,pentestpop,pjhartlieb,RReski,shart123456,SpamFaux,stryker2k2,Sw3d1shPh1sh,TheFunky1Markimark,theo2612,TheTechromancer,TMDeal" remote-organization-name: "blacklanternsecurity" remote-repository-name: "CLA" From e2787a1cc2f75b6ba07a3fcec526b54c9ef2ce27 Mon Sep 17 00:00:00 2001 From: aconite33 Date: Mon, 30 Mar 2026 16:42:46 -0600 Subject: [PATCH 03/21] ci: use dynamic org membership check for CLA --- .github/workflows/cla.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 825a076..462636a 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -24,8 +24,23 @@ jobs: owner: blacklanternsecurity repositories: CLA + - name: Check org membership + id: membership + if: github.event_name == 'pull_request_target' + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + run: | + AUTHOR="${{ github.event.pull_request.user.login }}" + if gh api "orgs/blacklanternsecurity/members/$AUTHOR" > /dev/null 2>&1; then + echo "is_member=true" >> "$GITHUB_OUTPUT" + else + echo "is_member=false" >> "$GITHUB_OUTPUT" + fi + - name: "CLA Assistant" - if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' + if: | + (steps.membership.outputs.is_member != 'true') && + ((github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target') uses: contributor-assistant/github-action@v2.6.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -34,6 +49,6 @@ jobs: path-to-signatures: "signatures/version1/cla.json" path-to-document: "https://github.com/blacklanternsecurity/CLA/blob/main/ICLA.md" branch: "main" - allowlist: "dependabot[bot],github-actions[bot],renovate[bot],aconite33,adeemm,ausmaster,bbot-deploy,blsaccess,blscode,en0f,GabKodes,holsick,jackpas23,kerrymilan,kevinoriley,liquidsec,lunarcowboy,MarcusAmes,Mercury0,MrBlackout20,Nasaltron,oversiemulated,pentestpop,pjhartlieb,RReski,shart123456,SpamFaux,stryker2k2,Sw3d1shPh1sh,TheFunky1Markimark,theo2612,TheTechromancer,TMDeal" + allowlist: "dependabot[bot],github-actions[bot],renovate[bot]" remote-organization-name: "blacklanternsecurity" remote-repository-name: "CLA" From ab32e6a62f6eaa96f867dc3dd81eb89f189efceb Mon Sep 17 00:00:00 2001 From: aconite33 Date: Mon, 30 Mar 2026 21:18:43 -0600 Subject: [PATCH 04/21] fix: use org-scoped app token for reliable CLA membership check --- .github/workflows/cla.yml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 462636a..8300a05 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -22,21 +22,34 @@ jobs: app-id: ${{ secrets.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} owner: blacklanternsecurity - repositories: CLA - name: Check org membership id: membership - if: github.event_name == 'pull_request_target' env: GH_TOKEN: ${{ steps.app-token.outputs.token }} run: | - AUTHOR="${{ github.event.pull_request.user.login }}" - if gh api "orgs/blacklanternsecurity/members/$AUTHOR" > /dev/null 2>&1; then + if [ "${{ github.event_name }}" = "pull_request_target" ]; then + AUTHOR="${{ github.event.pull_request.user.login }}" + else + PR_NUM="${{ github.event.issue.number }}" + AUTHOR=$(gh api "repos/${{ github.repository }}/pulls/$PR_NUM" --jq '.user.login' 2>/dev/null) + fi + if [ -n "$AUTHOR" ] && gh api "orgs/blacklanternsecurity/members/$AUTHOR" > /dev/null 2>&1; then echo "is_member=true" >> "$GITHUB_OUTPUT" else echo "is_member=false" >> "$GITHUB_OUTPUT" fi + - name: Skip CLA for org members + if: steps.membership.outputs.is_member == 'true' && github.event_name == 'pull_request_target' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh api --method POST "repos/${{ github.repository }}/statuses/${{ github.event.pull_request.head.sha }}" \ + -f state=success \ + -f context="CLAAssistant" \ + -f description="CLA check skipped — author is an org member" + - name: "CLA Assistant" if: | (steps.membership.outputs.is_member != 'true') && From 0ecc48ed66d7e2cfd5a2cb5f6ebca7dc5982284f Mon Sep 17 00:00:00 2001 From: aconite33 Date: Tue, 31 Mar 2026 08:29:56 -0600 Subject: [PATCH 05/21] fix: disable lock-pullrequest-aftermerge in CLA workflow --- .github/workflows/cla.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 8300a05..bb9c379 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -65,3 +65,4 @@ jobs: allowlist: "dependabot[bot],github-actions[bot],renovate[bot]" remote-organization-name: "blacklanternsecurity" remote-repository-name: "CLA" + lock-pullrequest-aftermerge: "false" From b79d73e88d953464eaad4beea1fe56c385f58c2f Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Mon, 28 Sep 2026 11:40:32 -0700 Subject: [PATCH 06/21] ci: pin the runner image and the one branch-ref action ubuntu-latest is a label GitHub moves. The image changes under us and a green pipeline turns red on a morning nobody touched the code. Pinning to ubuntu-24.04 means the runner moves when we move it. dtolnay/rust-toolchain was called at @stable, a branch, not a release. It is pinned to a commit, dated in the trailing comment because that repo publishes no release tag for it. Version-tagged actions are untouched. --- .github/workflows/benchmark.yml | 2 +- .github/workflows/cla.yml | 2 +- .github/workflows/python-tests.yml | 14 +++++++------- .github/workflows/rust-tests.yml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index d4203e6..e4a4e22 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -9,7 +9,7 @@ concurrency: jobs: benchmark: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index bb9c379..95bd896 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -13,7 +13,7 @@ permissions: jobs: CLAAssistant: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Generate token from GitHub App id: app-token diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index a6fed1e..f93e8b9 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -8,7 +8,7 @@ on: jobs: lint: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 - run: | @@ -16,7 +16,7 @@ jobs: ruff check test: needs: lint - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 strategy: matrix: python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] @@ -27,7 +27,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Set up Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # 2026-09-03, no release tag - name: Install the latest version of uv uses: astral-sh/setup-uv@v7 - name: Install dependencies @@ -42,7 +42,7 @@ jobs: files: ./cov.xml verbose: true publish: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: test if: github.event_name == 'push' && github.ref == 'refs/heads/stable' steps: @@ -52,7 +52,7 @@ jobs: with: python-version: "3.12" - name: Set up Rust - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # 2026-09-03, no release tag - name: Set up uv uses: astral-sh/setup-uv@v7 - name: Build PyPi package @@ -188,7 +188,7 @@ jobs: path: dist sdist: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: publish if: github.event_name == 'push' && github.ref == 'refs/heads/stable' steps: @@ -206,7 +206,7 @@ jobs: release: name: Release - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: [linux, musllinux, windows, macos, sdist] if: github.event_name == 'push' && github.ref == 'refs/heads/stable' permissions: diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index b96ddc6..8b07324 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -7,7 +7,7 @@ on: jobs: test: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 @@ -41,7 +41,7 @@ jobs: publish: needs: test - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 if: github.event_name == 'push' && github.ref == 'refs/heads/stable' steps: From 626795fe55e4dec28311dcbc14cd7f2eef41c34c Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Thu, 1 Oct 2026 09:20:49 -0700 Subject: [PATCH 07/21] ci(lint): pin ruff and Rust toolchain, fix resulting lint errors The lint job ran an unpinned `pipx install ruff`, which picked up 0.16.9 and failed on 8 pre-existing errors (import order, __slots__ sort, SIM102, SIM201). The Rust job tracked `stable`, whose clippy now denies for_kv_map in src/node/base.rs. Both blocked unrelated PRs such as #92. Pin ruff==0.16.9 in the workflow and dev group, pin Rust 1.97.1 with clippy and rustfmt in rust-toolchain.toml and rust-tests.yml, and fix the errors in source. --- .github/workflows/python-tests.yml | 2 +- .github/workflows/rust-tests.yml | 6 ++- pyproject.toml | 2 +- radixtarget/__init__.py | 3 +- radixtarget/radixtarget.py | 1 + radixtarget/test/test_rust_radixtarget.py | 10 +++-- radixtarget/tree/base.py | 2 +- radixtarget/tree/ip.py | 12 ++++-- rust-toolchain.toml | 4 ++ src/node/base.rs | 2 +- uv.lock | 47 +++++++++++------------ 11 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 rust-toolchain.toml diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index a6fed1e..37b3be6 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v6 - run: | - pipx install ruff + pipx install ruff==0.16.9 ruff check test: needs: lint diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index b96ddc6..4c1f378 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -15,7 +15,8 @@ jobs: - name: Install Rust toolchain uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.97.1 + components: clippy, rustfmt override: true profile: minimal @@ -50,7 +51,8 @@ jobs: - name: Install Rust toolchain uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.97.1 + components: clippy, rustfmt override: true profile: minimal diff --git a/pyproject.toml b/pyproject.toml index 15cc409..c2c18e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,5 +46,5 @@ dev = [ "maturin>=1.9.6", "pytest>=8.4.2", "pytest-cov>=7.0.0", - "ruff>=0.14.1", + "ruff==0.16.9", ] diff --git a/radixtarget/__init__.py b/radixtarget/__init__.py index 959812f..1831676 100644 --- a/radixtarget/__init__.py +++ b/radixtarget/__init__.py @@ -5,7 +5,8 @@ using a Rust-based radix tree implementation for optimal performance. """ -from ._radixtarget import PyRadixTarget, py_host_size_key as host_size_key +from ._radixtarget import PyRadixTarget +from ._radixtarget import py_host_size_key as host_size_key from .radixtarget import RadixTarget # Alias for convenience diff --git a/radixtarget/radixtarget.py b/radixtarget/radixtarget.py index 92ffe54..3ec11bb 100644 --- a/radixtarget/radixtarget.py +++ b/radixtarget/radixtarget.py @@ -1,4 +1,5 @@ import ipaddress + from ._radixtarget import PyRadixTarget diff --git a/radixtarget/test/test_rust_radixtarget.py b/radixtarget/test/test_rust_radixtarget.py index 099cb52..8cfa623 100644 --- a/radixtarget/test/test_rust_radixtarget.py +++ b/radixtarget/test/test_rust_radixtarget.py @@ -1,8 +1,10 @@ -import random import ipaddress +import random import time -import pytest from pathlib import Path + +import pytest + from radixtarget import RadixTarget @@ -961,8 +963,8 @@ def test_special_methods_coverage(): assert repr(target1) == "RadixTarget(strict_scope=false, 2 hosts)" # Test __eq__ with non-RadixTarget (line 153) - assert not (target1 == "not_a_target") - assert not (target1 == 42) + assert (target1 == "not_a_target") is False + assert (target1 == 42) is False # Test __hash__ (line 157) hash_val = hash(target1) diff --git a/radixtarget/tree/base.py b/radixtarget/tree/base.py index dd71fbf..f1fb9f4 100644 --- a/radixtarget/tree/base.py +++ b/radixtarget/tree/base.py @@ -2,7 +2,7 @@ class RadixTreeNode: - __slots__ = ("children", "host", "data") + __slots__ = ("children", "data", "host") def __init__(self): self.children = {} diff --git a/radixtarget/tree/ip.py b/radixtarget/tree/ip.py index 1118003..b834b5f 100644 --- a/radixtarget/tree/ip.py +++ b/radixtarget/tree/ip.py @@ -1,7 +1,8 @@ import ipaddress from contextlib import suppress -from radixtarget.helpers import network_to_bits, merge_subnets +from radixtarget.helpers import merge_subnets, network_to_bits + from radixtarget.tree.base import BaseRadixTree, RadixTreeNode, sentinel @@ -120,9 +121,12 @@ def get_node(self, query, raise_error=False): for bit in network_bits: if bit in node.children: node = node.children[bit] - if node.host and node.host.prefixlen <= query_network.prefixlen: - if query_network.network_address in node.host: - matched_node = node + if ( + node.host + and node.host.prefixlen <= query_network.prefixlen + and query_network.network_address in node.host + ): + matched_node = node else: break diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..9946197 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.97.1" +components = ["clippy", "rustfmt"] +profile = "minimal" diff --git a/src/node/base.rs b/src/node/base.rs index 8d8437c..2a853cf 100644 --- a/src/node/base.rs +++ b/src/node/base.rs @@ -39,7 +39,7 @@ pub trait BaseNode { Self: Sized, { let mut hosts = Vec::new(); - for (_, child) in self.children_mut().iter_mut() { + for child in self.children_mut().values_mut() { hosts.extend(child.clear()); if let Some(host) = child.host_string() { hosts.push(host); diff --git a/uv.lock b/uv.lock index 4d9ed6e..d0006c0 100644 --- a/uv.lock +++ b/uv.lock @@ -131,7 +131,7 @@ wheels = [ [package.optional-dependencies] toml = [ - { name = "tomli", marker = "python_full_version < '3.10'" }, + { name = "tomli" }, ] [[package]] @@ -238,7 +238,7 @@ wheels = [ [package.optional-dependencies] toml = [ - { name = "tomli", marker = "python_full_version >= '3.10' and python_full_version <= '3.11'" }, + { name = "tomli", marker = "python_full_version <= '3.11'" }, ] [[package]] @@ -246,7 +246,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -366,33 +366,32 @@ dev = [ { name = "maturin", specifier = ">=1.9.6" }, { name = "pytest", specifier = ">=8.4.2" }, { name = "pytest-cov", specifier = ">=7.0.0" }, - { name = "ruff", specifier = ">=0.14.1" }, + { name = "ruff", specifier = "==0.16.9" }, ] [[package]] name = "ruff" -version = "0.14.1" +version = "0.16.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/58/6ca66896635352812de66f71cdf9ff86b3a4f79071ca5730088c0cd0fc8d/ruff-0.14.1.tar.gz", hash = "sha256:1dd86253060c4772867c61791588627320abcb6ed1577a90ef432ee319729b69", size = 5513429, upload-time = "2025-10-16T18:05:41.766Z" } +sdist = { url = "https://files.pythonhosted.org/packages/96/bf/c935ca98e73fe8ce65b87ef08a280c0c1e85295d569228c15e87d8fdfaf1/ruff-0.16.9.tar.gz", hash = "sha256:12b625c6cfba78d285d9f48eda5f053374f1e53cb10ef17342a383750db99161", size = 4948764, upload-time = "2026-09-24T20:37:49.416Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/39/9cc5ab181478d7a18adc1c1e051a84ee02bec94eb9bdfd35643d7c74ca31/ruff-0.14.1-py3-none-linux_armv6l.whl", hash = "sha256:083bfc1f30f4a391ae09c6f4f99d83074416b471775b59288956f5bc18e82f8b", size = 12445415, upload-time = "2025-10-16T18:04:48.227Z" }, - { url = "https://files.pythonhosted.org/packages/ef/2e/1226961855ccd697255988f5a2474890ac7c5863b080b15bd038df820818/ruff-0.14.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f6fa757cd717f791009f7669fefb09121cc5f7d9bd0ef211371fad68c2b8b224", size = 12784267, upload-time = "2025-10-16T18:04:52.515Z" }, - { url = "https://files.pythonhosted.org/packages/c1/ea/fd9e95863124ed159cd0667ec98449ae461de94acda7101f1acb6066da00/ruff-0.14.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6191903d39ac156921398e9c86b7354d15e3c93772e7dbf26c9fcae59ceccd5", size = 11781872, upload-time = "2025-10-16T18:04:55.396Z" }, - { url = "https://files.pythonhosted.org/packages/1e/5a/e890f7338ff537dba4589a5e02c51baa63020acfb7c8cbbaea4831562c96/ruff-0.14.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed04f0e04f7a4587244e5c9d7df50e6b5bf2705d75059f409a6421c593a35896", size = 12226558, upload-time = "2025-10-16T18:04:58.166Z" }, - { url = "https://files.pythonhosted.org/packages/a6/7a/8ab5c3377f5bf31e167b73651841217542bcc7aa1c19e83030835cc25204/ruff-0.14.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5c9e6cf6cd4acae0febbce29497accd3632fe2025c0c583c8b87e8dbdeae5f61", size = 12187898, upload-time = "2025-10-16T18:05:01.455Z" }, - { url = "https://files.pythonhosted.org/packages/48/8d/ba7c33aa55406955fc124e62c8259791c3d42e3075a71710fdff9375134f/ruff-0.14.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fa2458527794ecdfbe45f654e42c61f2503a230545a91af839653a0a93dbc6", size = 12939168, upload-time = "2025-10-16T18:05:04.397Z" }, - { url = "https://files.pythonhosted.org/packages/b4/c2/70783f612b50f66d083380e68cbd1696739d88e9b4f6164230375532c637/ruff-0.14.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:39f1c392244e338b21d42ab29b8a6392a722c5090032eb49bb4d6defcdb34345", size = 14386942, upload-time = "2025-10-16T18:05:07.102Z" }, - { url = "https://files.pythonhosted.org/packages/48/44/cd7abb9c776b66d332119d67f96acf15830d120f5b884598a36d9d3f4d83/ruff-0.14.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7382fa12a26cce1f95070ce450946bec357727aaa428983036362579eadcc5cf", size = 13990622, upload-time = "2025-10-16T18:05:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/eb/56/4259b696db12ac152fe472764b4f78bbdd9b477afd9bc3a6d53c01300b37/ruff-0.14.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd0bf2be3ae8521e1093a487c4aa3b455882f139787770698530d28ed3fbb37c", size = 13431143, upload-time = "2025-10-16T18:05:13.46Z" }, - { url = "https://files.pythonhosted.org/packages/e0/35/266a80d0eb97bd224b3265b9437bd89dde0dcf4faf299db1212e81824e7e/ruff-0.14.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabcaa9ccf8089fb4fdb78d17cc0e28241520f50f4c2e88cb6261ed083d85151", size = 13132844, upload-time = "2025-10-16T18:05:16.1Z" }, - { url = "https://files.pythonhosted.org/packages/65/6e/d31ce218acc11a8d91ef208e002a31acf315061a85132f94f3df7a252b18/ruff-0.14.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:747d583400f6125ec11a4c14d1c8474bf75d8b419ad22a111a537ec1a952d192", size = 13401241, upload-time = "2025-10-16T18:05:19.395Z" }, - { url = "https://files.pythonhosted.org/packages/9f/b5/dbc4221bf0b03774b3b2f0d47f39e848d30664157c15b965a14d890637d2/ruff-0.14.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5a6e74c0efd78515a1d13acbfe6c90f0f5bd822aa56b4a6d43a9ffb2ae6e56cd", size = 12132476, upload-time = "2025-10-16T18:05:22.163Z" }, - { url = "https://files.pythonhosted.org/packages/98/4b/ac99194e790ccd092d6a8b5f341f34b6e597d698e3077c032c502d75ea84/ruff-0.14.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0ea6a864d2fb41a4b6d5b456ed164302a0d96f4daac630aeba829abfb059d020", size = 12139749, upload-time = "2025-10-16T18:05:25.162Z" }, - { url = "https://files.pythonhosted.org/packages/47/26/7df917462c3bb5004e6fdfcc505a49e90bcd8a34c54a051953118c00b53a/ruff-0.14.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0826b8764f94229604fa255918d1cc45e583e38c21c203248b0bfc9a0e930be5", size = 12544758, upload-time = "2025-10-16T18:05:28.018Z" }, - { url = "https://files.pythonhosted.org/packages/64/d0/81e7f0648e9764ad9b51dd4be5e5dac3fcfff9602428ccbae288a39c2c22/ruff-0.14.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cbc52160465913a1a3f424c81c62ac8096b6a491468e7d872cb9444a860bc33d", size = 13221811, upload-time = "2025-10-16T18:05:30.707Z" }, - { url = "https://files.pythonhosted.org/packages/c3/07/3c45562c67933cc35f6d5df4ca77dabbcd88fddaca0d6b8371693d29fd56/ruff-0.14.1-py3-none-win32.whl", hash = "sha256:e037ea374aaaff4103240ae79168c0945ae3d5ae8db190603de3b4012bd1def6", size = 12319467, upload-time = "2025-10-16T18:05:33.261Z" }, - { url = "https://files.pythonhosted.org/packages/02/88/0ee4ca507d4aa05f67e292d2e5eb0b3e358fbcfe527554a2eda9ac422d6b/ruff-0.14.1-py3-none-win_amd64.whl", hash = "sha256:59d599cdff9c7f925a017f6f2c256c908b094e55967f93f2821b1439928746a1", size = 13401123, upload-time = "2025-10-16T18:05:35.984Z" }, - { url = "https://files.pythonhosted.org/packages/b8/81/4b6387be7014858d924b843530e1b2a8e531846807516e9bea2ee0936bf7/ruff-0.14.1-py3-none-win_arm64.whl", hash = "sha256:e3b443c4c9f16ae850906b8d0a707b2a4c16f8d2f0a7fe65c475c5886665ce44", size = 12436636, upload-time = "2025-10-16T18:05:38.995Z" }, + { url = "https://files.pythonhosted.org/packages/0d/26/df51322b52ee1ada7eff2d071ea09d11d5c2d1dcc9f02594f5785c4d1635/ruff-0.16.9-py3-none-linux_armv6l.whl", hash = "sha256:95e6f022090368ab3b824c36276839c53b2adf1a3f4c09fefc33dfc400f6da96", size = 10082922, upload-time = "2026-09-24T20:37:13.045Z" }, + { url = "https://files.pythonhosted.org/packages/a5/27/7bf51f5a7aa375e9f339280a303aab44ca75dc1525f1cdc5991761685b0f/ruff-0.16.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a5f27be168556594a86d2f415db0cf43f5291917849318f873c7e2791f7a8c67", size = 10236360, upload-time = "2026-09-24T20:37:16.049Z" }, + { url = "https://files.pythonhosted.org/packages/b6/63/09659283f92f02dff45809da194a70da2f688d87c55d8875c4fae3536072/ruff-0.16.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1632eb1d6197f33bd00b1acbc5b71009e89a8895c158e2d2b03a834fac964ab6", size = 9892940, upload-time = "2026-09-24T20:37:17.957Z" }, + { url = "https://files.pythonhosted.org/packages/24/58/98de1b72ec172f5f8f1731236fe21585b3998bf7dfe9fcc44ae9ba626012/ruff-0.16.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3f951b14d865d5952c89d40a5ca07e87abe24fa5453299878411e127748fb1c", size = 10032114, upload-time = "2026-09-24T20:37:19.942Z" }, + { url = "https://files.pythonhosted.org/packages/c8/7d/f1e17c54ab59d4bad1dce8ee3e22a7a1d0ef4745240decacdcf3832b5bb2/ruff-0.16.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:447fc07e1573afff7cb02803462b12b6c8ece7cf10e2cd78565fa6d7a1c0bf8d", size = 9910227, upload-time = "2026-09-24T20:37:21.872Z" }, + { url = "https://files.pythonhosted.org/packages/34/19/436f647a65075bbd3bab2668b3bdaa5120559b294694018cdcefabbbf30b/ruff-0.16.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a3e039a6a40ed976c491722b60e0ae4a4aa1a86057f540ee7a37a5d19ae9120", size = 10547484, upload-time = "2026-09-24T20:37:24.229Z" }, + { url = "https://files.pythonhosted.org/packages/03/59/38430a6bc2f6d8095447ac39625cf8b6e9344a47e6c26225c8ba1bff3ffb/ruff-0.16.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4684dded7db60aa57cb118fa158630f5feade4af5782903b6053484bdf9bd129", size = 11412367, upload-time = "2026-09-24T20:37:26.307Z" }, + { url = "https://files.pythonhosted.org/packages/c8/bd/bbb6d7fc7f208c8b8c50dd5dc8206e4cfdb1e7a8fb852606a3adf370c880/ruff-0.16.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d29c934357e45642fda2f34c0b1f4025b4a6c01e15e4bf0016879d60078a142c", size = 10869787, upload-time = "2026-09-24T20:37:28.35Z" }, + { url = "https://files.pythonhosted.org/packages/bc/b8/9c543074918061abbefc3bd139bee22de35abedb00dde0f2d27288838962/ruff-0.16.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a21713e629d3e5bdb2f5c2def1cc7f04f47fa8e1a7eb0571b4a28e1da64bc728", size = 10406494, upload-time = "2026-09-24T20:37:30.624Z" }, + { url = "https://files.pythonhosted.org/packages/35/7a/5a8851bd146e7ccf8fd4b003f6c75c11f8fbdb0e60673b45097986b6bf41/ruff-0.16.9-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:7baa24ef5fc8e77aa93879e1d3f43754a01ae488e869f1ae30cf431afd4d2452", size = 10590083, upload-time = "2026-09-24T20:37:32.439Z" }, + { url = "https://files.pythonhosted.org/packages/87/f0/4c3467188f23f806960b46fa76575a7cd0514c9ba90562650b71efc96980/ruff-0.16.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a41aac6230aadfaa133bdfa1614488531ffa3e0837567ae04c0da2058a9c0f9e", size = 10119151, upload-time = "2026-09-24T20:37:34.581Z" }, + { url = "https://files.pythonhosted.org/packages/15/34/5a4def5adea572ce6aea0bb64f21f928ee317b80e0db747d7979b01d7261/ruff-0.16.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:c2529fb5896d49115b0e9aa8f887490b34bbe76baf879ec2264ac59406869ce7", size = 9911544, upload-time = "2026-09-24T20:37:36.796Z" }, + { url = "https://files.pythonhosted.org/packages/62/5d/d15ebea7499eef9373318c0ee6ca127832927c6529731f6d48e18dce7ca9/ruff-0.16.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:41e3870277694177429b56406d65dfbdb2c2802c52b715edaf6a0b829c69d4ee", size = 10269884, upload-time = "2026-09-24T20:37:38.857Z" }, + { url = "https://files.pythonhosted.org/packages/d1/56/c5d3cd119ded7a3c7aba0e961b69cb3df701c91662c98ad694467d060ce1/ruff-0.16.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8adbe4e58af167f767d7b2ba5e83c42e878350796cf78c2f5e14ab9903a92588", size = 10749366, upload-time = "2026-09-24T20:37:41.042Z" }, + { url = "https://files.pythonhosted.org/packages/ac/fe/734ec7527029ac757ecf821f143c9f3fcf69149c21f53a044a899b430f5a/ruff-0.16.9-py3-none-win32.whl", hash = "sha256:0e1dbc2073624dee6618d41d0098690a7244654af746704b64759e12b6b6b385", size = 10152355, upload-time = "2026-09-24T20:37:43.025Z" }, + { url = "https://files.pythonhosted.org/packages/14/21/26e4643629b3ebb44f0a06f9c9a53058d63d989415f63a9a3c28e2ee7f22/ruff-0.16.9-py3-none-win_amd64.whl", hash = "sha256:6bd40fec8cd4c8a3d4dd589bd8ad4e6320c13c29234159bfd959a40d529d597b", size = 10592965, upload-time = "2026-09-24T20:37:44.944Z" }, + { url = "https://files.pythonhosted.org/packages/51/60/5fb1a39dbb5ae314d5f59bc7348a63c1d5c20f3cd83914c4b5cb0be31d2d/ruff-0.16.9-py3-none-win_arm64.whl", hash = "sha256:ed1a252039200f57a59eebc063b54beabea67bfbaaca0eeaa7f54b5fbcda2284", size = 10458649, upload-time = "2026-09-24T20:37:46.882Z" }, ] [[package]] From 74c7c8d69e28ad065d874ec1ba2243d732b683a2 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Sat, 3 Oct 2026 00:57:47 -0700 Subject: [PATCH 08/21] ci(benchmark): skip the PR comment on fork PRs Fork PRs get a read-only GITHUB_TOKEN, so the comment step failed the job after the benchmark itself passed. --- .github/workflows/benchmark.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index e4a4e22..27d0a85 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -36,7 +36,8 @@ jobs: retention-days: 30 - name: Comment benchmark results on PR - if: github.event_name == 'pull_request' + # fork PRs get a read-only token and cannot comment + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository uses: actions/github-script@v8 with: script: | From 28323c6b48dbce3bebc770b8f7887846ea13c7e9 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Sat, 3 Oct 2026 01:33:19 -0700 Subject: [PATCH 09/21] ci: pin the windows and macos wheel runners windows-latest and macos-latest were still floating in the wheel matrix. --- .github/workflows/python-tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 29420ae..8cb3186 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -137,9 +137,9 @@ jobs: strategy: matrix: platform: - - runner: windows-latest + - runner: windows-2025 target: x64 - - runner: windows-latest + - runner: windows-2025 target: x86 steps: - uses: actions/checkout@v6 @@ -168,7 +168,7 @@ jobs: platform: - runner: macos-15-intel target: x86_64 - - runner: macos-latest + - runner: macos-15 target: aarch64 steps: - uses: actions/checkout@v6 From 777d2b4d9b28f5b6346acd523525036094cfb9d0 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Sat, 3 Oct 2026 04:35:35 -0700 Subject: [PATCH 10/21] ci: publish on version tags only, split publish.yml, shared CLA rust-tests.yml and python-tests.yml published to crates.io and PyPI on every push to stable, each with a long-lived token. Publishing moves to publish.yml, triggered only by v* tags. Its first job refuses tags outside vMAJOR.MINOR.PATCH or vMAJOR.MINOR.PATCH-rc.N and any tag that does not equal the Cargo.toml version. Both test workflows run before any wheel is built, every build must succeed before a registry sees the release, PyPI uses trusted publishing in the pypi environment, crates.io runs in the release environment, and the last job creates the GitHub Release with an SPDX JSON SBOM attached. actions-rs/toolchain is archived and is replaced by actions-rust-lang/setup-rust-toolchain reading rust-toolchain.toml. Every workflow declares least-privilege permissions, every action is pinned to a commit SHA, and CLA calls the shared reusable workflow. --- .github/workflows/benchmark.yml | 12 +- .github/workflows/cla.yml | 62 +------- .github/workflows/publish.yml | 232 +++++++++++++++++++++++++++++ .github/workflows/python-tests.yml | 226 +++------------------------- .github/workflows/rust-tests.yml | 64 ++------ 5 files changed, 281 insertions(+), 315 deletions(-) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 27d0a85..803c7c9 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -3,6 +3,10 @@ name: Benchmark on: pull_request: +permissions: + contents: read + pull-requests: write + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -11,10 +15,10 @@ jobs: benchmark: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 + uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 - name: Build benchmark binary run: cd benchmark && cargo build --release --bin benchmark @@ -27,7 +31,7 @@ jobs: - name: Upload benchmark results if: always() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: benchmark-results path: | @@ -38,7 +42,7 @@ jobs: - name: Comment benchmark results on PR # fork PRs get a read-only token and cannot comment if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository - uses: actions/github-script@v8 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | const fs = require('fs'); diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 95bd896..f6b10c0 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -1,4 +1,5 @@ -name: "CLA Assistant" +name: CLA + on: issue_comment: types: [created] @@ -6,63 +7,10 @@ on: types: [opened, closed, synchronize] permissions: - actions: write - contents: write pull-requests: write statuses: write jobs: - CLAAssistant: - runs-on: ubuntu-24.04 - steps: - - name: Generate token from GitHub App - id: app-token - uses: actions/create-github-app-token@v1 - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - owner: blacklanternsecurity - - - name: Check org membership - id: membership - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: | - if [ "${{ github.event_name }}" = "pull_request_target" ]; then - AUTHOR="${{ github.event.pull_request.user.login }}" - else - PR_NUM="${{ github.event.issue.number }}" - AUTHOR=$(gh api "repos/${{ github.repository }}/pulls/$PR_NUM" --jq '.user.login' 2>/dev/null) - fi - if [ -n "$AUTHOR" ] && gh api "orgs/blacklanternsecurity/members/$AUTHOR" > /dev/null 2>&1; then - echo "is_member=true" >> "$GITHUB_OUTPUT" - else - echo "is_member=false" >> "$GITHUB_OUTPUT" - fi - - - name: Skip CLA for org members - if: steps.membership.outputs.is_member == 'true' && github.event_name == 'pull_request_target' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh api --method POST "repos/${{ github.repository }}/statuses/${{ github.event.pull_request.head.sha }}" \ - -f state=success \ - -f context="CLAAssistant" \ - -f description="CLA check skipped — author is an org member" - - - name: "CLA Assistant" - if: | - (steps.membership.outputs.is_member != 'true') && - ((github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target') - uses: contributor-assistant/github-action@v2.6.1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PERSONAL_ACCESS_TOKEN: ${{ steps.app-token.outputs.token }} - with: - path-to-signatures: "signatures/version1/cla.json" - path-to-document: "https://github.com/blacklanternsecurity/CLA/blob/main/ICLA.md" - branch: "main" - allowlist: "dependabot[bot],github-actions[bot],renovate[bot]" - remote-organization-name: "blacklanternsecurity" - remote-repository-name: "CLA" - lock-pullrequest-aftermerge: "false" + cla: + uses: blacklanternsecurity/CLA/.github/workflows/cla-reusable.yml@4f85d3c525483f0f846ef4384a8ece24a3c74375 # 2026-09-29 + secrets: inherit diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..a6afedf --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,232 @@ +name: publish + +on: + push: + tags: ["v*", "!archive/**"] + +permissions: + contents: read + +concurrency: + group: publish-${{ github.ref }} + cancel-in-progress: false + +jobs: + version: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Tag matches the declared version + run: | + if ! [[ "$GITHUB_REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$ ]]; then + echo "::error::tag $GITHUB_REF_NAME is not vMAJOR.MINOR.PATCH or vMAJOR.MINOR.PATCH-rc.N" + exit 1 + fi + VERSION=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[0].version') + if [ "v$VERSION" != "$GITHUB_REF_NAME" ]; then + echo "::error::tag $GITHUB_REF_NAME does not match Cargo.toml $VERSION" + exit 1 + fi + + rust: + needs: version + uses: ./.github/workflows/rust-tests.yml + + python: + needs: version + uses: ./.github/workflows/python-tests.yml + secrets: inherit + + linux: + needs: [version, rust, python] + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: ubuntu-24.04 + target: x86_64 + - runner: ubuntu-24.04 + target: x86 + - runner: ubuntu-24.04 + target: aarch64 + - runner: ubuntu-24.04 + target: armv7 + - runner: ubuntu-24.04 + target: s390x + - runner: ubuntu-24.04 + target: ppc64le + steps: + - 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: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: false + manylinux: auto + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: wheels-linux-${{ matrix.platform.target }} + path: dist + + musllinux: + needs: [version, rust, python] + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: ubuntu-24.04 + target: x86_64 + - runner: ubuntu-24.04 + target: x86 + - runner: ubuntu-24.04 + target: aarch64 + - runner: ubuntu-24.04 + target: armv7 + steps: + - 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: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: false + manylinux: musllinux_1_2 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: wheels-musllinux-${{ matrix.platform.target }} + path: dist + + windows: + needs: [version, rust, python] + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: windows-2025 + target: x64 + - runner: windows-2025 + target: x86 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: 3.x + architecture: ${{ matrix.platform.target }} + - uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: false + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: wheels-windows-${{ matrix.platform.target }} + path: dist + + macos: + needs: [version, rust, python] + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: macos-15-intel + target: x86_64 + - runner: macos-15 + target: aarch64 + steps: + - 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: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: false + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: wheels-macos-${{ matrix.platform.target }} + path: dist + + sdist: + needs: [version, rust, python] + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 + with: + command: sdist + args: --out dist + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: wheels-sdist + path: dist + + crates: + environment: release + needs: [version, linux, musllinux, windows, macos, sdist] + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 + - run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} + + pypi: + environment: pypi + needs: [version, linux, musllinux, windows, macos, sdist] + runs-on: ubuntu-24.04 + permissions: + id-token: write + attestations: write + steps: + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + - uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 + with: + subject-path: 'wheels-*/*' + - uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 + with: + command: upload + args: --non-interactive wheels-*/* + + release: + needs: [crates, pypi] + runs-on: ubuntu-24.04 + permissions: + contents: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: anchore/sbom-action@66cbf4bc1f1c0d2edc94016e65bc221b6bb0ad6c # v0.24.3 + with: + path: . + format: spdx-json + output-file: ${{ github.event.repository.name }}-${{ github.ref_name }}.spdx.json + upload-artifact: false + upload-release-assets: false + - name: GitHub Release with SBOM + env: + GH_TOKEN: ${{ github.token }} + run: | + PRERELEASE=() + if [[ "$GITHUB_REF_NAME" == *-rc.* ]]; then PRERELEASE=(--prerelease); fi + gh release create "$GITHUB_REF_NAME" "${{ github.event.repository.name }}-$GITHUB_REF_NAME.spdx.json" \ + --repo "$GITHUB_REPOSITORY" --verify-tag --generate-notes "${PRERELEASE[@]}" diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 8cb3186..3446f21 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -2,15 +2,24 @@ name: Python tests on: push: - branches: - - stable + branches: [stable] pull_request: + workflow_call: + +permissions: + contents: read + +concurrency: + group: python-tests-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: lint: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - run: | pipx install ruff==0.16.9 ruff check @@ -21,211 +30,18 @@ jobs: matrix: python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v6 - - name: Set up Python - uses: actions/setup-python@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - - name: Set up Rust - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # 2026-09-03, no release tag - - name: Install the latest version of uv - uses: astral-sh/setup-uv@v7 - - name: Install dependencies - run: uv sync - - name: Run tests - run: | - uv run pytest --exitfirst --disable-warnings --log-cli-level=DEBUG --cov-report xml:cov.xml --cov=radixtarget . - - name: Upload Code Coverage - uses: codecov/codecov-action@v5 + - uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 + - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + - run: uv sync + - run: uv run pytest --exitfirst --disable-warnings --log-cli-level=DEBUG --cov-report xml:cov.xml --cov=radixtarget . + - uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./cov.xml verbose: true - publish: - runs-on: ubuntu-24.04 - needs: test - if: github.event_name == 'push' && github.ref == 'refs/heads/stable' - steps: - - uses: actions/checkout@v6 - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: "3.12" - - name: Set up Rust - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # 2026-09-03, no release tag - - name: Set up uv - uses: astral-sh/setup-uv@v7 - - name: Build PyPi package - run: uv run maturin build --release --out dist - - name: Publish PyPi package - run: uv run maturin publish --username __token__ --password ${{ secrets.PYPI_TOKEN }} - - linux: - runs-on: ${{ matrix.platform.runner }} - needs: publish - if: github.event_name == 'push' && github.ref == 'refs/heads/stable' - strategy: - matrix: - platform: - - runner: ubuntu-22.04 - target: x86_64 - - runner: ubuntu-22.04 - target: x86 - - runner: ubuntu-22.04 - target: aarch64 - - runner: ubuntu-22.04 - target: armv7 - - runner: ubuntu-22.04 - target: s390x - - runner: ubuntu-22.04 - target: ppc64le - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 - with: - python-version: 3.x - - name: Build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter - sccache: false - manylinux: auto - - name: Upload wheels - uses: actions/upload-artifact@v5 - with: - name: wheels-linux-${{ matrix.platform.target }} - path: dist - - musllinux: - runs-on: ${{ matrix.platform.runner }} - needs: publish - if: github.event_name == 'push' && github.ref == 'refs/heads/stable' - strategy: - matrix: - platform: - - runner: ubuntu-22.04 - target: x86_64 - - runner: ubuntu-22.04 - target: x86 - - runner: ubuntu-22.04 - target: aarch64 - - runner: ubuntu-22.04 - target: armv7 - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 - with: - python-version: 3.x - - name: Build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter - sccache: false - manylinux: musllinux_1_2 - - name: Upload wheels - uses: actions/upload-artifact@v5 - with: - name: wheels-musllinux-${{ matrix.platform.target }} - path: dist - - windows: - runs-on: ${{ matrix.platform.runner }} - needs: publish - if: github.event_name == 'push' && github.ref == 'refs/heads/stable' - strategy: - matrix: - platform: - - runner: windows-2025 - target: x64 - - runner: windows-2025 - target: x86 - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 - with: - python-version: 3.x - architecture: ${{ matrix.platform.target }} - - name: Build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter - sccache: false - - name: Upload wheels - uses: actions/upload-artifact@v5 - with: - name: wheels-windows-${{ matrix.platform.target }} - path: dist - - macos: - runs-on: ${{ matrix.platform.runner }} - needs: publish - if: github.event_name == 'push' && github.ref == 'refs/heads/stable' - strategy: - matrix: - platform: - - runner: macos-15-intel - target: x86_64 - - runner: macos-15 - target: aarch64 - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 - with: - python-version: 3.x - - name: Build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter - sccache: false - - name: Upload wheels - uses: actions/upload-artifact@v5 - with: - name: wheels-macos-${{ matrix.platform.target }} - path: dist - - sdist: - runs-on: ubuntu-24.04 - needs: publish - if: github.event_name == 'push' && github.ref == 'refs/heads/stable' - steps: - - uses: actions/checkout@v6 - - name: Build sdist - uses: PyO3/maturin-action@v1 - with: - command: sdist - args: --out dist - - name: Upload sdist - uses: actions/upload-artifact@v5 - with: - name: wheels-sdist - path: dist - - release: - name: Release - runs-on: ubuntu-24.04 - needs: [linux, musllinux, windows, macos, sdist] - if: github.event_name == 'push' && github.ref == 'refs/heads/stable' - permissions: - # Use to sign the release artifacts - id-token: write - # Used to upload release artifacts - contents: write - # Used to generate artifact attestation - attestations: write - steps: - - uses: actions/download-artifact@v6 - - name: Generate artifact attestation - uses: actions/attest-build-provenance@v3 - with: - subject-path: 'wheels-*/*' - - name: Publish wheels to PyPI - uses: PyO3/maturin-action@v1 - env: - MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - with: - command: upload - args: --non-interactive --skip-existing wheels-*/* diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index a456487..e389c29 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -2,59 +2,25 @@ name: Rust tests on: push: - branches: [ stable ] + branches: [stable] pull_request: + workflow_call: + +permissions: + contents: read + +concurrency: + group: rust-tests-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: test: runs-on: ubuntu-24.04 - - steps: - - uses: actions/checkout@v6 - - - name: Install Rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.97.1 - components: clippy, rustfmt - override: true - profile: minimal - - - name: Cache Rust dependencies - uses: actions/cache@v4 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo- - - - name: Check formatting - run: cargo fmt --all -- --check - - - name: Run clippy - run: cargo clippy --all-targets --all-features -- -D warnings - - - name: Run tests - run: cargo test --verbose --all-features - - publish: - needs: test - runs-on: ubuntu-24.04 - if: github.event_name == 'push' && github.ref == 'refs/heads/stable' - steps: - - uses: actions/checkout@v6 - - - name: Install Rust toolchain - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: - toolchain: 1.97.1 - components: clippy, rustfmt - override: true - profile: minimal - - - name: Publish to crates.io - run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} + persist-credentials: false + - uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 + - run: cargo fmt --all -- --check + - run: cargo clippy --all-targets --all-features -- -D warnings + - run: cargo test --verbose --all-features From 6b6738f81c8c4acf7dcb8eb8bcf9e73d315fc1f1 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Sat, 3 Oct 2026 07:10:03 -0700 Subject: [PATCH 11/21] style: format README code blocks with ruff ruff 0.16 formats Python blocks in Markdown, so ruff format --check failed on README.md and the lint job only ran ruff check. Formatting it lets lint run both checks. --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 470f535..8d7ee9c 100644 --- a/README.md +++ b/README.md @@ -38,27 +38,27 @@ rt = RadixTarget() # IPv4 rt.add("192.168.1.0/24") -rt.get("192.168.1.10") # IPv4Network("192.168.1.0/24") -rt.get("192.168.2.10") # None +rt.get("192.168.1.10") # IPv4Network("192.168.1.0/24") +rt.get("192.168.2.10") # None # IPv6 rt.add("dead::/64") -rt.get("dead::beef") # IPv6Network("dead::/64") -rt.get("dead:cafe::beef") # None +rt.get("dead::beef") # IPv6Network("dead::/64") +rt.get("dead:cafe::beef") # None # DNS rt.add("net") rt.add("www.example.com") rt.add("test.www.example.com") -rt.get("net") # "net" -rt.get("evilcorp.net") # "net" -rt.get("www.example.com") # "www.example.com" -rt.get("asdf.test.www.example.com") # "test.www.example.com" -rt.get("example.com") # None +rt.get("net") # "net" +rt.get("evilcorp.net") # "net" +rt.get("www.example.com") # "www.example.com" +rt.get("asdf.test.www.example.com") # "test.www.example.com" +rt.get("example.com") # None # Custom data nodes rt.add("evilcorp.co.uk", "custom_data") -rt.get("www.evilcorp.co.uk") # "custom_data" +rt.get("www.evilcorp.co.uk") # "custom_data" # Insertion returns unique identifier insertion_id = rt.insert("10.0.0.1/8") From 69c8e9da16532065f4320829b0ccc4a95d72d111 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Sat, 3 Oct 2026 07:10:04 -0700 Subject: [PATCH 12/21] build: read the Python package version from Cargo.toml pyproject.toml and Cargo.toml both declared 4.2.0, two sources that publish.yml could only compare against one of. maturin fills a dynamic [project] version from Cargo.toml, so Cargo.toml is now the single source for crates.io, PyPI, and the tag check. poetry.lock and .flake8 are left over from before the move to uv and ruff. Nothing reads them. --- .flake8 | 5 - poetry.lock | 297 ------------------------------------------------- pyproject.toml | 2 +- uv.lock | 1 - 4 files changed, 1 insertion(+), 304 deletions(-) delete mode 100644 .flake8 delete mode 100644 poetry.lock diff --git a/.flake8 b/.flake8 deleted file mode 100644 index a6f0573..0000000 --- a/.flake8 +++ /dev/null @@ -1,5 +0,0 @@ -[flake8] -select = F,E722 -ignore = F403,F405,F541 -per-file-ignores = - */__init__.py:F401,F403 diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 8930701..0000000 --- a/poetry.lock +++ /dev/null @@ -1,297 +0,0 @@ -# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["dev"] -markers = "sys_platform == \"win32\"" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "coverage" -version = "7.6.8" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "coverage-7.6.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50"}, - {file = "coverage-7.6.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf"}, - {file = "coverage-7.6.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3985b9be361d8fb6b2d1adc9924d01dec575a1d7453a14cccd73225cb79243ee"}, - {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:644ec81edec0f4ad17d51c838a7d01e42811054543b76d4ba2c5d6af741ce2a6"}, - {file = "coverage-7.6.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f188a2402f8359cf0c4b1fe89eea40dc13b52e7b4fd4812450da9fcd210181d"}, - {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e19122296822deafce89a0c5e8685704c067ae65d45e79718c92df7b3ec3d331"}, - {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13618bed0c38acc418896005732e565b317aa9e98d855a0e9f211a7ffc2d6638"}, - {file = "coverage-7.6.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:193e3bffca48ad74b8c764fb4492dd875038a2f9925530cb094db92bb5e47bed"}, - {file = "coverage-7.6.8-cp310-cp310-win32.whl", hash = "sha256:3988665ee376abce49613701336544041f2117de7b7fbfe91b93d8ff8b151c8e"}, - {file = "coverage-7.6.8-cp310-cp310-win_amd64.whl", hash = "sha256:f56f49b2553d7dd85fd86e029515a221e5c1f8cb3d9c38b470bc38bde7b8445a"}, - {file = "coverage-7.6.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:86cffe9c6dfcfe22e28027069725c7f57f4b868a3f86e81d1c62462764dc46d4"}, - {file = "coverage-7.6.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d82ab6816c3277dc962cfcdc85b1efa0e5f50fb2c449432deaf2398a2928ab94"}, - {file = "coverage-7.6.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13690e923a3932e4fad4c0ebfb9cb5988e03d9dcb4c5150b5fcbf58fd8bddfc4"}, - {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be32da0c3827ac9132bb488d331cb32e8d9638dd41a0557c5569d57cf22c9c1"}, - {file = "coverage-7.6.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e6c85bbdc809383b509d732b06419fb4544dca29ebe18480379633623baafb"}, - {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:768939f7c4353c0fac2f7c37897e10b1414b571fd85dd9fc49e6a87e37a2e0d8"}, - {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e44961e36cb13c495806d4cac67640ac2866cb99044e210895b506c26ee63d3a"}, - {file = "coverage-7.6.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ea8bb1ab9558374c0ab591783808511d135a833c3ca64a18ec927f20c4030f0"}, - {file = "coverage-7.6.8-cp311-cp311-win32.whl", hash = "sha256:629a1ba2115dce8bf75a5cce9f2486ae483cb89c0145795603d6554bdc83e801"}, - {file = "coverage-7.6.8-cp311-cp311-win_amd64.whl", hash = "sha256:fb9fc32399dca861584d96eccd6c980b69bbcd7c228d06fb74fe53e007aa8ef9"}, - {file = "coverage-7.6.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e683e6ecc587643f8cde8f5da6768e9d165cd31edf39ee90ed7034f9ca0eefee"}, - {file = "coverage-7.6.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1defe91d41ce1bd44b40fabf071e6a01a5aa14de4a31b986aa9dfd1b3e3e414a"}, - {file = "coverage-7.6.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7ad66e8e50225ebf4236368cc43c37f59d5e6728f15f6e258c8639fa0dd8e6d"}, - {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fe47da3e4fda5f1abb5709c156eca207eacf8007304ce3019eb001e7a7204cb"}, - {file = "coverage-7.6.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:202a2d645c5a46b84992f55b0a3affe4f0ba6b4c611abec32ee88358db4bb649"}, - {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4674f0daa1823c295845b6a740d98a840d7a1c11df00d1fd62614545c1583787"}, - {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:74610105ebd6f33d7c10f8907afed696e79c59e3043c5f20eaa3a46fddf33b4c"}, - {file = "coverage-7.6.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37cda8712145917105e07aab96388ae76e787270ec04bcb9d5cc786d7cbb8443"}, - {file = "coverage-7.6.8-cp312-cp312-win32.whl", hash = "sha256:9e89d5c8509fbd6c03d0dd1972925b22f50db0792ce06324ba069f10787429ad"}, - {file = "coverage-7.6.8-cp312-cp312-win_amd64.whl", hash = "sha256:379c111d3558272a2cae3d8e57e6b6e6f4fe652905692d54bad5ea0ca37c5ad4"}, - {file = "coverage-7.6.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b0c69f4f724c64dfbfe79f5dfb503b42fe6127b8d479b2677f2b227478db2eb"}, - {file = "coverage-7.6.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c15b32a7aca8038ed7644f854bf17b663bc38e1671b5d6f43f9a2b2bd0c46f63"}, - {file = "coverage-7.6.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63068a11171e4276f6ece913bde059e77c713b48c3a848814a6537f35afb8365"}, - {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4548c5ead23ad13fb7a2c8ea541357474ec13c2b736feb02e19a3085fac002"}, - {file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4b4299dd0d2c67caaaf286d58aef5e75b125b95615dda4542561a5a566a1e3"}, - {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9ebfb2507751f7196995142f057d1324afdab56db1d9743aab7f50289abd022"}, - {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c1b4474beee02ede1eef86c25ad4600a424fe36cff01a6103cb4533c6bf0169e"}, - {file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9fd2547e6decdbf985d579cf3fc78e4c1d662b9b0ff7cc7862baaab71c9cc5b"}, - {file = "coverage-7.6.8-cp313-cp313-win32.whl", hash = "sha256:8aae5aea53cbfe024919715eca696b1a3201886ce83790537d1c3668459c7146"}, - {file = "coverage-7.6.8-cp313-cp313-win_amd64.whl", hash = "sha256:ae270e79f7e169ccfe23284ff5ea2d52a6f401dc01b337efb54b3783e2ce3f28"}, - {file = "coverage-7.6.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de38add67a0af869b0d79c525d3e4588ac1ffa92f39116dbe0ed9753f26eba7d"}, - {file = "coverage-7.6.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b07c25d52b1c16ce5de088046cd2432b30f9ad5e224ff17c8f496d9cb7d1d451"}, - {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a66ff235e4c2e37ed3b6104d8b478d767ff73838d1222132a7a026aa548764"}, - {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b9f848b28081e7b975a3626e9081574a7b9196cde26604540582da60235fdf"}, - {file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:093896e530c38c8e9c996901858ac63f3d4171268db2c9c8b373a228f459bbc5"}, - {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a7b8ac36fd688c8361cbc7bf1cb5866977ece6e0b17c34aa0df58bda4fa18a4"}, - {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:38c51297b35b3ed91670e1e4efb702b790002e3245a28c76e627478aa3c10d83"}, - {file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2e4e0f60cb4bd7396108823548e82fdab72d4d8a65e58e2c19bbbc2f1e2bfa4b"}, - {file = "coverage-7.6.8-cp313-cp313t-win32.whl", hash = "sha256:6535d996f6537ecb298b4e287a855f37deaf64ff007162ec0afb9ab8ba3b8b71"}, - {file = "coverage-7.6.8-cp313-cp313t-win_amd64.whl", hash = "sha256:c79c0685f142ca53256722a384540832420dff4ab15fec1863d7e5bc8691bdcc"}, - {file = "coverage-7.6.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ac47fa29d8d41059ea3df65bd3ade92f97ee4910ed638e87075b8e8ce69599e"}, - {file = "coverage-7.6.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:24eda3a24a38157eee639ca9afe45eefa8d2420d49468819ac5f88b10de84f4c"}, - {file = "coverage-7.6.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4c81ed2820b9023a9a90717020315e63b17b18c274a332e3b6437d7ff70abe0"}, - {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd55f8fc8fa494958772a2a7302b0354ab16e0b9272b3c3d83cdb5bec5bd1779"}, - {file = "coverage-7.6.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f39e2f3530ed1626c66e7493be7a8423b023ca852aacdc91fb30162c350d2a92"}, - {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:716a78a342679cd1177bc8c2fe957e0ab91405bd43a17094324845200b2fddf4"}, - {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:177f01eeaa3aee4a5ffb0d1439c5952b53d5010f86e9d2667963e632e30082cc"}, - {file = "coverage-7.6.8-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:912e95017ff51dc3d7b6e2be158dedc889d9a5cc3382445589ce554f1a34c0ea"}, - {file = "coverage-7.6.8-cp39-cp39-win32.whl", hash = "sha256:4db3ed6a907b555e57cc2e6f14dc3a4c2458cdad8919e40b5357ab9b6db6c43e"}, - {file = "coverage-7.6.8-cp39-cp39-win_amd64.whl", hash = "sha256:428ac484592f780e8cd7b6b14eb568f7c85460c92e2a37cb0c0e5186e1a0d076"}, - {file = "coverage-7.6.8-pp39.pp310-none-any.whl", hash = "sha256:5c52a036535d12590c32c49209e79cabaad9f9ad8aa4cbd875b68c4d67a9cbce"}, - {file = "coverage-7.6.8.tar.gz", hash = "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc"}, -] - -[package.dependencies] -tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} - -[package.extras] -toml = ["tomli ; python_full_version <= \"3.11.0a6\""] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -groups = ["dev"] -markers = "python_version < \"3.11\"" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "maturin" -version = "1.9.4" -description = "Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages" -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "maturin-1.9.4-py3-none-linux_armv6l.whl", hash = "sha256:6ff37578e3f5fdbe685110d45f60af1f5a7dfce70a1e26dfe3810af66853ecae"}, - {file = "maturin-1.9.4-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:f3837bb53611b2dafa1c090436c330f2d743ba305ef00d8801a371f4495e7e1b"}, - {file = "maturin-1.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:4227d627d8e3bfe45877a8d65e9d8351a9d01434549f0da75d2c06a1b570de58"}, - {file = "maturin-1.9.4-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:1bb2aa0fa29032e9c5aac03ac400396ddea12cadef242f8967e9c8ef715313a1"}, - {file = "maturin-1.9.4-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:a0868d52934c8a5d1411b42367633fdb5cd5515bec47a534192282167448ec30"}, - {file = "maturin-1.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:68b7b833b25741c0f553b78e8b9e095b31ae7c6611533b3c7b71f84c2cb8fc44"}, - {file = "maturin-1.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:08dc86312afee55af778af919818632e35d8d0464ccd79cb86700d9ea560ccd7"}, - {file = "maturin-1.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:ef20ffdd943078c4c3699c29fb2ed722bb6b4419efdade6642d1dbf248f94a70"}, - {file = "maturin-1.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:368e958468431dfeec80f75eea9639b4356d8c42428b0128444424b083fecfb0"}, - {file = "maturin-1.9.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:273f879214f63f79bfe851cd7d541f8150bdbfae5dfdc3c0c4d125d02d1f41b4"}, - {file = "maturin-1.9.4-py3-none-win32.whl", hash = "sha256:ed2e54d132ace7e61829bd49709331007dd9a2cc78937f598aa76a4f69b6804d"}, - {file = "maturin-1.9.4-py3-none-win_amd64.whl", hash = "sha256:8e450bb2c9afdf38a0059ee2e1ec2b17323f152b59c16f33eb9c74edaf1f9f79"}, - {file = "maturin-1.9.4-py3-none-win_arm64.whl", hash = "sha256:7a6f980a9b67a5c13c844c268eabd855b54a6a765df4b4bb07d15a990572a4c9"}, - {file = "maturin-1.9.4.tar.gz", hash = "sha256:235163a0c99bc6f380fb8786c04fd14dcf6cd622ff295ea3de525015e6ac40cf"}, -] - -[package.dependencies] -tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0\""} - -[package.extras] -patchelf = ["patchelf"] -zig = ["ziglang (>=0.10.0,<0.13.0)"] - -[[package]] -name = "packaging" -version = "24.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, - {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, -] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pytest" -version = "8.3.4" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, - {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=1.5,<2" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "5.0.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, - {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, -] - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] - -[[package]] -name = "ruff" -version = "0.8.6" -description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "ruff-0.8.6-py3-none-linux_armv6l.whl", hash = "sha256:defed167955d42c68b407e8f2e6f56ba52520e790aba4ca707a9c88619e580e3"}, - {file = "ruff-0.8.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:54799ca3d67ae5e0b7a7ac234baa657a9c1784b48ec954a094da7c206e0365b1"}, - {file = "ruff-0.8.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e88b8f6d901477c41559ba540beeb5a671e14cd29ebd5683903572f4b40a9807"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0509e8da430228236a18a677fcdb0c1f102dd26d5520f71f79b094963322ed25"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a7ddb221779871cf226100e677b5ea38c2d54e9e2c8ed847450ebbdf99b32d"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:248b1fb3f739d01d528cc50b35ee9c4812aa58cc5935998e776bf8ed5b251e75"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:bc3c083c50390cf69e7e1b5a5a7303898966be973664ec0c4a4acea82c1d4315"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52d587092ab8df308635762386f45f4638badb0866355b2b86760f6d3c076188"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:61323159cf21bc3897674e5adb27cd9e7700bab6b84de40d7be28c3d46dc67cf"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ae4478b1471fc0c44ed52a6fb787e641a2ac58b1c1f91763bafbc2faddc5117"}, - {file = "ruff-0.8.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0c000a471d519b3e6cfc9c6680025d923b4ca140ce3e4612d1a2ef58e11f11fe"}, - {file = "ruff-0.8.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9257aa841e9e8d9b727423086f0fa9a86b6b420fbf4bf9e1465d1250ce8e4d8d"}, - {file = "ruff-0.8.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:45a56f61b24682f6f6709636949ae8cc82ae229d8d773b4c76c09ec83964a95a"}, - {file = "ruff-0.8.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:496dd38a53aa173481a7d8866bcd6451bd934d06976a2505028a50583e001b76"}, - {file = "ruff-0.8.6-py3-none-win32.whl", hash = "sha256:e169ea1b9eae61c99b257dc83b9ee6c76f89042752cb2d83486a7d6e48e8f764"}, - {file = "ruff-0.8.6-py3-none-win_amd64.whl", hash = "sha256:f1d70bef3d16fdc897ee290d7d20da3cbe4e26349f62e8a0274e7a3f4ce7a905"}, - {file = "ruff-0.8.6-py3-none-win_arm64.whl", hash = "sha256:7d7fc2377a04b6e04ffe588caad613d0c460eb2ecba4c0ccbbfe2bc973cbc162"}, - {file = "ruff-0.8.6.tar.gz", hash = "sha256:dcad24b81b62650b0eb8814f576fc65cfee8674772a6e24c9b747911801eeaa5"}, -] - -[[package]] -name = "tomli" -version = "2.2.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_full_version <= \"3.11.0a6\"" -files = [ - {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, - {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, - {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, - {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, - {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, - {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, - {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, - {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, - {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, - {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, -] - -[metadata] -lock-version = "2.1" -python-versions = ">=3.9" -content-hash = "f4a4a040d5ea1ef40daf9ab715e204239d6163f797b4f92be7e7bc51e40eca8c" diff --git a/pyproject.toml b/pyproject.toml index c2c18e6..d01e1da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "radixtarget" -version = "4.2.0" +dynamic = ["version"] description = "Fast radix tree for IP addresses and DNS names" authors = [{name = "TheTechromancer"}] license = {text = "GPL-3.0"} diff --git a/uv.lock b/uv.lock index d0006c0..44fba61 100644 --- a/uv.lock +++ b/uv.lock @@ -348,7 +348,6 @@ wheels = [ [[package]] name = "radixtarget" -version = "4.2.0" source = { editable = "." } [package.dev-dependencies] From 2bc8686b3371fc8066220e45e6f6296c7c4261ab Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Sat, 3 Oct 2026 07:14:37 -0700 Subject: [PATCH 13/21] ci(publish): crates.io trusted publishing instead of a stored token #139 replaces long-lived registry tokens with OIDC. crates.io supports trusted publishing: rust-lang/crates-io-auth-action exchanges the job's OIDC token for a short-lived publish token, so CARGO_REGISTRY_TOKEN no longer needs to exist as a secret. --- .github/workflows/publish.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a6afedf..3c5253f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -182,12 +182,19 @@ jobs: environment: release needs: [version, linux, musllinux, windows, macos, sdist] runs-on: ubuntu-24.04 + permissions: + contents: read + id-token: write steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 - - run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} + - uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5 + id: auth + - run: cargo publish + env: + CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} pypi: environment: pypi From bcbba9cfa6b1a7a364eda848ef21e08701a4d783 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Sat, 3 Oct 2026 07:41:15 -0700 Subject: [PATCH 14/21] ci: call the shared rust, python, release-check, and publish workflows rust-tests.yml, python-tests.yml, the CLA caller, and the release steps of publish.yml now use the org workflows in blacklanternsecurity/CLA at one pinned SHA instead of carrying copies. - python: python-tests.yml derives the matrix from requires-python, replacing the literal 3.9 to 3.14 list, runs ruff check and ruff format --check (format was never checked here), and builds the extension with maturin develop when maturin is the backend. - rust: rust-tests.yml with --all-features --locked on the rust-toolchain.toml channel. - publish: release-check.yml validates the tag against Cargo.toml (now the single version source). The wheel matrix and the crates.io and PyPI uploads stay here because they are radixtarget-specific and PyPI trusted publishing does not work in a reusable workflow. publish.yml creates the release with the SPDX SBOM and attaches the wheels. - archive/** is no longer excluded: archive tags are not created. --- .github/workflows/cla.yml | 2 +- .github/workflows/publish.yml | 67 +++++++++--------------------- .github/workflows/python-tests.yml | 39 ++++------------- .github/workflows/rust-tests.yml | 16 +++---- 4 files changed, 32 insertions(+), 92 deletions(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index f6b10c0..81eb7b7 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -12,5 +12,5 @@ permissions: jobs: cla: - uses: blacklanternsecurity/CLA/.github/workflows/cla-reusable.yml@4f85d3c525483f0f846ef4384a8ece24a3c74375 # 2026-09-29 + uses: blacklanternsecurity/CLA/.github/workflows/cla-reusable.yml@883bfbc89464cadbeb10307b2b82891ba7853f56 # 2026-10-03 secrets: inherit diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3c5253f..be637d5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,7 +2,7 @@ name: publish on: push: - tags: ["v*", "!archive/**"] + tags: ["v*"] permissions: contents: read @@ -12,35 +12,20 @@ concurrency: cancel-in-progress: false jobs: - version: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - name: Tag matches the declared version - run: | - if ! [[ "$GITHUB_REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$ ]]; then - echo "::error::tag $GITHUB_REF_NAME is not vMAJOR.MINOR.PATCH or vMAJOR.MINOR.PATCH-rc.N" - exit 1 - fi - VERSION=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[0].version') - if [ "v$VERSION" != "$GITHUB_REF_NAME" ]; then - echo "::error::tag $GITHUB_REF_NAME does not match Cargo.toml $VERSION" - exit 1 - fi + check: + uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@883bfbc89464cadbeb10307b2b82891ba7853f56 # 2026-10-03 rust: - needs: version + needs: check uses: ./.github/workflows/rust-tests.yml python: - needs: version + needs: check uses: ./.github/workflows/python-tests.yml secrets: inherit linux: - needs: [version, rust, python] + needs: [rust, python] runs-on: ${{ matrix.platform.runner }} strategy: matrix: @@ -76,7 +61,7 @@ jobs: path: dist musllinux: - needs: [version, rust, python] + needs: [rust, python] runs-on: ${{ matrix.platform.runner }} strategy: matrix: @@ -108,7 +93,7 @@ jobs: path: dist windows: - needs: [version, rust, python] + needs: [rust, python] runs-on: ${{ matrix.platform.runner }} strategy: matrix: @@ -136,7 +121,7 @@ jobs: path: dist macos: - needs: [version, rust, python] + needs: [rust, python] runs-on: ${{ matrix.platform.runner }} strategy: matrix: @@ -163,7 +148,7 @@ jobs: path: dist sdist: - needs: [version, rust, python] + needs: [rust, python] runs-on: ubuntu-24.04 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -180,7 +165,7 @@ jobs: crates: environment: release - needs: [version, linux, musllinux, windows, macos, sdist] + needs: [linux, musllinux, windows, macos, sdist] runs-on: ubuntu-24.04 permissions: contents: read @@ -198,7 +183,7 @@ jobs: pypi: environment: pypi - needs: [version, linux, musllinux, windows, macos, sdist] + needs: [linux, musllinux, windows, macos, sdist] runs-on: ubuntu-24.04 permissions: id-token: write @@ -214,26 +199,12 @@ jobs: args: --non-interactive wheels-*/* release: - needs: [crates, pypi] - runs-on: ubuntu-24.04 + needs: [check, crates, pypi] permissions: contents: write - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - uses: anchore/sbom-action@66cbf4bc1f1c0d2edc94016e65bc221b6bb0ad6c # v0.24.3 - with: - path: . - format: spdx-json - output-file: ${{ github.event.repository.name }}-${{ github.ref_name }}.spdx.json - upload-artifact: false - upload-release-assets: false - - name: GitHub Release with SBOM - env: - GH_TOKEN: ${{ github.token }} - run: | - PRERELEASE=() - if [[ "$GITHUB_REF_NAME" == *-rc.* ]]; then PRERELEASE=(--prerelease); fi - gh release create "$GITHUB_REF_NAME" "${{ github.event.repository.name }}-$GITHUB_REF_NAME.spdx.json" \ - --repo "$GITHUB_REPOSITORY" --verify-tag --generate-notes "${PRERELEASE[@]}" + uses: blacklanternsecurity/CLA/.github/workflows/publish.yml@883bfbc89464cadbeb10307b2b82891ba7853f56 # 2026-10-03 + with: + version: ${{ needs.check.outputs.version }} + prerelease: ${{ needs.check.outputs.prerelease }} + artifacts: wheels-* + assets: dist/* diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 3446f21..6d4a93c 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -10,38 +10,13 @@ permissions: contents: read concurrency: - group: python-tests-${{ github.ref }} + group: python-tests-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: - lint: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - run: | - pipx install ruff==0.16.9 - ruff check - test: - needs: lint - runs-on: ubuntu-24.04 - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: ${{ matrix.python-version }} - - uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 - - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 - - run: uv sync - - run: uv run pytest --exitfirst --disable-warnings --log-cli-level=DEBUG --cov-report xml:cov.xml --cov=radixtarget . - - uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - files: ./cov.xml - verbose: true + python: + uses: blacklanternsecurity/CLA/.github/workflows/python-tests.yml@883bfbc89464cadbeb10307b2b82891ba7853f56 # 2026-10-03 + with: + pytest-args: --exitfirst --disable-warnings --log-cli-level=DEBUG --cov-report xml:cov.xml --cov=radixtarget . + coverage: true + secrets: inherit diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index e389c29..f39012b 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -10,17 +10,11 @@ permissions: contents: read concurrency: - group: rust-tests-${{ github.ref }} + group: rust-tests-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: - test: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 - - run: cargo fmt --all -- --check - - run: cargo clippy --all-targets --all-features -- -D warnings - - run: cargo test --verbose --all-features + rust: + uses: blacklanternsecurity/CLA/.github/workflows/rust-tests.yml@883bfbc89464cadbeb10307b2b82891ba7853f56 # 2026-10-03 + with: + cargo-args: --all-features --locked From 9e3735d65f30e6522a5bce71f76b26173f0c9a12 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Sat, 3 Oct 2026 07:47:35 -0700 Subject: [PATCH 15/21] ci: pin the shared workflows to blacklanternsecurity/CLA e532142 Picks up secret-env skipping absent secrets on fork PRs and rust-tests running setup-script before clippy. No caller input changes. --- .github/workflows/cla.yml | 2 +- .github/workflows/publish.yml | 4 ++-- .github/workflows/python-tests.yml | 2 +- .github/workflows/rust-tests.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 81eb7b7..db38056 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -12,5 +12,5 @@ permissions: jobs: cla: - uses: blacklanternsecurity/CLA/.github/workflows/cla-reusable.yml@883bfbc89464cadbeb10307b2b82891ba7853f56 # 2026-10-03 + uses: blacklanternsecurity/CLA/.github/workflows/cla-reusable.yml@e532142ee9e7322888f6edc80d9a89e2f8c0d96d # 2026-10-03 secrets: inherit diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index be637d5..f7899bc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,7 +13,7 @@ concurrency: jobs: check: - uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@883bfbc89464cadbeb10307b2b82891ba7853f56 # 2026-10-03 + uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@e532142ee9e7322888f6edc80d9a89e2f8c0d96d # 2026-10-03 rust: needs: check @@ -202,7 +202,7 @@ jobs: needs: [check, crates, pypi] permissions: contents: write - uses: blacklanternsecurity/CLA/.github/workflows/publish.yml@883bfbc89464cadbeb10307b2b82891ba7853f56 # 2026-10-03 + uses: blacklanternsecurity/CLA/.github/workflows/publish.yml@e532142ee9e7322888f6edc80d9a89e2f8c0d96d # 2026-10-03 with: version: ${{ needs.check.outputs.version }} prerelease: ${{ needs.check.outputs.prerelease }} diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 6d4a93c..b0734a7 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -15,7 +15,7 @@ concurrency: jobs: python: - uses: blacklanternsecurity/CLA/.github/workflows/python-tests.yml@883bfbc89464cadbeb10307b2b82891ba7853f56 # 2026-10-03 + uses: blacklanternsecurity/CLA/.github/workflows/python-tests.yml@e532142ee9e7322888f6edc80d9a89e2f8c0d96d # 2026-10-03 with: pytest-args: --exitfirst --disable-warnings --log-cli-level=DEBUG --cov-report xml:cov.xml --cov=radixtarget . coverage: true diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index f39012b..f04b0d4 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -15,6 +15,6 @@ concurrency: jobs: rust: - uses: blacklanternsecurity/CLA/.github/workflows/rust-tests.yml@883bfbc89464cadbeb10307b2b82891ba7853f56 # 2026-10-03 + uses: blacklanternsecurity/CLA/.github/workflows/rust-tests.yml@e532142ee9e7322888f6edc80d9a89e2f8c0d96d # 2026-10-03 with: cargo-args: --all-features --locked From 0ba31d035683cc0c0e78f4498cbb894e8365360c Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Thu, 8 Oct 2026 09:43:52 -0700 Subject: [PATCH 16/21] ci: pin the shared workflows to blacklanternsecurity/CLA main e532142 sits on feat/shared-workflows, which was squash-merged and can stop resolving once the branch is deleted. 40c6e18 is CLA main and a superset: it adds optional registry login for image SBOMs to publish.yml, with defaults that leave existing callers unchanged. Refs blacklanternsecurity/bbot-enterprise#139 --- .github/workflows/cla.yml | 2 +- .github/workflows/publish.yml | 4 ++-- .github/workflows/python-tests.yml | 2 +- .github/workflows/rust-tests.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index db38056..65e1c15 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -12,5 +12,5 @@ permissions: jobs: cla: - uses: blacklanternsecurity/CLA/.github/workflows/cla-reusable.yml@e532142ee9e7322888f6edc80d9a89e2f8c0d96d # 2026-10-03 + uses: blacklanternsecurity/CLA/.github/workflows/cla-reusable.yml@40c6e18c0a6e32116eea4f89fc826f53c70889dc # 2026-10-07 secrets: inherit diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f7899bc..a8bf73b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,7 +13,7 @@ concurrency: jobs: check: - uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@e532142ee9e7322888f6edc80d9a89e2f8c0d96d # 2026-10-03 + uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@40c6e18c0a6e32116eea4f89fc826f53c70889dc # 2026-10-07 rust: needs: check @@ -202,7 +202,7 @@ jobs: needs: [check, crates, pypi] permissions: contents: write - uses: blacklanternsecurity/CLA/.github/workflows/publish.yml@e532142ee9e7322888f6edc80d9a89e2f8c0d96d # 2026-10-03 + uses: blacklanternsecurity/CLA/.github/workflows/publish.yml@40c6e18c0a6e32116eea4f89fc826f53c70889dc # 2026-10-07 with: version: ${{ needs.check.outputs.version }} prerelease: ${{ needs.check.outputs.prerelease }} diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index b0734a7..95d5f21 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -15,7 +15,7 @@ concurrency: jobs: python: - uses: blacklanternsecurity/CLA/.github/workflows/python-tests.yml@e532142ee9e7322888f6edc80d9a89e2f8c0d96d # 2026-10-03 + uses: blacklanternsecurity/CLA/.github/workflows/python-tests.yml@40c6e18c0a6e32116eea4f89fc826f53c70889dc # 2026-10-07 with: pytest-args: --exitfirst --disable-warnings --log-cli-level=DEBUG --cov-report xml:cov.xml --cov=radixtarget . coverage: true diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index f04b0d4..267c79b 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -15,6 +15,6 @@ concurrency: jobs: rust: - uses: blacklanternsecurity/CLA/.github/workflows/rust-tests.yml@e532142ee9e7322888f6edc80d9a89e2f8c0d96d # 2026-10-03 + uses: blacklanternsecurity/CLA/.github/workflows/rust-tests.yml@40c6e18c0a6e32116eea4f89fc826f53c70889dc # 2026-10-07 with: cargo-args: --all-features --locked From 594372c6265cf626c6a68cf20c2b1a7f788a0622 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Wed, 21 Oct 2026 05:49:50 -0700 Subject: [PATCH 17/21] ci(publish): release on merge to the trunk, per the publishing policy Follows .github-config#17 through CLA#11: publish.yml runs on push to the trunk instead of a v* tag, publishes in the release environment a bbot-leads member approves, re-runs safely (PyPI skip-existing, crates.io only when the version is new), and leaves the tag and the GitHub release to the bls-release App at the end of the run. The pypi environment and the long-lived registry token are gone. --- .github/workflows/publish.yml | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a8bf73b..b956d4f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,7 +2,7 @@ name: publish on: push: - tags: ["v*"] + branches: [stable] permissions: contents: read @@ -13,14 +13,16 @@ concurrency: jobs: check: - uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@40c6e18c0a6e32116eea4f89fc826f53c70889dc # 2026-10-07 + uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@4894c4adb0c98b978c7c621903e1f3205fc446b7 # CLA#11 rust: needs: check + if: needs.check.outputs.release == 'true' uses: ./.github/workflows/rust-tests.yml python: needs: check + if: needs.check.outputs.release == 'true' uses: ./.github/workflows/python-tests.yml secrets: inherit @@ -165,7 +167,7 @@ jobs: crates: environment: release - needs: [linux, musllinux, windows, macos, sdist] + needs: [check, linux, musllinux, windows, macos, sdist] runs-on: ubuntu-24.04 permissions: contents: read @@ -175,14 +177,23 @@ jobs: with: persist-credentials: false - uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 - - uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5 + - id: published + env: + VERSION: ${{ needs.check.outputs.version }} + run: | + if curl -sf -o /dev/null -H "User-Agent: $GITHUB_REPOSITORY" "https://crates.io/api/v1/crates/radixtarget/$VERSION"; then + echo "skip=true" >> "$GITHUB_OUTPUT" + fi + - if: steps.published.outputs.skip != 'true' + uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5 id: auth - - run: cargo publish + - if: steps.published.outputs.skip != 'true' + run: cargo publish --locked env: CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} pypi: - environment: pypi + environment: release needs: [linux, musllinux, windows, macos, sdist] runs-on: ubuntu-24.04 permissions: @@ -196,15 +207,19 @@ jobs: - uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 with: command: upload - args: --non-interactive wheels-*/* + args: --non-interactive --skip-existing wheels-*/* release: needs: [check, crates, pypi] + if: needs.check.outputs.release == 'true' permissions: - contents: write - uses: blacklanternsecurity/CLA/.github/workflows/publish.yml@40c6e18c0a6e32116eea4f89fc826f53c70889dc # 2026-10-07 + contents: read + uses: blacklanternsecurity/CLA/.github/workflows/publish.yml@4894c4adb0c98b978c7c621903e1f3205fc446b7 # CLA#11 with: + release-app-id: ${{ vars.RELEASE_APP_ID }} + tag: ${{ needs.check.outputs.tag }} version: ${{ needs.check.outputs.version }} - prerelease: ${{ needs.check.outputs.prerelease }} artifacts: wheels-* assets: dist/* + secrets: + release-app-key: ${{ secrets.RELEASE_APP_KEY }} From 1231d1ee789b267885226a459c9aa58971d2ee09 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Fri, 23 Oct 2026 04:40:52 -0700 Subject: [PATCH 18/21] ci(release): adopt CLA#11's environment-held credentials - publish: build wheels through CLA's maturin-wheels, which installs every interpreter requires-python allows, so Windows and macOS ship per-version wheels again; publish crates.io through CLA's crates.yml after PyPI; pass no App credentials - python-tests, rust-tests, cla: CODECOV_TOKEN and the CLA App credentials by name instead of secrets: inherit; drop the stable push triggers that duplicated the publish calls - python-tests: keep reporting the required test (3.11) to (3.15) contexts from the real result until the ruleset moves - stable-guard: refuse a pull request into stable whose version or dependencies cannot release - benchmark: explicit permissions and a pinned runner - re-pin every CLA reference to CLA#11 --- .github/workflows/benchmark.yml | 6 +- .github/workflows/cla.yml | 6 +- .github/workflows/publish.yml | 207 ++++------------------------- .github/workflows/python-tests.yml | 24 +++- .github/workflows/rust-tests.yml | 4 +- .github/workflows/stable-guard.yml | 12 ++ 6 files changed, 71 insertions(+), 188 deletions(-) create mode 100644 .github/workflows/stable-guard.yml diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 604aeb4..b1c3c5b 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -3,13 +3,17 @@ name: Benchmark on: pull_request: +permissions: + contents: read + pull-requests: write + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: benchmark: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Check out PR uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 65e1c15..87097d1 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -12,5 +12,7 @@ permissions: jobs: cla: - uses: blacklanternsecurity/CLA/.github/workflows/cla-reusable.yml@40c6e18c0a6e32116eea4f89fc826f53c70889dc # 2026-10-07 - secrets: inherit + uses: blacklanternsecurity/CLA/.github/workflows/cla-reusable.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + secrets: + APP_ID: ${{ secrets.APP_ID }} + APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b956d4f..3e37643 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,7 +13,7 @@ concurrency: jobs: check: - uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@4894c4adb0c98b978c7c621903e1f3205fc446b7 # CLA#11 + uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 rust: needs: check @@ -24,202 +24,53 @@ jobs: needs: check if: needs.check.outputs.release == 'true' uses: ./.github/workflows/python-tests.yml - secrets: inherit - - linux: - needs: [rust, python] - runs-on: ${{ matrix.platform.runner }} - strategy: - matrix: - platform: - - runner: ubuntu-24.04 - target: x86_64 - - runner: ubuntu-24.04 - target: x86 - - runner: ubuntu-24.04 - target: aarch64 - - runner: ubuntu-24.04 - target: armv7 - - runner: ubuntu-24.04 - target: s390x - - runner: ubuntu-24.04 - target: ppc64le - steps: - - 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: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 - with: - target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter - sccache: false - manylinux: auto - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: wheels-linux-${{ matrix.platform.target }} - path: dist - - musllinux: - needs: [rust, python] - runs-on: ${{ matrix.platform.runner }} - strategy: - matrix: - platform: - - runner: ubuntu-24.04 - target: x86_64 - - runner: ubuntu-24.04 - target: x86 - - runner: ubuntu-24.04 - target: aarch64 - - runner: ubuntu-24.04 - target: armv7 - steps: - - 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: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 - with: - target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter - sccache: false - manylinux: musllinux_1_2 - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: wheels-musllinux-${{ matrix.platform.target }} - path: dist - - windows: - needs: [rust, python] - runs-on: ${{ matrix.platform.runner }} - strategy: - matrix: - platform: - - runner: windows-2025 - target: x64 - - runner: windows-2025 - target: x86 - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: 3.x - architecture: ${{ matrix.platform.target }} - - uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 - with: - target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter - sccache: false - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: wheels-windows-${{ matrix.platform.target }} - path: dist - - macos: - needs: [rust, python] - runs-on: ${{ matrix.platform.runner }} - strategy: - matrix: - platform: - - runner: macos-15-intel - target: x86_64 - - runner: macos-15 - target: aarch64 - steps: - - 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: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 - with: - target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter - sccache: false - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: wheels-macos-${{ matrix.platform.target }} - path: dist + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - sdist: + wheels: needs: [rust, python] - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 - with: - command: sdist - args: --out dist - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: wheels-sdist - path: dist - - crates: - environment: release - needs: [check, linux, musllinux, windows, macos, sdist] - runs-on: ubuntu-24.04 - permissions: - contents: read - id-token: write - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0 - - id: published - env: - VERSION: ${{ needs.check.outputs.version }} - run: | - if curl -sf -o /dev/null -H "User-Agent: $GITHUB_REPOSITORY" "https://crates.io/api/v1/crates/radixtarget/$VERSION"; then - echo "skip=true" >> "$GITHUB_OUTPUT" - fi - - if: steps.published.outputs.skip != 'true' - uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5 - id: auth - - if: steps.published.outputs.skip != 'true' - run: cargo publish --locked - env: - CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} + uses: blacklanternsecurity/CLA/.github/workflows/maturin-wheels.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + with: + manylinux: auto pypi: - environment: release - needs: [linux, musllinux, windows, macos, sdist] + needs: wheels runs-on: ubuntu-24.04 + environment: release permissions: id-token: write attestations: write steps: - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + pattern: ${{ needs.wheels.outputs.artifacts }} + path: dist + merge-multiple: true - uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 with: - subject-path: 'wheels-*/*' - - uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0 + subject-path: dist/* + - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 with: - command: upload - args: --non-interactive --skip-existing wheels-*/* + skip-existing: true + + crates: + needs: [check, pypi] + if: needs.check.outputs.release == 'true' + permissions: + contents: read + id-token: write + uses: blacklanternsecurity/CLA/.github/workflows/crates.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + with: + version: ${{ needs.check.outputs.version }} release: - needs: [check, crates, pypi] + needs: [check, wheels, crates, pypi] if: needs.check.outputs.release == 'true' permissions: contents: read - uses: blacklanternsecurity/CLA/.github/workflows/publish.yml@4894c4adb0c98b978c7c621903e1f3205fc446b7 # CLA#11 + uses: blacklanternsecurity/CLA/.github/workflows/publish.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 with: - release-app-id: ${{ vars.RELEASE_APP_ID }} tag: ${{ needs.check.outputs.tag }} version: ${{ needs.check.outputs.version }} - artifacts: wheels-* + artifacts: ${{ needs.wheels.outputs.artifacts }} assets: dist/* - secrets: - release-app-key: ${{ secrets.RELEASE_APP_KEY }} diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 95d5f21..ff93035 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -1,10 +1,11 @@ name: Python tests on: - push: - branches: [stable] pull_request: workflow_call: + secrets: + CODECOV_TOKEN: + required: false permissions: contents: read @@ -15,8 +16,23 @@ concurrency: jobs: python: - uses: blacklanternsecurity/CLA/.github/workflows/python-tests.yml@40c6e18c0a6e32116eea4f89fc826f53c70889dc # 2026-10-07 + uses: blacklanternsecurity/CLA/.github/workflows/python-tests.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 with: pytest-args: --exitfirst --disable-warnings --log-cli-level=DEBUG --cov-report xml:cov.xml --cov=radixtarget . coverage: true - secrets: inherit + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + # Reports the contexts the default branch ruleset requires today. Remove once it requires python / passed. + required: + name: ${{ matrix.context }} + if: always() + needs: python + runs-on: ubuntu-24.04 + strategy: + matrix: + context: ["test (3.11)", "test (3.12)", "test (3.13)", "test (3.14)", "test (3.15)"] + steps: + - uses: re-actors/alls-green@b5b5b37504aa4183270bd3d855c52a67f212be35 # v1.3.0 + with: + jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index 267c79b..25186f3 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -1,8 +1,6 @@ name: Rust tests on: - push: - branches: [stable] pull_request: workflow_call: @@ -15,6 +13,6 @@ concurrency: jobs: rust: - uses: blacklanternsecurity/CLA/.github/workflows/rust-tests.yml@40c6e18c0a6e32116eea4f89fc826f53c70889dc # 2026-10-07 + uses: blacklanternsecurity/CLA/.github/workflows/rust-tests.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 with: cargo-args: --all-features --locked diff --git a/.github/workflows/stable-guard.yml b/.github/workflows/stable-guard.yml new file mode 100644 index 0000000..3d4939b --- /dev/null +++ b/.github/workflows/stable-guard.yml @@ -0,0 +1,12 @@ +name: stable guard + +on: + pull_request: + branches: [stable] + +permissions: + contents: read + +jobs: + guard: + uses: blacklanternsecurity/CLA/.github/workflows/stable-guard.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 From 3bdc148608c331763dc0f1ed4494c27eeef11f04 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Fri, 23 Oct 2026 04:43:04 -0700 Subject: [PATCH 19/21] chore(release): bump to 4.3.1 4.3.0 is on PyPI and crates.io with no v4.3.0 tag, so release-check would refuse it as partly published. --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ed8dcc..edcce8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,7 +265,7 @@ dependencies = [ [[package]] name = "radixtarget" -version = "4.3.0" +version = "4.3.1" dependencies = [ "idna", "ipnet", diff --git a/Cargo.toml b/Cargo.toml index d3a3b43..52cdb2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "radixtarget" -version = "4.3.0" +version = "4.3.1" edition = "2024" description = "Fast radix tree implementation for IP addresses and hostnames with target matching" license = "AGPL-3.0" From 3510c97a832a5d19c3dc35698a5396a0cabb8f50 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Mon, 26 Oct 2026 09:36:23 -0700 Subject: [PATCH 20/21] ci(publish): per-job permissions, drop dependabot auto-merge, document releasing publish.yml drops to permissions: {} and grants contents read per job. check also gets actions and pull-requests read for CLA#11's provenance check and environment guard. dependabot-auto-merge.yml is removed. Once dev drops to zero approvals it would merge Dependabot PRs on CI alone (pjhartlieb). The README gains a Releasing section: the four release approvals per run, and that PyPy and free-threaded interpreters get the sdist since the shared wheel build covers default CPython only. --- .github/workflows/dependabot-auto-merge.yml | 12 ------------ .github/workflows/publish.yml | 14 ++++++++++++-- README.md | 8 ++++++++ 3 files changed, 20 insertions(+), 14 deletions(-) delete mode 100644 .github/workflows/dependabot-auto-merge.yml diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml deleted file mode 100644 index 11dc1b1..0000000 --- a/.github/workflows/dependabot-auto-merge.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Dependabot auto-merge -on: pull_request - -permissions: {} - -jobs: - auto-merge: - permissions: - contents: write - pull-requests: write - checks: read - uses: blacklanternsecurity/CLA/.github/workflows/dependabot-auto-merge.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3e37643..d5a6d5f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,8 +4,7 @@ on: push: branches: [stable] -permissions: - contents: read +permissions: {} concurrency: group: publish-${{ github.ref }} @@ -13,22 +12,32 @@ concurrency: jobs: check: + permissions: + contents: read + actions: read + pull-requests: read uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 rust: needs: check if: needs.check.outputs.release == 'true' + permissions: + contents: read uses: ./.github/workflows/rust-tests.yml python: needs: check if: needs.check.outputs.release == 'true' + permissions: + contents: read uses: ./.github/workflows/python-tests.yml secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} wheels: needs: [rust, python] + permissions: + contents: read uses: blacklanternsecurity/CLA/.github/workflows/maturin-wheels.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 with: manylinux: auto @@ -38,6 +47,7 @@ jobs: runs-on: ubuntu-24.04 environment: release permissions: + contents: read id-token: write attestations: write steps: diff --git a/README.md b/README.md index a48469e..c421ebf 100644 --- a/README.md +++ b/README.md @@ -211,3 +211,11 @@ cargo fmt --all -- --check # Python linting uv run ruff check && uv run ruff format ``` + +## Releasing + +A release is a reviewed pull request into `stable` that bumps the version in `Cargo.toml`. The merge starts `publish.yml`, which tests and builds, then publishes to PyPI and crates.io and creates the `v` tag and the GitHub release. See the org [publishing policy](https://github.com/blacklanternsecurity/.github/blob/main/standards/releases.md). + +Each job that touches a credential runs in the `release` environment, so one release asks a `bbot-leads` member to approve four times: release-check's `credentials` job, `pypi`, `crates`, and the GitHub release. + +Wheels are built for released CPython in its default build only. PyPy and free-threaded (`t`) interpreters install from the sdist, which needs a Rust toolchain. From 83aec2766224c7d972162abcf1747d365c1a331b Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Fri, 30 Oct 2026 11:36:05 -0700 Subject: [PATCH 21/21] ci: pin shared workflows to release-workflows v1.0.0 Move every CLA reusable workflow call to blacklanternsecurity/release-workflows at v1.0.0 and pass BLS_RELEASE_PRIVATE_KEY to the release-check and publish calls, which receive release-environment secrets only when mapped. --- .github/workflows/cla.yml | 2 +- .github/workflows/publish.yml | 12 ++++++++---- .github/workflows/python-tests.yml | 2 +- .github/workflows/rust-tests.yml | 2 +- .github/workflows/stable-guard.yml | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 87097d1..e30d6f9 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -12,7 +12,7 @@ permissions: jobs: cla: - uses: blacklanternsecurity/CLA/.github/workflows/cla-reusable.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + uses: blacklanternsecurity/release-workflows/.github/workflows/cla-reusable.yml@c53c202eedeb26a86088936363e6cb06ce99ac15 # v1.0.0 secrets: APP_ID: ${{ secrets.APP_ID }} APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d5a6d5f..902c4a9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -16,7 +16,9 @@ jobs: contents: read actions: read pull-requests: read - uses: blacklanternsecurity/CLA/.github/workflows/release-check.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + uses: blacklanternsecurity/release-workflows/.github/workflows/release-check.yml@c53c202eedeb26a86088936363e6cb06ce99ac15 # v1.0.0 + secrets: + BLS_RELEASE_PRIVATE_KEY: ${{ secrets.BLS_RELEASE_PRIVATE_KEY }} rust: needs: check @@ -38,7 +40,7 @@ jobs: needs: [rust, python] permissions: contents: read - uses: blacklanternsecurity/CLA/.github/workflows/maturin-wheels.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + uses: blacklanternsecurity/release-workflows/.github/workflows/maturin-wheels.yml@c53c202eedeb26a86088936363e6cb06ce99ac15 # v1.0.0 with: manylinux: auto @@ -69,7 +71,7 @@ jobs: permissions: contents: read id-token: write - uses: blacklanternsecurity/CLA/.github/workflows/crates.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + uses: blacklanternsecurity/release-workflows/.github/workflows/crates.yml@c53c202eedeb26a86088936363e6cb06ce99ac15 # v1.0.0 with: version: ${{ needs.check.outputs.version }} @@ -78,9 +80,11 @@ jobs: if: needs.check.outputs.release == 'true' permissions: contents: read - uses: blacklanternsecurity/CLA/.github/workflows/publish.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + uses: blacklanternsecurity/release-workflows/.github/workflows/publish.yml@c53c202eedeb26a86088936363e6cb06ce99ac15 # v1.0.0 with: tag: ${{ needs.check.outputs.tag }} version: ${{ needs.check.outputs.version }} artifacts: ${{ needs.wheels.outputs.artifacts }} assets: dist/* + secrets: + BLS_RELEASE_PRIVATE_KEY: ${{ secrets.BLS_RELEASE_PRIVATE_KEY }} diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index ff93035..d81c156 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -16,7 +16,7 @@ concurrency: jobs: python: - uses: blacklanternsecurity/CLA/.github/workflows/python-tests.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + uses: blacklanternsecurity/release-workflows/.github/workflows/python-tests.yml@c53c202eedeb26a86088936363e6cb06ce99ac15 # v1.0.0 with: pytest-args: --exitfirst --disable-warnings --log-cli-level=DEBUG --cov-report xml:cov.xml --cov=radixtarget . coverage: true diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index 25186f3..fbc868d 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -13,6 +13,6 @@ concurrency: jobs: rust: - uses: blacklanternsecurity/CLA/.github/workflows/rust-tests.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + uses: blacklanternsecurity/release-workflows/.github/workflows/rust-tests.yml@c53c202eedeb26a86088936363e6cb06ce99ac15 # v1.0.0 with: cargo-args: --all-features --locked diff --git a/.github/workflows/stable-guard.yml b/.github/workflows/stable-guard.yml index 3d4939b..6f8cefa 100644 --- a/.github/workflows/stable-guard.yml +++ b/.github/workflows/stable-guard.yml @@ -9,4 +9,4 @@ permissions: jobs: guard: - uses: blacklanternsecurity/CLA/.github/workflows/stable-guard.yml@07e14bcbba5e737e1b29bd9e3f9128fbf2483be9 # CLA#11 + uses: blacklanternsecurity/release-workflows/.github/workflows/stable-guard.yml@c53c202eedeb26a86088936363e6cb06ce99ac15 # v1.0.0