Skip to content

test: harden release artifact audit coverage#3

Open
Boulea7 wants to merge 2 commits into
mainfrom
codex/release-artifact-dynamic-audit
Open

test: harden release artifact audit coverage#3
Boulea7 wants to merge 2 commits into
mainfrom
codex/release-artifact-dynamic-audit

Conversation

@Boulea7
Copy link
Copy Markdown
Owner

@Boulea7 Boulea7 commented May 27, 2026

Summary

  • derive required bundled skill files for sdist and wheel from src/agy_mcp/_skill_bodies instead of duplicating manual path lists
  • keep cache/platform files out of the dynamic required set
  • add direct tests for wheel dist-info metadata validation and RECORD payload coverage

Validation

  • env UV_CACHE_DIR=/private/tmp/agy-mcp-uv-cache uv run --default-index https://pypi.org/simple pytest tests/test_release_artifacts.py -q
  • env UV_CACHE_DIR=/private/tmp/agy-mcp-uv-cache uv run --default-index https://pypi.org/simple ruff check scripts/check_release_artifacts.py tests/test_release_artifacts.py
  • git diff --check
  • env UV_CACHE_DIR=/private/tmp/agy-mcp-uv-cache uv build --default-index https://pypi.org/simple
  • env UV_CACHE_DIR=/private/tmp/agy-mcp-uv-cache uv run --default-index https://pypi.org/simple python scripts/check_release_artifacts.py

Summary by Sourcery

Harden release artifact auditing by deriving required skill bundle contents from the source tree and expanding wheel metadata validation coverage.

Enhancements:

  • Derive required skill body file sets for sdists and wheels dynamically from the source skill_bodies directory, excluding cache and platform-specific noise files.

Tests:

  • Add tests to ensure the dynamically derived skill body files are all included in the required sdist and wheel file sets.
  • Add unit tests for wheel dist-info metadata validation, including handling of missing required metadata files and missing payload entries from RECORD.

Summary by cubic

Hardened the release artifact audit by deriving bundled agy_mcp skill-body files dynamically for sdist and wheel, validating wheel dist-info metadata/RECORD, and scanning only git-tracked files. Prevents missing files, packaging drift, and junk file leaks from local changes.

  • Refactors

    • Generate required file sets from src/agy_mcp/_skill_bodies; compute sdist and wheel paths dynamically.
    • Centralize inclusion rules; ignore __pycache__, .pyc/.pyo, .DS_Store, Thumbs.db.
  • Bug Fixes

    • Validate wheel dist-info; reject missing METADATA/WHEEL and payloads not listed in RECORD.
    • Limit skill-body scan to git-tracked files, with fallback outside a git checkout to avoid untracked-file noise.

Written for commit a800d96. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • Chores

    • Enhanced release artifact validation with dynamic file discovery instead of hardcoded lists.
  • Tests

    • Added comprehensive test coverage for release artifact packaging, skill-body bundling, and wheel metadata validation.

Review Change Stack

Change-Id: I6e160c1ca845ad3768711e9075bed5496554e82d
Copilot AI review requested due to automatic review settings May 27, 2026 07:41
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 27, 2026

Reviewer's Guide

This PR strengthens the release artifact audit by dynamically deriving required skill-body files for sdists and wheels from the source tree and by adding focused tests around skill bundle coverage and wheel dist-info metadata validation, including RECORD payload coverage.

Flow diagram for deriving required skill body files for sdists and wheels

flowchart TD
    A[SKILL_BODIES_ROOT] --> B{root.is_dir}
    B -- no --> C[Return empty set]
    B -- yes --> D[rglob * over root]

    D --> E[_is_required_skill_body_file]

    E --> F{path.is_file}
    F -- no --> G[Skip path]
    F -- yes --> H{component in SKILL_BODY_EXCLUDED_COMPONENTS}
    H -- yes --> G
    H -- no --> I{path.name is .DS_Store or Thumbs.db}
    I -- yes --> G
    I -- no --> J{path.name endswith SKILL_BODY_EXCLUDED_SUFFIXES}
    J -- yes --> G
    J -- no --> K[Include path]

    K --> L[_skill_body_files_for_sdist]
    L --> M[relative_to PROJECT_ROOT]
    M --> N[Add to REQUIRED_SDIST_FILES]

    K --> O[_skill_body_files_for_wheel]
    O --> P[relative_to SRC_ROOT]
    P --> Q[Add to REQUIRED_WHEEL_FILES]

    N --> R[Final REQUIRED_SDIST_FILES]
    Q --> S[Final REQUIRED_WHEEL_FILES]
Loading

File-Level Changes

Change Details Files
Derive required skill-body file sets for sdist and wheel dynamically from the source tree instead of hard-coding paths.
  • Introduce PROJECT_ROOT, SRC_ROOT, and SKILL_BODIES_ROOT constants to locate skill-body files relative to the repository and src layout.
  • Add _is_required_skill_body_file helper to exclude cache and platform-specific noise files when walking the skill bodies tree.
  • Implement _skill_body_files_for_sdist and _skill_body_files_for_wheel helpers that compute required file paths as they appear in sdists and wheels.
  • Refactor REQUIRED_SDIST_FILES and REQUIRED_WHEEL_FILES to be unions of static base file sets and dynamically discovered skill-body files, and remove the manually maintained skill-body entries from both required and allowed sets.
scripts/check_release_artifacts.py
Add unit tests to verify dynamic skill-body coverage and wheel metadata/RECORD validation behavior.
  • Expose internal helpers and constants from the release audit script into the tests module for direct testing.
  • Add a test ensuring all bundled skill-body files are included in the required file sets for both sdist and wheel, with correct path mapping.
  • Add tests that validate _check_wheel_metadata accepts a valid dist-info layout, rejects missing required dist-info files, and flags payload files that are absent from RECORD.
tests/test_release_artifacts.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

📝 Walkthrough

Walkthrough

This PR refactors release artifact validation to dynamically discover and include required agy_mcp/_skill_bodies files instead of hardcoding them. It adds helper functions for git-tracked file discovery with filesystem fallback, computes sdist and wheel required file sets via the discovery logic, and introduces comprehensive test coverage for skill-body packaging rules and wheel metadata validation.

Changes

Release artifact validation and skill-body packaging

Layer / File(s) Summary
Dynamic skill-body discovery and path configuration
scripts/check_release_artifacts.py
Path constants, exclusion rules, and helper functions gather git-tracked files in agy_mcp/_skill_bodies with filesystem fallback, and convert those paths into the exact layout-specific strings expected in sdist vs wheel distributions.
Computed required file sets for sdist and wheel
scripts/check_release_artifacts.py
Base required files are defined separately for sdist and wheel; final required file sets are computed by unioning those bases with dynamically discovered skill-body paths mapped to their correct sdist and wheel layouts.
Skill-body packaging validation tests
tests/test_release_artifacts.py
Tests validate that required skill-body files are bundled in both sdist and wheel, error handling when the skill-body root is missing, and correct ignoring of untracked markdown files via temporary git repository setup.
Wheel metadata audit tests
tests/test_release_artifacts.py
New unit tests for _check_wheel_metadata verify acceptance of valid dist-info payloads, rejection of missing required dist-info files, and rejection when wheel contents list files not in RECORD.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🐰 From scripts, a truth did grow—
Once hardcoded, now flows with git's ebb and flow!
Skill bodies found, their paths now free,
Both wheel and source, harmoniously! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.46% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test: harden release artifact audit coverage' clearly summarizes the main change: adding test coverage to strengthen release artifact validation. It directly aligns with the PR's primary objectives of improving release artifact auditing through test enhancements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/release-artifact-dynamic-audit

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the release artifact audit by dynamically deriving required bundled skill-body files from src/agy_mcp/_skill_bodies (instead of maintaining manual lists) and expands test coverage around wheel .dist-info metadata validation and RECORD payload coverage.

Changes:

  • Derive REQUIRED_SDIST_FILES / REQUIRED_WHEEL_FILES skill-body entries dynamically from the source tree while filtering out common noise files.
  • Add tests ensuring the dynamic skill-body sets are included in the required sets for both sdist and wheel.
  • Add tests for _check_wheel_metadata to validate required dist-info files and detect payload files missing from RECORD.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
tests/test_release_artifacts.py Adds coverage for dynamic required file derivation and wheel dist-info/RECORD validation.
scripts/check_release_artifacts.py Refactors required file sets to be derived from _skill_bodies dynamically and introduces wheel dist-info metadata checks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/check_release_artifacts.py Outdated
Comment on lines +52 to +53
if not root.is_dir():
return set()
Comment thread scripts/check_release_artifacts.py Outdated
Comment on lines +67 to +68
if not root.is_dir():
return set()
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread scripts/check_release_artifacts.py Outdated
Change-Id: Icf710f69475b12f03244045e386b32519f6443ff
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/check_release_artifacts.py (1)

456-467: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Check RECORD against all shipped wheel files.

This only compares non-.dist-info paths against RECORD, so a wheel that ships METADATA/WHEEL but forgets to record them still passes the audit. That leaves a malformed wheel case uncovered by the new metadata gate.

Suggested fix
         try:
             entries = record.data.decode("utf-8").splitlines()
         except UnicodeDecodeError:
             entries = []
         recorded_paths = {line.split(",", 1)[0] for line in entries if line}
-        # Every shipped python file must be listed in RECORD. Skipping
-        # the dist-info entries themselves keeps the check honest about
-        # the wheel payload rather than the metadata bookkeeping.
-        payload_paths = {
-            f.path for f in files if not _DIST_INFO_RE.match(f.path)
-        }
-        missing_from_record = sorted(payload_paths - recorded_paths)
+        shipped_paths = {f.path for f in files}
+        missing_from_record = sorted(shipped_paths - recorded_paths)
         for path in missing_from_record:
             problems.append(
                 f"[{label}] wheel ships {path} but RECORD does not list it",
             )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/check_release_artifacts.py` around lines 456 - 467, The current check
ignores .dist-info files when computing payload_paths so missing metadata like
METADATA/WHEEL/RECORD can go undetected; update the check in
check_release_artifacts.py to include .dist-info entries in the comparison (or
add an explicit assertion that all .dist-info paths are present in RECORD).
Locate the variables recorded_paths, payload_paths and missing_from_record and
either remove the _DIST_INFO_RE filter when building payload_paths (use all file
paths from files) or compute dist_info_paths = {f.path for f in files if
_DIST_INFO_RE.match(f.path)} and assert dist_info_paths ⊆ recorded_paths so
METADATA/WHEEL/RECORD are validated as recorded.
🧹 Nitpick comments (1)
tests/test_release_artifacts.py (1)

33-44: ⚡ Quick win

Make the wheel skill-body expectation independent of the helper under test.

REQUIRED_SDIST_FILES and REQUIRED_WHEEL_FILES are built from _skill_body_files_for_*() at import time, so the subset checks here will still pass if either helper drops or mis-maps a file. The sdist half already has an external oracle via rglob; the wheel half needs the same treatment.

Suggested test shape
-    sdist_skill_files = _skill_body_files_for_sdist()
-    wheel_skill_files = _skill_body_files_for_wheel()
+    repo_root = Path(__file__).resolve().parents[1]
+    expected_source_files = {
+        path for path in skill_root.rglob("*") if _is_required_skill_body_file(path)
+    }
+    sdist_skill_files = _skill_body_files_for_sdist()
+    wheel_skill_files = _skill_body_files_for_wheel()

     assert sdist_skill_files
     assert wheel_skill_files
     assert sdist_skill_files <= REQUIRED_SDIST_FILES
     assert wheel_skill_files <= REQUIRED_WHEEL_FILES
-    assert {
-        path.relative_to(Path(__file__).resolve().parents[1]).as_posix()
-        for path in skill_root.rglob("*")
-        if _is_required_skill_body_file(path)
-    } == sdist_skill_files
+    assert {
+        path.relative_to(repo_root).as_posix()
+        for path in expected_source_files
+    } == sdist_skill_files
+    assert {
+        path.relative_to(repo_root / "src").as_posix()
+        for path in expected_source_files
+    } == wheel_skill_files
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_release_artifacts.py` around lines 33 - 44, The test currently
verifies wheel outputs by comparing wheel_skill_files to REQUIRED_WHEEL_FILES
(both derived from _skill_body_files_for_wheel at import time), which makes the
check tautological; change the wheel assertion to mirror the sdist oracle:
compute the set of required wheel paths by walking skill_root via
skill_root.rglob("*") and filtering with _is_required_skill_body_file, mapping
each path to a relative posix string (the same expression already used for the
sdist assertion), then assert that resulting set equals wheel_skill_files
instead of comparing to REQUIRED_WHEEL_FILES; update references to
wheel_skill_files and _skill_body_files_for_wheel accordingly so the test no
longer depends on the helper under test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@scripts/check_release_artifacts.py`:
- Around line 456-467: The current check ignores .dist-info files when computing
payload_paths so missing metadata like METADATA/WHEEL/RECORD can go undetected;
update the check in check_release_artifacts.py to include .dist-info entries in
the comparison (or add an explicit assertion that all .dist-info paths are
present in RECORD). Locate the variables recorded_paths, payload_paths and
missing_from_record and either remove the _DIST_INFO_RE filter when building
payload_paths (use all file paths from files) or compute dist_info_paths =
{f.path for f in files if _DIST_INFO_RE.match(f.path)} and assert
dist_info_paths ⊆ recorded_paths so METADATA/WHEEL/RECORD are validated as
recorded.

---

Nitpick comments:
In `@tests/test_release_artifacts.py`:
- Around line 33-44: The test currently verifies wheel outputs by comparing
wheel_skill_files to REQUIRED_WHEEL_FILES (both derived from
_skill_body_files_for_wheel at import time), which makes the check tautological;
change the wheel assertion to mirror the sdist oracle: compute the set of
required wheel paths by walking skill_root via skill_root.rglob("*") and
filtering with _is_required_skill_body_file, mapping each path to a relative
posix string (the same expression already used for the sdist assertion), then
assert that resulting set equals wheel_skill_files instead of comparing to
REQUIRED_WHEEL_FILES; update references to wheel_skill_files and
_skill_body_files_for_wheel accordingly so the test no longer depends on the
helper under test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f19c0b10-3484-44a0-9266-e59512d37ce9

📥 Commits

Reviewing files that changed from the base of the PR and between 6d619b0 and a800d96.

📒 Files selected for processing (2)
  • scripts/check_release_artifacts.py
  • tests/test_release_artifacts.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants