Skip to content

Commit 5066971

Browse files
committed
add mise-driven ci tasks and hm/darwin module scaffolding
0 parents  commit 5066971

8 files changed

Lines changed: 258 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: NixOS Configuration CI
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
9+
jobs:
10+
check:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout repository
14+
uses: actions/checkout@v4
15+
16+
- name: Setup mise
17+
uses: jdx/mise-action@v2
18+
19+
- name: Install Nix
20+
uses: cachix/install-nix-action@v25
21+
with:
22+
nix_path: nixpkgs=channel:nixos-unstable
23+
extra_nix_config: |
24+
experimental-features = nix-command flakes
25+
26+
- name: Install toolchain
27+
run: mise install
28+
29+
- name: Validation
30+
run: mise run ci-validate
31+
32+
security:
33+
runs-on: ubuntu-latest
34+
steps:
35+
- name: Checkout repository
36+
uses: actions/checkout@v4
37+
38+
- name: Setup mise
39+
uses: jdx/mise-action@v2
40+
41+
- name: Install toolchain
42+
run: mise install
43+
44+
- name: Security checks
45+
run: mise run ci-security

mise.toml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
[tools]
2+
python = "3.13"
3+
4+
[tasks.fmt]
5+
description = "Format Nix files"
6+
run = '''
7+
set -euo pipefail
8+
nix fmt
9+
'''
10+
11+
[tasks.fmt-check]
12+
description = "Check Nix formatting"
13+
run = '''
14+
set -euo pipefail
15+
nix fmt -- --check .
16+
'''
17+
18+
[tasks.flake-check]
19+
description = "Run flake checks without building heavy outputs"
20+
run = '''
21+
set -euo pipefail
22+
nix flake check --no-build
23+
'''
24+
25+
[tasks.build-dryrun]
26+
description = "Dry-run build for canonical host configs"
27+
run = '''
28+
set -euo pipefail
29+
nix build .#nixosConfigurations.bit.config.system.build.toplevel --dry-run
30+
'''
31+
32+
[tasks.ci-validate]
33+
description = "CI validation pipeline"
34+
depends = ["fmt-check", "flake-check", "build-dryrun"]
35+
run = "echo 'validation complete'"
36+
37+
[tasks.ci-security]
38+
description = "CI security checks"
39+
run = '''
40+
set -euo pipefail
41+
python3 -m pip install --quiet detect-secrets
42+
43+
detect-secrets scan --baseline .secrets.baseline
44+
detect-secrets audit .secrets.baseline
45+
46+
if grep -rE "(password|secret|token|api_key|private_key)\\s*=\\s*['\\\"]\\S+" . --include="*.nix" | grep -v ".github"; then
47+
echo "Error: Found potential hardcoded secrets. Use sops-nix for secrets!"
48+
exit 1
49+
fi
50+
51+
if find . -type f -exec grep -l "BEGIN.*PRIVATE KEY" {} \\; | grep -v ".secrets.baseline"; then
52+
echo "Error: Found private keys in repository!"
53+
exit 1
54+
fi
55+
'''

modules/darwin/services.nix

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{ lib, pkgs, ... }:
2+
3+
{
4+
# Native nix-darwin service modules (prefer these over custom launchd jobs).
5+
services.postgresql.enable = lib.mkDefault true;
6+
services.redis.enable = lib.mkDefault true;
7+
services.eternal-terminal.enable = lib.mkDefault false;
8+
9+
# Services without first-class nix-darwin modules can still be managed via
10+
# launchd with nixpkgs binaries when needed.
11+
launchd.daemons.openvpn = {
12+
serviceConfig = {
13+
KeepAlive = true;
14+
RunAtLoad = false;
15+
ProgramArguments = [
16+
"${pkgs.openvpn}/sbin/openvpn"
17+
"--config"
18+
"/etc/openvpn/openvpn.conf"
19+
];
20+
};
21+
};
22+
23+
launchd.daemons.unbound = {
24+
serviceConfig = {
25+
KeepAlive = true;
26+
RunAtLoad = false;
27+
ProgramArguments = [
28+
"${pkgs.unbound}/sbin/unbound"
29+
"-d"
30+
"-c"
31+
"/etc/unbound/unbound.conf"
32+
];
33+
};
34+
};
35+
}

modules/users/giovanni.nix

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{ ... }:
2+
3+
{
4+
imports = [
5+
./ssh-config.nix
6+
./neovim
7+
./packages
8+
./runtimes-mise.nix
9+
];
10+
11+
# Home Manager configuration for user giovanni
12+
# This can be overridden per-host if needed
13+
14+
home.username = "giovanni";
15+
home.homeDirectory = "/home/giovanni";
16+
17+
# Git configuration
18+
programs.git = {
19+
enable = true;
20+
userName = "Giovanni";
21+
userEmail = "your.email@example.com"; # Change this
22+
extraConfig = {
23+
init.defaultBranch = "main";
24+
pull.rebase = true;
25+
};
26+
};
27+
28+
# Shell configuration
29+
programs.bash = {
30+
enable = true;
31+
shellAliases = {
32+
ll = "eza -la";
33+
cat = "bat";
34+
};
35+
};
36+
37+
# Fish shell (if preferred)
38+
# programs.fish.enable = true;
39+
40+
# This value determines the Home Manager release compatibility
41+
home.stateVersion = "24.11";
42+
43+
# Let Home Manager manage itself
44+
programs.home-manager.enable = true;
45+
}

modules/users/packages/core.nix

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{ pkgs, ... }:
2+
3+
{
4+
# Core user-facing CLI utilities.
5+
home.packages = with pkgs; [
6+
age
7+
bat
8+
bitwarden-cli
9+
chezmoi
10+
delta
11+
eza
12+
fd
13+
fzf
14+
ripgrep
15+
];
16+
}

modules/users/packages/default.nix

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
imports = [
3+
./core.nix
4+
./devops.nix
5+
];
6+
}

modules/users/packages/devops.nix

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{ pkgs, ... }:
2+
3+
{
4+
# Non-runtime devops/security utilities. Runtime/versioned tools are
5+
# intentionally owned by mise in runtimes-mise.nix.
6+
home.packages = with pkgs; [
7+
aws-vault
8+
checkov
9+
oci-cli
10+
trivy
11+
];
12+
}

modules/users/runtimes-mise.nix

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{ lib, pkgs, ... }:
2+
3+
let
4+
# These tools overlap with brew installs and should be version-owned by mise.
5+
runtimeTools = {
6+
awscli = "2.24.22";
7+
direnv = "2.21.3";
8+
gh = "2.45.0";
9+
go = "1.25.8";
10+
helm = "3.14.1";
11+
jq = "1.8.1";
12+
kubectl = "1.35.2";
13+
kubectx = "0.9.4";
14+
minikube = "1.37.0";
15+
neovim = "stable";
16+
node = "23.9.0";
17+
opentofu = "1.11.5";
18+
packer = "1.15.0";
19+
python = "3.13.12";
20+
shellcheck = "0.11.0";
21+
sops = "3.12.1";
22+
task = "3.49.1";
23+
terraform = "1.9.8";
24+
terraform-docs = "0.21.0";
25+
tflint = "0.55.1";
26+
tmux = "3.6a";
27+
trivy = "0.69.3";
28+
yq = "4.52.4";
29+
};
30+
in
31+
{
32+
# Keep version ownership centralized in mise, not mixed across package managers.
33+
programs.mise.enable = true;
34+
35+
# Ensure the executable is present even when the HM program module does not add it.
36+
home.packages = [ pkgs.mise ];
37+
38+
xdg.configFile."mise/config.toml".text = lib.concatStringsSep "\n"
39+
(
40+
[ "[tools]" ]
41+
++ map (name: "${name} = \"${runtimeTools.${name}}\"")
42+
(builtins.attrNames runtimeTools)
43+
) + "\n";
44+
}

0 commit comments

Comments
 (0)