Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ updates:
interval: "weekly"
commit-message:
prefix: "ci"
groups:
# github/codeql-action ships init, analyze, and upload-sarif as
# subdirectories of one repository, but Dependabot tracks each
# `uses:` path as its own dependency and opens one PR per path.
# init and analyze must run the same release -- analyze refuses a
# config file written by a different init version ("Loaded a
# configuration file for version '4.37.9', but running version
# '4.38.1'") -- so every split PR fails CodeQL on its own and
# none can merge. Grouping them bumps all three together.
codeql-action:
patterns:
- "github/codeql-action*"
14 changes: 7 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.12"
- run: uv run ruff check
Expand All @@ -40,7 +40,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.12"
- run: uv run mypy
Expand All @@ -52,7 +52,7 @@ jobs:
python-version: ["3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: ${{ matrix.python-version }}
- run: uv run --frozen pytest --cov=netprotocols --cov-report=term
Expand All @@ -67,7 +67,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.12"
- name: Export dev dependencies
Expand All @@ -83,7 +83,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
- run: uv build
- run: uv run --isolated --no-project --with dist/*.whl python -c "import netprotocols; print(netprotocols.__version__)"
# Builds are supposed to be a pure function of the source tree, so
Expand Down Expand Up @@ -116,7 +116,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.12"
- run: uv build
Expand Down Expand Up @@ -148,7 +148,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.12"
- name: Corpus decode throughput
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ jobs:
# mode the CodeQL Action's own docs recommend for interpreted
# languages, and it sidesteps the question of an autobuild step
# fitting this project's uv-based build at all.
- uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
- uses: github/codeql-action/init@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
with:
languages: python
build-mode: none

- uses: github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
- uses: github/codeql-action/analyze@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
4 changes: 2 additions & 2 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.12"
# Keyed by run id with a prefix restore-key: a fixed key would
Expand Down Expand Up @@ -79,7 +79,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.12"
- name: Run Atheris against decode_frame
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/mutation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: "3.12"
# mutmut hashes each mutated file plus the tests that cover it and
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
- run: uv build
# The QA ladder cannot catch a mistagged release: every check
# passes because the code is fine and only the tag is wrong. Read
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ jobs:

# Upload the results to GitHub's code scanning dashboard.
- name: Upload to code-scanning
uses: github/codeql-action/upload-sarif@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
uses: github/codeql-action/upload-sarif@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
with:
sarif_file: results.sarif
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Development

- **Tightened three DNS corpus assertions in `tests/test_dns.py` from substring/`endswith` checks to exact equality, closing 3 open CodeQL `py/incomplete-url-substring-sanitization` alerts (#166).** `test_names_decompress_to_real_domains` asserted `"example.com" in names` / `"accounts.youtube.com" in names` against a `set` decoded from a fixed pcap corpus, and `test_answers_parse_to_real_records` asserted `cname.rdata_text.endswith("google.com")` against the same corpus — not security-relevant trust checks, but exactly the substring/suffix pattern the rule flags regardless of what the value's actually validating. Both now compare against the known exact decoded values instead (`names == {"example.com", "accounts.youtube.com"}`, `rdata_text == "www3.l.google.com"`), which removes the pattern CodeQL keys on and is strictly more precise than the checks it replaces.
- **Consolidated six open Dependabot updates and grouped `github/codeql-action` so its sub-actions can no longer be bumped apart (#198, #199, #204, #205, #206, #207).** Dependabot tracks `github/codeql-action/init`, `/analyze`, and `/upload-sarif` as three separate dependencies and opened one PR each; `analyze` refuses a config file written by a different `init` release ("Loaded a configuration file for version '4.37.9', but running version '4.38.1'"), so #204 and #206 each failed CodeQL alone and neither could ever merge. All three now move to v4.38.1 together, alongside `astral-sh/setup-uv` 10.0.1 → 10.2.0, `hypothesis` 6.167.1 → 6.168.0, `ruff` 0.16.6 → 0.16.7, and `mutmut` 3.7.0 → 3.8.0 (lockfile byte-identical to Dependabot's). `dependabot.yml` gains a `codeql-action` group for the `github-actions` ecosystem, and `tests/test_workflows.py` gains `TestCodeQLActionVersionLockstep`, which fails the ordinary test job — naming the mismatched steps — whenever `github/codeql-action/*` steps across all workflows are pinned to more than one commit.

## [2.2.1] - 2026-09-07

Expand Down
63 changes: 63 additions & 0 deletions tests/test_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,69 @@ def test_remote_actions_are_pinned_to_a_commit_sha(
)


CODEQL_ACTION = "github/codeql-action/"


def codeql_action_pins(workflows: dict[str, str]) -> dict[str, list[str]]:
"""Map each commit a ``github/codeql-action/*`` step is pinned to
onto the ``file: sub-action`` steps pinned there, across every
workflow text in ``workflows`` (keyed by file name)."""
pins: dict[str, list[str]] = {}
for name, text in workflows.items():
for line in text.splitlines():
ref = uses_ref(line)
if ref is None or not ref.startswith(CODEQL_ACTION):
continue
action, _, pin = ref.rpartition("@")
sub_action = action.removeprefix(CODEQL_ACTION)
pins.setdefault(pin, []).append(f"{name}: {sub_action}")
return pins


class TestCodeQLActionVersionLockstep:
"""Every ``github/codeql-action/*`` step must run the same release.

``init`` writes a config file that ``analyze`` refuses to load when
their versions differ ("Loaded a configuration file for version
'4.37.9', but running version '4.38.1'"), and Dependabot bumps each
sub-action path in its own PR, so a half-applied bump is the
default outcome rather than a hypothetical one. Checking it here
fails the ordinary test job with the offending steps named, instead
of surfacing only as a CodeQL "configuration error".
"""

def test_all_workflows_pin_a_single_codeql_action_commit(self) -> None:
pins = codeql_action_pins(
{path.name: path.read_text() for path in ALL_WORKFLOWS}
)
steps = {step for group in pins.values() for step in group}
# Guard against passing vacuously: codeql.yml's init/analyze
# pair is the reason this check exists, so it must be seen.
assert {"codeql.yml: init", "codeql.yml: analyze"} <= steps, (
f"expected codeql.yml's init and analyze steps, found "
f"{sorted(steps)}"
)
assert len(pins) == 1, (
f"github/codeql-action steps are pinned to {len(pins)} "
f"different commits: {pins}"
)

def test_a_split_bump_is_detected(self) -> None:
"""The exact shape Dependabot produced: analyze bumped, init
left behind. Proves the check above can actually fail."""
old, new = "a" * 40, "b" * 40
split = {
"codeql.yml": (
f" - uses: github/codeql-action/init@{old} # v1\n"
f" - uses: github/codeql-action/analyze@{new} # v2\n"
)
}
assert codeql_action_pins(split) == {
old: ["codeql.yml: init"],
new: ["codeql.yml: analyze"],
}


class TestCIWorkflow:
"""Structural checks on jobs added to ci.yml's own QA ladder."""

Expand Down
Loading
Loading