nixpkgs/pkgs
2023-09-07 22:38:41 +08:00
..
applications Merge pull request #252885 from aaronjheng/ipfs-upload-client 2023-09-02 09:26:06 -04:00
build-support Merge pull request #251369 from srid/writeShellApplication-meta 2023-09-01 16:53:49 -04:00
common-updater
data elementary-xfce-icon-theme: 0.17 -> 0.18 2023-09-07 22:38:41 +08:00
desktops
development Merge pull request #252440 from figsoda/emmet 2023-09-02 09:38:02 -04:00
games
misc Merge pull request #250433 from kashw2/calaos_installer 2023-09-01 23:23:26 +02:00
os-specific Merge pull request #252898 from K900/kernels-20230902 2023-09-02 15:43:26 +02:00
pkgs-lib
servers Merge pull request #252824 from emilylange/matrix-sliding-sync 2023-09-02 15:58:42 +02:00
shells Merge pull request #250467 from kashw2/murex 2023-09-01 23:22:28 +02:00
stdenv
test
tools Merge pull request #252928 from sikmir/ttop 2023-09-02 10:03:41 -04:00
top-level Merge pull request #252440 from figsoda/emmet 2023-09-02 09:38:02 -04:00
README.md pkgs/README.md: slight rewording (#252820) 2023-09-01 20:04:48 +02:00

Contributing to Nixpkgs packages

This document is for people wanting to contribute specifically to the package collection in Nixpkgs. See the CONTRIBUTING.md document for more general information.

Overview

Quick Start to Adding a Package

We welcome new contributors of new packages to Nixpkgs, arguably the greatest software database known. However, each new package comes with a cost for the maintainers, Continuous Integration, caching servers and users downloading Nixpkgs.

Before adding a new package, please consider the following questions:

  • Is the package ready for general use? We don't want to include projects that are too immature or are going to be abandoned immediately. In case of doubt, check with upstream.
  • Does the project have a clear license statement? Remember that softwares are unfree by default (all rights reserved), and merely providing access to the source code does not imply its redistribution. In case of doubt, ask upstream.
  • How realistic is it that it will be used by other people? It's good that nixpkgs caters to various niches, but if it's a niche of 5 people it's probably too small.
  • Are you willing to maintain the package? You should care enough about the package to be willing to keep it up and running for at least one complete Nixpkgs' release life-cycle.

If any of these questions' answer is no, then you should probably not add the package.

This is section describes a general framework of understanding and exceptions might apply.

Luckily it's pretty easy to maintain your own package set with Nix, which can then be added to the Nix User Repository project.


Now that this is out of the way. To add a package to Nixpkgs:

  1. Checkout the Nixpkgs source tree:

    $ git clone https://github.com/NixOS/nixpkgs
    $ cd nixpkgs
    
  2. Find a good place in the Nixpkgs tree to add the Nix expression for your package. For instance, a library package typically goes into pkgs/development/libraries/pkgname, while a web browser goes into pkgs/applications/networking/browsers/pkgname. See the category hierarchy section for some hints on the tree organisation. Create a directory for your package, e.g.

    $ mkdir pkgs/development/libraries/libfoo
    
  3. In the package directory, create a Nix expression — a piece of code that describes how to build the package. In this case, it should be a function that is called with the package dependencies as arguments, and returns a build of the package in the Nix store. The expression should usually be called default.nix.

    $ emacs pkgs/development/libraries/libfoo/default.nix
    $ git add pkgs/development/libraries/libfoo/default.nix
    

    You can have a look at the existing Nix expressions under pkgs/ to see how its done. Here are some good ones:

    Some notes:

    • Add yourself as the maintainer of the package.

    • All other meta attributes are optional, but its still a good idea to provide at least the description, homepage and license.

    • You can use nix-prefetch-url url to get the SHA-256 hash of source distributions. There are similar commands as nix-prefetch-git and nix-prefetch-hg available in nix-prefetch-scripts package.

    • A list of schemes for mirror:// URLs can be found in pkgs/build-support/fetchurl/mirrors.nix.

    The exact syntax and semantics of the Nix expression language, including the built-in function, are described in the Nix manual.

  4. Add a call to the function defined in the previous step to pkgs/top-level/all-packages.nix with some descriptive name for the variable, e.g. libfoo.

    $ emacs pkgs/top-level/all-packages.nix
    

    The attributes in that file are sorted by category (like “Development / Libraries”) that more-or-less correspond to the directory structure of Nixpkgs, and then by attribute name.

  5. To test whether the package builds, run the following command from the root of the nixpkgs source tree:

    $ nix-build -A libfoo
    

    where libfoo should be the variable name defined in the previous step. You may want to add the flag -K to keep the temporary build directory in case something fails. If the build succeeds, a symlink ./result to the package in the Nix store is created.

  6. If you want to install the package into your profile (optional), do

    $ nix-env -f . -iA libfoo
    
  7. Optionally commit the new package and open a pull request to nixpkgs, or use the Patches category on Discourse for sending a patch without a GitHub account.

Category Hierarchy

Each package should be stored in its own directory somewhere in the pkgs/ tree, i.e. in pkgs/category/subcategory/.../pkgname. Below are some rules for picking the right category for a package. Many packages fall under several categories; what matters is the primary purpose of a package. For example, the libxml2 package builds both a library and some tools; but its a library foremost, so it goes under pkgs/development/libraries.

When in doubt, consider refactoring the pkgs/ tree, e.g. creating new categories or splitting up an existing category.

If its used to support software development:

  • If its a library used by other packages:

    • development/libraries (e.g. libxml2)
  • If its a compiler:

    • development/compilers (e.g. gcc)
  • If its an interpreter:

    • development/interpreters (e.g. guile)
  • If its a (set of) development tool(s):

    • If its a parser generator (including lexers):

      • development/tools/parsing (e.g. bison, flex)
    • If its a build manager:

      • development/tools/build-managers (e.g. gnumake)
    • If its a language server:

      • development/tools/language-servers (e.g. ccls or rnix-lsp)
    • Else:

      • development/tools/misc (e.g. binutils)
  • Else:

    • development/misc

If its a (set of) tool(s):

(A tool is a relatively small program, especially one intended to be used non-interactively.)

  • If its for networking:

    • tools/networking (e.g. wget)
  • If its for text processing:

    • tools/text (e.g. diffutils)
  • If its a system utility, i.e., something related or essential to the operation of a system:

    • tools/system (e.g. cron)
  • If its an archiver (which may include a compression function):

    • tools/archivers (e.g. zip, tar)
  • If its a compression program:

    • tools/compression (e.g. gzip, bzip2)
  • If its a security-related program:

    • tools/security (e.g. nmap, gnupg)
  • Else:

    • tools/misc

If its a shell:

  • shells (e.g. bash)

If its a server:

  • If its a web server:

    • servers/http (e.g. apache-httpd)
  • If its an implementation of the X Windowing System:

    • servers/x11 (e.g. xorg — this includes the client libraries and programs)
  • Else:

    • servers/misc

If its a desktop environment:

  • desktops (e.g. kde, gnome, enlightenment)

If its a window manager:

  • applications/window-managers (e.g. awesome, stumpwm)

If its an application:

A (typically large) program with a distinct user interface, primarily used interactively.

  • If its a version management system:

    • applications/version-management (e.g. subversion)
  • If its a terminal emulator:

    • applications/terminal-emulators (e.g. alacritty or rxvt or termite)
  • If its a file manager:

    • applications/file-managers (e.g. mc or ranger or pcmanfm)
  • If its for video playback / editing:

    • applications/video (e.g. vlc)
  • If its for graphics viewing / editing:

    • applications/graphics (e.g. gimp)
  • If its for networking:

    • If its a mailreader:

      • applications/networking/mailreaders (e.g. thunderbird)
    • If its a newsreader:

      • applications/networking/newsreaders (e.g. pan)
    • If its a web browser:

      • applications/networking/browsers (e.g. firefox)
    • Else:

      • applications/networking/misc
  • Else:

    • applications/misc

If its data (i.e., does not have a straight-forward executable semantics):

  • If its a font:

    • data/fonts
  • If its an icon theme:

    • data/icons
  • If its related to SGML/XML processing:

    • If its an XML DTD:

      • data/sgml+xml/schemas/xml-dtd (e.g. docbook)
    • If its an XSLT stylesheet:

      (Okay, these are executable...)

      • data/sgml+xml/stylesheets/xslt (e.g. docbook-xsl)
  • If its a theme for a desktop environment, a window manager or a display manager:

    • data/themes

If its a game:

  • games

Else:

  • misc

Conventions

Package naming

The key words must, must not, required, shall, shall not, should, should not, recommended, may, and optional in this section are to be interpreted as described in RFC 2119. Only emphasized words are to be interpreted in this way.

In Nixpkgs, there are generally three different names associated with a package:

  • The pname attribute of the derivation. This is what most users see, in particular when using nix-env.

  • The variable name used for the instantiated package in all-packages.nix, and when passing it as a dependency to other functions. Typically this is called the package attribute name. This is what Nix expression authors see. It can also be used when installing using nix-env -iA.

  • The filename for (the directory containing) the Nix expression.

Most of the time, these are the same. For instance, the package e2fsprogs has a pname attribute "e2fsprogs", is bound to the variable name e2fsprogs in all-packages.nix, and the Nix expression is in pkgs/os-specific/linux/e2fsprogs/default.nix.

There are a few naming guidelines:

  • The pname attribute should be identical to the upstream package name.

  • The pname and the version attribute must not contain uppercase letters — e.g., "mplayer" instead of "MPlayer"`.

  • The version attribute must start with a digit e.g`"0.3.1rc2".

  • If a package is a commit from a repository without a version assigned, then the version attribute should be the latest upstream version preceding that commit, followed by -unstable- and the date of the (fetched) commit. The date must be in "YYYY-MM-DD" format.

Example: Given a project had its latest releases 2.2 in November 2021, and 3.0 in January 2022, a commit authored on March 15, 2022 for an upcoming bugfix release 2.2.1 would have version = "2.2-unstable-2022-03-15".

  • Dashes in the package pname should be preserved in new variable names, rather than converted to underscores or camel cased — e.g., http-parser instead of http_parser or httpParser. The hyphenated style is preferred in all three package names.

  • If there are multiple versions of a package, this should be reflected in the variable names in all-packages.nix, e.g. json-c_0_9 and json-c_0_11. If there is an obvious “default” version, make an attribute like json-c = json-c_0_9;. See also versioning.

Versioning

Because every version of a package in Nixpkgs creates a potential maintenance burden, old versions of a package should not be kept unless there is a good reason to do so. For instance, Nixpkgs contains several versions of GCC because other packages dont build with the latest version of GCC. Other examples are having both the latest stable and latest pre-release version of a package, or to keep several major releases of an application that differ significantly in functionality.

If there is only one version of a package, its Nix expression should be named e2fsprogs/default.nix. If there are multiple versions, this should be reflected in the filename, e.g. e2fsprogs/1.41.8.nix and e2fsprogs/1.41.9.nix. The version in the filename should leave out unnecessary detail. For instance, if we keep the latest Firefox 2.0.x and 3.5.x versions in Nixpkgs, they should be named firefox/2.0.nix and firefox/3.5.nix, respectively (which, at a given point, might contain versions 2.0.0.20 and 3.5.4). If a version requires many auxiliary files, you can use a subdirectory for each version, e.g. firefox/2.0/default.nix and firefox/3.5/default.nix.

All versions of a package must be included in all-packages.nix to make sure that they evaluate correctly.

Meta attributes

  • meta.description must:
    • Be short, just one sentence.
    • Be capitalized.
    • Not start with the package name.
      • More generally, it should not refer to the package name.
    • Not end with a period (or any punctuation for that matter).
    • Provide factual information.
      • Avoid subjective language.
  • meta.license must be set and match the upstream license.
    • If there is no upstream license, meta.license should default to lib.licenses.unfree.
    • If in doubt, try to contact the upstream developers for clarification.
  • meta.mainProgram must be set when appropriate.
  • meta.maintainers should be set.

See the Nixpkgs manual for more details on standard meta-attributes.

Import From Derivation

Import From Derivation (IFD) is disallowed in Nixpkgs for performance reasons: Hydra evaluates the entire package set, and sequential builds during evaluation would increase evaluation times to become impractical.

Import From Derivation can be worked around in some cases by committing generated intermediate files to version control and reading those instead.

See also NixOS Wiki: Import From Derivation.

Sources

Fetching Sources

There are multiple ways to fetch a package source in nixpkgs. The general guideline is that you should package reproducible sources with a high degree of availability. Right now there is only one fetcher which has mirroring support and that is fetchurl. Note that you should also prefer protocols which have a corresponding proxy environment variable.

You can find many source fetch helpers in pkgs/build-support/fetch*.

In the file pkgs/top-level/all-packages.nix you can find fetch helpers, these have names on the form fetchFrom*. The intention of these are to provide snapshot fetches but using the same api as some of the version controlled fetchers from pkgs/build-support/. As an example going from bad to good:

  • Bad: Uses git:// which won't be proxied.

    src = fetchgit {
      url = "git@github.com:NixOS/nix.git"
      url = "git://github.com/NixOS/nix.git";
      rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
      hash = "sha256-7D4m+saJjbSFP5hOwpQq2FGR2rr+psQMTcyb1ZvtXsQ=";
    }
    
  • Better: This is ok, but an archive fetch will still be faster.

    src = fetchgit {
      url = "https://github.com/NixOS/nix.git";
      rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
      hash = "sha256-7D4m+saJjbSFP5hOwpQq2FGR2rr+psQMTcyb1ZvtXsQ=";
    }
    
  • Best: Fetches a snapshot archive and you get the rev you want.

    src = fetchFromGitHub {
      owner = "NixOS";
      repo = "nix";
      rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
      hash = "sha256-7D4m+saJjbSFP5hOwpQq2FGR2rr+psQMTcyb1ZvtXsQ=";
    }
    

When fetching from GitHub, commits must always be referenced by their full commit hash. This is because GitHub shares commit hashes among all forks and returns 404 Not Found when a short commit hash is ambiguous. It already happens for some short, 6-character commit hashes in nixpkgs. It is a practical vector for a denial-of-service attack by pushing large amounts of auto generated commits into forks and was already demonstrated against GitHub Actions Beta.

Find the value to put as hash by running nix-shell -p nix-prefetch-github --run "nix-prefetch-github --rev 1f795f9f44607cc5bec70d1300150bfefcef2aae NixOS nix".

Obtaining source hash

Preferred source hash type is sha256. There are several ways to get it.

  1. Prefetch URL (with nix-prefetch-XXX URL, where XXX is one of url, git, hg, cvs, bzr, svn). Hash is printed to stdout.

  2. Prefetch by package source (with nix-prefetch-url '<nixpkgs>' -A PACKAGE.src, where PACKAGE is package attribute name). Hash is printed to stdout.

    This works well when you've upgraded existing package version and want to find out new hash, but is useless if package can't be accessed by attribute or package has multiple sources (.srcs, architecture-dependent sources, etc).

  3. Upstream provided hash: use it when upstream provides sha256 or sha512 (when upstream provides md5, don't use it, compute sha256 instead).

    A little nuance is that nix-prefetch-* tools produce hash encoded with base32, but upstream usually provides hexadecimal (base16) encoding. Fetchers understand both formats. Nixpkgs does not standardize on any one format.

    You can convert between formats with nix-hash, for example:

    $ nix-hash --type sha256 --to-base32 HASH
    
  4. Extracting hash from local source tarball can be done with sha256sum. Use nix-prefetch-url file:///path/to/tarball if you want base32 hash.

  5. Fake hash: set the hash to one of

    • ""
    • lib.fakeHash
    • lib.fakeSha256
    • lib.fakeSha512

    in the package expression, attempt build and extract correct hash from error messages.

    Warning

    You must use one of these four fake hashes and not some arbitrarily-chosen hash. See here

    This is last resort method when reconstructing source URL is non-trivial and nix-prefetch-url -A isnt applicable (for example, one of kodi dependencies). The easiest way then would be replace hash with a fake one and rebuild. Nix build will fail and error message will contain desired hash.

Obtaining hashes securely

Let's say Man-in-the-Middle (MITM) sits close to your network. Then instead of fetching source you can fetch malware, and instead of source hash you get hash of malware. Here are security considerations for this scenario:

  • http:// URLs are not secure to prefetch hash from;

  • hashes from upstream (in method 3) should be obtained via secure protocol;

  • https:// URLs are secure in methods 1, 2, 3;

  • https:// URLs are secure in method 5 only if you use one of the listed fake hashes. If you use any other hash, fetchurl will pass --insecure to curl and may then degrade to HTTP in case of TLS certificate expiration.

Patches

Patches available online should be retrieved using fetchpatch.

patches = [
  (fetchpatch {
    name = "fix-check-for-using-shared-freetype-lib.patch";
    url = "http://git.ghostscript.com/?p=ghostpdl.git;a=patch;h=8f5d285";
    hash = "sha256-uRcxaCjd+WAuGrXOmGfFeu79cUILwkRdBu48mwcBE7g=";
  })
];

Otherwise, you can add a .patch file to the nixpkgs repository. In the interest of keeping our maintenance burden to a minimum, only patches that are unique to nixpkgs should be added in this way.

If a patch is available online but does not cleanly apply, it can be modified in some fixed ways by using additional optional arguments for fetchpatch. Check the fetchpatch reference for details.

patches = [ ./0001-changes.patch ];

If you do need to do create this sort of patch file, one way to do so is with git:

  1. Move to the root directory of the source code you're patching.

    $ cd the/program/source
    
  2. If a git repository is not already present, create one and stage all of the source files.

    $ git init
    $ git add .
    
  3. Edit some files to make whatever changes need to be included in the patch.

  4. Use git to create a diff, and pipe the output to a patch file:

    $ git diff -a > nixpkgs/pkgs/the/package/0001-changes.patch
    

Deprecating/removing packages

There is currently no policy when to remove a package.

Before removing a package, one should try to find a new maintainer or fix smaller issues first.

Steps to remove a package from Nixpkgs

We use jbidwatcher as an example for a discontinued project here.

  1. Have Nixpkgs checked out locally and up to date.

  2. Create a new branch for your change, e.g. git checkout -b jbidwatcher

  3. Remove the actual package including its directory, e.g. git rm -rf pkgs/applications/misc/jbidwatcher

  4. Remove the package from the list of all packages (pkgs/top-level/all-packages.nix).

  5. Add an alias for the package name in pkgs/top-level/aliases.nix (There is also pkgs/applications/editors/vim/plugins/aliases.nix. Package sets typically do not have aliases, so we can't add them there.)

    For example in this case:

    jbidwatcher = throw "jbidwatcher was discontinued in march 2021"; # added 2021-03-15
    

    The throw message should explain in short why the package was removed for users that still have it installed.

  6. Test if the changes introduced any issues by running nix-env -qaP -f . --show-trace. It should show the list of packages without errors.

  7. Commit the changes. Explain again why the package was removed. If it was declared discontinued upstream, add a link to the source.

    $ git add pkgs/applications/misc/jbidwatcher/default.nix pkgs/top-level/all-packages.nix pkgs/top-level/aliases.nix
    $ git commit
    

    Example commit message:

    jbidwatcher: remove
    
    project was discontinued in march 2021. the program does not work anymore because ebay changed the login.
    
    https://web.archive.org/web/20210315205723/http://www.jbidwatcher.com/
    
  8. Push changes to your GitHub fork with git push

  9. Create a pull request against Nixpkgs. Mention the package maintainer.

This is how the pull request looks like in this case: https://github.com/NixOS/nixpkgs/pull/116470

Package tests

To run the main types of tests locally:

  • Run package-internal tests with nix-build --attr pkgs.PACKAGE.passthru.tests
  • Run NixOS tests with nix-build --attr nixosTest.NAME, where NAME is the name of the test listed in nixos/tests/all-tests.nix
  • Run global package tests with nix-build --attr tests.PACKAGE, where PACKAGE is the name of the test listed in pkgs/test/default.nix
  • See lib/tests/NAME.nix for instructions on running specific library tests

Tests are important to ensure quality and make reviews and automatic updates easy.

The following types of tests exists:

  • NixOS module tests, which spawn one or more NixOS VMs. They exercise both NixOS modules and the packaged programs used within them. For example, a NixOS module test can start a web server VM running the nginx module, and a client VM running curl or a graphical firefox, and test that they can talk to each other and display the correct content.
  • Nix package tests are a lightweight alternative to NixOS module tests. They should be used to create simple integration tests for packages, but cannot test NixOS services, and some programs with graphical user interfaces may also be difficult to test with them.
  • The checkPhase of a package, which should execute the unit tests that are included in the source code of a package.

Here in the nixpkgs manual we describe mostly package tests; for module tests head over to the corresponding section in the NixOS manual.

Writing inline package tests

For very simple tests, they can be written inline:

{ , yq-go }:

buildGoModule rec {
  

  passthru.tests = {
    simple = runCommand "${pname}-test" {} ''
      echo "test: 1" | ${yq-go}/bin/yq eval -j > $out
      [ "$(cat $out | tr -d $'\n ')" = '{"test":1}' ]
    '';
  };
}

Writing larger package tests

This is an example using the phoronix-test-suite package with the current best practices.

Add the tests in passthru.tests to the package definition like this:

{ stdenv, lib, fetchurl, callPackage }:

stdenv.mkDerivation {
  

  passthru.tests = {
    simple-execution = callPackage ./tests.nix { };
  };

  meta = {  };
}

Create tests.nix in the package directory:

{ runCommand, phoronix-test-suite }:

let
  inherit (phoronix-test-suite) pname version;
in

runCommand "${pname}-tests" { meta.timeout = 60; }
  ''
    # automatic initial setup to prevent interactive questions
    ${phoronix-test-suite}/bin/phoronix-test-suite enterprise-setup >/dev/null
    # get version of installed program and compare with package version
    if [[ `${phoronix-test-suite}/bin/phoronix-test-suite version` != *"${version}"*  ]]; then
      echo "Error: program version does not match package version"
      exit 1
    fi
    # run dummy command
    ${phoronix-test-suite}/bin/phoronix-test-suite dummy_module.dummy-command >/dev/null
    # needed for Nix to register the command as successful
    touch $out
  ''

Running package tests

You can run these tests with:

$ cd path/to/nixpkgs
$ nix-build -A phoronix-test-suite.tests

Examples of package tests

Here are examples of package tests:

Linking NixOS module tests to a package

Like package tests as shown above, NixOS module tests can also be linked to a package, so that the tests can be easily run when changing the related package.

For example, assuming we're packaging nginx, we can link its module test via passthru.tests:

{ stdenv, lib, nixosTests }:

stdenv.mkDerivation {
  ...

  passthru.tests = {
    nginx = nixosTests.nginx;
  };

  ...
}

Reviewing contributions

Package updates

A package update is the most trivial and common type of pull request. These pull requests mainly consist of updating the version part of the package name and the source hash.

It can happen that non-trivial updates include patches or more complex changes.

Reviewing process:

  • Ensure that the package versioning fits the guidelines.
  • Ensure that the commit text fits the guidelines.
  • Ensure that the package maintainers are notified.
    • CODEOWNERS will make GitHub notify users based on the submitted changes, but it can happen that it misses some of the package maintainers.
  • Ensure that the meta field information is correct.
    • License can change with version updates, so it should be checked to match the upstream license.
    • If the package has no maintainer, a maintainer must be set. This can be the update submitter or a community member that accepts to take maintainership of the package.
  • Ensure that the code contains no typos.
  • Building the package locally.
    • pull requests are often targeted to the master or staging branch, and building the pull request locally when it is submitted can trigger many source builds.

    • It is possible to rebase the changes on nixos-unstable or nixpkgs-unstable for easier review by running the following commands from a nixpkgs clone.

      $ git fetch origin nixos-unstable
      $ git fetch origin pull/PRNUMBER/head
      $ git rebase --onto nixos-unstable BASEBRANCH FETCH_HEAD
      
      • The first command fetches the nixos-unstable branch.
      • The second command fetches the pull request changes, PRNUMBER is the number at the end of the pull request title and BASEBRANCH the base branch of the pull request.
      • The third command rebases the pull request changes to the nixos-unstable branch.
    • The nixpkgs-review tool can be used to review a pull request content in a single command. PRNUMBER should be replaced by the number at the end of the pull request title. You can also provide the full github pull request url.

      $ nix-shell -p nixpkgs-review --run "nixpkgs-review pr PRNUMBER"
      
  • Running every binary.

Sample template for a package update review is provided below.

##### Reviewed points

- [ ] package name fits guidelines
- [ ] package version fits guidelines
- [ ] package build on ARCHITECTURE
- [ ] executables tested on ARCHITECTURE
- [ ] all depending packages build
- [ ] patches have a comment describing either the upstream URL or a reason why the patch wasn't upstreamed
- [ ] patches that are remotely available are fetched rather than vendored

##### Possible improvements

##### Comments

New packages

New packages are a common type of pull requests. These pull requests consists in adding a new nix-expression for a package.

Review process:

  • Ensure that the package versioning fits the guidelines.
  • Ensure that the commit name fits the guidelines.
  • Ensure that the meta fields contain correct information.
    • License must match the upstream license.
    • Platforms should be set (or the package will not get binary substitutes).
    • Maintainers must be set. This can be the package submitter or a community member that accepts taking up maintainership of the package.
  • Report detected typos.
  • Ensure the package source:
    • Uses mirror URLs when available.
    • Uses the most appropriate functions (e.g. packages from GitHub should use fetchFromGitHub).
  • Building the package locally.
  • Running every binary.

Sample template for a new package review is provided below.

##### Reviewed points

- [ ] package path fits guidelines
- [ ] package name fits guidelines
- [ ] package version fits guidelines
- [ ] package build on ARCHITECTURE
- [ ] executables tested on ARCHITECTURE
- [ ] `meta.description` is set and fits guidelines
- [ ] `meta.license` fits upstream license
- [ ] `meta.platforms` is set
- [ ] `meta.maintainers` is set
- [ ] build time only dependencies are declared in `nativeBuildInputs`
- [ ] source is fetched using the appropriate function
- [ ] the list of `phases` is not overridden
- [ ] when a phase (like `installPhase`) is overridden it starts with `runHook preInstall` and ends with `runHook postInstall`.
- [ ] patches have a comment describing either the upstream URL or a reason why the patch wasn't upstreamed
- [ ] patches that are remotely available are fetched rather than vendored

##### Possible improvements

##### Comments

Security

Submitting security fixes

Security fixes are submitted in the same way as other changes and thus the same guidelines apply.

  • If a new version fixing the vulnerability has been released, update the package;

  • If the security fix comes in the form of a patch and a CVE is available, then add the patch to the Nixpkgs tree, and apply it to the package. The name of the patch should be the CVE identifier, so e.g. CVE-2019-13636.patch; If a patch is fetched the name needs to be set as well, e.g.:

    (fetchpatch {
      name = "CVE-2019-11068.patch";
      url = "https://gitlab.gnome.org/GNOME/libxslt/commit/e03553605b45c88f0b4b2980adfbbb8f6fca2fd6.patch";
      hash = "sha256-SEKe/8HcW0UBHCfPTTOnpRlzmV2nQPPeL6HOMxBZd14=";
    })
    

If a security fix applies to both master and a stable release then, similar to regular changes, they are preferably delivered via master first and cherry-picked to the release branch.

Critical security fixes may by-pass the staging branches and be delivered directly to release branches such as master and release-*.

Vulnerability Roundup

Issues

Vulnerable packages in Nixpkgs are managed using issues. Currently opened ones can be found using the following:

github.com/NixOS/nixpkgs/issues?q=is:issue+is:open+"Vulnerability+roundup"

Each issue correspond to a vulnerable version of a package; As a consequence:

  • One issue can contain several CVEs;
  • One CVE can be shared across several issues;
  • A single package can be concerned by several issues.

A "Vulnerability roundup" issue usually respects the following format:

<link to relevant package search on search.nix.gsc.io>, <link to relevant files in Nixpkgs on GitHub>

<list of related CVEs, their CVSS score, and the impacted NixOS version>

<list of the scanned Nixpkgs versions>

<list of relevant contributors>

Note that there can be an extra comment containing links to previously reported (and still open) issues for the same package.

Triaging and Fixing

Note: An issue can be a "false positive" (i.e. automatically opened, but without the package it refers to being actually vulnerable). If you find such a "false positive", comment on the issue an explanation of why it falls into this category, linking as much information as the necessary to help maintainers double check.

If you are investigating a "true positive":