Skip to content

Instantly share code, notes, and snippets.

@0atman
Last active May 16, 2024 20:49
Show Gist options
  • Save 0atman/1a5133b842f929ba4c1e195ee67599d5 to your computer and use it in GitHub Desktop.
Save 0atman/1a5133b842f929ba4c1e195ee67599d5 to your computer and use it in GitHub Desktop.
A rebuild script that commits on a successful build
{
config,
pkgs,
options,
...
}: let
hostname = "oatman-pc"; # to alllow per-machine config
in {
networking.hostName = hostname;
imports = [
/etc/nixos/hardware-configuration.nix
(/home/oatman/dotfiles/nixos + "/${hostname}.nix")
];
}
#!/usr/bin/env bash
#
# I believe there are a few ways to do this:
#
# 1. My current way, using a minimal /etc/nixos/configuration.nix that just imports my config from my home directory (see it in the gist)
# 2. Symlinking to your own configuration.nix in your home directory (I think I tried and abandoned this and links made relative paths weird)
# 3. My new favourite way: as @clot27 says, you can provide nixos-rebuild with a path to the config, allowing it to be entirely inside your dotfies, with zero bootstrapping of files required.
# `nixos-rebuild switch -I nixos-config=path/to/configuration.nix`
# 4. If you uses a flake as your primary config, you can specify a path to `configuration.nix` in it and then `nixos-rebuild switch —flake` path/to/directory
# As I hope was clear from the video, I am new to nixos, and there may be other, better, options, in which case I'd love to know them! (I'll update the gist if so)
# A rebuild script that commits on a successful build
set -e
# Edit your config
$EDITOR configuration.nix
# cd to your config dir
pushd ~/dotfiles/nixos/
# Early return if no changes were detected (thanks @singiamtel!)
if git diff --quiet '*.nix'; then
echo "No changes detected, exiting."
popd
exit 0
fi
# Autoformat your nix files
alejandra . &>/dev/null \
|| ( alejandra . ; echo "formatting failed!" && exit 1)
# Shows your changes
git diff -U0 '*.nix'
echo "NixOS Rebuilding..."
# Rebuild, output simplified errors, log trackebacks
sudo nixos-rebuild switch &>nixos-switch.log || (cat nixos-switch.log | grep --color error && exit 1)
# Get current generation metadata
current=$(nixos-rebuild list-generations | grep current)
# Commit all changes witih the generation metadata
git commit -am "$current"
# Back to where you were
popd
# Notify all OK!
notify-send -e "NixOS Rebuilt OK!" --icon=software-update-available
@0atman
Copy link
Author

0atman commented Mar 19, 2024

One improvement that I made when I started using it was to handle the script itself the nix way by storing is a nixos-rebuild.nix file:
@Lemm1

Very interesting idea! I have a clean division between my system (managed by nixos) and my home directory and dotfiles (managed by ME). So I don't think I'll do this just yet, but everyone else, take note!

@0atman
Copy link
Author

0atman commented Mar 19, 2024

@aikomastboom love the alejandra tweak - added.

Interesting sudo tweak - but on my machine root using sudo is a no-op and can safely run both normal and sudoed commands?

@aikomastboom
Copy link

Yeah, I know.. I came across it when fiddling with a VM that only had root and no sudo installed

I like the idea to nixify the script too ( to ensure those dependency commands are available)

@MvRens
Copy link

MvRens commented Mar 19, 2024

Fellow NixOS noob here thanks to your video! thanks for sharing this script as well.

FYI, I had to surround the two references to '*.nix' in single quotes to prevent bash from expanding the glob which resulted in 'No changes detected' and no diff output. Probably because my configuration is mostly in subfolders.

@0atman
Copy link
Author

0atman commented Mar 20, 2024

@MvRens updated, well spotted!

@mipdableep
Copy link

Hi! First of all, great video and an amazing script!
A weird problem i got stuck with is the fact that the nixos-rebuild hashing would not rebuild if the git repo was dirty - this blog post helped but i realized that staging the files fixed it - git add ./*.nix before the rebuild stage.
Aside from that, i found that using sudo nix-env -p /nix/var/nix/profiles/system --list-generations | grep "current" gave a cleaner output then nixos-rebuild list-generations

@JustCoderdev
Copy link

I added a bit where if a rebuild fails it asks if you want to open the logs or not

# In my case I use flakes but here it checks whether it fails or not
if sudo nixos-rebuild switch --flake ".#$1" &>.nixos-switch.log; then
	echo -e "Done\n"
else
	echo ""
	cat .nixos-switch.log | grep --color error

	# this is needed otherwise the script would not start next time telling you "no changes detected"
	# (The weird patter is to include all subdirectories)
	sudo git restore --staged ./**/*.nix

	if read -p "Open log? (y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then
		cat .nixos-switch.log | vim - 	
	fi

	# Clean stuff and exit
	shopt -u globstar
	popd > /dev/null
	exit 1
fi

thx @0atman for the *hem inspiration ;)

@0atman
Copy link
Author

0atman commented Mar 26, 2024

Very cool!

@taiwithers
Copy link

Here's a version that's I edited to work with Home Manager and custom *.nix file locations, I've also added a segment to check for untracked *.nix files since these don't get picked up by git diff
Not sure if ether of those things are useful to anyone else but shrug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment