about summary refs log tree commit diff
path: root/pkgs/README.md
diff options
context:
space:
mode:
authorTravis A. Everett <travis.a.everett@gmail.com>2024-06-11 03:51:03 -0500
committerGitHub <noreply@github.com>2024-06-11 10:51:03 +0200
commit9ff9bbdb34236dc00362a81da5d8985d275633d1 (patch)
treed836dfd8a82f6e5804ef7328572fe4b871b043b6 /pkgs/README.md
parentdbd21091275939591b241987b1e2176554de246c (diff)
doc: add stdenv passthru chapter (#315909)
* doc: add stdenv passthru chapter

Broad strokes:
- create the chapter
- move existing stdenv passthru coverage into it
- move out-of-place coverage of passthru.tests from the stdenv meta chapter into it
- (try to) apply 1-sentence-per-line to text I've touched
- add legacy anchors for everything moved
- update existing links to the new anchors
- add tentative motivating text
- make nixpkgs-internal links relative/branchless

razor: if it is only ever needed by contributors, which is likely if links
refer to the latest revision of the source code, then it's for
the contributor guide

Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
Diffstat (limited to 'pkgs/README.md')
-rw-r--r--pkgs/README.md174
1 files changed, 174 insertions, 0 deletions
diff --git a/pkgs/README.md b/pkgs/README.md
index 0087439d04d4c..7c79931ae4452 100644
--- a/pkgs/README.md
+++ b/pkgs/README.md
@@ -599,6 +599,34 @@ buildGoModule rec {
 }
 ```
 
+Any derivaton can be specified as a test, even if it's in a different file.
+Such a derivaton that implements a test can depend on the package under test, even in the presence of `overrideAttrs`.
+
+In the following example, `(my-package.overrideAttrs f).passthru.tests` will work as expected, as long as the definition of `tests` does not rely on the original `my-package` or overrides all occurrences of `my-package`:
+
+```nix
+# my-package/default.nix
+{ stdenv, callPackage }:
+stdenv.mkDerivation (finalAttrs: {
+  # ...
+  passthru.tests.example = callPackage ./example.nix { my-package = finalAttrs.finalPackage; };
+})
+```
+
+```nix
+# my-package/example.nix
+{ runCommand, lib, my-package, ... }:
+runCommand "my-package-test" {
+  nativeBuildInputs = [ my-package ];
+  src = lib.sources.sourcesByRegex ./. [ ".*.in" ".*.expected" ];
+} ''
+  my-package --help
+  my-package <example.in >example.actual
+  diff -U3 --color=auto example.expected example.actual
+  mkdir $out
+''
+```
+
 ### Writing larger package tests
 [larger-package-tests]: #writing-larger-package-tests
 
@@ -684,6 +712,152 @@ stdenv.mkDerivation {
 }
 ```
 
+## Automatic package updates
+[automatic-package-updates]: #automatic-package-updates
+
+Nixpkgs periodically tries to update all packages that have a `passthru.updateScript` attribute.
+
+> [!Note]
+> A common pattern is to use the [`nix-update-script`](../pkgs/common-updater/nix-update.nix) attribute provided in Nixpkgs, which runs [`nix-update`](https://github.com/Mic92/nix-update):
+>
+> ```nix
+> { stdenv, nix-update-script }:
+> stdenv.mkDerivation {
+>   # ...
+>   passthru.updateScript = nix-update-script { };
+> }
+> ```
+>
+> For simple packages, this is often enough, and will ensure that the package is updated automatically by [`nixpkgs-update`](https://ryantm.github.io/nixpkgs-update) when a new version is released.
+> The [update bot](https://nix-community.org/update-bot) runs periodically to attempt to automatically update packages, and will run `passthru.updateScript` if set.
+> While not strictly necessary if the project is listed on [Repology](https://repology.org), using `nix-update-script` allows the package to update via many more sources (e.g. GitHub releases).
+
+The `passthru.updateScript` attribute can contain one of the following:
+
+- an executable file, either on the file system:
+
+  ```nix
+  { stdenv }:
+  stdenv.mkDerivation {
+    # ...
+    passthru.updateScript = ./update.sh;
+  }
+  ```
+
+  or inside the expression itself:
+
+  ```nix
+  { stdenv, writeScript }:
+  stdenv.mkDerivation {
+    # ...
+    passthru.updateScript = writeScript "update-zoom-us" ''
+      #!/usr/bin/env nix-shell
+      #!nix-shell -i bash -p curl pcre2 common-updater-scripts
+
+      set -eu -o pipefail
+
+      version="$(curl -sI https://zoom.us/client/latest/zoom_x86_64.tar.xz | grep -Fi 'Location:' | pcre2grep -o1 '/(([0-9]\.?)+)/')"
+      update-source-version zoom-us "$version"
+    '';
+  }
+  ```
+
+- a list, a script file followed by arguments to be passed to it:
+
+  ```nix
+  { stdenv }:
+  stdenv.mkDerivation {
+    # ...
+    passthru.updateScript = [ ../../update.sh pname "--requested-release=unstable" ];
+  }
+  ```
+
+- an attribute set containing:
+  - `command`
+
+    A string or list in the [format expected by `passthru.updateScript`][automatic-package-updates]
+
+  - `attrPath` (optional)
+
+    A string containing the canonical attribute path for the package.
+
+    If present, it will be passed to the update script instead of the attribute path on which the package was discovered during Nixpkgs traversal.
+
+  - `supportedFeatures` (optional)
+
+    A list of the [extra features the script supports][supported-features].
+
+    ```nix
+    { stdenv }:
+    stdenv.mkDerivation rec {
+      pname = "my-package";
+      # ...
+      passthru.updateScript = {
+        command = [ ../../update.sh pname ];
+        attrPath = pname;
+        supportedFeatures = [ /* ... */ ];
+      };
+    }
+    ```
+
+### How are update scripts executed?
+
+Update scripts are to be invoked by the [automatic package update script](../maintainers/scripts/update.nix).
+You can run `nix-shell maintainers/scripts/update.nix` in the root of Nixpkgs repository for information on how to use it.
+`update.nix` offers several modes for selecting packages to update, and it will execute update scripts for all matched packages that have an `updateScript` attribute.
+
+Each update script will be passed the following environment variables:
+
+- [`UPDATE_NIX_NAME`] – content of the `name` attribute of the updated package
+- [`UPDATE_NIX_PNAME`] – content of the `pname` attribute of the updated package
+- [`UPDATE_NIX_OLD_VERSION`] – content of the `version` attribute of the updated package
+- [`UPDATE_NIX_ATTR_PATH`] – attribute path the `update.nix` discovered the package on (or the package's specified `attrPath` when available). Example: `pantheon.elementary-terminal`
+
+> [!Note]
+> An update script will be usually run from the root of the Nixpkgs repository, but you should not rely on that.
+> Also note that `update.nix` executes update scripts in parallel by default, so you should avoid running `git commit` or any other commands that cannot handle that.
+
+While update scripts should not create commits themselves, `update.nix` supports automatically creating commits when running it with `--argstr commit true`.
+If you need to customize commit message, you can have the update script implement the `commit` feature.
+
+### Supported features
+[update-script-supported-features]: #supported-features
+
+- `commit`
+
+  This feature allows update scripts to *ask* `update.nix` to create Git commits.
+
+  When support of this feature is declared, whenever the update script exits with `0` return status, it is expected to print a JSON list containing an object described below for each updated attribute to standard output.
+  Example:
+
+  ```json
+  [
+    {
+      "attrPath": "volume_key",
+      "oldVersion": "0.3.11",
+      "newVersion": "0.3.12",
+      "files": [
+        "/path/to/nixpkgs/pkgs/development/libraries/volume-key/default.nix"
+      ]
+    }
+  ]
+  ```
+  :::
+
+  When `update.nix` is run with `--argstr commit true`, it will create a separate commit for each of the objects.
+  An empty list can be returned when the script did not update any files; for example, when the package is already at the latest version.
+
+  The commit object contains the following values:
+
+  - `attrPath` – a string containing the attribute path
+  - `oldVersion` – a string containing the old version
+  - `newVersion` – a string containing the new version
+  - `files` – a non-empty list of file paths (as strings) to add to the commit
+  - `commitBody` (optional) – a string with extra content to be appended to the default commit message (useful for adding changelog links)
+  - `commitMessage` (optional) – a string to use instead of the default commit message
+
+  If the returned list contains exactly one object (e.g. `[{}]`), all values are optional and will be determined automatically.
+
 ## Reviewing contributions
 
 ### Package updates