From b79d73e88d953464eaad4beea1fe56c385f58c2f Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Mon, 28 Sep 2026 11:40:32 -0700 Subject: [PATCH 01/20] 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 02/20] 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 03/20] 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 04/20] 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 05/20] 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 06/20] 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 07/20] 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 08/20] 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 09/20] 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 10/20] 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 11/20] 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 d3aa8eeabd027f2831e4b36856ce7cdf23a4ddfa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:36:40 +0000 Subject: [PATCH 12/20] Bump the github-actions group across 1 directory with 9 updates Bumps the github-actions group with 9 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `6` | `7` | | [actions-rust-lang/setup-rust-toolchain](https://github.com/actions-rust-lang/setup-rust-toolchain) | `1` | `2` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `5` | `7` | | [actions/github-script](https://github.com/actions/github-script) | `8` | `9` | | [actions/setup-python](https://github.com/actions/setup-python) | `6` | `7` | | [codecov/codecov-action](https://github.com/codecov/codecov-action) | `5` | `7` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `6` | `8` | | [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) | `3` | `4` | | [actions/cache](https://github.com/actions/cache) | `4` | `6` | Updates `actions/checkout` from 6 to 7 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v6...v7) Updates `actions-rust-lang/setup-rust-toolchain` from 1 to 2 - [Release notes](https://github.com/actions-rust-lang/setup-rust-toolchain/releases) - [Changelog](https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions-rust-lang/setup-rust-toolchain/compare/v1...v2) Updates `actions/upload-artifact` from 5 to 7 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v5...v7) Updates `actions/github-script` from 8 to 9 - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v8...v9) Updates `actions/setup-python` from 6 to 7 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v6...v7) Updates `codecov/codecov-action` from 5 to 7 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v5...v7) Updates `actions/download-artifact` from 6 to 8 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v6...v8) Updates `actions/attest-build-provenance` from 3 to 4 - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/v3...v4) Updates `actions/cache` from 4 to 6 - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions-rust-lang/setup-rust-toolchain dependency-version: '2' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions/github-script dependency-version: '9' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions/setup-python dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: codecov/codecov-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions/download-artifact dependency-version: '8' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions/attest-build-provenance dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions/cache dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/benchmark.yml | 10 +++---- .github/workflows/python-tests.yml | 44 +++++++++++++++--------------- .github/workflows/rust-tests.yml | 6 ++-- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index e9ea64a..e4fc124 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -12,18 +12,18 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out PR - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: path: head - name: Check out target branch - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: ref: ${{ github.event.pull_request.base.sha }} path: base - name: Install Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@v1 + uses: actions-rust-lang/setup-rust-toolchain@v2 with: cache: false @@ -61,7 +61,7 @@ jobs: - name: Upload benchmark results if: always() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: benchmark-results path: | @@ -76,7 +76,7 @@ jobs: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const fs = require('fs'); diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 4aae778..482fd0c 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -10,7 +10,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - run: | pipx install ruff ruff check @@ -21,9 +21,9 @@ jobs: matrix: python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@v7 with: python-version: ${{ matrix.python-version }} - name: Set up Rust @@ -36,7 +36,7 @@ jobs: 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: codecov/codecov-action@v7 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./cov.xml @@ -46,9 +46,9 @@ jobs: needs: test if: github.event_name == 'push' && github.ref == 'refs/heads/stable' steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@v7 with: python-version: "3.12" - name: Set up Rust @@ -80,8 +80,8 @@ jobs: - runner: ubuntu-22.04 target: ppc64le steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: python-version: 3.x - name: Build wheels @@ -92,7 +92,7 @@ jobs: sccache: false manylinux: auto - name: Upload wheels - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: wheels-linux-${{ matrix.platform.target }} path: dist @@ -113,8 +113,8 @@ jobs: - runner: ubuntu-22.04 target: armv7 steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: python-version: 3.x - name: Build wheels @@ -125,7 +125,7 @@ jobs: sccache: false manylinux: musllinux_1_2 - name: Upload wheels - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: wheels-musllinux-${{ matrix.platform.target }} path: dist @@ -142,8 +142,8 @@ jobs: - runner: windows-latest target: x86 steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: # maturin --find-interpreter only builds for interpreters on the runner python-version: | @@ -160,7 +160,7 @@ jobs: args: --release --out dist --find-interpreter sccache: false - name: Upload wheels - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: wheels-windows-${{ matrix.platform.target }} path: dist @@ -177,8 +177,8 @@ jobs: - runner: macos-latest target: aarch64 steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: # maturin --find-interpreter only builds for interpreters on the runner python-version: | @@ -194,7 +194,7 @@ jobs: args: --release --out dist --find-interpreter sccache: false - name: Upload wheels - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: wheels-macos-${{ matrix.platform.target }} path: dist @@ -204,14 +204,14 @@ jobs: needs: publish if: github.event_name == 'push' && github.ref == 'refs/heads/stable' steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Build sdist uses: PyO3/maturin-action@v1 with: command: sdist args: --out dist - name: Upload sdist - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: name: wheels-sdist path: dist @@ -229,9 +229,9 @@ jobs: # Used to generate artifact attestation attestations: write steps: - - uses: actions/download-artifact@v6 + - uses: actions/download-artifact@v8 - name: Generate artifact attestation - uses: actions/attest-build-provenance@v3 + uses: actions/attest-build-provenance@v4 with: subject-path: 'wheels-*/*' - name: Publish wheels to PyPI diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index b96ddc6..5460473 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Install Rust toolchain uses: actions-rs/toolchain@v1 @@ -20,7 +20,7 @@ jobs: profile: minimal - name: Cache Rust dependencies - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: | ~/.cargo/registry @@ -45,7 +45,7 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/stable' steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: Install Rust toolchain uses: actions-rs/toolchain@v1 From 594372c6265cf626c6a68cf20c2b1a7f788a0622 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Wed, 21 Oct 2026 05:49:50 -0700 Subject: [PATCH 13/20] 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 4b628bf225dd5a21d465daabe7551735fe0d457a Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Fri, 23 Oct 2026 01:10:35 +0800 Subject: [PATCH 14/20] ci(dependabot): weekly grouped updates and shared auto-merge for minor and patch (#106) * ci(dependabot): group updates weekly and auto-merge minor and patch Individual dependabot PRs pile up faster than one engineer can review them and go stale until they conflict (bbot-enterprise#141). Every ecosystem now runs weekly against dev and opens at most two grouped PRs: one for minor and patch bumps, one for majors. A pull_request_target workflow enables auto-merge (squash) on the minor/patch group so it lands once required checks pass. Majors still need a human. * ci(dependabot): call the shared auto-merge workflow The auto-merge job was a byte-identical copy in ten repositories. It now calls dependabot-auto-merge.yml in blacklanternsecurity/.github, pinned by SHA, so the fetch-metadata pin and merge policy live in one place. The trigger moves from pull_request_target to pull_request. Dependabot branches live in this repository, so the privileged target context was never needed and zizmor flags it as a dangerous trigger. The cargo ecosystem also scans /benchmark, which carries its own Cargo.toml and Cargo.lock that were previously never updated. * ci(dependabot): call auto-merge from the public CLA repository blacklanternsecurity/.github is private, so public repositories cannot call reusable workflows from it and the run failed as a workflow file issue. The shared workflow lives in blacklanternsecurity/CLA, which is public and already hosts cla-reusable.yml. * ci(dependabot): gate auto-merge on finished checks dev carries no required checks (#139), so gh pr merge --auto would merge immediately rather than on green. The shared workflow now waits for every other check on the head commit, refuses on failure or cancel, and merges with --match-head-commit. The caller grants checks: read so it can read check state. * ci(dependabot): pin the shared workflow to the current CLA tip Aligns with the SHA the other shared CLA workflows are pinned to. The auto-merge workflow is unchanged between the two commits. * ci(dependabot): pin auto-merge to CLA main at ad6e7d7 The e532142 pin filtered its own check by workflow name. Off the default branch GitHub reports that name as the file path, so the job waited on itself until the 3h timeout and never merged. CLA#7 drops the check by run id instead, and is on CLA main. --- .github/dependabot.yml | 59 ++++++++++++++++----- .github/workflows/dependabot-auto-merge.yml | 12 +++++ 2 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/dependabot-auto-merge.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 334d9ab..f2a13f9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,22 +1,55 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file - version: 2 updates: + - package-ecosystem: "cargo" + directories: + - "/" + - "/benchmark" + target-branch: "dev" + schedule: + interval: "weekly" + groups: + cargo-minor-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" + cargo-major: + patterns: + - "*" + update-types: + - "major" - package-ecosystem: "uv" directory: "/" + target-branch: "dev" schedule: interval: "weekly" - target-branch: "dev" - open-pull-requests-limit: 10 - - package-ecosystem: github-actions - directory: / groups: - github-actions: + uv-minor-patch: patterns: - - "*" # Group all Actions updates into a single larger pull request - schedule: - interval: weekly + - "*" + update-types: + - "minor" + - "patch" + uv-major: + patterns: + - "*" + update-types: + - "major" + - package-ecosystem: "github-actions" + directory: "/" target-branch: "dev" + schedule: + interval: "weekly" + groups: + github-actions-minor-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" + github-actions-major: + patterns: + - "*" + update-types: + - "major" diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml new file mode 100644 index 0000000..3d257bb --- /dev/null +++ b/.github/workflows/dependabot-auto-merge.yml @@ -0,0 +1,12 @@ +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@ad6e7d77546f99f569e51085a0e7aad496e23b9c # 2026-10-20 From 1231d1ee789b267885226a459c9aa58971d2ee09 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Fri, 23 Oct 2026 04:40:52 -0700 Subject: [PATCH 15/20] 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 16/20] 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 fcde8cd5276c44b481e344690c2aa4f347ebe385 Mon Sep 17 00:00:00 2001 From: Philip Hartlieb Date: Fri, 23 Oct 2026 18:02:10 -0400 Subject: [PATCH 17/20] Update license metadata to AGPL-3.0-or-later --- README.md | 2 +- THIRD_PARTY_NOTICES.md | 38 ++++++++++++++++++++++++++++++++++++++ pyproject.toml | 4 ++-- 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 THIRD_PARTY_NOTICES.md diff --git a/README.md b/README.md index e2220ad..84b2bdd 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![PyPI](https://img.shields.io/pypi/v/radixtarget)](https://pypi.org/project/radixtarget/) [![Rust Version](https://img.shields.io/badge/rust-1.70+-orange)](https://www.rust-lang.org) [![Crates.io](https://img.shields.io/crates/v/radixtarget?color=orange)](https://crates.io/crates/radixtarget) -[![License](https://img.shields.io/badge/license-GPLv3-blue.svg)](https://github.com/blacklanternsecurity/radixtarget/blob/stable/LICENSE) +[![License](https://img.shields.io/badge/license-AGPLv3-blue.svg)](LICENSE) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![Rust Tests](https://github.com/blacklanternsecurity/radixtarget/actions/workflows/rust-tests.yml/badge.svg?branch=stable)](https://github.com/blacklanternsecurity/radixtarget/actions/workflows/rust-tests.yml) [![Python Tests](https://github.com/blacklanternsecurity/radixtarget/actions/workflows/python-tests.yml/badge.svg?branch=stable)](https://github.com/blacklanternsecurity/radixtarget/actions/workflows/python-tests.yml) diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md new file mode 100644 index 0000000..05d13fe --- /dev/null +++ b/THIRD_PARTY_NOTICES.md @@ -0,0 +1,38 @@ +# Third-party notices + +This repository is licensed under AGPL-3.0-or-later (see `LICENSE`). The material listed below +comes from third parties and remains under its original license. + +## treebitmap (Hroi Sigurdsson) + +- Source: https://github.com/hroi/treebitmap +- Used in: `src/treebitmap/` and the TreeBitmap structure in `src/treebitmap.rs` +- License: MIT + +``` +Copyright (c) 2016 Hroi Sigurdsson + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +``` diff --git a/pyproject.toml b/pyproject.toml index da4d09e..921c2e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,14 +3,14 @@ name = "radixtarget" version = "4.3.0" description = "Fast radix tree for IP addresses and DNS names" authors = [{name = "TheTechromancer"}] -license = {text = "AGPL-3.0"} +license = {text = "AGPL-3.0-or-later"} readme = "README.md" requires-python = ">=3.11" keywords = ["radix", "tree", "ip", "dns", "networking"] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", From d8642790ba36a9f13eecc21c6688d8840546e965 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Oct 2026 14:55:02 +0000 Subject: [PATCH 18/20] Bump ruff from 0.17.1 to 0.17.2 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.17.1 to 0.17.2. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.17.1...0.17.2) --- updated-dependencies: - dependency-name: ruff dependency-version: 0.17.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- uv.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/uv.lock b/uv.lock index b017613..6f4c9bd 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.11" [[package]] @@ -242,27 +242,27 @@ dev = [ [[package]] name = "ruff" -version = "0.17.1" +version = "0.17.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e7/e6d5749983b020e6cb1055abec0a6f361a8e94f0184cdcf56d4760995f02/ruff-0.17.1.tar.gz", hash = "sha256:5bb796c5112e9fb9527f2ef2faa0a130d6312d19de92bcfaddd70dbb2d41020f", size = 5323349, upload-time = "2026-10-15T15:23:18.64Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/58/690cf56da80c8f2c8bf12042b6017beac2c34fe961f65420bcb3fb7fac38/ruff-0.17.2.tar.gz", hash = "sha256:84d632402d14c23b488f941db23712d6736a013225162062d34558c3f3c780eb", size = 5333400, upload-time = "2026-10-22T18:38:00.181Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2e/78/90c46ca6250709f7c37e397b60d06061adee8d0f7d13959ed6a8e49b14fd/ruff-0.17.1-py3-none-linux_armv6l.whl", hash = "sha256:1796c41eafec66f4635125dd1e074a7aa27b8d20c187d484360acf11d247fc4a", size = 10147528, upload-time = "2026-10-15T15:22:33.667Z" }, - { url = "https://files.pythonhosted.org/packages/aa/d2/a2e28bc35b083ae51fa07dfba5280a667c8b01ecaee7802fc8849dcd5c46/ruff-0.17.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8eadb09a788010be29c895418bdfa513e4e1c65e64b94e5b19e4cd381f6cc7fb", size = 10225974, upload-time = "2026-10-15T15:22:36.328Z" }, - { url = "https://files.pythonhosted.org/packages/8e/71/7a9029a81c8206ee01a98f6cfeeb56e6c095af86857581a37045c46d7e94/ruff-0.17.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:29b454f18ca3eeaf37fbf140841dcf27d36109e29dee9aae8acecb68c26c6f74", size = 9270361, upload-time = "2026-10-15T15:22:38.651Z" }, - { url = "https://files.pythonhosted.org/packages/c0/8c/e075e9c917cb0575297880c96768304e881240171c870cbd8d9b7b54bec2/ruff-0.17.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872e03dd231744d6c5ec5c8af6be52b71323fc6ee096e4c8b34d9f844ee3b978", size = 9938300, upload-time = "2026-10-15T15:22:41.284Z" }, - { url = "https://files.pythonhosted.org/packages/87/27/0b4bb926a49de2383f161272b4d863571a4c7ecdbf595a6bc58813a13367/ruff-0.17.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4c0d6cb5f8fbac77eec9af49f4fc0eaf856b05545e372b0694d24b4e76b1c640", size = 9948464, upload-time = "2026-10-15T15:22:43.681Z" }, - { url = "https://files.pythonhosted.org/packages/14/27/518d57e0e02aecb8ea4acac6b57b51a53173d25fa734952bfdd7d531e88e/ruff-0.17.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78beced4a3c94dfedbee4b999b95b6a27b35820fdc0afbacc6d37a8da26c1cd1", size = 10638639, upload-time = "2026-10-15T15:22:46.081Z" }, - { url = "https://files.pythonhosted.org/packages/01/82/d89a4e498ade59e6cee52d67f8da569019372212b87468c1fdeae884601c/ruff-0.17.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7feefc63921202894f0e158b0e32f45a5950d70a7fb693ccb9264816c25b1c05", size = 11337238, upload-time = "2026-10-15T15:22:48.894Z" }, - { url = "https://files.pythonhosted.org/packages/a2/7c/3b0fdef9352656317c977086fe1d802902406e4f2a0d8578da90c0e6d1c5/ruff-0.17.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:684154861a819bf1f433669d2a0ce9c3e54677c65b8ebb866cc2a7ec86345785", size = 10896327, upload-time = "2026-10-15T15:22:51.45Z" }, - { url = "https://files.pythonhosted.org/packages/62/86/5566290219708ce2928f3a29c4f843a1185b341ec6111c4631a33c5ceced/ruff-0.17.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6ef98e51de8ef38082f90653ceeb84944bd7673783eea13e1647c5b9b064189", size = 10350811, upload-time = "2026-10-15T15:22:54.401Z" }, - { url = "https://files.pythonhosted.org/packages/ad/d2/ca8462dabb3c413990d49703ba306c30c862195a75448d080fa8fcce9775/ruff-0.17.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:8f9aa5b5bd5fa1937803ea609c8f153b8de39bf3e0e149897ae34b0c5b52f467", size = 10569994, upload-time = "2026-10-15T15:22:57.142Z" }, - { url = "https://files.pythonhosted.org/packages/e3/ad/dd1864c1f1db17c8cfb297ce70b352388e6977620f66f7182c52855407df/ruff-0.17.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:80e53b0e5faa3c5667f035daaa032893ae42b7cfe708c886d39ed131e54688ab", size = 10059672, upload-time = "2026-10-15T15:23:00.084Z" }, - { url = "https://files.pythonhosted.org/packages/65/45/3f56cf1d2168c2165cdd5ac6f9668aee66a4cfdd4caf2b2cc5ccb2b1d568/ruff-0.17.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:056c5d5fa0ac790051ae165d7035c7bf956d02de2db557f2e9b31d877a505fca", size = 9947803, upload-time = "2026-10-15T15:23:03.132Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4b/5457cb2be4c1d1ea5e919558131a0f197a4a454a0530d9e30820e8206e4c/ruff-0.17.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bd8f5a55b10f371642eacd0e8665a42a8b97da15c9a7187c79e697b77b5e0ce4", size = 10351807, upload-time = "2026-10-15T15:23:05.628Z" }, - { url = "https://files.pythonhosted.org/packages/49/fb/db15b4f8fa24a1e36b99e1401f42ef6df16ee299a48670d5d262b771e7d7/ruff-0.17.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ce05e6f3973611d9550a600e04bb531061e368baba31610eb57c1509a8f21a0a", size = 10765716, upload-time = "2026-10-15T15:23:08.092Z" }, - { url = "https://files.pythonhosted.org/packages/0a/e8/1e186578076aff7a80735f625005fde678412ab609cd323ed182eb7d6b87/ruff-0.17.1-py3-none-win32.whl", hash = "sha256:1de0030a8aa78c65c5fecb84b2e5c390ac684c0452875a02afc7c083d49a496a", size = 9895093, upload-time = "2026-10-15T15:23:10.582Z" }, - { url = "https://files.pythonhosted.org/packages/6a/2e/da3d9589bae8e8b58f3a48bd5bc0b980232fb14a83bf02c3be7660f87c1b/ruff-0.17.1-py3-none-win_amd64.whl", hash = "sha256:5df76f16580fab58d0f6c98a3ac254a4abceb7b2489b8b678335869cff77b3d7", size = 10097955, upload-time = "2026-10-15T15:23:13.309Z" }, - { url = "https://files.pythonhosted.org/packages/df/c9/0f2a4dea06a5e12c1191ee3d96b1e1233797d0d5e18f97a2b909a95a9836/ruff-0.17.1-py3-none-win_arm64.whl", hash = "sha256:42400b9a6ff8515ff27796f07f92e0195be011c86e81e381606f58ea5502fef4", size = 9853542, upload-time = "2026-10-15T15:23:16.05Z" }, + { url = "https://files.pythonhosted.org/packages/98/b8/8b6d69c57e8fe1cc6af1aa7493b72a1a5b5a8afe34694e302025441729d4/ruff-0.17.2-py3-none-linux_armv6l.whl", hash = "sha256:96a65e755d8dba094707fb23ab602111d9a31ec2835b3a6992a1914a8fcb211e", size = 10183857, upload-time = "2026-10-22T18:37:14.956Z" }, + { url = "https://files.pythonhosted.org/packages/e8/61/12cc2ff7b2fa90a268ce1e2162c23aaf76e601d22623f6a31b0eeaa764b0/ruff-0.17.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:39c5b55c960515cdb32be16e69efb5734c589c06a0eb38a22694524a336b889d", size = 10210904, upload-time = "2026-10-22T18:37:17.985Z" }, + { url = "https://files.pythonhosted.org/packages/e8/7c/b8850a8e4ad29f64a827dd6c6902db4a9aa538fb2b9eef4e26084001a3bb/ruff-0.17.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:92a80d2f44584dabb0189b3a6c393e37e525e04942838482010575cb81945be7", size = 9408439, upload-time = "2026-10-22T18:37:20.964Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b6/6a64fae86ca5e5e29d5adc311e5481de726cedf9aee607435a16c31c442a/ruff-0.17.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7d0906677d89bbf3cf73cde64b5bbe2ab35df3ae43e49ee2627301e91265bac", size = 10047078, upload-time = "2026-10-22T18:37:23.717Z" }, + { url = "https://files.pythonhosted.org/packages/10/19/23d376547715175aa1bd46df48df6aacc7c6439d9daf19cac15975180aa5/ruff-0.17.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7cfd783590edf2b77317882631900f6a13ea2e8eacefe6ebf2370d2715299160", size = 9990478, upload-time = "2026-10-22T18:37:26.584Z" }, + { url = "https://files.pythonhosted.org/packages/93/6c/34cda32cbe13adac5c6b291a307a5570d8ebd37c0c86339f0fe628e55632/ruff-0.17.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122258f6ecde0e0dd1bb60b24263c3edde4338caf723fca711cc729f9bfd414a", size = 10673624, upload-time = "2026-10-22T18:37:29.767Z" }, + { url = "https://files.pythonhosted.org/packages/bf/10/5d762a4dbc851d8bb47863cf3a28a61bf31c804d393b70d891fac899f5d1/ruff-0.17.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f8fba429d6ac4128ab29cfb8fa6240d2fa671d04adf7f84d3b22fc7b6b6bea4", size = 11351797, upload-time = "2026-10-22T18:37:32.535Z" }, + { url = "https://files.pythonhosted.org/packages/3f/04/a0e92a81faf5c81c1c98d4374c8401734ccf2b8cca7d0170cb0fec08c6e2/ruff-0.17.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:583bd67bb9e7061dd09bc46a0a884bae2bbd214dbcd48e509813612619683869", size = 10949414, upload-time = "2026-10-22T18:37:35.501Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d8/59894cf630d2d86882457a2a6a0a1533410c5c805bfbac6f6eb4b5aef69d/ruff-0.17.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c60f93fec7142dba5b8f487f94bf2f6231dae24dc11e4c48648347c8b0720004", size = 10528000, upload-time = "2026-10-22T18:37:37.88Z" }, + { url = "https://files.pythonhosted.org/packages/ab/95/d6e30c51e851d37e10762ad91fa1e76ddaad998589b5667962a3cfbc9edd/ruff-0.17.2-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:c555a877f8f41447e318101cfefea9bf12dfa9f82eedf90c376e57e069f917d0", size = 10571779, upload-time = "2026-10-22T18:37:40.444Z" }, + { url = "https://files.pythonhosted.org/packages/f4/5a/a7e1d74fb464250137d3d4eca645d323536533b672004d04ee0e46e0caf3/ruff-0.17.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ba405cbd5ec7bda1f555d5e52be1fd68d02608d4d95d24591bdac92cfacb579f", size = 10051707, upload-time = "2026-10-22T18:37:42.812Z" }, + { url = "https://files.pythonhosted.org/packages/6e/f2/02fca29ca7999380f0350a7212fe755c11ab9c22d61327356cce8decdbc6/ruff-0.17.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8c21b4ab24485358f17291a4f8dc5399b834e963b8efedd920fe4fdb02081bb4", size = 9998227, upload-time = "2026-10-22T18:37:45.224Z" }, + { url = "https://files.pythonhosted.org/packages/d1/00/55aa604a093dfdc1526e570fae0bb7d37a2221c7b4728d5f080b2add16ba/ruff-0.17.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5875a16b0de70b43cb81eabea5ae5e8f5d1b2fd1b5e6ed07f80cfe5019d0bd5a", size = 10377692, upload-time = "2026-10-22T18:37:47.704Z" }, + { url = "https://files.pythonhosted.org/packages/e4/5a/a7a640f47bb906ec8fa233ea84319d503e6dee02b59e3901bd312ebd1f9b/ruff-0.17.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:2d086be452eed686aa51271ecf2cbe5037956517cc6ee39a17b4489ac12f8bbe", size = 10790587, upload-time = "2026-10-22T18:37:50.191Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d4/c3b74e1b4808438ea7f14bb914478025e2d51261f60774a54a0fa222ec46/ruff-0.17.2-py3-none-win32.whl", hash = "sha256:6bce7d1f5165701ae18f5df85c65afe78cddfa6c5fb4b9bdb0014d60388f3edd", size = 9870537, upload-time = "2026-10-22T18:37:52.486Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/c7da96c2c96d20704cf9027f7a5121da272a8c05f1d1531ba949e3b3df04/ruff-0.17.2-py3-none-win_amd64.whl", hash = "sha256:1b59d447f197bef9ef48a22ba1a6016137753c6099e9bac9c36eb566e422424c", size = 10282826, upload-time = "2026-10-22T18:37:55.2Z" }, + { url = "https://files.pythonhosted.org/packages/81/60/a3604c79cb02777b6cb84da894104021986f06c4bc41375102cc95049a32/ruff-0.17.2-py3-none-win_arm64.whl", hash = "sha256:195ad918027f817c119310ca89a42d347887dfc28934aaa869325e9c5dc9d962", size = 9827036, upload-time = "2026-10-22T18:37:58.031Z" }, ] [[package]] From 3510c97a832a5d19c3dc35698a5396a0cabb8f50 Mon Sep 17 00:00:00 2001 From: Shane Engelman Date: Mon, 26 Oct 2026 09:36:23 -0700 Subject: [PATCH 19/20] 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 20/20] 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