Skip to content

maintainers/scripts/update: Allow updating in (reverse) topological order#386490

Merged
jtojnar merged 10 commits intoNixOS:masterfrom
jtojnar:update-topo
Mar 11, 2025
Merged

maintainers/scripts/update: Allow updating in (reverse) topological order#386490
jtojnar merged 10 commits intoNixOS:masterfrom
jtojnar:update-topo

Conversation

@jtojnar
Copy link
Member

@jtojnar jtojnar commented Mar 2, 2025

Previously, when updating multiple packages, we just updated them in arbitrary order. However, when some of those packages depended on each other, it could happen that some of the intermediary commits would not build because of version constraints on dependencies.

If we want each commit in the history to build when feasible, we need to consider four different scenarios:

  1. Updated dependant is compatible with both the old and the new version of the dependency. Order of commits does not matter. But updating dependents first (i.e. reverse topological order) is useful since it allows building each package on the commit that updates it with minimal rebuilds.
  2. Updated dependant raises the minimal dependency version. Dependency needs to be updated first (i.e. topological order).
  3. Old dependant sets the maximal dependency version. Dependant needs to be updated first (i.e. reverse topological order).
  4. Updated dependant depends on exact version of dependency and they are expected to be updated in lockstep. The earlier commit will be broken no matter the order.

This change allows selecting the order of updates to facilitate the first three scenarios. Since most package sets only have loose version constraints, the reverse topological order will generally be the most convenient. In major package set updates like bumping GNOME release, there will be exceptions (e.g. libadwaita typically requires GTK 4 from the same release) but those were probably in broken order before as well.

The downside of this feature is that it is quite slow – it requires instantiating each package and then querying Nix store for requisites.
It may also fail to detect dependency if there are multiple variants of the package and dependant uses a different one than the canonical one.

Testing with:

env GNOME_UPDATE_STABILITY=unstable NIX_PATH=nixpkgs=$HOME/Projects/nixpkgs nix-shell maintainers/scripts/update.nix --arg predicate '(path: pkg: path == ["gnome-shell"] || path == ["mutter"] || path == ["glib"] || path == ["gtk3"] || path == ["pango"] || path == ["gnome-text-editor"])' --argstr order reverse-topological --argstr commit true --argstr max-workers 4

Also include some cleanups of the Python script and some fixes of update scripts that were required for updating GNOME to work.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 25.05 Release Notes (or backporting 24.11 and 25.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

@jtojnar jtojnar requested a review from bobby285271 March 2, 2025 22:05
@github-actions github-actions bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux. labels Mar 2, 2025
@jtojnar jtojnar force-pushed the update-topo branch 2 times, most recently from 8a58f2e to 0e53ba5 Compare March 2, 2025 23:37
@github-actions github-actions bot added 6.topic: GNOME GNOME desktop environment and its underlying platform 6.topic: updaters Tooling for (semi-)automated updating of packages labels Mar 2, 2025
jtojnar added 5 commits March 3, 2025 00:46
…ot one

This can happen e.g. due to an error during `merge_changes` since we do not do `stderr=PIPE` for git commands.
…straint

We only allow a single value for `attrPath` across all sequenced update scripts.
But previously `null` (representing `passthru.updateScript.attrPath` not being defined) was counted as one value.
This would prevent us from explicitly specifying `attrPath` in `gnome.updateScript` in the next commit.

Let’s ignore update scripts without specified `attrPath` attribute for the purpose of this check.
Without this, `update.nix` will discover `libxml2` as `emscriptenPackages.libxml2`.
But since that instantiates a different, and much less common derivation,
it will be erroneously considered a leaf package in topological order of packages.
Just minor refactorings:

- Extract `updater_tasks` into a variable.
- Make `main` itself async.
…rder

Previously, when updating multiple packages, we just updated them in arbitrary order. However, when some of those packages depended on each other, it could happen that some of the intermediary commits would not build because of version constraints on dependencies.

If we want each commit in the history to build when feasible, we need to consider four different scenarios:

1. Updated dependant is compatible with both the old and the new version of the dependency. Order of commits does not matter. But updating dependents first (i.e. reverse topological order) is useful since it allows building each package on the commit that updates it with minimal rebuilds.
2. Updated dependant raises the minimal dependency version. Dependency needs to be updated first (i.e. topological order).
3. Old dependant sets the maximal dependency version. Dependant needs to be updated first (i.e. reverse topological order).
4. Updated dependant depends on exact version of dependency and they are expected to be updated in lockstep. The earlier commit will be broken no matter the order.

This change allows selecting the order of updates to facilitate the first three scenarios. Since most package sets only have loose version constraints, the reverse topological order will generally be the most convenient. In major package set updates like bumping GNOME release, there will be exceptions (e.g. libadwaita typically requires GTK 4 from the same release) but those were probably in broken order before as well.

The downside of this feature is that it is quite slow – it requires instantiating each package and then querying Nix store for requisites.
It may also fail to detect dependency if there are multiple variants of the package and dependant uses a different one than the canonical one.

Testing with:

    env GNOME_UPDATE_STABILITY=unstable NIX_PATH=nixpkgs=$HOME/Projects/nixpkgs nix-shell maintainers/scripts/update.nix --arg predicate '(path: pkg: path == ["gnome-shell"] || path == ["mutter"] || path == ["glib"] || path == ["gtk3"] || path == ["pango"] || path == ["gnome-text-editor"])' --argstr order reverse-topological --argstr commit true --argstr max-workers 4
@jtojnar jtojnar mentioned this pull request Mar 3, 2025
@jtojnar jtojnar moved this to To Do in GNOME 48 Mar 11, 2025
@jtojnar jtojnar added this to GNOME 48 Mar 11, 2025
@jtojnar
Copy link
Member Author

jtojnar commented Mar 11, 2025

Examples of where reverse topological order failed in #386514 due to bumped min version in the dependent:

  • libadwaita
    • snapshot
    • gnome-calendar
    • gnome-maps
  • gtk4
    • g-i-s
    • x-d-p-g
    • gtksourceview_5
    • gtkmm4
  • glib
    • glibmm
    • gvfs
  • vte
    • gnome-terminal
  • e-d-s:
    • evo

Not much we can do about that without analysing sources or build outputs.


Examples where the dependency was incorrectly detected:

  • sysprof should come after glib (due to libsysprof-capture)

We could collect alternative attr names when uniqueing them but so far it has not been so common as to bother me into implementing that.

@jtojnar jtojnar merged commit 1238304 into NixOS:master Mar 11, 2025
36 of 37 checks passed
@jtojnar jtojnar deleted the update-topo branch March 11, 2025 10:28
@github-project-automation github-project-automation bot moved this from To Do to Done in GNOME 48 Mar 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: GNOME GNOME desktop environment and its underlying platform 6.topic: updaters Tooling for (semi-)automated updating of packages 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant