git.delta.rocks / jrsonnet / refs/heads / master

difftreelog

source

nix/post-comment.nix4.5 KiBsourcehistory
1{2  config,3  lib,4  withSystem,5  ...6}:7let8  inherit (lib)9    mkOption10    mkIf11    types12    concatStringsSep13    ;14  cfg = config.hercules-ci.post-comment;15in16{17  options.hercules-ci.post-comment = {18    enable = mkOption {19      type = types.bool;20      default = false;21      description = ''22        Whether to post a GitHub commit comment for every commit Hercules CI runs on.23      '';24    };25    script = mkOption {26      type = types.lines;27      description = ''28        Bash snippet that writes the comment body to `$out`. Runs as part of the effect29        (after secrets are loaded), so the helpers below are in scope:3031        - `nixTar <store-path>` — prints a signed deltarocks URL that streams the path32          as a tar.zst, realised through the configured caches.33        - `nixRender <store-path>` — prints a signed deltarocks URL that renders the34          path's AsciiDoc content as HTML.35      '';36      example = lib.literalExpression ''37        '''38          {39            echo "Render: $(nixRender ''${benchmarks})"40            echo "Tar:    $(nixTar ''${binary})"41          } > $out42        '''43      '';44    };45    system = mkOption {46      type = types.str;47      default = "x86_64-linux";48      description = ''49        System on which the effect runs.50      '';51    };52    baseUrl = mkOption {53      type = types.str;54      default = "https://delta.rocks";55      description = ''56        Base URL of the deltarocks signing service.57      '';58    };59    caches = mkOption {60      type = types.listOf types.str;61      default = [ ];62      example = [ "jrsonnet.cachix.org" ];63      description = ''64        Cache hosts the signing service should use as substituters when realising the65        signed store path.66      '';67    };68    signSecret = mkOption {69      type = types.str;70      default = "deltarocks-nix-sign";71      description = ''72        Name of the Hercules CI agent secret that holds the deltarocks signing key.73        Its `data` must have a field named `ogSecret`.74      '';75    };76  };7778  config = mkIf cfg.enable {79    herculesCI =80      { config, ... }:81      {82        onPush.default.outputs.effects.post-comment = withSystem cfg.system (83          { pkgs, hci-effects, ... }:84          hci-effects.mkEffect {85            name = "post-comment";86            inputs = [ pkgs.openssl ];87            secretsMap = {88              token = {89                type = "GitToken";90              };91              ogSecret = cfg.signSecret;92            };93            owner = config.repo.owner;94            repoName = config.repo.name;95            rev = config.repo.rev;96            baseUrl = cfg.baseUrl;97            caches = concatStringsSep " " cfg.caches;98            effectScript = ''99              set -euo pipefail100101              token=$(readSecretString token .token)102              ogSecret=$(readSecretString ogSecret .ogSecret)103              read -ra cacheArr <<<"$caches"104              if [[ ''${#cacheArr[@]} -eq 0 ]]; then105                echo "hercules-ci.post-comment: at least one cache host is required" >&2106                exit 1107              fi108              sortedCaches=$(printf '%s\n' "''${cacheArr[@]}" | LC_ALL=C sort | paste -sd,)109110              _hmacHex() {111                printf '%s' "$1" \112                  | openssl dgst -sha256 -hmac "$ogSecret" -hex \113                  | sed 's/^.*= //'114              }115116              _uri() {117                jq -nj --arg s "$1" '$s|@uri'118              }119120              _signedUrl() {121                local endpoint=$1 drv=$2122                local sig123                sig=$(_hmacHex "''${endpoint}:''${sortedCaches}:''${drv}")124                local query=""125                for c in "''${cacheArr[@]}"; do126                  query+="cache=$(_uri "$c")&"127                done128                query+="drv=$(_uri "$drv")&sig=''${sig}"129                printf '%s/%s?%s' "$baseUrl" "$endpoint" "$query"130              }131132              nixTar() { _signedUrl nixTar "$1"; }133              nixRender() { _signedUrl nixRender "$1"; }134135              out=$(mktemp)136              ${cfg.script}137138              jq -n --rawfile content "$out" '{body: $content}' \139                | curl -fsSL -X POST \140                    -H "Authorization: Bearer $token" \141                    -H "Accept: application/vnd.github+json" \142                    -H "X-GitHub-Api-Version: 2022-11-28" \143                    --data-binary @- \144                    "https://api.github.com/repos/$owner/$repoName/commits/$rev/comments"145            '';146          }147        );148      };149  };150}