NixOS: Installing software from pull requests

Sometimes we need to use software that is not in the upstream yet.

NixOS upstream is nice and fast, but there’s a time gap between pull request submit and merge that is not possible to avoid.

For trying pull request locally there’s nice software called nix-review, but it’s not something that you can use in your configuration.nix globally.

So, we need to start from “what is pull request”? Pull request is just a branch that you can fetch with git.

Also, GitHub provides access to archives. Which means you only need to know the hash of the branch.

Let’s say you have a pull request 64977.

The easiest way to get hash is to append .patch to URL, so for URL https://github.com/NixOS/nixpkgs/pull/64977 we can get hash with this command:

$ curl -sL https://github.com/NixOS/nixpkgs/pull/64977.patch \
                | head -n 1 | grep -o -E -e "[0-9a-f]{40}"
7da8de19b1f394c92f27b8d953b85cfce1770427

Then use it with a package override, like that:

let
  nixpkgs-tars = "https://github.com/NixOS/nixpkgs/archive/";
in {
  nixpkgs.config = {
    packageOverrides = pkgs: {
      pr64977 = import (fetchTarball 
        "${nixpkgs-tars}7da8de19b1f394c92f27b8d953b85cfce1770427.tar.gz") 
          { config = config.nixpkgs.config; };
    };
  };

And inside systemPackages:

environment.systemPackages = with pkgs; [
  ...
  # Package from pull request 64977
  pr64977.telega-server
  ...
];

You can write a simple bash function (and put it to .bashrc):

function get-pr-override() {
        PR_NO=$1
        HASH=$(curl -sL https://github.com/NixOS/nixpkgs/pull/${PR_NO}.patch \
                | head -n 1 | grep -o -E -e "[0-9a-f]{40}")
        echo pr${PR_NO} = "import (fetchTarball"
        echo "  \"\${nixpkgs-tars}${HASH}.tar.gz\")"
        echo "    { config = config.nixpkgs.config; };"
}

Which will be helpful for regular use:

$ get-pr-override 65110
pr65110 = import (fetchTarball
  "${nixpkgs-tars}dc7c4d003c754581d86c609ae960a25ad3e43b92.tar.gz")
    { config = config.nixpkgs.config; };

You can use any amount of pull requests inside your configuration.nix:

nixpkgs.config = {
  packageOverrides = pkgs: {
    pr64977 = import (fetchTarball
      "${nixpkgs-tars}7da8de19b1f394c92f27b8d953b85cfce1770427.tar.gz")
        { config = config.nixpkgs.config; };
    pr65110 = import (fetchTarball
      "${nixpkgs-tars}dc7c4d003c754581d86c609ae960a25ad3e43b92.tar.gz")
        { config = config.nixpkgs.config; };
  };
};

environment.systemPackages = with pkgs; [
  ...
  pr64977.telega-server
  pr65110.sublime-merge
  ...
];

Enjoy and do not waste time waiting for the merge.

Do not forget to write the comment to pull requests to mention that everything works well (it’ll help people merge it faster).

A complete example of usage.