From 847e216e9acb5f10ae16f09424cb7e6dfbf99838 Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Sat, 23 Sep 2023 04:03:53 +0200 Subject: [PATCH] nix: refactor library --- flake.nix | 12 +++---- lib/default.nix | 12 +++++++ lib/github/default.nix | 6 ++++ lib/github/mkGithubJobsets.nix | 34 ++++++++++++++++++ lib/github/mkGithubProject.nix | 29 ++++++++++++++++ lib/github/mkGithubStatus.nix | 63 ++++++++++++++++++++++++++++++++++ lib/mkAction.nix | 8 +++++ lib/mkGitJobsets.nix | 29 ++++++++++++++++ lib/mkProject.nix | 35 +++++++++++++++++++ lib/systems.nix | 3 ++ lib/utils.nix | 18 ++++++++++ secrets | 0 12 files changed, 243 insertions(+), 6 deletions(-) create mode 100644 lib/default.nix create mode 100644 lib/github/default.nix create mode 100644 lib/github/mkGithubJobsets.nix create mode 100644 lib/github/mkGithubProject.nix create mode 100644 lib/github/mkGithubStatus.nix create mode 100644 lib/mkAction.nix create mode 100644 lib/mkGitJobsets.nix create mode 100644 lib/mkProject.nix create mode 100644 lib/systems.nix create mode 100644 lib/utils.nix create mode 100644 secrets diff --git a/flake.nix b/flake.nix index 5ccdf798..fed61312 100644 --- a/flake.nix +++ b/flake.nix @@ -18,14 +18,16 @@ }; }; - outputs = { + outputs = inputs @ { self, flake-utils, nixpkgs, crane, rust-overlay, - }: - flake-utils.lib.eachDefaultSystem (system: let + }: let + lib = import ./lib inputs; + in + flake-utils.lib.eachSystem lib.systems (system: let pkgs = import nixpkgs { inherit system; overlays = [(import rust-overlay)]; @@ -42,7 +44,6 @@ pkgs.callPackage ./nix/api-client-test.nix {inherit craneLib;}; typhon-devshell = pkgs.callPackage ./nix/devshell.nix {inherit rustToolchain;}; - typhon-actions = import ./nix/actions {inherit pkgs;}; in { packages = { inherit typhon typhon-webapp typhon-doc typhon-api-client-test; @@ -58,10 +59,9 @@ formatted = pkgs.callPackage ./nix/check-formatted.nix {inherit rustToolchain;}; nixos = pkgs.callPackage ./nix/nixos/test.nix {typhon = self;}; }; - - actions = typhon-actions; }) // { + inherit lib; nixosModules.default = import ./nix/nixos/typhon.nix self; }; } diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 00000000..50aedb5b --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,12 @@ +inputs: let + utils = import ./utils.nix inputs; + x = utils.importer "lib" [ + ./github + ./mkAction.nix + ./mkGitJobsets.nix + ./mkProject.nix + ./systems.nix + ] + x; +in + x.lib diff --git a/lib/github/default.nix b/lib/github/default.nix new file mode 100644 index 00000000..345426ad --- /dev/null +++ b/lib/github/default.nix @@ -0,0 +1,6 @@ +utils: +utils.importer "github" [ + ./mkGithubJobsets.nix + ./mkGithubProject.nix + ./mkGithubStatus.nix +] diff --git a/lib/github/mkGithubJobsets.nix b/lib/github/mkGithubJobsets.nix new file mode 100644 index 00000000..3160ecda --- /dev/null +++ b/lib/github/mkGithubJobsets.nix @@ -0,0 +1,34 @@ +utils: {lib}: let + inherit + (lib) + mkAction + ; +in { + mkGithubJobsets = { + owner, + repo, + }: + mkAction (system: let + pkgs = utils.pkgs.${system}; + in + pkgs.writeShellApplication { + name = "action"; + runtimeInputs = [ + pkgs.curl + pkgs.gnused + pkgs.jq + ]; + text = '' + input=$(cat) + + token=$(echo "$input" | jq '.secrets.github_token' -r) + + curl -s \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $token" \ + https://api.github.com/repos/${owner}/${repo}/branches \ + -k \ + | jq --arg o "${owner}" --arg r "${repo}" 'map({ key: .name, value: { "flake": ("github:" + $o + "/" + $r + "/" + .name) }}) | from_entries' + ''; + }); +} diff --git a/lib/github/mkGithubProject.nix b/lib/github/mkGithubProject.nix new file mode 100644 index 00000000..ce29ed26 --- /dev/null +++ b/lib/github/mkGithubProject.nix @@ -0,0 +1,29 @@ +_: {lib}: let + inherit + (lib) + mkProject + ; + inherit + (lib.github) + mkGithubJobsets + mkGithubStatus + ; +in { + mkGithubProject = { + owner, + repo, + secrets, + title ? repo, + description ? "", + homepage ? "https://github.com/${owner}/${repo}", + }: + mkProject { + meta = {inherit title description homepage;}; + actions = { + jobsets = mkGithubJobsets {inherit owner repo;}; + begin = mkGithubStatus {inherit owner repo;}; + end = mkGithubStatus {inherit owner repo;}; + }; + inherit secrets; + }; +} diff --git a/lib/github/mkGithubStatus.nix b/lib/github/mkGithubStatus.nix new file mode 100644 index 00000000..f69670a6 --- /dev/null +++ b/lib/github/mkGithubStatus.nix @@ -0,0 +1,63 @@ +utils: {lib}: let + inherit + (lib) + mkAction + ; +in { + mkGithubStatus = { + owner, + repo, + }: + mkAction (system: let + pkgs = utils.pkgs.${system}; + in + pkgs.writeShellApplication { + name = "action"; + runtimeInputs = [ + pkgs.curl + pkgs.gnused + pkgs.jq + ]; + text = '' + input=$(cat) + + build=$(echo "$input" | jq '.input.build' -r) + data=$(echo "$input" | jq '.input.data' -r) + evaluation=$(echo "$input" | jq '.input.evaluation' -r) + flake_locked=$(echo "$input" | jq '.input.flake_locked' -r) + job=$(echo "$input" | jq '.input.job' -r) + jobset=$(echo "$input" | jq '.input.jobset' -r) + project=$(echo "$input" | jq '.input.project' -r) + status=$(echo "$input" | jq '.input.status' -r) + + token=$(echo "$input" | jq '.secrets.github_token' -r) + + rev=$(echo "$flake_locked" | sed 's/github:.*\/.*\/\(.*\)/\1/') + target_url="$(echo "$data" | jq '.url' -r)/builds/$build" + context="Typhon: $job" + description="$project:$jobset:$evaluation:$job" + case $status in + "error") + state="failure" + ;; + "pending") + state="pending" + ;; + "success") + state="success" + ;; + *) + state="error" + ;; + esac + + curl -s \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $token" \ + "https://api.github.com/repos/${owner}/${repo}/statuses/$rev" \ + -d "{\"state\":\"$state\",\"target_url\":\"$target_url\",\"description\":\"$description\",\"context\":\"$context\"}" \ + -k >&2 + ''; + }); +} diff --git a/lib/mkAction.nix b/lib/mkAction.nix new file mode 100644 index 00000000..4c8de00b --- /dev/null +++ b/lib/mkAction.nix @@ -0,0 +1,8 @@ +utils: {lib}: let + inherit + (lib) + systems + ; +in { + mkAction = utils.lib.genAttrs systems; +} diff --git a/lib/mkGitJobsets.nix b/lib/mkGitJobsets.nix new file mode 100644 index 00000000..afb4e88f --- /dev/null +++ b/lib/mkGitJobsets.nix @@ -0,0 +1,29 @@ +utils: {lib}: let + inherit + (lib) + mkAction + ; +in { + mkGitJobsets = url: + mkAction (system: let + pkgs = utils.pkgs.${system}; + in + pkgs.writeShellApplication { + name = "action"; + runtimeInputs = [ + pkgs.git + pkgs.gnused + pkgs.jq + ]; + text = '' + heads=$(git ls-remote --heads ${url} | sed 's/.*refs\/heads\/\(.*\)/\1/') + cmd="" + for head in $heads + do + cmd="$cmd . += {\"$head\": { \"flake\": \"git+${url}?ref=$head\" } } |" + done + array=$(echo "{}" | jq "$cmd .") + echo "$array" + ''; + }); +} diff --git a/lib/mkProject.nix b/lib/mkProject.nix new file mode 100644 index 00000000..236364a3 --- /dev/null +++ b/lib/mkProject.nix @@ -0,0 +1,35 @@ +utils: {lib}: let + inherit + (lib) + systems + ; +in { + mkProject = args @ { + actions ? {}, + meta ? {}, + secrets ? null, + }: { + inherit meta; + actions = utils.lib.genAttrs systems ( + system: let + pkgs = utils.pkgs.${system}; + linkAction = name: + if actions ? ${name} && actions.${name} ? ${system} + then "ln -s ${actions.${name}.${system}}/bin/action ${name}" + else ""; + linkSecrets = + if secrets != null + then "ln -s ${secrets} secrets" + else ""; + in + pkgs.runCommand "actions" {} '' + mkdir $out + cd $out + ${linkAction "jobsets"} + ${linkAction "begin"} + ${linkAction "end"} + ${linkSecrets} + '' + ); + }; +} diff --git a/lib/systems.nix b/lib/systems.nix new file mode 100644 index 00000000..5051e147 --- /dev/null +++ b/lib/systems.nix @@ -0,0 +1,3 @@ +utils: _: { + systems = utils.inputs.flake-utils.lib.defaultSystems; +} diff --git a/lib/utils.nix b/lib/utils.nix new file mode 100644 index 00000000..60ec5a4f --- /dev/null +++ b/lib/utils.nix @@ -0,0 +1,18 @@ +inputs @ {nixpkgs, ...}: let + self = rec { + inherit inputs; + + lib = nixpkgs.lib; + + pkgs = nixpkgs.legacyPackages; + + importer = scope: + lib.foldr + (file: fn: lib: + self.lib.recursiveUpdate + {${scope} = import file self lib;} + (fn lib)) + (_: {}); + }; +in + self diff --git a/secrets b/secrets new file mode 100644 index 00000000..e69de29b