Skip to content

feat(wizard): annotate submodule/vendored lockfiles in discovery - #295

Closed
vpetersson wants to merge 3 commits into
masterfrom
feat/wizard-nested-repo-annotation
Closed

feat(wizard): annotate submodule/vendored lockfiles in discovery#295
vpetersson wants to merge 3 commits into
masterfrom
feat/wizard-nested-repo-annotation

Conversation

@vpetersson

Copy link
Copy Markdown
Contributor

Summary

Lockfiles that live inside a git submodule or a vendored repo checkout belong to another repository — you likely want to set up SBOM generation there instead of bundling them into this repo's workflow. The wizard's discover screen now makes that visible:

  • Each affected row is annotated with the enclosing repo, e.g. extern/lib/Cargo.lock (rust) (submodule: extern/lib).
  • Those rows start deselected (everything else still defaults to selected), and a one-line note above the list explains why. They can still be toggled on with Space.

Detection

  • Submodules: .gitmodules is parsed directly for path = entries (handles quoted paths) — no git binary needed, and declared-but-uninitialized submodules are covered too.
  • Vendored clones: any ancestor directory carrying its own .git entry — a file for submodule checkouts, a directory for committed-wholesale clones.
  • The annotation reports the innermost enclosing repo; ancestor lookups are memoized per directory. DiscoveredLockfile gains nested_repo / nested_repo_kind fields (both default None, so existing call sites are unaffected).

Tests

  • Discovery: submodule annotation (including lockfiles nested deeper inside the submodule), vendored .git-dir and .git-file shapes, quoted .gitmodules paths with spaces.
  • Textual pilot: default-deselection, row annotation, and the explanatory note on the discover screen.

ruff check / ruff format --check clean; wizard suites pass (145 tests).

🤖 Generated with Claude Code

Lockfiles that live inside a git submodule (declared in .gitmodules)
or a vendored clone (a directory with its own .git) belong to another
repository and are better tracked from there. The discover screen now
annotates those rows with the enclosing repo path and leaves them
deselected by default, with a note explaining why.

Detection parses .gitmodules directly (works without a git binary and
for declared-but-uninitialized submodules) and checks ancestors for a
.git entry — a file for submodule checkouts, a directory for vendored
clones.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 20, 2026 15:16

Copilot AI 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.

Pull request overview

This PR improves the wizard’s lockfile discovery UX by detecting when discovered lockfiles live inside a nested repository (git submodule or vendored clone) and surfacing that context in the discover screen so users don’t accidentally configure SBOM generation for “someone else’s repo”.

Changes:

  • Extend DiscoveredLockfile with optional nested_repo / nested_repo_kind metadata to represent an enclosing submodule/vendored repo.
  • Add discovery-time detection for submodules (via .gitmodules) and nested repos (via ancestor .git entries) with memoization.
  • Update the discover screen to annotate nested-repo rows and default-deselect them; add test coverage for discovery + Textual UI behavior.

Reviewed changes

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

Show a summary per file
File Description
tests/test_wizard_textual.py Adds a Textual pilot test to verify nested-repo rows are annotated and deselected by default, and that the explanatory note appears.
tests/test_wizard_discovery.py Adds unit tests for submodule parsing (including quoted paths) and .git-based vendored repo detection.
sbomify_action/cli/wizard/state.py Adds NestedRepoKind and optional nested-repo fields to DiscoveredLockfile while keeping defaults None for compatibility.
sbomify_action/cli/wizard/screens/discover.py Annotates nested-repo lockfiles in the list and changes default selection behavior + adds an explanatory note.
sbomify_action/cli/wizard/discovery.py Implements .gitmodules parsing and ancestor-based nested repo detection with caching; plumbs results into DiscoveredLockfile.

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

An attest-build-provenance signature carries the Sigstore identity of
the workflow that ran it. For lockfiles inside a submodule or vendored
checkout, that identity is the parent repo — but the SBOM describes
code owned by another repository, so the attestation would fail
verification against the repo the code actually comes from.

When attestation is enabled, every matrix row now carries an 'attest'
boolean and the attest step is gated on it; nested-repo rows get
attest: false. This is also the per-entry hook the upcoming
attach-or-backfill submodule flow will need.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 21, 2026 11:00

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment on lines +59 to +61
if lf.nested_repo:
kind = "submodule" if lf.nested_repo_kind == "submodule" else "vendored repo"
label += f" [#F4B57F]({kind}: {lf.nested_repo})[/]"
Each attest: false row now carries an explicit 'Deliberately NOT
signed' comment naming the nested repo and why, so the generated YAML
documents the decision where it takes effect, not only at the attest
step.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 21, 2026 11:55

Copilot AI 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.

Pull request overview

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

Comment on lines +68 to +70
- ``submodule`` — under a path declared in ``.gitmodules``.
- ``vendored`` — under a directory with its own ``.git`` (a checked-in
clone that isn't a registered submodule).
Comment on lines +233 to +236
A directory counts if it is declared in ``.gitmodules`` (submodule)
or has its own ``.git`` entry — a file for submodule checkouts, a
directory for vendored clones. Results are memoised per directory
since sibling lockfiles share ancestors.
@vpetersson

Copy link
Copy Markdown
Contributor Author

Superseded by #296 — the wizard-side detection and the runtime attach-or-backfill mode are one feature and ship together there (this branch's commits are included in #296).

@vpetersson vpetersson closed this Jul 21, 2026
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