Repository navigation
Conversation
stable now requires python / passed, rust / passed, clippy-python-feature and guard / release ready, so the job that reported the old python-tests and rust-tests contexts is no longer needed.
…k-names ci: drop the legacy check names from tests.yml
…tory with 5 updates Bumps the github-actions-minor-patch group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions-rust-lang/setup-rust-toolchain](https://github.com/actions-rust-lang/setup-rust-toolchain) | `2.0.0` | `2.0.1` | | [actions/setup-python](https://github.com/actions/setup-python) | `7.0.0` | `7.1.0` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `7.0.1` | `7.0.2` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `8.0.1` | `8.0.2` | | [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) | `1.14.2` | `1.14.3` | Updates `actions-rust-lang/setup-rust-toolchain` from 2.0.0 to 2.0.1 - [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](actions-rust-lang/setup-rust-toolchain@ecabd13...a188e68) Updates `actions/setup-python` from 7.0.0 to 7.1.0 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](actions/setup-python@5fda3b9...6d4fd22) Updates `actions/upload-artifact` from 7.0.1 to 7.0.2 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](actions/upload-artifact@043fb46...cf430e0) Updates `actions/download-artifact` from 8.0.1 to 8.0.2 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](actions/download-artifact@3e5f45b...9000827) Updates `pypa/gh-action-pypi-publish` from 1.14.2 to 1.14.3 - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](pypa/gh-action-pypi-publish@dc37677...7245906) --- updated-dependencies: - dependency-name: actions-rust-lang/setup-rust-toolchain dependency-version: 2.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-minor-patch - dependency-name: actions/download-artifact dependency-version: 8.0.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-minor-patch - dependency-name: actions/setup-python dependency-version: 7.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-minor-patch - dependency-name: actions/upload-artifact dependency-version: 7.0.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-minor-patch - dependency-name: pypa/gh-action-pypi-publish dependency-version: 1.14.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-minor-patch ... Signed-off-by: dependabot[bot] <support@github.com>
…h 2 updates Bumps the uv-minor-patch group with 2 updates in the / directory: [maturin](https://github.com/pyo3/maturin) and [ruff](https://github.com/astral-sh/ruff). Updates `maturin` from 1.10.2 to 1.16.0 - [Release notes](https://github.com/pyo3/maturin/releases) - [Changelog](https://github.com/PyO3/maturin/blob/main/Changelog.md) - [Commits](PyO3/maturin@v1.10.2...v1.16.0) Updates `ruff` from 0.14.8 to 0.17.3 - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](astral-sh/ruff@0.14.8...0.17.3) --- updated-dependencies: - dependency-name: maturin dependency-version: 1.16.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: uv-minor-patch - dependency-name: ruff dependency-version: 0.17.3 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: uv-minor-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Calls release-workflows dev-security.yml (v1.1.0), the security checks policy rule 3 requires on dev. Fixes what zizmor reports: the CLA triggers are marked as reviewed (cla-reusable.yml never checks out pull request code), benchmark checkouts drop persisted credentials, and publish.yml's local workflow calls are marked as reviewed (same-repository calls on stable).
zizmor dependabot-cooldown (the workflow-lint check): version updates now wait 7 days after a release is published, so a compromised release has time to be caught and pulled before it is proposed here. Security updates are not delayed.
…ctions/dev/github-actions-minor-patch-5b8456e292 build(deps): bump the github-actions-minor-patch group across 1 directory with 5 updates
ci: run dependency review and workflow lint on pull requests
Bumps the github-actions-major group with 1 update in the / directory: [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv). Updates `astral-sh/setup-uv` from 7.6.0 to 10.3.3 - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](astral-sh/setup-uv@37802ad...68559e9) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 10.3.3 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions-major ... Signed-off-by: dependabot[bot] <support@github.com>
…ctions/dev/github-actions-major-7313d4f700 build(deps): bump astral-sh/setup-uv from 7.6.0 to 10.3.3 in the github-actions-major group across 1 directory
Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to 2.20.0. - [Release notes](https://github.com/pygments/pygments/releases) - [Changelog](https://github.com/pygments/pygments/blob/master/CHANGES) - [Commits](pygments/pygments@2.19.2...2.20.0) --- updated-dependencies: - dependency-name: pygments dependency-version: 2.20.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
hickory-resolver 0.26 replaced NameServerConfig::socket_addr with an `ip` field, so get_system_resolvers() reads that instead.
…er-0.26 Bump hickory-resolver from 0.25.2 to 0.26.2
ruff 0.17 formats Python code blocks in Markdown, so ruff format --check failed on two mock_dns examples in README.md.
…v-minor-patch-ed6531f1dc build(deps-dev): bump the uv-minor-patch group across 1 directory with 2 updates
…nts-2.20.0 build(deps): bump pygments from 2.19.2 to 2.20.0
System resolvers were formatted as "{ip}:53" and parsed back, which
turns 2001:db8::1 into the different address 2001:db8::1:53 and rejects
addresses with no zero run. Build the socket addresses directly instead.
Closes #176
…olvers fix: keep IPv6 system resolver addresses intact
chore(release): bump version to 2.0.4
DNS Resolver Benchmark
All metrics
|
en0f
left a comment
There was a problem hiding this comment.
Reviewed at 764c362.
🟢 Dropping the legacy check names is safe for stable
The removed required job only existed to report python-tests (3.x) and rust-tests for the old ruleset. The stable ruleset now requires python / passed, rust / passed, clippy-python-feature and guard / release ready, classic branch protection on stable requires nothing, and all four reported success at this head. Nothing stable requires is left unreported, and the alls-green shim goes with it, as the removed comment planned.
🟢 The hickory-resolver 0.26 bump changes no public type, so 2.0.4 is an honest patch
hickory_resolver is used only in src/utils.rs for system_conf, and src/lib.rs re-exports none of it. get_system_resolvers keeps its Result<Vec<IpAddr>, BlastDNSError> signature, and ns.socket_addr.ip() to ns.ip is just the 0.26 field rename. Crate and wheel users see no type change, which is what a patch version promises.
🟢 benchmark.yml no longer leaves the token in .git/config while PR code builds
Both checkouts in benchmark.yml now set persist-credentials: false, and the job goes on to run uv sync and maturin develop on the PR's own build code. The GITHUB_TOKEN is no longer written into .git/config where that code could read it (per standards/ci.md § Permissions). The job still holds pull-requests: write for the report comment, so this closes the easy path rather than every path.
Reproduce this review
# save the script below as verify-179.sh and the patch as control-179.patch, then:
bash verify-179.sh blacklanternsecurity/blastdns 764c362544edaff3948d8c26419afab93b4b44de
# expected: SUMMARY 7 PASS, 0 FAIL, 0 SKIP, 0 BROKEN
# control: bash verify-179.sh blacklanternsecurity/blastdns 764c362544edaff3948d8c26419afab93b4b44de control-179.patch -> V01=FAIL V02=FAIL V03=FAIL V04=FAIL#!/usr/bin/env bash
# verify-179.sh: reproducible checks for blacklanternsecurity/blastdns#179 (Dev -> Stable 2.0.4)
# Usage: bash verify-179.sh <owner/repo> <sha> [<control-patch>]
# Changes nothing outside a mktemp directory and nothing on GitHub (PR-VF-02).
#
# CONTROL: patch control-179.patch
# CONTROL-EXPECT: V01=FAIL V02=FAIL V03=FAIL V04=FAIL
# AUTHOR-CODE: none
set -uo pipefail
REPO="${1:?owner/repo}"; SHA="${2:?sha}"; PATCH="${3:-}"
PASS=0; FAIL=0; SKIP=0; BROKEN=0
pass() { echo "PASS $1 $2"; PASS=$((PASS+1)); }
fail() { echo "FAIL $1 $2 -- $3"; FAIL=$((FAIL+1)); }
skip() { echo "SKIP $1 $2 -- $3"; SKIP=$((SKIP+1)); }
broken() { echo "BROKEN $1 $2 -- $3"; BROKEN=$((BROKEN+1)); }
summary() { echo "SUMMARY $PASS PASS, $FAIL FAIL, $SKIP SKIP, $BROKEN BROKEN"; [ "$FAIL" -eq 0 ] && [ "$BROKEN" -eq 0 ]; }
echo "script_sha256 $(shasum -a 256 "$0" | cut -d' ' -f1)"
echo "git $(git --version | cut -d' ' -f3)"
echo "gh $(gh --version | head -1 | cut -d' ' -f3)"
echo "jq $(jq --version)"
if [ -n "$PATCH" ]; then PATCH="$(cd "$(dirname "$PATCH")" && pwd)/$(basename "$PATCH")"; fi
WORK="$(mktemp -d)"; trap 'rm -rf "$WORK"' EXIT
export GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 GIT_TERMINAL_PROMPT=0
# Every git call (including blob fetches of the partial clone) gets the gh helper.
export GIT_CONFIG_COUNT=2 GIT_CONFIG_KEY_0=credential.helper GIT_CONFIG_VALUE_0= \
GIT_CONFIG_KEY_1=credential.helper GIT_CONFIG_VALUE_1='!gh auth git-credential'
git clone --quiet --filter=blob:none --no-checkout "https://github.com/$REPO.git" "$WORK/src" || { broken V00 "clone" "clone failed"; summary; exit 1; }
cd "$WORK/src"
git cat-file -e "$SHA^{commit}" 2>/dev/null || git fetch --quiet origin "+refs/pull/*/head:refs/remotes/pr/*" || true
git checkout --quiet --detach "$SHA" || { broken V00 "checkout $SHA" "checkout failed"; summary; exit 1; }
[ "$(git rev-parse HEAD)" = "$SHA" ] || { broken V00 "HEAD is $SHA" "HEAD mismatch"; summary; exit 1; }
if [ -n "$PATCH" ]; then git apply "$PATCH" || { broken V00 "apply control patch" "git apply failed"; summary; exit 1; }; fi
# ---- checks: each line states the desired property --------------------------
# V01: the hickory-resolver 0.25 -> 0.26 bump stays internal, so a patch version is honest.
users="$(grep -rl 'hickory_resolver' src | sort | tr '\n' ' ')"
if [ "$users" = "src/utils.rs " ] && ! grep -Eq '^pub use .*hickory_resolver' src/lib.rs; then
pass V01 "hickory_resolver is used only in src/utils.rs and never re-exported from src/lib.rs"
else
fail V01 "hickory_resolver is used only in src/utils.rs and never re-exported from src/lib.rs" "files: ${users:-none}; lib.rs re-exports: $(grep -c 'hickory_resolver' src/lib.rs)"
fi
# V02: every checkout in benchmark.yml (which builds and runs PR code) drops the token.
W=.github/workflows/benchmark.yml
n_co="$(grep -c 'uses: actions/checkout@' "$W")"
n_pc="$(grep -c 'persist-credentials: false' "$W")"
if [ "$n_co" -ge 1 ] && [ "$n_co" = "$n_pc" ]; then
pass V02 "every actions/checkout in benchmark.yml sets persist-credentials: false ($n_co of $n_co)"
else
fail V02 "every actions/checkout in benchmark.yml sets persist-credentials: false" "$n_pc of $n_co"
fi
# V03: the release version is 2.0.4 in Cargo.toml and Cargo.lock, and the wheel reads it.
v_toml="$(awk -F'"' '/^\[package\]/{p=1} p && /^version = /{print $2; exit}' Cargo.toml)"
v_lock="$(awk -F'"' '/^name = "blastdns"$/{getline; print $2; exit}' Cargo.lock)"
if [ "$v_toml" = "2.0.4" ] && [ "$v_lock" = "2.0.4" ] && grep -q '^dynamic = \["version"\]' pyproject.toml; then
pass V03 "Cargo.toml and Cargo.lock both say 2.0.4 and pyproject.toml takes the version from Cargo"
else
fail V03 "Cargo.toml and Cargo.lock both say 2.0.4 and pyproject.toml takes the version from Cargo" "toml=$v_toml lock=$v_lock"
fi
# V04: tests.yml no longer reports the legacy contexts.
LEGACY='"python-tests \(|[[ ,]rust-tests[],]' # the context names, not the reusable *-tests.yml files
if ! grep -Eq "$LEGACY" .github/workflows/tests.yml; then
pass V04 "tests.yml reports no legacy python-tests / rust-tests contexts"
else
fail V04 "tests.yml reports no legacy python-tests / rust-tests contexts" "$(grep -Eo "$LEGACY" .github/workflows/tests.yml | head -3 | tr '\n' ' ')"
fi
# V05: every status check the stable ruleset requires reported success at this SHA,
# so dropping the legacy names leaves nothing required unreported.
req="$(gh api --method GET "repos/$REPO/rules/branches/stable" --jq '.[] | select(.type=="required_status_checks") | .parameters.required_status_checks[].context' 2>/dev/null | sort -u)"
runs="$(gh api --method GET "repos/$REPO/commits/$SHA/check-runs" -F per_page=100 --jq '.check_runs[] | select(.conclusion=="success") | .name' 2>/dev/null | sort -u)"
if [ -z "$req" ] || [ -z "$runs" ]; then
skip V05 "every context the stable ruleset requires reported success at $SHA" "API read returned nothing"
else
missing="$(comm -23 <(echo "$req") <(echo "$runs") | tr '\n' ';')"
legacy="$(echo "$req" | grep -E 'python-tests|rust-tests' | tr '\n' ';')"
if [ -z "$missing" ] && [ -z "$legacy" ]; then
pass V05 "every context the stable ruleset requires reported success at $SHA ($(echo "$req" | tr '\n' ';'))"
else
fail V05 "every context the stable ruleset requires reported success at $SHA" "missing=$missing legacy_required=$legacy"
fi
fi
# V06: every remote uses: in the workflows is pinned to a full 40-character SHA (ci.md).
bad="$(grep -hE '^[[:space:]]*-?[[:space:]]*uses:' .github/workflows/*.yml | grep -v 'uses: \./' | grep -Ev 'uses: [^@ ]+@[0-9a-f]{40}( |$)' | head -3 | tr '\n' ';')"
if [ -z "$bad" ]; then
pass V06 "every remote uses: in .github/workflows is pinned to a 40-character SHA"
else
fail V06 "every remote uses: in .github/workflows is pinned to a 40-character SHA" "$bad"
fi
# V07 (challenge C1): classic branch protection on stable requires no status check
# either, so the ruleset read in V05 is the whole list of required contexts.
classic="$(gh api --method GET "repos/$REPO/branches/stable" --jq '[.protection.required_status_checks.contexts[]?, .protection.required_status_checks.checks[]?.context] | join(";")' 2>/dev/null)"
rc=$?
if [ $rc -ne 0 ]; then
skip V07 "classic branch protection on stable requires no status checks" "API read failed"
elif [ -z "$classic" ]; then
pass V07 "classic branch protection on stable requires no status checks"
else
fail V07 "classic branch protection on stable requires no status checks" "requires: $classic"
fi
# ------------------------------------------------------------------------------
summarydiff -ru a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml
--- a/.github/workflows/benchmark.yml 2026-11-10 13:52:22
+++ b/.github/workflows/benchmark.yml 2026-11-10 13:52:22
@@ -17,8 +17,6 @@
steps:
# The PR merged into its base, so the comparison isolates exactly this change.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- with:
- persist-credentials: false
- name: Check out base
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
diff -ru a/.github/workflows/tests.yml b/.github/workflows/tests.yml
--- a/.github/workflows/tests.yml 2026-11-10 13:52:22
+++ b/.github/workflows/tests.yml 2026-11-10 13:52:22
@@ -37,3 +37,14 @@
pytest-args: blastdns/tests tests/cli_tests.py -vv
setup-script: scripts/ci-setup.sh
teardown-script: scripts/ci-teardown.sh
+
+ required:
+ name: ${{ matrix.context }}
+ if: always()
+ needs: [rust, clippy-python-feature, python]
+ runs-on: ubuntu-24.04
+ strategy:
+ matrix:
+ context: ["python-tests (3.11)", rust-tests]
+ steps:
+ - run: true
diff -ru a/Cargo.toml b/Cargo.toml
--- a/Cargo.toml 2026-11-10 13:52:22
+++ b/Cargo.toml 2026-11-10 13:52:22
@@ -1,6 +1,6 @@
[package]
name = "blastdns"
-version = "2.0.4"
+version = "2.0.5"
edition = "2024"
description = "Async DNS lookup library for bulk/parallel DNS resolution"
license = "AGPL-3.0"
diff -ru a/src/lib.rs b/src/lib.rs
--- a/src/lib.rs 2026-11-10 13:52:22
+++ b/src/lib.rs 2026-11-10 13:52:22
@@ -27,5 +27,6 @@
pub use limiter::RateLimiter;
pub use mock::MockBlastDNSClient;
pub use resolver::DnsResolver;
+pub use hickory_resolver::system_conf;
pub use utils::{check_ulimits, get_system_resolvers};
pub use zone_transfer::{ZoneTransferResult, zone_transfer};
Patch release of current
dev, version 2.0.4. The version bump is #178.[addr:53]:53or fail to parse (fix: keep IPv6 system resolver addresses intact #177, closes IPv6 system resolvers get the wrong address #176)