Skip to content

Commit 062778a

Browse files
committedJan 27, 2025·
Implement NixOS configuration for webforge with CI/CD Nix workflow
Signed-off-by: Benoit Donneaux <benoit@leastauthority.com>
1 parent 67392a2 commit 062778a

18 files changed

+842
-0
lines changed
 

‎.github/workflows/nix.yml

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
name: Nix
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- '.github/workflows/nix.yml'
9+
- 'nix/**'
10+
- 'flake.*'
11+
- 'secrets/**'
12+
pull_request:
13+
paths:
14+
- '.github/workflows/nix.yml'
15+
- 'nix/**'
16+
- 'flake.*'
17+
- 'secrets/**'
18+
19+
jobs:
20+
check:
21+
name: Check
22+
runs-on: ubuntu-24.04
23+
outputs:
24+
matrix: ${{ steps.set-matrix.outputs.matrix }}
25+
steps:
26+
- name: Checkout
27+
id: checkout
28+
uses: actions/checkout@v4
29+
30+
- name: Install Nix
31+
id: install_nix
32+
uses: nixbuild/nix-quick-install-action@v28
33+
34+
- name: Check Nix Flake
35+
id: check
36+
run: |
37+
nix flake show
38+
nix flake check
39+
40+
- name: Set matrix
41+
id: set-matrix
42+
run: |
43+
# Extract targets from the flake
44+
IFS=","
45+
target_arr=( $(nix eval --json --apply 'builtins.attrNames' .#nixosConfigurations | sed -r -e 's/\[([^\[]+)\]/\1/' -e 's/"//g') )
46+
index=0
47+
size=${#target_arr[@]}
48+
output="matrix={\"include\":["
49+
IFS=" "
50+
for target in ${target_arr[@]}; do
51+
output+="{\"target\":\"${target}\","
52+
output+="\"hostname\":$(nix eval .#nixosConfigurations.${target}.config.networking.hostName),"
53+
output+="\"domain\":$(nix eval .#nixosConfigurations.${target}.config.networking.domain)}"
54+
if [[ $((index++)) -lt $((size -1)) ]]; then
55+
output+=","
56+
fi
57+
done
58+
output+="]}"
59+
echo $output
60+
echo $output >> $GITHUB_OUTPUT
61+
62+
build:
63+
name: Build
64+
runs-on: ubuntu-22.04
65+
if: github.event_name == 'pull_request'
66+
needs: check
67+
strategy:
68+
fail-fast: false
69+
matrix: ${{fromJson(needs.check.outputs.matrix)}}
70+
steps:
71+
- name: Checkout
72+
id: checkout
73+
uses: actions/checkout@v4
74+
75+
- name: Install Nix
76+
id: install_nix
77+
uses: nixbuild/nix-quick-install-action@v28
78+
79+
- name: Restore and cache Nix store ${{ matrix.target }}
80+
uses: nix-community/cache-nix-action@v5
81+
with:
82+
# restore and save a cache using this key
83+
primary-key: ${{ runner.os }}-Nix-${{ matrix.target }}-${{ hashFiles('flake.*', 'nix/common/*.nix', 'nix/modules/**.nix', format('nix/hosts/{0}/*.nix', matrix.target)) }}
84+
# if there's no cache hit, restore a cache by this prefix
85+
restore-prefixes-first-match: ${{ runner.os }}-Nix-${{ matrix.target }}-
86+
# collect garbage until Nix store size (in bytes) is at most this number
87+
# before trying to save a new cache
88+
gc-max-store-size-linux: 1073741824
89+
# do purge caches
90+
purge: true
91+
# purge all versions of the cache
92+
purge-prefixes: ${{ runner.os }}-Nix-${{ matrix.target }}-
93+
# created more than 0 seconds ago relative to the start of the `Post Restore` phase
94+
purge-created: 0
95+
# except the version with the `primary-key`, if it exists
96+
purge-primary-key: never
97+
98+
- name: Build nixosConfiguration for ${{ matrix.target }}
99+
id: check_target
100+
run: |
101+
nix build .#nixosConfigurations.${{ matrix.target }}.config.system.build.toplevel
102+
103+
deploy:
104+
name: Deploy
105+
runs-on: ubuntu-24.04
106+
if: github.ref == 'refs/heads/main'
107+
needs: check
108+
strategy:
109+
fail-fast: false
110+
matrix: ${{fromJson(needs.check.outputs.matrix)}}
111+
steps:
112+
- name: Checkout
113+
id: checkout
114+
uses: actions/checkout@v4
115+
116+
- name: Load ssh key in agent
117+
id: ssh_agent
118+
uses: LeastAuthority/ssh-agent-action@v1
119+
with:
120+
private_key: ${{ secrets.DEPLOYMENT_SSH_KEY }}
121+
122+
- name: Deploy nixosConfiguration on ${{ matrix.target }}
123+
id: deploy_target
124+
run: |
125+
# Specifying the target revision we want to deploy
126+
target_rev=$(git log -n 1 --format='format:%H')
127+
echo "Target revision: ${target_rev}"
128+
echo -n "${target_rev}" | \
129+
ssh -T -o "UserKnownHostsFile=nix/known_hosts" "bot-cd@${{ matrix.hostname }}.${{ matrix.domain }}"

‎.sops.yaml

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# This files uses YAML anchors which allows reuse of multiple keys
2+
# without having to repeat yourself.
3+
# Also see https://github.com/Mic92/dotfiles/blob/master/nixos/.sops.yaml
4+
# for a more complex example.
5+
keys:
6+
# The following public keys can be found in secrets/.public-keys
7+
# They have to be imported and trusted
8+
# E.g.: `gpg --import ...` and `gpg --edit-key ...`
9+
# First the GPG fingerprints of the admin (hardware token recommanded)
10+
- &adm_btlogy 411eb16d13b422490feba1155a7a09f0c279fcd6
11+
- &adm_hacklschorsch 5244970fbec8aa66658ec4b6d7d4a441431a73f1
12+
# Then the GPG fingerprints derivated of the sshd RSA key of the servers
13+
# which can be obtain by running the following command on the server
14+
# nix-shell -p ssh-to-pgp --run "ssh-to-pgp -i /etc/ssh/ssh_host_rsa_key"
15+
- &srv_webforge 122ace3a40ab7fc47e5659c29c159e5083d0ed64
16+
creation_rules:
17+
# The following files can be created with:
18+
# `nix-shell -p sops --run "sops <file>"`
19+
# To update after changing the keys:
20+
# `nix-shell -p sops --run "sops updatekeys <file>"`
21+
- path_regex: secrets/common\.(yaml|json|env|ini)$
22+
key_groups:
23+
- pgp:
24+
- *adm_btlogy
25+
- *adm_hacklschorsch
26+
- *srv_webforge
27+
- path_regex: secrets/webforge\.(yaml|json|env|ini)$
28+
key_groups:
29+
- pgp:
30+
- *adm_btlogy
31+
- *adm_hacklschorsch
32+
- *srv_webforge
33+
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
34+
key_groups:
35+
- pgp:
36+
- *adm_btlogy
37+
- *adm_hacklschorsch

‎flake.lock

+184
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.