grace/dots

dotfiles/nix configs

git clone https://git.gae.moe/grace/dots

Grace Yoderidk003ed04

main
2.7 KiB119 linesraw
1{ pkgs, lib, ... }:
2
3let
4  gitDir = "/mnt/ext/git";
5
6  deploy = pkgs.writeShellScript "git-deploy" ''
7    set -euo pipefail
8
9    export PATH="${
10      lib.makeBinPath [
11        pkgs.git
12        pkgs.gnutar
13        pkgs.coreutils
14        pkgs.nix
15      ]
16    }:$PATH"
17
18    export NIX_PATH="nixpkgs=${pkgs.path}"
19
20    repo="$1"
21    rev="$2"
22    artifactDir="$3"
23    htmlDir="$4"
24    ref="$5"
25
26    tmp="$(mktemp -d)"
27    finish() {
28      status=$?
29      trap - EXIT
30      rm -rf "$tmp"
31      if [ "$status" -eq 0 ]; then
32        outcome=succeeded
33      else
34        outcome=failed
35      fi
36      credentials=/var/lib/git-build-notify/credentials.curl
37      if [ -r "$credentials" ]; then
38        printf 'Build/deploy %s: %s (%s) at %s\nArtifacts: %s\n' \
39          "$outcome" "$repo" "$ref" "$rev" "$artifactDir" |
40          ${pkgs.curl}/bin/curl --config "$credentials" \
41            --fail --silent --show-error --connect-timeout 3 --max-time 10 \
42            --header "Title: Git build/deploy $outcome" \
43            --data-binary @- --output /dev/null \
44            https://ntfy.gae.moe/githooks || true
45      fi
46      exit "$status"
47    }
48    trap finish EXIT
49
50    while read -r key; do
51      unset "$key"
52    done < <(git rev-parse --local-env-vars)
53
54    git -C "$repo" archive "$rev" | tar -xf - -C "$tmp"
55    cd "$tmp"
56
57    result="$(nix-build --no-out-link ./hook.nix \
58      --argstr artifactDir "$artifactDir" \
59      --argstr htmlDir "$htmlDir")"
60
61    mkdir -p "$artifactDir" "$htmlDir"
62    "$result/bin/deploy"
63  '';
64in
65{
66  users.users.git.linger = true;
67
68  programs.git = {
69    enable = true;
70    config.core.hooksPath = "/etc/git/hooks";
71  };
72
73  environment.etc."git/hooks/post-receive".source = pkgs.writeShellScript "post-receive" ''
74    set -euo pipefail
75
76    export PATH="${
77      lib.makeBinPath [
78        pkgs.git
79        pkgs.coreutils
80        pkgs.systemd
81      ]
82    }:$PATH"
83
84    export XDG_RUNTIME_DIR="/run/user/$(id -u)"
85
86    root="${gitDir}"
87    repoPath="$(pwd -P)"
88
89    case "$repoPath" in
90      "$root"/*) ;;
91      *) exit 0 ;;
92    esac
93
94    repo="''${repoPath#"$root"/}"
95    repo="''${repo%.git}"
96
97    while read -r old new ref; do
98      case "$ref" in
99        refs/heads/*) name="''${ref#refs/heads/}" ;;
100        refs/tags/*) name="''${ref#refs/tags/}" ;;
101        *) continue ;;
102      esac
103      [[ "$new" =~ ^0+$ ]] && continue
104
105      git cat-file -e "$new:hook.nix" 2>/dev/null || continue
106
107      systemd-run --user --no-block --collect \
108        --unit="git-deploy-$(date +%s%N)-$RANDOM" \
109        "${deploy}" \
110        "$repoPath" \
111        "$new" \
112        "${gitDir}/artifacts/$repo/$name" \
113        "${gitDir}/www/$repo/$name" \
114        "$ref"
115
116      echo "Queued deployment for $ref" >&2
117    done
118  '';
119}