Skip to content

Conversation

@wolfgangwalther
Copy link
Contributor

@wolfgangwalther wolfgangwalther commented May 25, 2025

The core idea here is to make it harder to accidentally do bad things when checking out nixpkgs in CI. The most obvious thing is to avoid running code from the untrusted PR branch, of course. Just using the terms "merge commit" and "target commit" is not really telling that story, though. So, I renamed the checkout locations to untrusted/ and trusted/ instead. This means you'll have to explicitly write either "trusted" or "untrusted" when referring to any of them, which makes it mostly obvious when executing untrusted code. To encourage this pattern, I'm also moving the the checkouts into actions/get-merge-commit. You'll have to explicitly do something very different to break it now.

Found some inconsistencies, too:

  • A bug for PRs with merge conflicts and multiple commits. In this case, the parent of the merged commit is not equal to the target commit, because those are head and base commits of the PRs branch respectively.
  • Slight refactor of actions/get-merge-commit to use core.setOutput.
  • The nixpkgs-vet workflow... actually executes untrusted code, because it creates a download URL from the pinned version which is taken from the head branch... It doesn't have access to any secrets, so I don't think this is critical. By moving to the pinned nixpkgs instance, provided by the trusted target commitwhich is run in the nix sandbox, this is avoided. Also a regular nix-build ci will now include nixpkgs-vet, too, albeit only running the basic checks, not the "ratchet" checks.
  • I would have liked to slightly optimize our checkouts with git worktree, but hit a Nix bug. Slightly annoying to debug, because the lix I am using locally works just fine with worktrees, so that was confusing.

Things done


Add a 👍 reaction to pull requests you find important.

In PRs with multiple commits and merge conflicts the logic "targetSha ==
immediate parent of mergedSha" doesn't hold anymore. The head and base
commits of the PR's branch have some commits inbetween them, instead.

Before this change, we'd get a "fatal: invalid reference" on the
"worktree add". Now, not anymore, because we fetch the right commit
directly.
Using core.setOutput is much nicer than having to parse the json
"result" on the outside. This also avoids some very odd errors, when the
result can, for unknown reasons, *not* be parsed as JSON later on.

Also avoiding a bit of duplication between the "if mergeable" branches.
By consistently checking out nixpkgs into the same location in every
workflow, it's easier to reason about the different workflows at once.
We also use crystal-clear names to make clear, which checkouts are
considered trusted, because they only contain target-branch-code and
which checkouts are untrusted, because they contain code from the head
branch. By naming the checkout directories trusted/untrusted, it's
obvious at the call-site.

One example of where we likely did the wrong thing is the nixpkgs-vet
workflow: Fetching the toolVersion from the untrusted checkout opens the
door for an injection into the download URL, thus code could be
downloaded from anywhere. This is not a problem, because this workflow
does not run with elevated privileges, but it's a scary oversight
nonetheless.
@wolfgangwalther wolfgangwalther requested a review from winterqt May 25, 2025 12:56
@github-actions github-actions bot added 6.topic: continuous integration Affects continuous integration (CI) in Nixpkgs, including Ofborg and GitHub Actions 6.topic: policy discussion Discuss policies to work in and around Nixpkgs backport release-25.05 labels May 25, 2025
We have added nixpkgs-vet as a regular package to nixpkgs a while ago,
so we can now use it from pinned nixpkgs. This avoids pulling a
platform-specific binary version from upstream.

This change also allows to run the tool easily locally, the same way as
other tools:

  nix-build ci -A nixpkgs-vet

This will do a full check of the repo with the exception of
nixpkgs-vet's "ratchet" checks: Those depend on having two branches to
compare, but the default is to only look at the head branch. Those
ratchet checks will still be run in CI, though.
@wolfgangwalther wolfgangwalther force-pushed the ci-consistent-checkouts branch from cd5349a to 228170a Compare May 25, 2025 13:02
@github-actions github-actions bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux. labels May 25, 2025
This makes checking out the nixpkgs repo even more consistent and almost
forces us to use the trusted/untrusted path pattern.
@wolfgangwalther wolfgangwalther force-pushed the ci-consistent-checkouts branch from 228170a to 0e1c284 Compare May 25, 2025 13:14
@Mic92 Mic92 merged commit 17d1bdd into NixOS:master May 25, 2025
26 of 29 checks passed
@nixpkgs-ci
Copy link
Contributor

nixpkgs-ci bot commented May 25, 2025

Successfully created backport PR for release-25.05:

@github-actions github-actions bot added the 8.has: port to stable This PR already has a backport to the stable release. label May 25, 2025
@wolfgangwalther wolfgangwalther deleted the ci-consistent-checkouts branch May 25, 2025 15:14
@Mic92
Copy link
Member

Mic92 commented May 25, 2025

@wolfgangwalther why do you actually need a .git? Could you not get rid of this before running nix instead of whatever breaks with the current shallow clone worktree? Hopefully the fix in nix is soon there, but just in case.

@wolfgangwalther
Copy link
Contributor Author

When using worktrees, two things break:

  • nix flake check in eval aliases - not sure whether that would work without .git
  • nixpkgs-vet, which has this:
  filtered =
    with lib.fileset;
    path:
    toSource {
      fileset = (gitTracked path);
      root = path;
    };

So this does depend on the git repo via gitTracked -> builtins.fetchGit.

It only makes a small difference of a few seconds, so I wouldn't want to introduce more workarounds for it. Once this is fixed in Nix, we can take advantage, though. But it's not blocking anything else either.

@Mic92
Copy link
Member

Mic92 commented May 26, 2025

gitTracked

This actually sets shallow = true; but I encountered another bug in nix, where the revCount is computed anyway. This is also fixed in: NixOS/nix#13260

nix flake check can be worked around today by nix flake check git+file:///path?shallow=1. NixOS/nix#13260 make this the new default.

@wolfgangwalther
Copy link
Contributor Author

gitTracked

This actually sets shallow = true; but I encountered another bug in nix, where the revCount is computed anyway. This is also fixed in: NixOS/nix#13260

Ah, OK. I was about to test that again, because I thought I actually tried adding shallow=1, too. But that should explain my observation.

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

Labels

6.topic: continuous integration Affects continuous integration (CI) in Nixpkgs, including Ofborg and GitHub Actions 6.topic: policy discussion Discuss policies to work in and around Nixpkgs 8.has: port to stable This PR already has a backport to the stable release. 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants