diff options
author | Travis A. Everett <travis.a.everett@gmail.com> | 2024-06-11 03:51:03 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-11 10:51:03 +0200 |
commit | 9ff9bbdb34236dc00362a81da5d8985d275633d1 (patch) | |
tree | d836dfd8a82f6e5804ef7328572fe4b871b043b6 /pkgs/README.md | |
parent | dbd21091275939591b241987b1e2176554de246c (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.md | 174 |
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 |