feat(github): add auto-conventional-commit hook with opencode integration
CI / Flake check (aarch64-linux) (push) Successful in 1m30s
CI / Flake check (x86_64-linux) (push) Successful in 1m17s
CI / Pre-commit checks (x86_64-linux) (push) Failing after 19s

- Add prepare-commit-msg git hook that generates conventional commit messages
- Modularize fish configuration with separate conf.d files
- Convert configuration files from .text to .source format for structured data
- Add sops-nix SOPS configuration with explicit secret definitions
- Upgrade age identity to single key file management approach
- Add system activation script for age key management
- Generate .sops.yaml for SOPS creation rules
- Restructure README.md with improved table and cleaner formatting
- Refactor config files to use pkgs.formats.json/toml generators
- Implement YAML format for ashell and walker service configurations
- Update SSH config source to use sops secrets
- Convert zed and other config files to use structured .source format
This commit is contained in:
2026-07-12 17:55:52 +02:00
parent 5116faf0d3
commit 205a1ccc8f
22 changed files with 581 additions and 443 deletions
+46 -46
View File
@@ -143,6 +143,10 @@
};
};
# Workaround: aa-remove-unknown references missing rc.apparmor.functions in apparmor-parser 5.0.0
# Reload via restart instead (stop → start, reloads all profiles)
systemd.services.apparmor.reloadIfChanged = lib.mkForce false;
services = {
# for SSD/NVME
fstrim.enable = true;
@@ -156,52 +160,48 @@
# Additional systemd hardening
systemd = {
coredump.extraConfig = ''
Storage=none
ProcessSizeMax=0
'';
};
environment.systemPackages = [pkgs.cryptsetup pkgs.age inputs.agenix.packages.${pkgs.stdenv.hostPlatform.system}.default];
age.identityPaths = ["/etc/ssh/ssh_host_ed25519_key"];
age.secrets = {
gitea_laptop = {
file = ../../secrets/gitea_laptop.age;
mode = "600";
owner = "someone";
group = "users";
};
hetzner_server = {
file = ../../secrets/hetzner_server.age;
mode = "600";
owner = "someone";
group = "users";
};
aur = {
file = ../../secrets/aur.age;
mode = "600";
owner = "someone";
group = "users";
};
ssh_config = {
file = ../../secrets/ssh_config.age;
mode = "600";
owner = "someone";
group = "users";
};
github_key = {
file = ../../secrets/github_key.age;
mode = "600";
owner = "someone";
group = "users";
};
sporestack_server = {
file = ../../secrets/sporestack_server.age;
mode = "600";
owner = "someone";
group = "users";
coredump.settings = {
Coredump.Storage = "none";
Coredump.ProcessSizeMax = 0;
};
};
boot.loader.limine.bootMode = lib.mkDefault "bios";
# sops-nix configuration
sops = {
defaultSopsFile = ./../../secrets/secrets.yaml;
age.keyFile = "/etc/age/keys.txt";
# Explicitly define secrets to ensure they're generated
secrets = {
discordo = { owner = "someone"; group = "users"; mode = "0440"; };
openrouter = { owner = "someone"; group = "users"; mode = "0440"; };
github = { owner = "someone"; group = "users"; mode = "0440"; };
twt = { owner = "someone"; group = "users"; mode = "0440"; };
gemini = { owner = "someone"; group = "users"; mode = "0440"; };
context7 = { owner = "someone"; group = "users"; mode = "0440"; };
exa = { owner = "someone"; group = "users"; mode = "0440"; };
ssh_config = { owner = "someone"; group = "users"; mode = "0440"; };
gitea_laptop = { owner = "someone"; group = "users"; mode = "0400"; };
hetzner_server = { owner = "someone"; group = "users"; mode = "0400"; };
};
};
environment.systemPackages = [pkgs.cryptsetup pkgs.age pkgs.nixd pkgs.apparmor-parser pkgs.xdg-desktop-portal-wlr];
# Provide age private key for sops decryption at activation time
systemd.tmpfiles.rules = [
"d /etc/age 0700 root root -"
"w /etc/age/keys.txt 0600 root root - # created by activation script"
];
# Activation script to write age key
system.activationScripts.write-age-key = ''
cat > /etc/age/keys.txt << 'AGEEOF'
# created: 2026-07-12T10:20:38+02:00
# public key: age1n2kvnwdzrd5vw70wwmm90a4lg6wj3665egzpnz72r98epr0rhc0q3yp356
AGE-SECRET-KEY-1A49GYAG5AJWGW0XM7HWC8QFE6UUF0S3Z99T252SKX2JHW6NM0HDQESWAQC
AGEEOF
chmod 600 /etc/age/keys.txt
'';
}
+32
View File
@@ -0,0 +1,32 @@
{lib, ...}: {
disko.devices = {
disk.main = {
device = lib.mkDefault "/dev/nvme0n1";
type = "disk";
content = {
type = "gpt";
partitions = {
esp = {
name = "ESP";
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot/efi";
};
};
root = {
name = "root";
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
}
+31 -1
View File
@@ -5,6 +5,7 @@
}: let
# shorten paths
inherit (inputs.nixpkgs.lib) nixosSystem;
lib = inputs.nixpkgs.lib;
# Server uses its own pinned 24.05 nixpkgs (kept isolated from the laptop's unstable)
nixosSystem24 = inputs.nixos-24-05.lib.nixosSystem;
unstablePkgs = import inputs.nixpkgs-unstable {system = "x86_64-linux";};
@@ -23,7 +24,7 @@
"${mod}/services/gnome-services.nix"
"${mod}/core/limine.nix"
"${home}"
inputs.agenix.nixosModules.default
inputs.sops-nix.nixosModules.sops
];
in {
flake.nixosConfigurations = {
@@ -50,6 +51,35 @@ in {
];
};
# Laptop UEFI: explicit UEFI boot mode
laptop-uefi = nixosSystem {
inherit specialArgs;
modules =
laptop
++ sharedModules
++ [
"${mod}/services/location.nix"
({ config, ... }: {
boot.loader.limine.bootMode = "uefi";
})
];
};
# Laptop BIOS: explicit BIOS boot mode
laptop-bios = nixosSystem {
inherit specialArgs;
modules =
laptop
++ sharedModules
++ [
"${mod}/services/location.nix"
({ config, ... }: {
boot.loader.limine.bootMode = "bios";
boot.loader.limine.biosDevice = "/dev/nvme0n1";
})
];
};
# Server: severijnse.eu (Hetzner) — fully isolated under servers/hetzner/.
# Uses nixos-24.05 + disko + sops-nix and does NOT inherit the laptop's shared modules.
hetzner = nixosSystem24 {