Automatically publishing using git push

Now that my site is hosted on Google Cloud, I wanted to automatically publish on git push. Easy enough:

Inspired by another post-receive setup in a Nix environment, I slightly adapted his configuration like this:

# This is /etc/nixos/gefla-blog.nix
{ config, lib, pkgs, ... }:
let
  home = "/var/lib/blog";

  env = pkgs.buildEnv {
    name = "post-receive-env";
    paths = with pkgs; [
      git
      google-cloud-sdk
      hugo
      nix
      coreutils
      gnutar
      xz
    ];
  };

  post-receive = pkgs.writeShellScript "post-receive" ''
    export PATH=${env}/bin
    set -ex

    GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
    if [ -z "$GIT_DIR" ]; then
            echo >&2 "fatal: post-receive: GIT_DIR not set"
            exit 1
    fi

    TMPDIR=$(mktemp -d)
    function cleanup() {
      rm -rf "$TMPDIR"
    }
    trap cleanup EXIT

    git clone "$GIT_DIR" "$TMPDIR"
    unset GIT_DIR
    cd "$TMPDIR"
    git submodule update --init --recursive
    hugo
    exec gsutil rsync -R public/. gs://gerd-flaig-blog
  '';
in
{
  config = {
    users.users.blog = {
      inherit home;
      createHome = true;
      isNormalUser = true;
      # openssh = config.users.users.gefla.openssh
    };
    systemd.services."blog-prepare-git-repo" = {
      wantedBy = [ "multi-user.target" ];
      path = [
        pkgs.git
      ];
      script = ''
        set -ex
        cd ${home}
        chmod +rX ${home} # no secrets in that home dir, everyone can read my public blog
        test -e repo || git init --bare repo
        ln -nsf ${post-receive} repo/hooks/post-receive
      '';
      serviceConfig = {
        Kind = "one-shot";
        User = "blog";
      };
    };
  };
}

Then I added it to /etc/nixos/configuration.nix like so:

{ config, pkgs, ...  }:

{
  imports = [ ./gefla-blog.nix ];
  
  # rest of my config
}

Next, I created a service account with access to the storage bucket, downloaded the key file and authenticated using

$ sudo -u blog -s
blog$ gcloud auth activate-service-account --key-file ${key_file}

Lastly, in a copy of my blog repository, I added a public branch and did my first push:

$ cd blog
$ git remote add public blog@myserver:repo
$ git push public
[...]
remote: + cd /tmp/tmp.SX2yKBomL9
remote: + hugo
[...]
remote: Total in 17 ms
remote: + exec gsutil rsync -R public/. gs://gerd-flaig-blog
remote: Building synchronization state...
remote: Starting synchronization...
remote: Copying file://public/./categories/index.xml [Content-Type=text/xml]...
[...]

Done!

Optional: Invalidate CDN cache after push using something like gcloud compute url-maps invalidate-cdn-cache blog-lb --path=/.