Skip to content

Instantly share code, notes, and snippets.

@0atman
Last active November 15, 2024 13:06
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
@JustCoderdev
Copy link

JustCoderdev commented Aug 14, 2024

@0atman You can test the full version of the script by taking it from my dotfiles. This way you can get a feel if you like it or not [link]

let me know ;)

edit: You might want to disable certain stuff like the automatic host recognition, the flake auto-update (based on the current host), the auto-restore (so that it can properly detect if it's rebuilding with changes after a failed attempt) and the auto-commit (for obvious reasons)

@0atman
Copy link
Author

0atman commented Aug 14, 2024

Thank you! Hopefully useful for others too!

@JustCoderdev
Copy link

I found out something very useful

You can unlink nixos files without extra permissions and on the next rebuild they will get recreated

This means that when you want to quickly iterate over a configuration (waybar for example) you can remove the nixos link, point it to your configuration folder, modify it and test things out without having to rebuild

When you're done just rebuild and nixos will bake the new config into the next generation

@S1rDev10us
Copy link

Isn't the current autoformatting command forgetting to popd on formatting failure?

@0atman
Copy link
Author

0atman commented Aug 27, 2024

@S1rDev10us huh, I don't think pushd/popd work in the way I (or maybe you!) think. Perhaps someone smarter than I can explain what happens to the directory stack on an early exit?

A script I just tried that surprised me:

#!/usr/bin/env bash
set -e
pushd ~/Music
pwd
exit 1
# after exit, cwd is back where we started, despite not popd-ing

@JustCoderdev
Copy link

@0atman As far I know pushd and popd act only inside of the shell that get's created when you execute the script, like if you had two terminals and you changed directory in one of them. Once the script has terminated it exits to the "outer shell" (bash or zsh) and resume the previous environment

@0atman
Copy link
Author

0atman commented Aug 28, 2024

oh of course! it's running in the shebang's process, not hijacking the outer shell 😅

@JustCoderdev
Copy link

I have a laptop with only two cores and - since everytime I started a rebuild it would freeze my desktop - I implemented the simplest throttling mechanism to tell nixos-rebuild to use only half of the available cores (snippet below)

# Detect processors
procs="$(nproc)"
if [ -z "${procs:-}" ]; then
	echo "No processors detected! Assuming 2..."
	procs="2"
fi

hprocs="$(( procs / 2 ))"
echo "Detected ${procs} processors, using ${hprocs} of them"

nixos-rebuild switch --max-jobs "${hprocs}" #...

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