Skip to content

Add --verify to check the built package against build-info - #24

Merged
jordancalhoun merged 4 commits into
codecarton:nextfrom
rodchristiansen:feat/verify
Aug 2, 2026
Merged

Add --verify to check the built package against build-info#24
jordancalhoun merged 4 commits into
codecarton:nextfrom
rodchristiansen:feat/verify

Conversation

@rodchristiansen

@rodchristiansen rodchristiansen commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

--verify re-reads a built package and checks it matches build-info (identifier, version, signing / notarization state) — a cheap post-build gate for CI.

Tests: PackageVerifierTests; verify-loop.sh covers it; full suite green.


Part of a 9-PR series splitting a batch of features into small, themed, independently reviewable PRs. Each applies cleanly to main on its own; the ordering below only minimizes rebases as they land:

  1. Process and exit-code correctness: pipe drain, notarization failure, distinct exit codes #19 — process & exit-code correctness
  2. Version resolution: --pkg-version/--output-dir overrides and dynamic version tokens #20 — version resolution · munki-pkg drop-in compatibility: name handling, keychain paths, --skip-import, receipt-only, notarization deferral #21 — munki-pkg compatibility
  3. Add --output-format json build manifest #22 — json manifest · Add --lint to validate a project without building #23 — lint · Add --verify to check the built package against build-info #24 — verify · Add --provenance attestation sidecar #25 — provenance · Add .env build-time variable substitution for scripts #26 — .env substitution
  4. Add GitHub Action and Azure DevOps templates for building packages #27 — CI templates

Happy to squash, split, or reorder any of these to suit your review preferences.

Summary by CodeRabbit

  • New Features
    • Added a --verify flag to validate a built package after creation.
    • Post-build verification now compares embedded package identifier/version metadata, and—when enabled—also checks signing and notarization/Gatekeeper status.
    • Added an additional verification scenario to confirm the expected verification output package is produced.
  • Documentation
    • Updated command-line help to document the new --verify behavior.
  • Tests
    • Expanded automated coverage for metadata mismatches and for success/failure paths of signature and notarization verification.

After building, --verify asserts reality matches what build-info declared:
pkgutil --check-signature when signing was requested, and an spctl
Gatekeeper assessment when notarization was requested. A mismatch fails the
build. On an unsigned/un-notarized build it is a no-op. Threaded through
PackageBuildOptions so the GUI can adopt it.

The notarization branch in buildPackage becomes an if-let so verification
still runs when no notarization is configured.

Tests: PackageVerifierTests (no checks when nothing declared; signature
check runs and passes on status 0, fails on non-zero; notarized runs
spctl). verify-loop.sh builds with --verify.
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: acc24b08-8a90-4aec-bf7c-3f100a94323a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds a --verify CLI option for post-build package metadata, signature, and notarization checks, with build integration and unit and shell verification coverage.

Changes

Package verification

Layer / File(s) Summary
Verification option and CLI wiring
swiftpkg/PackageBuildOptions.swift, swiftpkgCLI/CLI.swift
Adds the verifies build option and exposes it through the --verify CLI flag.
Metadata, signature, and notarization checks
swiftpkg/PackageVerifier.swift, swiftpkg/Support.swift, swiftpkgTests/PackageVerifierTests.swift
Checks embedded package identifier and version, conditionally runs pkgutil and spctl, reports diagnostics, defines the spctl path, and tests these paths.
Build integration and end-to-end validation
swiftpkg/PackageBuilder.swift, scripts/verify-loop.sh
Runs verification after package creation and adds a shell scenario that builds with --verify.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: jordancalhoun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% 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
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding --verify to validate the built package against build-info.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@rodchristiansen

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@rodchristiansen

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 57 minutes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
swiftpkgTests/PackageVerifierTests.swift (1)

5-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use RecordingRunner for command assertions.

StatusRunner duplicates the shared recording test double. Use RecordingRunner for command-construction assertions, retaining a minimal result-configurable fake only where failure-status simulation requires 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 `@swiftpkgTests/PackageVerifierTests.swift` around lines 5 - 16, Replace
StatusRunner in command-construction assertions with the shared RecordingRunner
test double. Retain a minimal status-configurable fake only in tests that
specifically simulate non-success process statuses, and update affected setup
and assertions accordingly.

Source: Coding guidelines

🤖 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.

Nitpick comments:
In `@swiftpkgTests/PackageVerifierTests.swift`:
- Around line 5-16: Replace StatusRunner in command-construction assertions with
the shared RecordingRunner test double. Retain a minimal status-configurable
fake only in tests that specifically simulate non-success process statuses, and
update affected setup and assertions accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 23630337-21bd-43ee-a739-4339616c24c6

📥 Commits

Reviewing files that changed from the base of the PR and between 25f222d and 15821e9.

📒 Files selected for processing (7)
  • scripts/verify-loop.sh
  • swiftpkg/PackageBuildOptions.swift
  • swiftpkg/PackageBuilder.swift
  • swiftpkg/PackageVerifier.swift
  • swiftpkg/Support.swift
  • swiftpkgCLI/CLI.swift
  • swiftpkgTests/PackageVerifierTests.swift

@rodchristiansen

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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.

Inline comments:
In `@swiftpkg/PackageVerifier.swift`:
- Around line 12-27: Extend verify(package:signed:notarized:) to accept the
expected build-info identifier and version, then retrieve the package metadata
and compare both values before verification succeeds. Throw
MunkiPkgError.message with the existing verification-failure pattern when either
value mismatches, and update callers to pass the expected metadata through this
path.

In `@swiftpkgTests/PackageVerifierTests.swift`:
- Around line 5-16: Replace the local StatusRunner test double with the shared
RecordingRunner from TestSupport.swift, configuring its results to represent
successful and failing subprocess calls as needed. Replace the fixed /tmp URL
with TemporaryDirectory, and update the affected tests to use these helpers
while preserving their command-construction assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ac4e1eab-2d96-4d61-a4f3-31e759fd95f9

📥 Commits

Reviewing files that changed from the base of the PR and between 25f222d and 15821e9.

📒 Files selected for processing (7)
  • scripts/verify-loop.sh
  • swiftpkg/PackageBuildOptions.swift
  • swiftpkg/PackageBuilder.swift
  • swiftpkg/PackageVerifier.swift
  • swiftpkg/Support.swift
  • swiftpkgCLI/CLI.swift
  • swiftpkgTests/PackageVerifierTests.swift

Comment thread swiftpkg/PackageVerifier.swift Outdated
Comment thread swiftpkgTests/PackageVerifierTests.swift Outdated
--verify now expands the built package's PackageInfo and fails when its
identifier or version differ from build-info, so a stale or mismatched artifact
can no longer pass verification on signature and Gatekeeper alone. The metadata
comparison is factored into a pure function; the verifier tests now use the
shared RecordingRunner and TemporaryDirectory helpers.
@rodchristiansen

Copy link
Copy Markdown
Contributor Author

Both addressed in the latest commit: verify now expands the built package's PackageInfo and fails when the identifier or version don't match build-info (comparison factored into a pure, unit-tested metadataMismatch); best-effort, so distribution-style packages without a top-level PackageInfo are skipped rather than failed. The verifier tests now use the shared RecordingRunner + TemporaryDirectory helpers. Suite green (28 tests).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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.

Inline comments:
In `@swiftpkg/PackageVerifier.swift`:
- Around line 42-46: Update the verification flow around runner.run and the
PackageInfo loading guard so a nonzero pkgutil --expand status, or
unreadable/malformed expansion output, throws an error containing the command
diagnostics instead of returning successfully. Preserve the skip only when
expansion succeeds and the distribution package has no top-level PackageInfo.
- Around line 60-65: Update the verification logic after parser.parse() and
delegate.pkgInfo succeeds to require both “identifier” and “version” attributes
before comparing them with expectedIdentifier and expectedVersion. Return an
appropriate validation error for missing metadata, while preserving the existing
nil/best-effort behavior only when distribution metadata cannot be extracted or
parsed.

In `@swiftpkgTests/PackageVerifierTests.swift`:
- Around line 17-19: Update the assertions in the verifier test to require that
runner.calls is non-empty before checking that every call contains “--expand”.
Preserve the existing assertions that signature checking and spctl are not
invoked, and ensure the test fails when verify performs no tool calls.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e827be45-f1b1-4fb8-b1d9-e2f7751beee5

📥 Commits

Reviewing files that changed from the base of the PR and between 15821e9 and 6448b87.

📒 Files selected for processing (3)
  • swiftpkg/PackageBuilder.swift
  • swiftpkg/PackageVerifier.swift
  • swiftpkgTests/PackageVerifierTests.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • swiftpkg/PackageBuilder.swift

Comment thread swiftpkg/PackageVerifier.swift
Comment thread swiftpkg/PackageVerifier.swift
Comment thread swiftpkgTests/PackageVerifierTests.swift Outdated
Address follow-up review of the metadata check: a non-zero pkgutil --expand now
fails verification instead of silently skipping, and a PackageInfo that parses
but omits identifier or version is rejected rather than passed. Tests assert the
expansion ran and cover both new failure paths; RecordingRunner gains an
optional per-call result provider.
@rodchristiansen

Copy link
Copy Markdown
Contributor Author

Follow-up review addressed: a non-zero pkgutil --expand now fails verification (rather than silently skipping), and a PackageInfo that parses but is missing identifier/version is now rejected. Added tests asserting the expansion ran and covering both new failure paths. Suite green (30 tests). The absent-PackageInfo case (distribution-style packages) remains a deliberate skip.

@jordancalhoun
jordancalhoun changed the base branch from main to next August 2, 2026 14:04
@jordancalhoun
jordancalhoun merged commit ce83959 into codecarton:next Aug 2, 2026
2 checks passed
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