{ writeShellApplication , jq , curl , lib , release ? "25.05" , channels ? [ { name = "nixos-${release}"; input = "nixpkgs"; } { name = "nixos-unstable"; input = "nixos-unstable"; } ] , flakeFile ? "flake.nix" , lockFile ? "flake.lock" }: writeShellApplication { name = "nixos-updater"; runtimeInputs = [ jq curl ]; text = '' FLAKE_FILE="${flakeFile}" LOCK_FILE="${lockFile}" update_channel() { local channel_name="$1" local flake_input_name="$2" local new old echo "Checking channel: $channel_name -> $flake_input_name..." # Get latest revision from Hydra new=$(curl -sL "https://monitoring.nixos.org/prometheus/api/v1/query?query=channel_revision" | jq -r ".data.result[] | select(.metric.channel==\"$channel_name\") | .metric.revision") if [ -z "$new" ]; then echo "Failed to get revision for $channel_name" return 1 fi # Get current revision from flake.lock old=$(jq -r ".nodes as \$nodes | .nodes.root.inputs[\"$flake_input_name\"] as \$target_input | \$nodes | to_entries[] | select(.key == \$target_input) | .value.locked.rev" "$LOCK_FILE") if [ "$old" = "$new" ]; then echo "No update needed for $flake_input_name" return 0 fi # Update the flake.nix file sed -i "s|\($flake_input_name\.url = \"github:NixOS/nixpkgs/\)[^\"]*|\1$new|" "$FLAKE_FILE" echo "Updated $flake_input_name: $old -> $new" return 0 } # Process channels based on parameters ${lib.concatMapStringsSep "\n" (channel: '' update_channel "${channel.name}" "${channel.input}" '') channels} ''; }