Add webhook-triggered rebuilds for Pelican sites
Adds a webhook-deploy service that listens for Codeberg push events and triggers per-site nixos-rebuild runs. Skips rebuilds if the flake lock revision is unchanged. Fixes root SSH client config so nix flake update can reach Codeberg using the existing deploy key. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
cd4d53386c
commit
bb419a13af
4 changed files with 94 additions and 2 deletions
87
modules/services/webhook-deploy.nix
Normal file
87
modules/services/webhook-deploy.nix
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
sites = [
|
||||
{ name = "sublunar"; input = "sublunar"; }
|
||||
{ name = "tobias-raayoni-last"; input = "flux_vision"; }
|
||||
{ name = "nmns"; input = "nfc_web"; }
|
||||
];
|
||||
|
||||
# Template hooks.json with a placeholder secret — real secret injected at
|
||||
# service start time from the sops-managed file.
|
||||
hooksTemplate = pkgs.writeText "webhook-hooks-template.json" (builtins.toJSON
|
||||
(map (site: {
|
||||
id = "rebuild-${site.name}";
|
||||
execute-command = "/run/current-system/sw/bin/systemctl";
|
||||
pass-arguments-to-command = [
|
||||
{ source = "string"; name = "start"; }
|
||||
{ source = "string"; name = "--no-block"; }
|
||||
{ source = "string"; name = "update-${site.name}"; }
|
||||
];
|
||||
response-message = "Queued rebuild of ${site.name}";
|
||||
trigger-rule.match = {
|
||||
type = "payload-hmac-sha256";
|
||||
secret = "placeholder";
|
||||
parameter = { source = "header"; name = "X-Gitea-Signature"; };
|
||||
};
|
||||
}) sites)
|
||||
);
|
||||
|
||||
# Writes /run/webhook-deploy/hooks.json with the real secret at startup.
|
||||
makeHooks = pkgs.writeShellScript "make-webhook-hooks" ''
|
||||
set -euo pipefail
|
||||
${pkgs.jq}/bin/jq \
|
||||
--arg s "$(cat ${config.sops.secrets.webhook_secret.path})" \
|
||||
'map(.["trigger-rule"].match.secret = $s)' \
|
||||
${hooksTemplate} > /run/webhook-deploy/hooks.json
|
||||
'';
|
||||
|
||||
updateScript = site: pkgs.writeShellScript "do-update-${site.name}" ''
|
||||
set -euo pipefail
|
||||
cd /etc/nixos
|
||||
OLD=$(${pkgs.jq}/bin/jq -r '.nodes.${site.input}.locked.rev' flake.lock)
|
||||
nix flake update ${site.input}
|
||||
NEW=$(${pkgs.jq}/bin/jq -r '.nodes.${site.input}.locked.rev' flake.lock)
|
||||
if [ "$OLD" = "$NEW" ]; then
|
||||
echo "${site.name}: no change, skipping rebuild"
|
||||
exit 0
|
||||
fi
|
||||
echo "${site.name}: updated $OLD -> $NEW, rebuilding"
|
||||
nixos-rebuild switch --flake /etc/nixos#bucur
|
||||
'';
|
||||
in
|
||||
{
|
||||
sops.secrets.webhook_secret = {
|
||||
owner = "root";
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
# System-wide SSH client config so root can reach Codeberg via the deploy key.
|
||||
programs.ssh.extraConfig = ''
|
||||
Host codeberg.org
|
||||
IdentityFile /etc/ssh/codeberg_id_ed25519
|
||||
StrictHostKeyChecking accept-new
|
||||
'';
|
||||
|
||||
systemd.services = lib.listToAttrs
|
||||
(map (site: lib.nameValuePair "update-${site.name}" {
|
||||
description = "Pull and rebuild ${site.name}";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = updateScript site;
|
||||
};
|
||||
}) sites)
|
||||
// {
|
||||
webhook-deploy = {
|
||||
description = "Webhook server for Pelican site rebuilds";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" "sops-nix.service" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
RuntimeDirectory = "webhook-deploy";
|
||||
ExecStartPre = "+${makeHooks}";
|
||||
ExecStart = "${pkgs.webhook}/bin/webhook -hooks /run/webhook-deploy/hooks.json -port 9000";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue