How do I apply a GitHub commit to my configuration.nix?

How do I apply a GitHub commit(s) to my configuration.nix? I feel like this is probably a common question, but alas, I’m struggling with it.

Specifically, I had this issue, which someone graciously merged a fix for. I’d like to cherry-pick the fix to test it, but can’t figure out how.

I tried this:

nixpkgs.config.packageOverrides = pkgs: {
  # https://github.com/NixOS/nixpkgs/issues/176484
  pr176561 = import (fetchTarball
    "${nixpkgs-tars}955d1a6dde9862822fbb0f2d6be9bfa51fdbc689.tar.gz")
      { config = config.nixpkgs.config; };
};

It didn’t give any errors, but I’m pretty sure it didn’t apply (it should have modified the pipewire user’s home directory, but did not). Are there logs that confirm whether it was applied? Am I missing something in the above configuration? And, for future reference, does anyone have a complete “how to cherry-pick a GitHub pull request into your NixOS configuration” tutorial/guide?

I tried changing pr176561 = ... to pipewire = ... (…does the name here matter?..) and actually did get an error: error: Dependency is not of a valid type: element 6 of buildInputs for SDL2.

All you are doing here is adding a checkout of that config as a package named pr176561. That doesn’t affect your configuration at all. However the same import statement at nixpkgs.pkgs would work.

Setting { config = config.nixpkgs.config; } there may actually lead to infinite recursion. If it does, simply define your desired nixpkgs config inline.

If you would rather not override your entire configurations nixpkgs, but instead just use this one changed module, you could leave it the way it is and instead disable the module from your configuration’s nixpkgs, and import it from your pr176561 package like so:

{pkgs, ...}: {
  disabledModules = [ "services/desktops/pipewire/pipewire.nix" ];
  imports = [ "${pkgs.pr176561}/nixos/modules/services/desktops/pipewire/pipewire.nix" ];
}

You could even use GitHub’s raw api to fetch just the module file itself, to avoid the large fetch and extra evaluation cost.

On an unrelated note, using packageOverrides directly has been discouraged for a while. Probably better to use overlays, or as some would suggest, just define your custom packages and/or overrides at the call-site.

1 Like

Using flakes:

{
  description = "NixOS configuration";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.05";
    nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
    nixpkgs-pr176561.url = "github:NixOS/nixpkgs/955d1a6dde9862822fbb0f2d6be9bfa51fdbc689"
  }
  outputs = { self, nixpkgs, nixpkgs-unstable, nixpkgs-pr176561,
    ... }@inputs: {
    let
      nixpkgs = {
        overlays = [
           # Unstable packages overlay
           (final: prev: {
             inherit (import nixpkgs-unstable { system = "x86_64-linux"; })
               ungoogled-chromium firefox-esr
           })
           # Cherry picked overlay
           (final: prev: {
             inherit (import nixpkgs-pr176561 { system = "x86_64-linux"; })
               iosevka;
           })
        ];
      };
    in 
    nixosConfigurations = {
      your-host = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
   (...)
        modules = [
   (...)
}

Regards

1 Like

However the same import statement at nixpkgs.pkgs would work.

Ok, so, I assume you mean to do:

  imports = [
    (fetchTarball "${nixpkgs-tars}955d1a6dde9862822fbb0f2d6be9bfa51fdbc689.tar.gz") { config = config.nixpkgs.config; }
  ];

This leads to:

error: assertion '(((args) ? localSystem) -> (! ((args) ? system)))' failed

       at /nix/store/i70l6f7f160g0pnf3qd7xv69papg4ad3-source/pkgs/top-level/impure.nix:79:1:

           78| # not be passed, and vice-versa.
           79| assert args ? localSystem -> !(args ? system);
             | ^
           80| assert args ? system -> !(args ? localSystem);
(use '--show-trace' to show detailed location information)

Also, you said:

Setting { config = config.nixpkgs.config; } there may actually lead to infinite recursion. If it does, simply define your desired nixpkgs config inline.

What do you mean by “inline”? Can you show an example?

Also, I tried your other suggestion:

{pkgs, ...}: {
  disabledModules = [ "services/desktops/pipewire/pipewire.nix" ];
  imports = [ "${pkgs.pr176561}/nixos/modules/services/desktops/pipewire/pipewire.nix" ];
}

This leads to:

       at /nix/var/nix/profiles/per-user/root/channels/nixos/lib/modules.nix:496:28:

          495|         builtins.addErrorContext (context name)
          496|           (args.${name} or config._module.args.${name})
             |                            ^
          497|       ) (lib.functionArgs f);
(use '--show-trace' to show detailed location information)
building the system configuration...
error: infinite recursion encountered

This happens even when I’m not setting my original nixpkgs.config.packageOverrides, which means I’m not using { config = config.nixpkgs.config; } anywhere.

actually no, I meant set the value of the nixos module option nixpkgs.pkgs to the import statement you wrote previous, in other words: nixpkgs.pkgs = import someNixpkgs {};.

Inline as in, don’t import it from config.nixpkgs.config. Instead take whatever you have defined for nixpkgs.config elsewhere in your configuration and place it here.

This is probably because of the override. Fortunately there is no real point to exposing this import as a package override at all, so you could probably just remove the override and do imports = let pr176561 = import ... in [ ... ]. For the record, this would probably be the best way to do it as following a PR branch may end up leaving you stagnant for a while until its merged. Better to track a well cached branch like nixos-22.05 or nixos-unstable as your base system and import just this one module.

1 Like

I’m going to be completely honest: I’m a software engineer, I’ve used NixOS for ~1 year, and I barely understand any of what you’ve just said. Clearly I’m not a NixOS power user.

NixOS has for the most part worked out of the box. This is the first time I’ve needed to apply a bug fix. And it sounds like, in order to do so, I’m going to have to sit down, actually read the NixOS docs, and try to become a non-beginner.

Well I could always work on my exposition skills, don’t just blame yourself, obviously I’m making things too complicated :laughing:

For now you could probably jus copy this snippet and it would work:

{config, ...}: {
  disabledModules = ["services/desktops/pipewire/pipewire.nix"];
  imports = let
    pr176561 =
      fetchTarball
      "https://github.com/nixos/nixpkgs/archive/955d1a6dde9862822fbb0f2d6be9bfa51fdbc689.tar.gz";
  in ["${pr176561}/nixos/modules/services/desktops/pipewire/pipewire.nix"];
}

All I’m doing is definig the custom nixpkgs in a let block right where it is consumed instead of bothering with modifying the nixpkgs fixed point with an override. There is also no need to import it since all we need is one file from the source tree. I’ll leave pulling just a single file with the GitHub raw api as an optional excercise for you.

1 Like

Awesome, the patch applied successfully. Thanks!

(Actually, the patch didn’t fix my issue. :sweat_smile: But…I’ll take that convo elsewhere.)