Skip to content

Conversation

@Defelo
Copy link
Contributor

@Defelo Defelo commented Sep 11, 2025

Resolves #563

cc @GaetanLepage @thefossguy

Summary by CodeRabbit

  • New Features
    • Added configurable shallow fetch depth for faster, lighter PR fetches.
    • Improved handling of head vs. merge commits with smarter checkout behavior across modes.
    • Stabilized worktree state with a post-build checkout when applicable.
  • Bug Fixes
    • Increased robustness by validating merge commit ancestry before evaluation.
  • Refactor
    • Streamlined PR evaluation to derive base/head from the merge commit, reducing fetch complexity.
  • Tests
    • Introduced a reusable repository setup helper and updated PR tests for clearer, more reliable coverage.

@coderabbitai
Copy link

coderabbitai bot commented Sep 11, 2025

Walkthrough

Refactors PR/build logic to explicitly handle base, head, and merge commits; updates checkout paths based on selected mode; adds shallow fetch depth control; adjusts build_pr to fetch merge commit and derive parents; updates tests to use a shared repo setup helper returning base/head/merge SHAs.

Changes

Cohort / File(s) Summary
Build/checkout flow refactor
nixpkgs_review/review.py
build_commit signature now `(base_commit, head_commit
Fetch API enhancement
nixpkgs_review/review.py
fetch_refs gains shallow_depth: int = 1; applies depth when repository is shallow; continues locked writes of refs; used by build_pr.
Tests PR setup consolidation
tests/test_pr.py
Adds setup_repo(nixpkgs) -> (base, head, merge) helper to create PR-like history; replaces inline git setup across tests; updates imports to from .conftest import Helpers, Nixpkgs; tests pass derived SHAs into mocks and expectations.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User as CLI/User
  participant Review as Review.build_pr
  participant Git as Git Repo
  participant Builder as Review.build_commit

  Note over Review,Git: PR evaluation (local/ofborg/action)

  User->>Review: build_pr(pr, options)
  Review->>Git: fetch_refs(pr.merge_commit_sha, shallow_depth=2)
  Review->>Git: verify_commit_hash(pr.merge_commit_sha)
  Git-->>Review: merge_rev
  Review->>Git: derive parents (merge_rev^1, merge_rev^2)
  Git-->>Review: base_rev, head_rev

  alt CheckoutOption.MERGE
    Review->>Git: checkout worktree at merge_rev
  else
    Review->>Git: checkout worktree at head_rev
  end

  Review->>Builder: build_commit(base_rev, head_rev, merge_rev, staged)
  alt only-packages path
    Builder->>Git: checkout/merge per mode (COMMIT/MERGE)
  else
    Builder->>Git: merge base_rev with head/merge as needed
  end
  opt COMMIT mode with head_commit present
    Builder->>Git: final checkout head_commit
  end
  Builder-->>Review: build results
  Review-->>User: results
Loading
sequenceDiagram
  autonumber
  participant Review as Review.build_commit
  participant Git as Git Repo

  Note over Review,Git: Worktree control flow

  alt only_packages
    alt COMMIT and head_commit
      Review->>Git: checkout(head_commit)
    else MERGE and merge_commit
      Review->>Git: checkout(merge_commit)
    else MERGE without merge_commit
      Review->>Git: merge(head_commit)
    else head_commit None (unstaged)
      Review->>Git: apply unstaged changes
    end
  else full build
    alt merge_commit provided
      Review->>Git: merge base_commit..merge_commit
    else
      Review->>Git: merge base_commit..head_commit
    end
  end

  opt COMMIT mode and head_commit present
    Review->>Git: checkout(head_commit)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–60 minutes

Suggested reviewers

  • Mic92

Poem

I nibbled the branches of commits three,
Base, Head, and Merge, in a tidy tree.
With shallow hops I fetch and see,
Then check out cleanly, as modes decree.
Tests now burrow with one clear key—
All carrots aligned for CI glee! 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Linked Issues Check ❓ Inconclusive The changes refactor commit handling (separating head and merge commits), adjust worktree checkout logic, and extend fetch semantics, and tests were updated to create explicit base/head/merge states; these modifications address the likely root cause described in issue #563 (incorrect commit/checkout causing wrong package detection). However the PR summary includes "not tested yet" and the provided diffs/summaries do not include a focused regression test or CI proof that unrelated packages are no longer built, so I cannot conclusively verify the bug is fixed from the available information. The code changes appear targeted at the linked issue but verification is missing. Run the full test suite and add a focused regression test that reproduces issue #563 (showing before/after impacted-package lists), then attach CI results or logs demonstrating only the expected packages are rebuilt so the fix can be conclusively verified.
✅ 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 "Fix detection of changed packages" is short, a single clear sentence, and directly matches the PR objective of correcting package-change detection that caused unrelated rebuilds (issue #563). It succinctly communicates the primary intent without extraneous detail or noise. Teammates scanning history should understand the main purpose from this title alone.
Out of Scope Changes Check ✅ Passed All modifications shown in the summary are confined to review logic (nixpkgs_review/review.py) and related PR tests (tests/test_pr.py); they modify commit/fetch/checkout behavior and centralize test repo setup, which are directly related to fixing package-detection regressions. I do not see unrelated subsystem changes or cosmetic edits outside the scope of the linked issue. No out-of-scope changes are apparent from the provided summary.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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.

@thefossguy
Copy link

thefossguy commented Sep 13, 2025

[thefossguy@build01:/home/thefossguy/my-git-repos/pratham/nixpkgs 0]$ nix run github:Mic92/nixpkgs-review/7b680e12fdee27955511a8707e2093b81b9ae780#nixpkgs-review -- pr --print-result --eval local 440950

================================================================================
PR #440950: COSMIC Beta
================================================================================
Author: HeitorAugustoLN
Branch: HeitorAugustoLN:cosmic-beta -> NixOS:master
State: open
Status: Draft

Description:
----------------------------------------
<!--
^ Please summarise the changes you have done and explain why they are necessary here ^

For package updates please link to a changelog or describe changes, this helps your fellow maintainers discover breaking updates.
For new packages please briefly describe the package or provide a link to its homepage.
-->

Preparing new packages and package updates for COSMIC Desktop Environment Beta
cc: @NixOS/cosmic

## Things done

<!-- Please check what applies. Note that these are not hard requirements but merely serve as information for reviewers. -->

- Built on platform:
  - [ ] x86_64-linux
  - [ ] aarch64-linux
  - [ ] x86_64-darwin
  - [ ] aarch64-darwin
- Tested, as applicable:
  - [ ] [NixOS tests] in [nixos/tests].
  - [ ] [Package tests] at `passthru.tests`.
  - [ ] Tests in [lib/tests] or [pkgs/test] for functions and "core" functionality.
- [ ] Ran `nixpkgs-review` on this PR. See [nixpkgs-review usage].
- [ ] Tested basic functionality of all binary fil

... (truncated)
----------------------------------------

Files changed (2 files):
  - nixos/modules/services/desktop-managers/cosmic.nix
  - pkgs/by-name/co/cosmic-initial-setup/package.nix

----------------------------------------
Diff preview (showing first 500 lines):
----------------------------------------
----------------------------------------
================================================================================

$ git -c fetch.prune=false fetch --no-tags --force https://github.com/NixOS/nixpkgs 88c194747efd610c2b219b6475058b39256185b9:refs/nixpkgs-review/0
From https://github.com/NixOS/nixpkgs
   b95e6eb5acd5..88c194747efd  88c194747efd610c2b219b6475058b39256185b9 -> refs/nixpkgs-review/0
$ git worktree add /home/thefossguy/.cache/nixpkgs-review/pr-440950-2/nixpkgs 9c2a8e4d5a12dd887ea2211e7b1f5625ad7c085f
Preparing worktree (detached HEAD 9c2a8e4d5a12)
Updating files: 100% (49004/49004), done.
HEAD is now at 9c2a8e4d5a12 ISSUE_TEMPLATE/03_bug_report_nixos: remove git blame (#442428)
Local evaluation for computing rebuilds
$ nix-env --extra-experimental-features no-url-literals --option system x86_64-linux -f <nixpkgs> --nix-path nixpkgs=/home/thefossguy/.cache/nixpkgs-review/pr-440950-2/nixpkgs nixpkgs-overlays=/tmp/tmpwsnbjljd -qaP --xml --out-path --show-trace --no-allow-import-from-derivation
$ git checkout 88c194747efd610c2b219b6475058b39256185b9
Previous HEAD position was 9c2a8e4d5a12 ISSUE_TEMPLATE/03_bug_report_nixos: remove git blame (#442428)
HEAD is now at 88c194747efd Merge a8f9173c14820abd7b666492e46fd5fab9632afe into 9c2a8e4d5a12dd887ea2211e7b1f5625ad7c085f
$ nix-env --extra-experimental-features no-url-literals --option system x86_64-linux -f <nixpkgs> --nix-path nixpkgs=/home/thefossguy/.cache/nixpkgs-review/pr-440950-2/nixpkgs nixpkgs-overlays=/tmp/tmpwsnbjljd -qaP --xml --out-path --show-trace --no-allow-import-from-derivation --meta
--------- Impacted packages on 'x86_64-linux' ---------
1 package added:
cosmic-initial-setup (init at 0-unstable-2025-09-10)

3 packages updated:
nixos-install-tools nixos-system-nixos-test nixpkgs-manual


$ nom build --file /nix/store/3wskaz95nc1b0fp885pzxwb40kbq285f-nixpkgs-review/lib/python3.13/site-packages/nixpkgs_review/nix/review-shell.nix --nix-path 'nixpkgs=/home/thefossguy/.cache/nixpkgs-review/pr-440950-2/nixpkgs nixpkgs-overlays=/tmp/tmpwsnbjljd' --extra-experimental-features 'nix-command no-url-literals' --no-link --keep-going --no-allow-import-from-derivation --option build-use-sandbox relaxed --argstr local-system x86_64-linux --argstr nixpkgs-path /home/thefossguy/.cache/nixpkgs-review/pr-440950-2/nixpkgs --argstr nixpkgs-config-path /tmp/tmpwouxg3o6.nix --argstr attrs-path /home/thefossguy/.cache/nixpkgs-review/pr-440950-2/attrs.nix
these 5 derivations will be built:
  /nix/store/0p0sba7k3blp8mjwmi6l7dqf5iy2fcn8-options.json.drv
  /nix/store/2vqrb36kgp7w8ghpjd0l6d93kbpzsc00-treefmt-function-locations.drv
  /nix/store/vvhbki6aqp3imlld91nwjy35hp47ksjk-treefmt-functions-doc.drv
  /nix/store/790z7l2vqrn8gsv20v45bqfjb1p249l7-nixpkgs-manual.drv
  /nix/store/0lvjy04w8mdzjxrcik3wwlp5gzghl2ix-review-shell.drv
this path will be fetched (0.05 MiB download, 0.29 MiB unpacked):
  /nix/store/fx8bjds4x1dnb8x7nsvzfvbfpm7ky1vg-nixpkgs-lib-docs
copying path '/nix/store/fx8bjds4x1dnb8x7nsvzfvbfpm7ky1vg-nixpkgs-lib-docs' from 'https://cache.nixos.org'
options.json> building '/nix/store/0p0sba7k3blp8mjwmi6l7dqf5iy2fcn8-options.json.drv'
treefmt-function-locations> building '/nix/store/2vqrb36kgp7w8ghpjd0l6d93kbpzsc00-treefmt-function-locations.drv'
treefmt-functions-doc> building '/nix/store/vvhbki6aqp3imlld91nwjy35hp47ksjk-treefmt-functions-doc.drv'
nixpkgs-manual> building '/nix/store/790z7l2vqrn8gsv20v45bqfjb1p249l7-nixpkgs-manual.drv'
nixpkgs-manual> Running phase: unpackPhase
nixpkgs-manual> unpacking source archive /nix/store/r7ab1dq1qdkpdv2lfsfmk47a80vrpiy4-source
nixpkgs-manual> source root is source
nixpkgs-manual> Running phase: patchPhase
nixpkgs-manual> Running phase: updateAutotoolsGnuConfigScriptsPhase
nixpkgs-manual> Running phase: configurePhase
nixpkgs-manual> no configure script, doing nothing
nixpkgs-manual> Running phase: buildPhase
nixpkgs-manual> Running phase: installPhase
nixpkgs-manual> Running phase: fixupPhase
nixpkgs-manual> shrinking RPATHs of ELF executables and libraries in /nix/store/k89cnqj2bb8lw1m2nr6hcxcriyvdijfn-nixpkgs-manual
nixpkgs-manual> checking for references to /build/ in /nix/store/k89cnqj2bb8lw1m2nr6hcxcriyvdijfn-nixpkgs-manual...
nixpkgs-manual> patching script interpreter paths in /nix/store/k89cnqj2bb8lw1m2nr6hcxcriyvdijfn-nixpkgs-manual
review-shell> building '/nix/store/0lvjy04w8mdzjxrcik3wwlp5gzghl2ix-review-shell.drv'
review-shell> Running phase: buildPhase
┏━ Dependency Graph:
┃    ┌─ ↓ ✔ nixpkgs-lib-docs
┃    ├─ ✔ options.json 
┃    │  ┌─ ✔ treefmt-function-locations 
┃    ├─ ✔ treefmt-functions-doc 
┃ ┌─ ✔ nixpkgs-manual ⏱ 1s
┃ ✔ review-shell 
┣━━━ Builds          │ Downloads       │ Host                         
┃        │ ✔ 5 │     │     │     │     │ localhost                    
┃        │     │     │     │ ↓ 1 │     │ https://cache.nixos.org      
┗━ ∑ ⏵ 0 │ ✔ 5 │ ⏸ 0 │ ↓ 0 │ ↓ 1 │ ⏸ 0 │ Finished at 04:21:53 after 6s

Link to currently reviewing PR:
https://github.com/NixOS/nixpkgs/pull/440950
--------- Report for 'x86_64-linux' ---------
2 packages blacklisted:
nixos-install-tools tests.nixos-functions.nixos-test

2 packages built:
cosmic-initial-setup nixpkgs-manual

Logs can be found under:
/home/thefossguy/.cache/nixpkgs-review/pr-440950-2/logs

## `nixpkgs-review` result

Generated using [`nixpkgs-review`](https://github.com/Mic92/nixpkgs-review).

Command: `nixpkgs-review pr 440950`
Commit: `a8f9173c14820abd7b666492e46fd5fab9632afe`

---
### `x86_64-linux`
<details>
  <summary>:fast_forward: 2 packages blacklisted:</summary>
  <ul>
    <li>nixos-install-tools</li>
    <li>tests.nixos-functions.nixos-test</li>
  </ul>
</details>
<details>
  <summary>:white_check_mark: 2 packages built:</summary>
  <ul>
    <li>cosmic-initial-setup</li>
    <li>nixpkgs-manual</li>
  </ul>
</details>


$ /home/thefossguy/.nix-profile/bin/nom-shell --argstr local-system x86_64-linux --argstr nixpkgs-path /home/thefossguy/.cache/nixpkgs-review/pr-440950-2/nixpkgs --argstr nixpkgs-config-path /tmp/tmpwouxg3o6.nix --argstr attrs-path /home/thefossguy/.cache/nixpkgs-review/pr-440950-2/attrs.nix --nix-path 'nixpkgs=/home/thefossguy/.cache/nixpkgs-review/pr-440950-2/nixpkgs nixpkgs-overlays=/tmp/tmpwsnbjljd' /nix/store/3wskaz95nc1b0fp885pzxwb40kbq285f-nixpkgs-review/lib/python3.13/site-packages/nixpkgs_review/nix/review-shell.nix


[nix-shell:~/.cache/nixpkgs-review/pr-440950-2]$ 
exit
$ git worktree remove -f /home/thefossguy/.cache/nixpkgs-review/pr-440950-2/nixpkgs

[thefossguy@build01:/home/thefossguy/my-git-repos/pratham/nixpkgs 0]$ 

Copy link

@thefossguy thefossguy left a comment

Choose a reason for hiding this comment

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

Verified that the PR fixes detection of changed packages (as per the comment just above with the output).

@Defelo Defelo marked this pull request as ready for review September 13, 2025 15:03
Copy link

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (3)
nixpkgs_review/review.py (3)

871-912: Make fetch independent of CWD, support “no depth” fetch, and improve error messages.

  • Current calls assume the process CWD is the repository. Use --git-dir to target the right repo.
  • Allow shallow_depth=None to disable the depth flag (used by the fallback above).
  • Error mentions {repo} when probing local shallow state; clarify.
-def fetch_refs(repo: str, *refs: str, shallow_depth: int = 1) -> list[str]:
-    shallow = subprocess.run(
-        ["git", "rev-parse", "--is-shallow-repository"],
+def fetch_refs(repo: str, *refs: str, shallow_depth: int | None = 1) -> list[str]:
+    dotgit = resolve_git_dir()
+    shallow = subprocess.run(
+        ["git", "--git-dir", str(dotgit), "rev-parse", "--is-shallow-repository"],
         text=True,
         stdout=subprocess.PIPE,
         check=False,
     )
     if shallow.returncode != 0:
-        msg = f"Failed to detect if {repo} is shallow repository"
+        msg = "Failed to detect if local repository is shallow"
         raise NixpkgsReviewError(msg)
 
-    fetch_cmd = [
+    fetch_cmd = [
         "git",
+        "--git-dir",
+        str(dotgit),
         "-c",
         "fetch.prune=false",
         "fetch",
         "--no-tags",
         "--force",
         repo,
     ]
-    if shallow.stdout.strip() == "true":
-        fetch_cmd.append(f"--depth={shallow_depth}")
+    if shallow.stdout.strip() == "true" and shallow_depth is not None:
+        fetch_cmd.append(f"--depth={shallow_depth}")
     for i, ref in enumerate(refs):
         fetch_cmd.append(f"{ref}:refs/nixpkgs-review/{i}")
-    dotgit = resolve_git_dir()
     with locked_open(dotgit / "nixpkgs-review", "w"):
-        res = sh(fetch_cmd)
+        res = sh(fetch_cmd)
         if res.returncode != 0:
             msg = f"Failed to fetch {refs} from {repo}. git fetch failed with exit code {res.returncode}"
             raise NixpkgsReviewError(msg)
         shas = []
         for i, ref in enumerate(refs):
-            rev_parse_cmd = ["git", "rev-parse", "--verify", f"refs/nixpkgs-review/{i}"]
+            rev_parse_cmd = ["git", "--git-dir", str(dotgit), "rev-parse", "--verify", f"refs/nixpkgs-review/{i}"]
             out = subprocess.run(
                 rev_parse_cmd, text=True, stdout=subprocess.PIPE, check=False
             )
             if out.returncode != 0:
                 msg = f"Failed to fetch {ref} from {repo} with command: {''.join(rev_parse_cmd)}"
                 raise NixpkgsReviewError(msg)
             shas.append(out.stdout.strip())
         return shas

283-289: Delta preview receives no stdin; nothing gets rendered.

Pipe the prepared diff to delta via input=limited_diff.

-                subprocess.run(
+                subprocess.run(
                     [delta_cmd, "--side-by-side", "--line-numbers", "--paging=never"],
-                    stdin=subprocess.PIPE,
+                    stdin=subprocess.PIPE,
                     stderr=subprocess.PIPE,
                     text=True,
-                    check=True,
+                    input=limited_diff,
+                    check=True,
                 )

319-324: URLError is referenced but urllib.error isn’t imported.

This can raise during exception handling. Import the module.

-        try:
+        try:
             with urllib.request.urlopen(diff_url) as response:  # noqa: S310
                 diff_content = response.read().decode("utf-8")
             self._display_diff_preview(diff_content)
-        except (urllib.error.URLError, OSError):
+        except (urllib.error.URLError, OSError):
             pass

Add import near other imports:

-import urllib.request
+import urllib.request
+import urllib.error
🧹 Nitpick comments (2)
tests/test_pr.py (2)

71-74: Prefer BytesIO over mock_open for urlopen responses.

urllib.request.urlopen(...).read() returns bytes. mock_open is text-oriented and can behave inconsistently with bytes. Use io.BytesIO for robustness.

-    mocks = [
-        mock_open(read_data=json.dumps(pr_response).encode())(),
-        mock_open(read_data=diff_content.encode())(),
-    ]
+    mocks = [
+        io.BytesIO(json.dumps(pr_response).encode("utf-8")),
+        io.BytesIO(diff_content.encode("utf-8")),
+    ]

89-96: Minor: use the repo test helper or absolute git path to silence S607 (partial executable path).

Low impact, but you can reuse conftest.run(...) for consistency.

-    subprocess.run(["git", "checkout", "-b", "pull/1/head"], check=True)
+    run(["git", "checkout", "-b", "pull/1/head"])
-    subprocess.run(["git", "add", "."], check=True)
+    run(["git", "add", "."])
-    subprocess.run(["git", "commit", "-m", "example-change"], check=True)
+    run(["git", "commit", "-m", "example-change"])
-    subprocess.run(["git", "checkout", "-b", "pull/1/merge", "master"], check=True)
+    run(["git", "checkout", "-b", "pull/1/merge", "master"])
-    subprocess.run(["git", "merge", "--no-ff", "pull/1/head"], check=True)
+    run(["git", "merge", "--no-ff", "pull/1/head"])
-    subprocess.run(["git", "push", str(nixpkgs.remote), "pull/1/merge"], check=True)
+    run(["git", "push", str(nixpkgs.remote), "pull/1/merge"])
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81e9f92 and 558b6d4.

📒 Files selected for processing (2)
  • nixpkgs_review/review.py (9 hunks)
  • tests/test_pr.py (8 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/test_pr.py (1)
tests/conftest.py (6)
  • Helpers (163-241)
  • Nixpkgs (22-24)
  • nixpkgs (192-241)
  • run (27-28)
  • helpers (245-246)
  • read_asset (169-170)
nixpkgs_review/review.py (1)
nixpkgs_review/git.py (1)
  • verify_commit_hash (34-41)
🪛 Ruff (0.12.2)
tests/test_pr.py

89-89: Starting a process with a partial executable path

(S607)


91-91: Starting a process with a partial executable path

(S607)


92-92: Starting a process with a partial executable path

(S607)


93-93: Starting a process with a partial executable path

(S607)


94-94: Starting a process with a partial executable path

(S607)


95-95: subprocess call: check for execution of untrusted input

(S603)


95-95: Starting a process with a partial executable path

(S607)

🔇 Additional comments (2)
nixpkgs_review/review.py (1)

437-439: Post-diff checkout in COMMIT mode looks good.

Ensures builds run against PR head when requested.

tests/test_pr.py (1)

88-101: Good test helper to create a realistic base/head/merge triple.

This centralizes repo setup and makes tests deterministic.

Comment on lines +405 to 411
if head_commit is None:
self.apply_unstaged(staged)
elif self.checkout == CheckoutOption.COMMIT:
self.git_checkout(reviewed_commit)
elif merge_commit:
self.git_checkout(merge_commit)
else:
self.git_merge(reviewed_commit)
self.git_merge(head_commit)

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

CheckoutOption.COMMIT is ignored in local-eval diffs when a merge_commit exists (mis-detection risk).

In the non-only-packages path, you always prefer the merge commit if provided. This diverges from COMMIT semantics and makes the diff include base-branch changes, which can overbuild. Prefer merging head_commit into base_commit when checkout == COMMIT, even if merge_commit is available.

-        if head_commit is None:
+        if head_commit is None:
             self.apply_unstaged(staged)
-        elif merge_commit:
-            self.git_checkout(merge_commit)
-        else:
-            self.git_merge(head_commit)
+        elif self.checkout == CheckoutOption.COMMIT:
+            # Evaluate diffs against base+PR only (ignore target branch head)
+            self.git_merge(head_commit)
+        elif merge_commit:
+            # Evaluate diffs against the actual GitHub merge result
+            self.git_checkout(merge_commit)
+        else:
+            self.git_merge(head_commit)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if head_commit is None:
self.apply_unstaged(staged)
elif self.checkout == CheckoutOption.COMMIT:
self.git_checkout(reviewed_commit)
elif merge_commit:
self.git_checkout(merge_commit)
else:
self.git_merge(reviewed_commit)
self.git_merge(head_commit)
if head_commit is None:
self.apply_unstaged(staged)
elif self.checkout == CheckoutOption.COMMIT:
# Evaluate diffs against base+PR only (ignore target branch head)
self.git_merge(head_commit)
elif merge_commit:
# Evaluate diffs against the actual GitHub merge result
self.git_checkout(merge_commit)
else:
self.git_merge(head_commit)
🤖 Prompt for AI Agents
In nixpkgs_review/review.py around lines 405-411, the current logic prefers
using merge_commit if present which ignores CheckoutOption.COMMIT semantics and
pulls base-branch changes into local-eval diffs; change the branch-selection
logic so that when checkout == CheckoutOption.COMMIT you explicitly check out
the base commit and then merge head_commit into it (i.e.,
git_checkout(base_commit) followed by git_merge(head_commit)), only falling back
to using merge_commit when checkout is not COMMIT and merge_commit is the
intended behavior; keep the existing apply_unstaged(head_commit is None)
behavior for unstaged cases.

Comment on lines +513 to 516
[merge_rev] = fetch_refs(self.remote, pr["merge_commit_sha"], shallow_depth=2)
base_rev = git.verify_commit_hash(f"{merge_rev}^1")
head_rev = git.verify_commit_hash(f"{merge_rev}^2")

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fetching only the merge commit with depth=2 can miss parent(2) in shallow repos. Add fallback or fetch parents robustly.

rev-parse <merge>^2 can fail if the second parent isn't present. Add a fallback unshallow fetch (or disable depth) when parent resolution fails.

-        [merge_rev] = fetch_refs(self.remote, pr["merge_commit_sha"], shallow_depth=2)
-        base_rev = git.verify_commit_hash(f"{merge_rev}^1")
-        head_rev = git.verify_commit_hash(f"{merge_rev}^2")
+        try:
+            [merge_rev] = fetch_refs(self.remote, pr["merge_commit_sha"], shallow_depth=2)
+            base_rev = git.verify_commit_hash(f"{merge_rev}^1")
+            head_rev = git.verify_commit_hash(f"{merge_rev}^2")
+        except NixpkgsReviewError:
+            # Fallback: fetch without depth-limit to ensure both parents are available
+            [merge_rev] = fetch_refs(self.remote, pr["merge_commit_sha"], shallow_depth=None)
+            base_rev = git.verify_commit_hash(f"{merge_rev}^1")
+            head_rev = git.verify_commit_hash(f"{merge_rev}^2")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[merge_rev] = fetch_refs(self.remote, pr["merge_commit_sha"], shallow_depth=2)
base_rev = git.verify_commit_hash(f"{merge_rev}^1")
head_rev = git.verify_commit_hash(f"{merge_rev}^2")
try:
[merge_rev] = fetch_refs(self.remote, pr["merge_commit_sha"], shallow_depth=2)
base_rev = git.verify_commit_hash(f"{merge_rev}^1")
head_rev = git.verify_commit_hash(f"{merge_rev}^2")
except NixpkgsReviewError:
# Fallback: fetch without depth-limit to ensure both parents are available
[merge_rev] = fetch_refs(self.remote, pr["merge_commit_sha"], shallow_depth=None)
base_rev = git.verify_commit_hash(f"{merge_rev}^1")
head_rev = git.verify_commit_hash(f"{merge_rev}^2")
🤖 Prompt for AI Agents
In nixpkgs_review/review.py around lines 513 to 516, resolving the merge commit
parents with shallow_depth=2 can fail because the second parent may not be
present in shallow clones; wrap the parent resolution in a try/except and on
failure perform a corrective fetch (e.g., fetch the missing parents or run an
unshallow/fetch without depth, or explicitly fetch merge_commit^2) then retry
git.verify_commit_hash for f"{merge_rev}^1" and f"{merge_rev}^2"; ensure the
fallback only runs when parent resolution fails and preserve existing behavior
otherwise.

Copy link

@thefossguy thefossguy left a comment

Choose a reason for hiding this comment

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

No changes in 558b6d4 -> 7b680e1.

Copy link
Collaborator

@GaetanLepage GaetanLepage left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for the fix!

@GaetanLepage GaetanLepage merged commit a6ec1b3 into Mic92:master Sep 13, 2025
3 checks passed
@Defelo Defelo deleted the push-plquszmtolwo branch September 13, 2025 19:17
@GaetanLepage
Copy link
Collaborator

@Mic92 do you think we should make a (minor) release to ship this fix?

@Mic92
Copy link
Owner

Mic92 commented Sep 21, 2025

@GaetanLepage go ahead.

@GaetanLepage
Copy link
Collaborator

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.

Bug in detection of updated packages

4 participants