difftreelog
ci post results as a comment
in: master
2 files changed
flake.nixdiffbeforeafterboth--- a/flake.nix
+++ b/flake.nix
@@ -39,12 +39,104 @@
mkForce
optionals
optionalAttrs
+ concatMapStringsSep
;
+ rel = system: inputs.self.legacyPackages.${system}.release;
+ releaseSections = [
+ {
+ name = "Linux (glibc)";
+ artifacts = [
+ {
+ label = "jrsonnet-x86_64-linux-glibc";
+ drv = (rel "x86_64-linux").jrsonnet-linux-glibc;
+ }
+ {
+ label = "jrsonnet-experimental-x86_64-linux-glibc";
+ drv = (rel "x86_64-linux").jrsonnet-experimental-linux-glibc;
+ }
+ {
+ label = "jrsonnet-aarch64-linux-glibc";
+ drv = (rel "aarch64-linux").jrsonnet-linux-glibc;
+ }
+ {
+ label = "jrsonnet-experimental-aarch64-linux-glibc";
+ drv = (rel "aarch64-linux").jrsonnet-experimental-linux-glibc;
+ }
+ {
+ label = "jrsonnet-i686-linux-glibc";
+ drv = (rel "i686-linux").jrsonnet-linux-glibc;
+ }
+ {
+ label = "jrsonnet-experimental-i686-linux-glibc";
+ drv = (rel "i686-linux").jrsonnet-experimental-linux-glibc;
+ }
+ {
+ label = "jrsonnet-armv7l-linux-glibc";
+ drv = (rel "armv7l-linux").jrsonnet-linux-glibc;
+ }
+ {
+ label = "jrsonnet-experimental-armv7l-linux-glibc";
+ drv = (rel "armv7l-linux").jrsonnet-experimental-linux-glibc;
+ }
+ ];
+ }
+ {
+ name = "Linux (musl)";
+ artifacts = [
+ {
+ label = "jrsonnet-x86_64-linux-musl";
+ drv = (rel "x86_64-linux").jrsonnet-linux-musl;
+ }
+ {
+ label = "jrsonnet-experimental-x86_64-linux-musl";
+ drv = (rel "x86_64-linux").jrsonnet-experimental-linux-musl;
+ }
+ {
+ label = "jrsonnet-aarch64-linux-musl";
+ drv = (rel "aarch64-linux").jrsonnet-linux-musl;
+ }
+ {
+ label = "jrsonnet-experimental-aarch64-linux-musl";
+ drv = (rel "aarch64-linux").jrsonnet-experimental-linux-musl;
+ }
+ ];
+ }
+ {
+ name = "macOS";
+ artifacts = [
+ {
+ label = "jrsonnet-aarch64-darwin";
+ drv = (rel "aarch64-linux").jrsonnet-darwin;
+ }
+ {
+ label = "jrsonnet-experimental-aarch64-darwin";
+ drv = (rel "aarch64-linux").jrsonnet-experimental-darwin;
+ }
+ ];
+ }
+ {
+ name = "Windows";
+ artifacts = [
+ {
+ label = "jrsonnet-x86_64-windows";
+ drv = (rel "x86_64-linux").jrsonnet-windows;
+ windows = true;
+ }
+ {
+ label = "jrsonnet-experimental-x86_64-windows";
+ drv = (rel "x86_64-linux").jrsonnet-experimental-windows;
+ windows = true;
+ }
+ ];
+ }
+ ];
+ releaseArtifacts = builtins.concatMap (s: s.artifacts) releaseSections;
in
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
inputs.shelly.flakeModule
inputs.hercules-ci-effects.flakeModule
+ ./nix/post-comment.nix
];
systems = [
"x86_64-linux"
@@ -310,80 +402,10 @@
]);
};
};
- hercules-ci.github-releases.files =
- let
- rel = system: inputs.self.legacyPackages.${system}.release;
- bin = drv: "${drv}/bin/jrsonnet";
- exe = drv: "${drv}/bin/jrsonnet.exe";
- in
- [
- {
- label = "jrsonnet-x86_64-linux-musl";
- path = bin (rel "x86_64-linux").jrsonnet-linux-musl;
- }
- {
- label = "jrsonnet-experimental-x86_64-linux-musl";
- path = bin (rel "x86_64-linux").jrsonnet-experimental-linux-musl;
- }
- {
- label = "jrsonnet-aarch64-darwin";
- path = bin (rel "aarch64-linux").jrsonnet-darwin;
- }
- {
- label = "jrsonnet-experimental-aarch64-darwin";
- path = bin (rel "aarch64-linux").jrsonnet-experimental-darwin;
- }
- {
- label = "jrsonnet-x86_64-windows.exe";
- path = exe (rel "x86_64-linux").jrsonnet-windows;
- }
- {
- label = "jrsonnet-experimental-x86_64-windows.exe";
- path = exe (rel "x86_64-linux").jrsonnet-experimental-windows;
- }
-
- {
- label = "jrsonnet-aarch64-linux-musl";
- path = bin (rel "aarch64-linux").jrsonnet-linux-musl;
- }
- {
- label = "jrsonnet-experimental-aarch64-linux-musl";
- path = bin (rel "aarch64-linux").jrsonnet-experimental-linux-musl;
- }
-
- {
- label = "jrsonnet-x86_64-linux-glibc";
- path = bin (rel "x86_64-linux").jrsonnet-linux-glibc;
- }
- {
- label = "jrsonnet-experimental-x86_64-linux-glibc";
- path = bin (rel "x86_64-linux").jrsonnet-experimental-linux-glibc;
- }
- {
- label = "jrsonnet-aarch64-linux-glibc";
- path = bin (rel "aarch64-linux").jrsonnet-linux-glibc;
- }
- {
- label = "jrsonnet-experimental-aarch64-linux-glibc";
- path = bin (rel "aarch64-linux").jrsonnet-experimental-linux-glibc;
- }
- {
- label = "jrsonnet-i686-linux-glibc";
- path = bin (rel "i686-linux").jrsonnet-linux-glibc;
- }
- {
- label = "jrsonnet-experimental-i686-linux-glibc";
- path = bin (rel "i686-linux").jrsonnet-experimental-linux-glibc;
- }
- {
- label = "jrsonnet-armv7l-linux-glibc";
- path = bin (rel "armv7l-linux").jrsonnet-linux-glibc;
- }
- {
- label = "jrsonnet-experimental-armv7l-linux-glibc";
- path = bin (rel "armv7l-linux").jrsonnet-experimental-linux-glibc;
- }
- ];
+ hercules-ci.github-releases.files = map (a: {
+ label = a.label + (if a.windows or false then ".exe" else "");
+ path = "${a.drv}/bin/jrsonnet${if a.windows or false then ".exe" else ""}";
+ }) releaseArtifacts;
hercules-ci.cargo-publish = {
enable = true;
secretName = "crates-io";
@@ -398,6 +420,30 @@
dayOfWeek = [ "Sat" ];
};
};
+ hercules-ci.post-comment = {
+ enable = true;
+ caches = [ "jrsonnet.cachix.org" ];
+ script =
+ let
+ benchmarks = inputs.self.legacyPackages.x86_64-linux.benchmarks.default;
+ renderSection = s: ''
+ echo
+ echo "### ${s.name}"
+ echo
+ ${concatMapStringsSep "\n" (a: ''echo "- [${a.label}]($(nixTar ${a.drv}))"'') s.artifacts}
+ '';
+ in
+ ''
+ {
+ echo "## Benchmark results"
+ echo
+ echo "[View rendered]($(nixRender ${benchmarks}))"
+ echo
+ echo "## Downloads"
+ ${concatMapStringsSep "\n" renderSection releaseSections}
+ } > $out
+ '';
+ };
herculesCI =
{ lib, config, ... }:
{
nix/post-comment.nixdiffbeforeafterboth1{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=readSecretString102 ogSecret=readSecretString103 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=mktemp136 ${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}