summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yaml4
-rw-r--r--.github/workflows/example.yaml3
-rw-r--r--README.md107
-rw-r--r--lib.nix98
-rw-r--r--module.nix99
-rw-r--r--test/lib/flake.nix39
-rw-r--r--test/module/flake.nix12
7 files changed, 206 insertions, 156 deletions
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 7468b02..f4a5e3e 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -28,7 +28,7 @@ jobs:
for dir in "lib" "module"; do
pushd test/"$dir"
- echo "$dir=$(nix eval --show-trace --json .#githubWorkflow.matrix)" >> "$GITHUB_OUTPUT"
+ echo "$dir=$(nix eval --show-trace --json .#workflowMatrix)" >> "$GITHUB_OUTPUT"
popd
done
@@ -37,6 +37,7 @@ jobs:
needs: eval
strategy:
+ fail-fast: false
matrix: ${{ fromJSON(needs.eval.outputs.lib-matrix) }}
name: Build (lib/${{ matrix.attr }})
@@ -70,6 +71,7 @@ jobs:
needs: eval
strategy:
+ fail-fast: false
matrix: ${{ fromJSON(needs.eval.outputs.module-matrix) }}
name: Build (module/${{ matrix.attr }})
diff --git a/.github/workflows/example.yaml b/.github/workflows/example.yaml
index 0c214e9..3405f41 100644
--- a/.github/workflows/example.yaml
+++ b/.github/workflows/example.yaml
@@ -22,12 +22,13 @@ jobs:
run: |
set -eu
- echo "matrix=$(nix eval --show-trace --json .#githubWorkflow.matrix)" >> "$GITHUB_OUTPUT"
+ echo "matrix=$(nix eval --show-trace --json .#workflowMatrix)" >> "$GITHUB_OUTPUT"
build:
needs: eval
strategy:
+ fail-fast: false
matrix: ${{ fromJSON(needs.eval.outputs.matrix) }}
name: Build (${{matrix.attr}})
diff --git a/README.md b/README.md
index 656adaa..83dd3ae 100644
--- a/README.md
+++ b/README.md
@@ -1,91 +1,100 @@
# nix2workflow
-![test status](https://github.com/getchoo/nix2workflow/actions/workflows/ci.yaml/badge.svg)
+![Test Status](https://github.com/getchoo/nix2workflow/actions/workflows/ci.yaml/badge.svg)
[![FlakeHub](https://img.shields.io/endpoint?url=https://flakehub.com/f/getchoo/nix2workflow/badge)](https://flakehub.com/flake/getchoo/nix2workflow)
-nix2workflow is a library for generating github matrices from regular nix flake outputs.
+nix2workflow is a library for generating GitHub matrices from nix flake outputs.
-## usage
+## Usage
-we offer both a standard library for use in any flake, along with
+We offer both a standard library for use in any flake, along with
a [flake-parts](https://flake.parts/) module for easier integration.
-you can find an example workflow for use in your own project in
+You can find an example workflow for use in your own project in
[./.github/workflows/example.yaml](./.github/workflows/example.yaml).
-### flake module
+### Flake module
-a basic setup might look like this. please see the [module](./module.nix)
+A basic setup might look like this. Please see the [module](./module.nix)
for all options
```nix
-{
- imports = [nix2workflow.flakeModule];
+{self, ...}: {
+ imports = [ nix2workflow.flakeModule ];
- githubWorkflowGenerator = {
- outputs = [
- "checks"
- "devShells"
- "nixosConfigurations"
- "packages"
- ];
+ nix2workflow = {
+ # this will automatically build all standard outputs in self
+ root = self;
overrides = {
- checks.systems = ["x86_64-linux"];
+ checks.systems = [ "x86_64-linux" ];
};
};
}
```
-a full example can be found in [./test/module/flake.nix](./test/module/flake.nix)
+A full example can be found in [./test/module/flake.nix](./test/module/flake.nix)
-### library
+### Library
-the regular library will have a more complicated setup, though
+The regular library will have a more complicated setup, though
it also allows using lower level functions and has no restrictions on
what flake outputs are used.
```nix
{
- githubworkflow = let
- workflow = nix2workflow.lib {inherit self;};
- outputs = [
- "checks"
- "devShells"
- "nixosConfigurations"
- "packages"
- ];
- in {
- matrix.include = lib.concatLists (
- map (
- output:
- workflow.mkMatrix {
- inherit output;
- # you can also specify what systems to build each output for
- systems = ["x86_64-linux" "aarch64-darwin"];
- }
- )
- outputs
+ workflowMatrix = let
+ platforms = {
+ x86_64-linux = {
+ os = "ubuntu-latest";
+ arch = "x64";
+ };
+
+ x86_64-darwin = {
+ os = "macos-latest";
+ arch = "x64";
+ };
+ };
+
+ inherit (nix2workflow.lib { inherit platforms; }) mkMatrix;
+
+ jobs = lib.flatten (
+ (mkMatrix {
+ root = self;
+ output = "packages";
+ })
+
+ (mkMatrix {
+ root = self;
+ output = "checks";
+ systems = [ "x86_64-linux" ];
+ })
);
+ in {
+ include = jobs;
};
}
```
-you can see a full example in [./test/lib/flake.nix](./test/lib/flake.nix)
+You can see a full example in [./test/lib/flake.nix](./test/lib/flake.nix)
-### in workflows
+### In workflows
-when the matrix is imported, a few variables with added to the `matrix` context.
-these can allow you to customize your workflow based on what packages are building -
+When the matrix is imported, a few variables with added to the `matrix` context.
+These can allow you to customize your workflow based on what packages are building -
such as enabling QEMU when building for aarch64
| name | use |
| --- | --- |
-| `os` | the operating system of the current output. usually `ubuntu-latest` or `macos-latest` |
-| `arch` | the architecture of the current output. will be `aarch64` or `x64` |
-| `attr` | the flake attribute of the current output (can really be anything) |
+| `os` | The operating system of the current output. Usually `ubuntu-latest` or `macos-latest` |
+| `arch` | The architecture of the current output. Will be `aarch64` or `x64` |
+| `attr` | The flake attribute of the current output (can really be anything).
+ Note that you will still need to prefix this with the `root` attribute if set (i.e. `.#hydraJobs.${{ matrix.attrr }}`) |
-## related projects
+## Related projects
- [nix-community/nix-github-actions](https://github.com/nix-community/nix-github-actions/)
- - this is the primary inspiration for this project - and i believe also one of the first
- projects to attempt this, so kudos! i just wanted a more opionated and expandable approach :)
+ - This is the primary inspiration for this project - and I believe also one of the first
+ projects to attempt this, so kudos!
+ - [nix-community/nix-eval-jobs](https://github.com/nix-community/nix-eval-jobs)
+ - I liked the idea of using `hydraJobs` (and possibly others) on GitHub Actions, and
+ thought it might be fun to make a direct translation of these attributes in pure nix
diff --git a/lib.nix b/lib.nix
index f7f07f3..7d0c0ab 100644
--- a/lib.nix
+++ b/lib.nix
@@ -1,80 +1,72 @@
-lib: {
- self,
- platforms ? {
- "x86_64-linux" = {
+lib: {platforms ? null}: let
+ defaultPlatforms = {
+ x86_64-linux = {
os = "ubuntu-latest";
arch = "x64";
};
- "aarch64-linux" = {
+ aarch64-linux = {
os = "ubuntu-latest";
arch = "aarch64";
};
- "x86_64-darwin" = {
+ x86_64-darwin = {
os = "macos-latest";
arch = "x64";
};
- },
- ...
-}: let
+ };
+
platforms' =
- platforms
- // {
- fallback = lib.warn "an output in the job matrix is not supported!" {
- os = null;
- arch = null;
- };
- };
+ if platforms != null
+ then platforms
+ else defaultPlatforms;
+
+ fallback = lib.warn "an output in the job matrix is not supported!" {
+ os = null;
+ arch = null;
+ };
- mkMatrixMulti = systems: output:
+ platformNames = lib.attrNames platforms';
+
+ findSystem = deriv: deriv.system or deriv.pkgs.system or deriv.activationPackage.system;
+in {
+ mkMatrix = {
+ root,
+ output,
+ systems ? platformNames,
+ }:
lib.flatten (
lib.mapAttrsToList (
system:
lib.mapAttrsToList (
attr: _: {
- inherit (platforms'.${system} or platforms'.fallback) arch os;
+ inherit (platforms'.${system} or fallback) arch os;
attr = "${output}.${system}.${attr}";
}
)
)
- (lib.getAttrs systems self.${output})
+ (lib.filterAttrs (system: _: lib.elem system systems) root.${output})
);
- mkMatrixFlat = {
+ mkMatrix' = {
+ root,
output,
- suffix ? "",
+ systems ? platformNames,
}:
- lib.mapAttrsToList (
- attr: deriv: {
- inherit (platforms'.${deriv.pkgs.system} or platforms'.fallback) os arch;
- attr = "${output}.${attr}${suffix}";
- }
- )
- self.${output};
-in {
- inherit
- mkMatrixMulti
- mkMatrixFlat
- ;
-
- mkMatrix = {
- output,
- systems ? (builtins.attrNames platforms),
- }: let
- systemMatrix = mkMatrixFlat {
- inherit output;
- suffix = ".config.system.build.toplevel";
- };
- in
- {
- "nixosConfigurations" = systemMatrix;
- "darwinConfigurations" = systemMatrix;
- "homeConfigurations" = mkMatrixFlat {
- inherit output;
- suffix = ".activationPackage";
- };
- }
- .${output}
- or (mkMatrixMulti systems output);
+ lib.flatten (
+ lib.mapAttrsToList (
+ attr: deriv: let
+ system = findSystem deriv;
+ in {
+ inherit (platforms'.${system} or fallback) arch os;
+ attr = "${output}.${attr}";
+ }
+ )
+ (
+ lib.filterAttrs (
+ _: deriv: builtins.elem (findSystem deriv) systems
+ )
+ root.${output}
+ )
+ );
}
diff --git a/module.nix b/module.nix
index cfaa45b..233d0ab 100644
--- a/module.nix
+++ b/module.nix
@@ -4,7 +4,7 @@ workflowLib': {
self,
...
}: let
- cfg = config.githubWorkflowGenerator;
+ cfg = config.nix2workflow;
inherit
(lib)
@@ -12,24 +12,24 @@ workflowLib': {
concatLists
elem
filter
+ filterAttrs
+ literalExpression
+ mapAttrsToList
mdDoc
mkOption
- literalExpression
+ recursiveUpdate
types
;
- workflowLib = workflowLib' {
- inherit self;
- inherit (cfg) platforms;
- };
+ workflowLib = workflowLib' {inherit (cfg) platforms;};
+ inherit (workflowLib) mkMatrix mkMatrix';
supportedOutputs = [
- "apps"
"checks"
"devShells"
+ "nixosConfigurations"
"darwinConfigurations"
"homeConfigurations"
- "nixosConfigurations"
"packages"
];
@@ -61,45 +61,66 @@ workflowLib': {
};
};
- unfilteredJobs = concatLists (
- map (
- output:
- workflowLib.mkMatrix (
- {inherit output;} // cfg.overrides.${output} or {}
- )
+ jobs = concatLists (
+ mapAttrsToList (
+ output: value: let
+ common =
+ recursiveUpdate
+ {
+ root = cfg.output;
+ inherit output;
+ }
+ (cfg.overrides.${output} or {});
+
+ flat = mkMatrix' common;
+ multi = mkMatrix common;
+ in
+ {
+ # TODO: maybe make this configurable? or follow flake-schemas?
+ # these are known "flat" values
+ "nixosConfigurations" = flat;
+ "darwinConfigurations" = flat;
+ "homeConfigurations" = flat;
+ }
+ .${output}
+ or multi
)
- cfg.outputs
+ (filterAttrs (output: _: elem output supportedOutputs) cfg.output)
);
in {
options = {
- githubWorkflowGenerator = {
- outputs = mkOption {
- description = mdDoc "outputs to include in workflow";
- type = types.listOf types.str;
- default = filter (output: elem output supportedOutputs) (attrNames self);
+ nix2workflow = {
+ output = mkOption {
+ description = mdDoc "Root attribute for CI jobs";
+ type = types.lazyAttrsOf types.raw;
+ default = self;
+ example = literalExpression "hydraJobs";
};
platforms = mkOption {
description = mdDoc ''
an attrset that can map a nix system to an architecture and os supported by github
'';
- type = types.attrsOf (types.submodule platformMap);
- default = {
- "x86_64-linux" = {
- os = "ubuntu-latest";
- arch = "x64";
- };
+ type = types.nullOr (types.attrsOf (types.submodule platformMap));
+ default = null;
+ example = literalExpression ''
+ {
+ "x86_64-linux" = {
+ os = "ubuntu-latest";
+ arch = "x64";
+ };
- "aarch64-linux" = {
- os = "ubuntu-latest";
- arch = "aarch64";
- };
+ "aarch64-linux" = {
+ os = "self-hosted";
+ arch = "aarch64";
+ };
- "x86_64-darwin" = {
- os = "macos-latest";
- arch = "x64";
- };
- };
+ "x86_64-darwin" = {
+ os = "macos-latest";
+ arch = "x64";
+ };
+ }
+ '';
};
exclude = mkOption {
@@ -108,7 +129,7 @@ in {
default = [];
example = literalExpression ''
{
- githubWorkflowGenerator.exclude = [
+ nix2workflow.exclude = [
"packages.x86_64-linux.foo"
];
}
@@ -121,7 +142,7 @@ in {
default = {};
example = literalExpression ''
{
- githubWorkflowGenerator.overrides = {
+ nix2workflow.overrides = {
checks.systems = [ "x86_64-linux" ];
};
}
@@ -130,7 +151,7 @@ in {
};
};
- config.flake.githubWorkflow = {
- matrix.include = filter (job: !builtins.elem job.attr cfg.exclude) unfilteredJobs;
+ config.flake.workflowMatrix = {
+ include = filter (job: !elem job.attr cfg.exclude) jobs;
};
}
diff --git a/test/lib/flake.nix b/test/lib/flake.nix
index c4607dc..985c421 100644
--- a/test/lib/flake.nix
+++ b/test/lib/flake.nix
@@ -19,8 +19,8 @@
"aarch64-darwin"
];
- forAllSystems = fn: lib.genAttrs systems (sys: fn nixpkgs.legacyPackages.${sys});
- workflow = (call-flake ../../.).lib {inherit self;};
+ forSystem = system: fn: fn nixpkgs.legacyPackages.${system};
+ forAllSystems = fn: lib.genAttrs systems (sys: forSystem sys fn);
in {
devShells = forAllSystems (pkgs: {
default = pkgs.mkShell {
@@ -28,21 +28,40 @@
};
});
+ flatPackages = forSystem "x86_64-linux" ({hello, ...}: {inherit hello;});
+
packages = forAllSystems (pkgs: {
inherit (pkgs) hello;
default = pkgs.hello;
});
- githubWorkflow = let
- outputs = ["packages" "devShells"];
- jobs = lib.concatLists (
- map (
- output: workflow.mkMatrix {inherit output;}
- )
- outputs
+ workflowMatrix = let
+ platforms = {
+ x86_64-linux = {
+ os = "ubuntu-latest";
+ arch = "x64";
+ };
+
+ aarch64-linux = {
+ os = "ubuntu-latest";
+ arch = "aarch64";
+ };
+ };
+
+ inherit ((call-flake ../../.).lib {inherit platforms;}) mkMatrix mkMatrix';
+
+ jobs = lib.flatten (
+ (mkMatrix' {
+ root = self;
+ output = "flatPackages";
+ })
+ ++ (mkMatrix {
+ root = self;
+ output = "packages";
+ })
);
in {
- matrix.include = jobs;
+ include = jobs;
};
};
}
diff --git a/test/module/flake.nix b/test/module/flake.nix
index 0bbbc54..c3d3e0e 100644
--- a/test/module/flake.nix
+++ b/test/module/flake.nix
@@ -25,9 +25,15 @@
"aarch64-darwin"
];
- githubWorkflowGenerator.exclude = [
- "packages.x86_64-linux.otherHello"
- ];
+ nix2workflow = {
+ exclude = [
+ "packages.x86_64-linux.otherHello"
+ ];
+
+ overrides = {
+ devShells.systems = ["x86_64-linux"];
+ };
+ };
perSystem = {pkgs, ...}: {
devShells.default = pkgs.mkShell {