Commit 38d37962cad1
Changed files (7)
modules
nixpkgs-consolidate
pkgs
systems
aomi
tools
nixpkgs-consolidate
modules/nixpkgs-consolidate/default.nix
@@ -1,132 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-
-with lib;
-
-let
- cfg = config.services.nixpkgs-consolidate;
-
- consolidateScript = pkgs.writeShellScript "nixpkgs-consolidate-wrapper" ''
- set -euo pipefail
-
- export NIXPKGS_REPO_PATH="${cfg.repoPath}"
- export NIXPKGS_WORKTREE_PATH="${cfg.worktreePath}"
- export NIXPKGS_CONFIG_FILE="${cfg.configFile}"
- export NTFY_TOKEN_FILE="${cfg.ntfyTokenFile}"
- export LOG_DIR="${cfg.logDir}"
-
- exec ${pkgs.nixpkgs-consolidate}/bin/nixpkgs-consolidate
- '';
-in
-{
- options.services.nixpkgs-consolidate = {
- enable = mkEnableOption "automated nixpkgs branch consolidation";
-
- repoPath = mkOption {
- type = types.str;
- default = "/home/vincent/src/nixpkgs";
- description = "Path to nixpkgs repository";
- };
-
- worktreePath = mkOption {
- type = types.str;
- default = "/home/vincent/src/nixpkgs-consolidate-work";
- description = "Path to worktree for consolidation work";
- };
-
- configFile = mkOption {
- type = types.str;
- default = "/home/vincent/.config/nixpkgs-automation/branches.conf";
- description = "Path to branches configuration file";
- };
-
- schedule = mkOption {
- type = types.str;
- default = "daily";
- example = "Mon,Thu *-*-* 02:00:00";
- description = ''
- Systemd timer schedule (OnCalendar format).
- Use "daily", "weekly", or systemd calendar syntax.
- '';
- };
-
- user = mkOption {
- type = types.str;
- default = "vincent";
- description = "User to run consolidation as (needs git access)";
- };
-
- ntfyTokenFile = mkOption {
- type = types.str;
- default = "/run/agenix/ntfy-token";
- description = "Path to ntfy authentication token";
- };
-
- logDir = mkOption {
- type = types.str;
- default = "/var/log/nixpkgs-consolidate";
- description = "Directory for log files";
- };
-
- randomizedDelaySec = mkOption {
- type = types.int;
- default = 1800; # 30 minutes
- description = "Random delay in seconds before starting";
- };
- };
-
- config = mkIf cfg.enable {
- systemd.services.nixpkgs-consolidate = {
- description = "Nixpkgs branch consolidation automation";
-
- serviceConfig = {
- Type = "oneshot";
- User = cfg.user;
- ExecStart = "${consolidateScript}";
- Environment = ''"GIT_SSH_COMMAND=ssh -o ControlMaster=no"'';
-
- # Security hardening
- PrivateTmp = true;
- ProtectSystem = "strict";
- ProtectHome = "false"; # Need full access to home for git operations
- ReadWritePaths = [
- cfg.repoPath
- cfg.worktreePath
- cfg.logDir
- ];
- NoNewPrivileges = true;
-
- # Logging
- StandardOutput = "journal";
- StandardError = "journal";
- SyslogIdentifier = "nixpkgs-consolidate";
- };
-
- # Trigger notification on failure
- unitConfig.OnFailure = [ "job-notify@%n.service" ];
- };
-
- systemd.timers.nixpkgs-consolidate = {
- description = "Timer for nixpkgs branch consolidation";
- wantedBy = [ "timers.target" ];
-
- timerConfig = {
- OnCalendar = cfg.schedule;
- RandomizedDelaySec = cfg.randomizedDelaySec;
- Persistent = true;
- };
- };
-
- # Ensure directories exist
- systemd.tmpfiles.rules = [
- "d ${cfg.logDir} 0750 ${cfg.user} users -"
- "d ${cfg.repoPath} 0750 ${cfg.user} users -"
- "d ${cfg.worktreePath} 0750 ${cfg.user} users -"
- "d ${builtins.dirOf cfg.configFile} 0755 ${cfg.user} users -"
- ];
- };
-}
pkgs/default.nix
@@ -34,7 +34,6 @@ in
music-playlist-dl = pkgs.callPackage ../tools/music-playlist-dl { };
nix-flake-update = pkgs.callPackage ../tools/nix-flake-update { };
slack-archive = pkgs.callPackage ../tools/slack-archive { };
- nixpkgs-consolidate = pkgs.callPackage ../tools/nixpkgs-consolidate { };
gcal-to-org = pkgs.callPackage ../tools/gcal-to-org { };
review-tool = pkgs.callPackage ../tools/review-tool { };
beets-lidarr-fields = pkgs.python3Packages.callPackage ./beets-lidarr-fields { };
systems/aomi/extra.nix
@@ -32,7 +32,6 @@
# Remote build system
../../modules/job-notify
- ../../modules/nixpkgs-consolidate
../../modules/microshift
# Binary cache
@@ -129,15 +128,6 @@
defaultTopic = "builds";
};
- # Nixpkgs WIP branch consolidation automation
- services.nixpkgs-consolidate = {
- enable = true;
- user = "vincent";
- schedule = "daily";
- ntfyTokenFile = config.age.secrets."ntfy-token".path;
- configFile = "/home/vincent/.config/nixpkgs-automation/branches.conf";
- };
-
# XMPP Research Bot (uses Vertex AI for Claude, direct API for Gemini)
services.xmpp-research-bot = {
enable = true;
tools/nixpkgs-consolidate/branches.conf.example
@@ -1,72 +0,0 @@
-# Nixpkgs Branch Consolidation Configuration
-#
-# This file defines which branches to consolidate into a single branch.
-# Copy this file to ~/.config/nixpkgs-automation/branches.conf and customize.
-#
-# Usage:
-# mkdir -p ~/.config/nixpkgs-automation
-# cp tools/nixpkgs-consolidate/branches.conf.example \
-# ~/.config/nixpkgs-automation/branches.conf
-# vim ~/.config/nixpkgs-automation/branches.conf
-
-# Base Branch Configuration
-# -------------------------
-# The first non-comment line starting with "base:" defines the upstream base branch.
-# This is the branch that your WIP branches will be cherry-picked on top of.
-#
-# Common choices:
-# - nixos-unstable: Rolling release, most up-to-date packages
-# - master: Main development branch
-# - nixos-24.11: Stable release branch
-
-base: nixos-unstable
-
-# WIP Branches to Consolidate
-# ----------------------------
-# List your work-in-progress branches below, one per line.
-# Branches will be cherry-picked in the order listed.
-#
-# Branch names should match branches in your fork remote (typically 'origin').
-# These branches should exist at: git@github.com:yourusername/nixpkgs.git
-#
-# Naming conventions (recommended):
-# - wip-<feature-name>: Work in progress features
-# - pr-<number>-<description>: Branches for open pull requests
-# - fix-<issue>: Bug fixes
-#
-# Examples:
-
-# wip-package-update-foo
-# wip-fix-bar-build
-# pr-12345-add-new-service
-# fix-python-package-build
-
-# Guidelines:
-# -----------
-# 1. Order matters: Branches are cherry-picked in listed order
-# 2. Keep it clean: Remove branches after PRs are merged upstream
-# 3. Test first: Use DRY_RUN=true to test before actual push
-# 4. Watch for conflicts: Script will abort if cherry-pick conflicts occur
-#
-# Environment Variables:
-# ---------------------
-# You can override defaults with environment variables:
-#
-# NIXPKGS_REPO_PATH - Where nixpkgs is cloned (default: ~/src/nixpkgs)
-# NIXPKGS_WORKTREE_PATH - Worktree for consolidation work
-# NIXPKGS_UPSTREAM_REMOTE - Upstream remote name (default: upstream)
-# NIXPKGS_FORK_REMOTE - Your fork remote name (default: origin)
-# NIXPKGS_CONSOLIDATED_BRANCH - Output branch name (default: wip-consolidated)
-# DRY_RUN - Set to "true" to test without pushing
-#
-# Example with custom settings:
-# NIXPKGS_CONSOLIDATED_BRANCH=personal-main \
-# DRY_RUN=true \
-# nixpkgs-consolidate
-
-# Your WIP Branches
-# -----------------
-# Add your branches below (uncomment and modify as needed):
-
-# wip-my-feature
-# pr-54321-awesome-package
tools/nixpkgs-consolidate/default.nix
@@ -1,53 +0,0 @@
-{
- lib,
- stdenv,
- makeWrapper,
- git,
- curl,
- coreutils,
- openssh,
-}:
-
-stdenv.mkDerivation {
- pname = "nixpkgs-consolidate";
- version = "1.0.0";
-
- src = ./.;
-
- nativeBuildInputs = [ makeWrapper ];
-
- dontUnpack = true;
- dontBuild = true;
-
- installPhase = ''
- runHook preInstall
-
- mkdir -p $out/bin
- cp ${./nixpkgs-consolidate.sh} $out/bin/nixpkgs-consolidate
- chmod +x $out/bin/nixpkgs-consolidate
-
- # Patch shebang
- patchShebangs $out/bin/nixpkgs-consolidate
-
- # Wrap with runtime dependencies
- wrapProgram $out/bin/nixpkgs-consolidate \
- --prefix PATH : ${
- lib.makeBinPath [
- git
- curl
- coreutils
- openssh
- ]
- }
-
- runHook postInstall
- '';
-
- meta = with lib; {
- description = "Consolidate multiple nixpkgs WIP branches into a single branch";
- homepage = "https://github.com/vdemeester/home";
- license = licenses.mit;
- platforms = platforms.unix;
- mainProgram = "nixpkgs-consolidate";
- };
-}
tools/nixpkgs-consolidate/nixpkgs-consolidate.sh
@@ -1,394 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-# Nixpkgs Branch Consolidation Tool
-# Consolidates multiple WIP/PR branches into a single consolidated branch via cherry-picking
-# Uses git worktrees to avoid interfering with main repository
-
-# Configuration from environment or defaults
-NIXPKGS_REPO_PATH="${NIXPKGS_REPO_PATH:-/home/vincent/src/nixpkgs}"
-NIXPKGS_WORKTREE_PATH="${NIXPKGS_WORKTREE_PATH:-/home/vincent/src/nixpkgs-consolidate-work}"
-NIXPKGS_UPSTREAM_REMOTE="${NIXPKGS_UPSTREAM_REMOTE:-upstream}"
-NIXPKGS_FORK_REMOTE="${NIXPKGS_FORK_REMOTE:-origin}"
-NIXPKGS_FORK_URL="${NIXPKGS_FORK_URL:-git@github.com:vdemeester/nixpkgs.git}"
-NIXPKGS_UPSTREAM_URL="${NIXPKGS_UPSTREAM_URL:-https://github.com/NixOS/nixpkgs.git}"
-NIXPKGS_CONSOLIDATED_BRANCH="${NIXPKGS_CONSOLIDATED_BRANCH:-wip-consolidated}"
-NIXPKGS_CONFIG_FILE="${NIXPKGS_CONFIG_FILE:-$HOME/.config/nixpkgs-automation/branches.conf}"
-HOME_FLAKE_PATH="${HOME_FLAKE_PATH:-/home/vincent/src/home}"
-NTFY_SERVER="${NTFY_SERVER:-https://ntfy.sbr.pm}"
-NTFY_TOPIC="${NTFY_TOPIC:-git-builds}"
-NTFY_TOKEN_FILE="${NTFY_TOKEN_FILE:-/run/agenix/ntfy-token}"
-LOG_DIR="${LOG_DIR:-/var/log/nixpkgs-consolidate}"
-DRY_RUN="${DRY_RUN:-false}"
-
-# Global state variables
-BASE_BRANCH=""
-WIP_BRANCHES=()
-TOTAL_COMMITS=0
-COMPLETED_BRANCHES=()
-FAILED_BRANCH=""
-
-# Setup logging
-LOG_FILE="$LOG_DIR/$(date +%Y%m%d-%H%M%S).log"
-mkdir -p "$LOG_DIR"
-
-log() {
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
-}
-
-notify() {
- local priority="$1"
- local title="$2"
- local message="$3"
- local tags="$4"
-
- if [ -f "$NTFY_TOKEN_FILE" ]; then
- curl -s \
- -H "Authorization: Bearer $(tr -d '\n' < "$NTFY_TOKEN_FILE")" \
- -H "Title: $title" \
- -H "Priority: $priority" \
- -H "Tags: $tags" \
- -d "$message" \
- "$NTFY_SERVER/$NTFY_TOPIC" || true
- else
- log "WARNING: ntfy token file not found at $NTFY_TOKEN_FILE, skipping notification"
- fi
-}
-
-cleanup() {
- local exit_code=$?
-
- # Note: We intentionally do NOT remove the worktree here
- # It will be reused on the next run, avoiding "Device or resource busy" issues
- # The worktree will be cleaned up automatically by setup_worktree() on next run
-
- if [ $exit_code -ne 0 ]; then
- log "ERROR: Consolidation failed with exit code $exit_code"
-
- # Build completed branches string
- local completed_str=""
- if [ ${#COMPLETED_BRANCHES[@]} -gt 0 ]; then
- completed_str=$(IFS=", "; echo "${COMPLETED_BRANCHES[*]}")
- else
- completed_str="(none)"
- fi
-
- # Send failure notification
- local failure_msg="Rebase conflict or error during consolidation
-
-Base: $BASE_BRANCH
-Completed: $completed_str
-Failed at: ${FAILED_BRANCH:-unknown}
-
-Logs: $LOG_FILE"
-
- notify "high" \
- "❌ Nixpkgs Consolidation Failed" \
- "$failure_msg" \
- "x,warning,git,nixpkgs"
- fi
-}
-
-trap cleanup EXIT
-
-detect_home_nixpkgs_rev() {
- if [ ! -f "$HOME_FLAKE_PATH/flake.lock" ]; then
- return 1
- fi
-
- # Try to extract the main "nixpkgs" input revision from flake.lock using jq
- # This specifically targets the "nixpkgs" node which should track nixos-unstable
- if command -v jq >/dev/null 2>&1; then
- local rev
- # Get the revision for the nixpkgs node (not nixpkgs-master, nixpkgs-wip-consolidated, etc.)
- rev=$(jq -r '.nodes.nixpkgs.locked.rev // empty' "$HOME_FLAKE_PATH/flake.lock" 2>/dev/null)
-
- if [ -n "$rev" ]; then
- echo "$rev"
- return 0
- fi
- fi
-
- # Fallback: try nix flake metadata (slower but more reliable)
- if command -v nix >/dev/null 2>&1; then
- local rev
- rev=$(nix flake metadata "$HOME_FLAKE_PATH" --json 2>/dev/null | \
- jq -r '.locks.nodes.nixpkgs.locked.rev // empty' 2>/dev/null)
-
- if [ -n "$rev" ]; then
- echo "$rev"
- return 0
- fi
- fi
-
- return 1
-}
-
-parse_config() {
- log "Reading configuration from $NIXPKGS_CONFIG_FILE"
-
- if [ ! -f "$NIXPKGS_CONFIG_FILE" ]; then
- log "ERROR: Configuration file not found: $NIXPKGS_CONFIG_FILE"
- echo "Please create a configuration file at $NIXPKGS_CONFIG_FILE"
- echo "See tools/nixpkgs-consolidate/branches.conf.example for an example"
- exit 1
- fi
-
- # Parse configuration file
- while IFS= read -r line || [ -n "$line" ]; do
- # Skip comments and empty lines
- [[ "$line" =~ ^[[:space:]]*# ]] && continue
- [[ -z "${line// }" ]] && continue
-
- # Extract base branch (line starting with "base:")
- if [[ "$line" =~ ^base:[[:space:]]*(.*) ]]; then
- BASE_BRANCH="${BASH_REMATCH[1]}"
- log "Base branch from config: $BASE_BRANCH"
- continue
- fi
-
- # Otherwise it's a WIP branch
- branch=$(echo "$line" | tr -d ' ')
- if [ -n "$branch" ]; then
- WIP_BRANCHES+=("$branch")
- fi
- done < "$NIXPKGS_CONFIG_FILE"
-
- # Validate configuration
- if [ -z "$BASE_BRANCH" ]; then
- log "ERROR: No base branch defined in config (should start with 'base:')"
- exit 1
- fi
-
- # Try to detect and use home flake nixpkgs revision
- log "Attempting to detect nixpkgs revision from home flake at $HOME_FLAKE_PATH"
- local detected_rev
- if detected_rev=$(detect_home_nixpkgs_rev); then
- log "✓ Detected nixpkgs revision from home flake: $detected_rev"
- log "Using detected revision as base (overriding config: $BASE_BRANCH)"
- BASE_BRANCH="$detected_rev"
- else
- log "Could not detect nixpkgs revision from home flake"
- log "Using configured base branch: $BASE_BRANCH"
- fi
-
- if [ ${#WIP_BRANCHES[@]} -eq 0 ]; then
- log "WARNING: No WIP branches defined in config"
- log "Nothing to consolidate, exiting"
- exit 0
- fi
-
- log "WIP branches (${#WIP_BRANCHES[@]}): ${WIP_BRANCHES[*]}"
-}
-
-ensure_repo() {
- if [ ! -d "$NIXPKGS_REPO_PATH/.git" ]; then
- log "Repository not found at $NIXPKGS_REPO_PATH"
- log "Cloning from fork: $NIXPKGS_FORK_URL"
-
- mkdir -p "$(dirname "$NIXPKGS_REPO_PATH")"
- git clone "$NIXPKGS_FORK_URL" "$NIXPKGS_REPO_PATH"
-
- cd "$NIXPKGS_REPO_PATH"
-
- # Setup upstream remote
- if ! git remote | grep -q "^${NIXPKGS_UPSTREAM_REMOTE}$"; then
- log "Adding upstream remote: $NIXPKGS_UPSTREAM_URL"
- git remote add "$NIXPKGS_UPSTREAM_REMOTE" "$NIXPKGS_UPSTREAM_URL"
- fi
-
- log "Repository cloned successfully"
- else
- log "Repository exists at $NIXPKGS_REPO_PATH"
- fi
-
- cd "$NIXPKGS_REPO_PATH"
-
- # Verify remotes exist
- if ! git remote | grep -q "^${NIXPKGS_UPSTREAM_REMOTE}$"; then
- log "ERROR: Remote '$NIXPKGS_UPSTREAM_REMOTE' not found"
- log "Available remotes: $(git remote | tr '\n' ' ')"
- exit 1
- fi
-
- if ! git remote | grep -q "^${NIXPKGS_FORK_REMOTE}$"; then
- log "ERROR: Remote '$NIXPKGS_FORK_REMOTE' not found"
- log "Available remotes: $(git remote | tr '\n' ' ')"
- exit 1
- fi
-}
-
-setup_worktree() {
- cd "$NIXPKGS_REPO_PATH"
-
- # Check if worktree is registered in git
- if git worktree list | grep -q "$NIXPKGS_WORKTREE_PATH"; then
- log "Reusing existing worktree at $NIXPKGS_WORKTREE_PATH"
- cd "$NIXPKGS_WORKTREE_PATH"
-
- # Reset to upstream base branch
- log "Resetting worktree to $NIXPKGS_UPSTREAM_REMOTE/$BASE_BRANCH"
- git checkout -B "$NIXPKGS_CONSOLIDATED_BRANCH" "$NIXPKGS_UPSTREAM_REMOTE/$BASE_BRANCH" 2>&1 | tee -a "$LOG_FILE"
- log "Worktree reset successfully"
- return
- fi
-
- # Worktree not registered - clean up stale references and create fresh
- log "Creating new worktree at $NIXPKGS_WORKTREE_PATH"
- log "Branching from $NIXPKGS_UPSTREAM_REMOTE/$BASE_BRANCH"
-
- # Clean up any stale worktree references and remove directory if exists
- git worktree prune 2>&1 | tee -a "$LOG_FILE" || true
- if [ -d "$NIXPKGS_WORKTREE_PATH" ]; then
- log "Removing stale worktree directory"
- [[ -n "$NIXPKGS_WORKTREE_PATH" ]] && rm -rf "$NIXPKGS_WORKTREE_PATH"
- fi
-
- # Delete local consolidated branch if it exists and is not checked out
- if git show-ref --verify --quiet "refs/heads/$NIXPKGS_CONSOLIDATED_BRANCH"; then
- log "Deleting existing local branch $NIXPKGS_CONSOLIDATED_BRANCH"
- git branch -D "$NIXPKGS_CONSOLIDATED_BRANCH" 2>&1 | tee -a "$LOG_FILE" || true
- fi
-
- if git worktree add -b "$NIXPKGS_CONSOLIDATED_BRANCH" \
- "$NIXPKGS_WORKTREE_PATH" \
- "$NIXPKGS_UPSTREAM_REMOTE/$BASE_BRANCH" 2>&1 | tee -a "$LOG_FILE"; then
- log "Worktree created successfully"
- else
- log "ERROR: Failed to create worktree"
- exit 1
- fi
-}
-
-consolidate_branches() {
- cd "$NIXPKGS_WORKTREE_PATH"
-
- for branch in "${WIP_BRANCHES[@]}"; do
- log "Processing WIP branch: $branch"
- FAILED_BRANCH="$branch"
-
- # Check if branch exists on fork remote
- if ! git rev-parse --verify "$NIXPKGS_FORK_REMOTE/$branch" >/dev/null 2>&1; then
- log "ERROR: Branch $branch not found on remote $NIXPKGS_FORK_REMOTE"
- exit 1
- fi
-
- # Count commits before rebase (for logging)
- local commits_before
- commits_before=$(git rev-list --count HEAD)
-
- # Rebase the WIP branch onto wip-consolidated
- # This automatically drops empty commits (already in base)
- log "Rebasing $NIXPKGS_FORK_REMOTE/$branch onto wip-consolidated..."
- if ! git -c commit.gpgsign=false rebase "$NIXPKGS_FORK_REMOTE/$branch" 2>&1 | tee -a "$LOG_FILE"; then
- log "ERROR: Rebase failed for branch $branch"
- log "Aborting rebase..."
- git rebase --abort 2>&1 | tee -a "$LOG_FILE" || true
- exit 1
- fi
-
- # Count commits after rebase
- local commits_after
- commits_after=$(git rev-list --count HEAD)
- local commits_added=$((commits_after - commits_before))
-
- log "Successfully rebased $branch: added $commits_added commit(s)"
- COMPLETED_BRANCHES+=("$branch")
- FAILED_BRANCH=""
- TOTAL_COMMITS=$((TOTAL_COMMITS + commits_added))
- done
-
- log "Total commits added: $TOTAL_COMMITS"
-}
-
-main() {
- log "=== Starting nixpkgs branch consolidation ==="
- log "Repository: $NIXPKGS_REPO_PATH"
- log "Worktree path: $NIXPKGS_WORKTREE_PATH"
- log "Fork remote: $NIXPKGS_FORK_REMOTE ($NIXPKGS_FORK_URL)"
- log "Upstream remote: $NIXPKGS_UPSTREAM_REMOTE ($NIXPKGS_UPSTREAM_URL)"
- log "Consolidated branch: $NIXPKGS_CONSOLIDATED_BRANCH"
- log "Configuration: $NIXPKGS_CONFIG_FILE"
- log "Dry run: $DRY_RUN"
-
- # Parse configuration
- parse_config
-
- # Ensure repository exists
- ensure_repo
-
- # Fetch latest from remotes
- log "Fetching from $NIXPKGS_UPSTREAM_REMOTE..."
- cd "$NIXPKGS_REPO_PATH"
- git fetch "$NIXPKGS_UPSTREAM_REMOTE" 2>&1 | tee -a "$LOG_FILE"
-
- log "Fetching from $NIXPKGS_FORK_REMOTE..."
- git fetch "$NIXPKGS_FORK_REMOTE" 2>&1 | tee -a "$LOG_FILE"
-
- # List available branches on fork remote
- log "Available branches on $NIXPKGS_FORK_REMOTE:"
- git branch -r | grep "^ $NIXPKGS_FORK_REMOTE/" | sed "s|^ $NIXPKGS_FORK_REMOTE/||" | while read -r branch; do
- log " - $branch"
- done
-
- # Verify base branch exists
- if ! git rev-parse --verify "$NIXPKGS_UPSTREAM_REMOTE/$BASE_BRANCH" >/dev/null 2>&1; then
- log "ERROR: Base branch $BASE_BRANCH not found on remote $NIXPKGS_UPSTREAM_REMOTE"
- exit 1
- fi
-
- # Setup worktree for consolidation work
- setup_worktree
-
- # Cherry-pick WIP branches (happens in worktree)
- consolidate_branches
-
- # Show summary
- log "=== Consolidation Summary ==="
- log "Base branch: $BASE_BRANCH"
- log "WIP branches consolidated: ${#COMPLETED_BRANCHES[@]}"
- for branch in "${COMPLETED_BRANCHES[@]}"; do
- log " - $branch"
- done
- log "Total commits: $TOTAL_COMMITS"
-
- # Push to remote (from worktree)
- cd "$NIXPKGS_WORKTREE_PATH"
-
- if [ "$DRY_RUN" = "true" ]; then
- log "DRY RUN: Would push $NIXPKGS_CONSOLIDATED_BRANCH to $NIXPKGS_FORK_REMOTE"
- log "Current HEAD: $(git rev-parse HEAD)"
- log "Branch differs from upstream/$BASE_BRANCH by $TOTAL_COMMITS commits"
- else
- log "Force pushing $NIXPKGS_CONSOLIDATED_BRANCH to $NIXPKGS_FORK_REMOTE (with --force-with-lease)..."
- if git push --force-with-lease "$NIXPKGS_FORK_REMOTE" "$NIXPKGS_CONSOLIDATED_BRANCH:$NIXPKGS_CONSOLIDATED_BRANCH" 2>&1 | tee -a "$LOG_FILE"; then
- log "Successfully pushed to $NIXPKGS_FORK_REMOTE/$NIXPKGS_CONSOLIDATED_BRANCH"
- else
- log "ERROR: Push failed. This might mean the remote branch was updated by someone else."
- log "Check the remote branch and try again."
- exit 1
- fi
- fi
-
- # Success notification
- local branches_str
- branches_str=$(IFS=$'\n'; echo "${COMPLETED_BRANCHES[*]}")
- local success_msg="Consolidated ${#COMPLETED_BRANCHES[@]} branch(es) into $NIXPKGS_CONSOLIDATED_BRANCH
-
-Base: $BASE_BRANCH
-Branches:
-$branches_str
-
-Total commits: $TOTAL_COMMITS
-
-${DRY_RUN:+[DRY RUN] }Pushed to $NIXPKGS_FORK_REMOTE/$NIXPKGS_CONSOLIDATED_BRANCH"
-
- notify "default" \
- "✅ Nixpkgs Consolidation Success" \
- "$success_msg" \
- "white_check_mark,git,nixpkgs"
-
- log "=== Consolidation completed successfully ==="
-}
-
-main "$@"
tools/nixpkgs-consolidate/README.md
@@ -1,541 +0,0 @@
-# Nixpkgs Branch Consolidation Tool
-
-Automatically consolidate multiple WIP/PR branches from your nixpkgs fork into a single consolidated branch using cherry-picking.
-
-## Overview
-
-This tool helps manage multiple work-in-progress (WIP) branches in your nixpkgs fork by:
-
-1. Fetching latest from upstream nixpkgs
-2. Creating a fresh consolidated branch from the base (e.g., `nixos-unstable`)
-3. Cherry-picking commits from each WIP branch in order
-4. Force-pushing the result to your fork
-5. Sending notifications on success/failure
-
-**Key Features:**
-
-- Uses git worktrees to avoid interfering with your main nixpkgs checkout
-- Cherry-pick strategy (no merge commits)
-- Handles conflicts gracefully with detailed error reporting
-- Integrates with ntfy for notifications
-- Dry-run mode for safe testing
-- Comprehensive logging
-
-## Use Case
-
-Perfect for nixpkgs contributors who:
-
-- Maintain multiple WIP branches for different packages/features
-- Want to test all changes together in a single branch
-- Need an automated way to keep a consolidated branch up-to-date with upstream
-- Want to reference one branch in their NixOS flake instead of managing overlays
-
-## Installation
-
-### Manual Usage
-
-```bash
-# Run directly from the tools directory
-./tools/nixpkgs-consolidate/nixpkgs-consolidate.sh
-```
-
-### Nix Package (Recommended)
-
-```bash
-# Build and install
-nix build .#nixpkgs-consolidate
-nix profile install .#nixpkgs-consolidate
-
-# Run
-nixpkgs-consolidate
-```
-
-### Automated with NixOS Module
-
-Add to your system configuration (e.g., `systems/aomi/extra.nix`):
-
-```nix
-{
- services.nixpkgs-consolidate = {
- enable = true;
- user = "vincent";
- schedule = "daily"; # or "Mon,Thu *-*-* 02:00:00"
- configFile = "/home/vincent/.config/nixpkgs-automation/branches.conf";
- };
-}
-```
-
-## Configuration
-
-### Automatic Base Branch Detection
-
-**NEW:** The script automatically detects the nixpkgs revision from your home flake!
-
-When running, the script will:
-1. Read the configured base branch from `branches.conf` (e.g., `nixos-unstable`)
-2. Check your home flake at `$HOME_FLAKE_PATH/flake.lock`
-3. Extract the exact nixpkgs commit hash from the `nixpkgs` input
-4. Use that commit hash as the base instead of the configured branch
-
-**Benefits:**
-- Consolidated branch is based on the exact same nixpkgs as your home configuration
-- No manual hash updates needed - it follows your flake.lock
-- More reliable testing of packages in your actual NixOS environment
-- Falls back to configured base if detection fails
-
-**Example:**
-```
-# branches.conf contains:
-base: nixos-unstable
-
-# But your flake.lock has nixpkgs pinned to:
-31926ce9afb1c915fa4190b77ca9be389ccaf18e
-
-# Script will use the commit hash from flake.lock as the base
-```
-
-### Setup
-
-1. **Create configuration directory:**
- ```bash
- mkdir -p ~/.config/nixpkgs-automation
- ```
-
-2. **Copy example configuration:**
- ```bash
- cp tools/nixpkgs-consolidate/branches.conf.example \
- ~/.config/nixpkgs-automation/branches.conf
- ```
-
-3. **Edit configuration:**
- ```bash
- vim ~/.config/nixpkgs-automation/branches.conf
- ```
-
-### Configuration File Format
-
-`~/.config/nixpkgs-automation/branches.conf`:
-
-```bash
-# Base branch (required)
-base: nixos-unstable
-
-# WIP branches to consolidate (one per line)
-wip-package-foo
-wip-fix-bar
-pr-12345-add-service
-```
-
-**Rules:**
-
-- First line starting with `base:` defines the upstream base branch
-- Other non-comment, non-empty lines are treated as WIP branch names
-- Branches are cherry-picked in the order listed
-- Comments start with `#`
-
-### Environment Variables
-
-Override defaults with environment variables:
-
-| Variable | Default | Description |
-|----------|---------|-------------|
-| `NIXPKGS_REPO_PATH` | `~/src/nixpkgs` | Path to nixpkgs repository |
-| `NIXPKGS_WORKTREE_PATH` | `~/src/nixpkgs-consolidate-work` | Worktree for consolidation |
-| `NIXPKGS_UPSTREAM_REMOTE` | `upstream` | Upstream remote name |
-| `NIXPKGS_FORK_REMOTE` | `origin` | Your fork remote name |
-| `NIXPKGS_CONSOLIDATED_BRANCH` | `wip-consolidated` | Output branch name |
-| `NIXPKGS_CONFIG_FILE` | `~/.config/nixpkgs-automation/branches.conf` | Config file path |
-| `HOME_FLAKE_PATH` | `~/src/home` | Path to home flake for auto-detecting nixpkgs revision |
-| `NTFY_SERVER` | `https://ntfy.sbr.pm` | ntfy server URL |
-| `NTFY_TOPIC` | `git-builds` | ntfy notification topic |
-| `NTFY_TOKEN_FILE` | `/run/agenix/ntfy-token` | ntfy auth token file |
-| `LOG_DIR` | `/var/log/nixpkgs-consolidate` | Log directory |
-| `DRY_RUN` | `false` | Set to `true` for dry-run |
-
-## Usage
-
-### Basic Usage
-
-```bash
-# Run with defaults
-nixpkgs-consolidate
-
-# Or directly:
-./tools/nixpkgs-consolidate/nixpkgs-consolidate.sh
-```
-
-### Dry Run (Recommended First)
-
-Test without actually pushing:
-
-```bash
-DRY_RUN=true nixpkgs-consolidate
-```
-
-This will:
-- Parse configuration
-- Fetch from remotes
-- Create worktree
-- Cherry-pick all commits
-- Show what would be pushed
-- NOT actually push to remote
-
-### Custom Branch Name
-
-```bash
-NIXPKGS_CONSOLIDATED_BRANCH=personal-main nixpkgs-consolidate
-```
-
-### Different Base Branch
-
-```bash
-# Edit config file to change base:
-echo "base: master" > ~/.config/nixpkgs-automation/branches.conf
-# Then run:
-nixpkgs-consolidate
-```
-
-## Workflow
-
-### Initial Setup
-
-1. **Fork nixpkgs on GitHub** (if you haven't already)
-
-2. **Clone nixpkgs locally:**
- ```bash
- git clone git@github.com:NixOS/nixpkgs.git ~/src/nixpkgs
- cd ~/src/nixpkgs
- git remote add upstream git@github.com:NixOS/nixpkgs.git
- # Assumes 'origin' points to your fork
- ```
-
-3. **Create WIP branches:**
- ```bash
- git checkout -b wip-my-feature nixos-unstable
- # Make changes...
- git push origin wip-my-feature
- ```
-
-4. **Configure consolidation:**
- ```bash
- mkdir -p ~/.config/nixpkgs-automation
- cat > ~/.config/nixpkgs-automation/branches.conf <<EOF
- base: nixos-unstable
- wip-my-feature
- wip-another-feature
- EOF
- ```
-
-5. **Run consolidation:**
- ```bash
- DRY_RUN=true nixpkgs-consolidate # Test first
- nixpkgs-consolidate # Actually push
- ```
-
-### Regular Usage
-
-1. **Work on WIP branches as usual:**
- ```bash
- git checkout wip-my-feature
- # Make changes...
- git commit -m "Update package foo"
- git push origin wip-my-feature
- ```
-
-2. **Run consolidation** (manually or via systemd timer):
- ```bash
- nixpkgs-consolidate
- ```
-
-3. **Use consolidated branch in your flake:**
- ```nix
- {
- inputs = {
- nixpkgs.url = "github:vdemeester/nixpkgs/wip-consolidated";
- };
- }
- ```
-
-4. **Clean up when PRs land:**
- - Remove merged branches from `branches.conf`
- - Delete remote branches: `git push origin --delete wip-merged-feature`
-
-## Git Workflow Details
-
-### Worktree Usage
-
-The script uses git worktrees to keep your main repository clean:
-
-1. **Main repository** (`~/src/nixpkgs`):
- - Stays on whatever branch you're working on
- - Not affected by consolidation process
-
-2. **Consolidation worktree** (`~/src/nixpkgs-consolidate-work`):
- - Created automatically
- - Used for all cherry-picking operations
- - Removed automatically after completion
-
-### Cherry-Pick Strategy
-
-For each WIP branch:
-
-```bash
-# Get commits unique to WIP branch
-commits = $(git log upstream/nixos-unstable..origin/wip-feature)
-
-# Cherry-pick each commit
-for commit in commits; do
- git cherry-pick $commit
-done
-```
-
-**Why cherry-pick instead of merge?**
-
-- Clean linear history
-- No merge commits
-- Easy to see what changed
-- Better for testing package updates
-
-### Conflict Handling
-
-If a cherry-pick conflicts:
-
-1. Script aborts immediately
-2. Sends detailed notification with:
- - Which branch caused the conflict
- - Which commit failed
- - What was successfully completed
-3. Cleans up worktree
-4. Returns non-zero exit code
-
-**Resolution:**
-
-- Fix conflicts in the WIP branch
-- Rebase WIP branch on latest upstream
-- Run consolidation again
-
-## Notifications
-
-### Success Notification
-
-Sent to `ntfy.sbr.pm/git-builds`:
-
-```
-✅ Nixpkgs Consolidation Success
-
-Consolidated 3 branch(es) into wip-consolidated
-
-Base: nixos-unstable
-Branches:
-wip-package-foo
-wip-fix-bar
-pr-12345-add-service
-
-Total commits: 15
-
-Pushed to origin/wip-consolidated
-```
-
-### Failure Notification
-
-```
-❌ Nixpkgs Consolidation Failed
-
-Cherry-pick conflict in branch: wip-fix-bar
-Commit: abc123def456
-
-Base: nixos-unstable
-Completed: wip-package-foo
-Failed at: wip-fix-bar
-
-Logs: /var/log/nixpkgs-consolidate/20260108-103015.log
-```
-
-## Logging
-
-Logs are written to:
-
-```
-/var/log/nixpkgs-consolidate/YYYYMMDD-HHMMSS.log
-```
-
-**Log format:**
-
-```
-[2026-01-08 10:30:15] Starting nixpkgs branch consolidation
-[2026-01-08 10:30:16] Reading configuration from ~/.config/nixpkgs-automation/branches.conf
-[2026-01-08 10:30:17] Base branch: nixos-unstable
-[2026-01-08 10:30:17] WIP branches (3): wip-foo wip-bar pr-12345
-[2026-01-08 10:30:20] Fetching from upstream...
-[2026-01-08 10:30:25] Creating worktree at ~/src/nixpkgs-consolidate-work
-[2026-01-08 10:30:26] Processing WIP branch: wip-foo
-[2026-01-08 10:30:27] Found 5 commit(s) to cherry-pick
-[2026-01-08 10:30:28] Cherry-picking abc123: Update foo to 1.2.3
-...
-```
-
-## Troubleshooting
-
-### "Configuration file not found"
-
-**Problem:** `~/.config/nixpkgs-automation/branches.conf` doesn't exist
-
-**Solution:**
-```bash
-mkdir -p ~/.config/nixpkgs-automation
-cp tools/nixpkgs-consolidate/branches.conf.example \
- ~/.config/nixpkgs-automation/branches.conf
-vim ~/.config/nixpkgs-automation/branches.conf
-```
-
-### "Remote 'upstream' not found"
-
-**Problem:** nixpkgs repository doesn't have upstream remote configured
-
-**Solution:**
-```bash
-cd ~/src/nixpkgs
-git remote add upstream git@github.com:NixOS/nixpkgs.git
-git fetch upstream
-```
-
-### "Branch not found on remote origin"
-
-**Problem:** WIP branch listed in config doesn't exist in your fork
-
-**Solution:**
-- Check branch exists: `git ls-remote origin | grep wip-feature`
-- Push branch to fork: `git push origin wip-feature`
-- Or remove from config if no longer needed
-
-### Cherry-pick conflicts
-
-**Problem:** Commits conflict when cherry-picked
-
-**Solution:**
-
-1. Check the logs to see which branch caused the conflict
-2. Rebase that branch on latest upstream:
- ```bash
- git checkout wip-problematic-branch
- git fetch upstream
- git rebase upstream/nixos-unstable
- git push --force-with-lease origin wip-problematic-branch
- ```
-3. Run consolidation again
-
-### Force push rejected
-
-**Problem:** `git push --force-with-lease` fails
-
-**Cause:** Someone else (or another process) updated the consolidated branch
-
-**Solution:**
-- If it was you from another machine: Re-run consolidation
-- If unexpected: Check remote branch with `git log origin/wip-consolidated`
-
-## Integration with NixOS Flake
-
-Once consolidation is running, reference the consolidated branch in your flake:
-
-```nix
-{
- inputs = {
- # Use your consolidated branch instead of official nixpkgs
- nixpkgs.url = "github:vdemeester/nixpkgs/wip-consolidated";
-
- # Or for testing with local changes:
- # nixpkgs.url = "path:/home/vincent/src/nixpkgs";
- };
-
- outputs = { nixpkgs, ... }: {
- # Your configuration...
- };
-}
-```
-
-**Benefits:**
-
-- Test all your WIP packages together
-- Single flake input instead of multiple overlays
-- Automatically updated as you run consolidation
-
-## Automation with Systemd
-
-### Manual Trigger
-
-```bash
-systemctl start nixpkgs-consolidate.service
-```
-
-### Check Status
-
-```bash
-systemctl status nixpkgs-consolidate.service
-journalctl -u nixpkgs-consolidate.service -f
-```
-
-### List Timer Schedule
-
-```bash
-systemctl list-timers | grep nixpkgs
-```
-
-### Modify Schedule
-
-Edit your system configuration:
-
-```nix
-services.nixpkgs-consolidate = {
- enable = true;
- schedule = "Mon,Thu *-*-* 02:00:00"; # Monday and Thursday at 2 AM
-};
-```
-
-## Best Practices
-
-1. **Test with dry-run first:**
- ```bash
- DRY_RUN=true nixpkgs-consolidate
- ```
-
-2. **Keep WIP branches rebased:**
- ```bash
- git checkout wip-feature
- git fetch upstream
- git rebase upstream/nixos-unstable
- git push --force-with-lease origin wip-feature
- ```
-
-3. **Clean up merged branches:**
- - Remove from `branches.conf`
- - Delete from fork: `git push origin --delete wip-merged`
-
-4. **Use descriptive branch names:**
- - `wip-update-python-312` ✅
- - `wip-stuff` ❌
-
-5. **Order matters in config:**
- - Put independent changes first
- - Put dependent changes later
-
-6. **Monitor notifications:**
- - Subscribe to ntfy topic `git-builds`
- - Fix conflicts promptly
-
-## Security
-
-- **Git Authentication:** Uses existing SSH keys (`~/.ssh/`)
-- **ntfy Token:** Stored in agenix (`/run/agenix/ntfy-token`)
-- **Logs:** Written to `/var/log` with restricted permissions
-- **Systemd:** Service runs with security hardening (ProtectSystem, ProtectHome, etc.)
-
-## See Also
-
-- [Nixpkgs Contributing Guide](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md)
-- [Git Worktrees Documentation](https://git-scm.com/docs/git-worktree)
-- [ntfy Documentation](https://ntfy.sh)
-
-## License
-
-MIT