Skip to content

Implement NixOS configuration for webforge with CI/CD Nix workflow #1

Implement NixOS configuration for webforge with CI/CD Nix workflow

Implement NixOS configuration for webforge with CI/CD Nix workflow #1

Workflow file for this run

name: Nix
on:
push:
branches:
- main
paths:
- '.github/workflows/nix.yml'
- 'nix/**'
- 'flake.*'
- 'secrets/**'
pull_request:
paths:
- '.github/workflows/nix.yml'
- 'nix/**'
- 'flake.*'
- 'secrets/**'
jobs:
check:
name: Check
runs-on: ubuntu-24.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
- name: Install Nix
id: install_nix
uses: nixbuild/nix-quick-install-action@v28
- name: Check Nix Flake
id: check
run: |
nix flake show
nix flake check
- name: Set matrix
id: set-matrix
run: |
# Extract targets from the flake
IFS=","
target_arr=( $(nix eval --json --apply 'builtins.attrNames' .#nixosConfigurations | sed -r -e 's/\[([^\[]+)\]/\1/' -e 's/"//g') )
index=0
size=${#target_arr[@]}
output="matrix={\"include\":["
IFS=" "
for target in ${target_arr[@]}; do
output+="{\"target\":\"${target}\","
output+="\"hostname\":$(nix eval .#nixosConfigurations.${target}.config.networking.hostName),"
output+="\"domain\":$(nix eval .#nixosConfigurations.${target}.config.networking.domain)}"
if [[ $((index++)) -lt $((size -1)) ]]; then
output+=","
fi
done
output+="]}"
echo $output
echo $output >> $GITHUB_OUTPUT
build:
name: Build
runs-on: ubuntu-22.04
if: github.event_name == 'pull_request'
needs: check
strategy:
fail-fast: false
matrix: ${{fromJson(needs.check.outputs.matrix)}}
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
- name: Install Nix
id: install_nix
uses: nixbuild/nix-quick-install-action@v28
- name: Restore and cache Nix store ${{ matrix.target }}
uses: nix-community/cache-nix-action@v5
with:
# restore and save a cache using this key
primary-key: ${{ runner.os }}-Nix-${{ matrix.target }}-${{ hashFiles('flake.*', 'nix/common/*.nix', 'nix/modules/**.nix', format('nix/hosts/{0}/*.nix', matrix.target)) }}
# if there's no cache hit, restore a cache by this prefix
restore-prefixes-first-match: ${{ runner.os }}-Nix-${{ matrix.target }}-
# collect garbage until Nix store size (in bytes) is at most this number
# before trying to save a new cache
gc-max-store-size-linux: 1073741824
# do purge caches
purge: true
# purge all versions of the cache
purge-prefixes: ${{ runner.os }}-Nix-${{ matrix.target }}-
# created more than 0 seconds ago relative to the start of the `Post Restore` phase
purge-created: 0
# except the version with the `primary-key`, if it exists
purge-primary-key: never
- name: Build nixosConfiguration for ${{ matrix.target }}
id: check_target
run: |
nix build .#nixosConfigurations.${{ matrix.target }}.config.system.build.toplevel
deploy:
name: Deploy
runs-on: ubuntu-24.04
if: github.ref == 'refs/heads/main'
needs: check
strategy:
fail-fast: false
matrix: ${{fromJson(needs.check.outputs.matrix)}}
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
- name: Load ssh key in agent
id: ssh_agent
uses: LeastAuthority/ssh-agent-action@v1
with:
private_key: ${{ secrets.DEPLOYMENT_SSH_KEY }}
- name: Deploy nixosConfiguration on ${{ matrix.target }}
id: deploy_target
run: |
# Specifying the target revision we want to deploy
target_rev=$(git log -n 1 --format='format:%H')
echo "Target revision: ${target_rev}"
echo -n "${target_rev}" | \
ssh -T -o "UserKnownHostsFile=nix/known_hosts" "bot-cd@${{ matrix.hostname }}.${{ matrix.domain }}"