ci: nested matrix build

This commit is contained in:
Matt Sturgeon 2025-05-25 23:20:50 +01:00
parent ce432ab608
commit ed2c309964
No known key found for this signature in database
GPG key ID: 4F91844CED1A8299
3 changed files with 79 additions and 36 deletions

View file

@ -6,13 +6,8 @@ on:
name:
required: true
type: string
system:
required: true
type: string
os:
required: true
type: string
attr:
builds:
description: "json array of builds: [ { system, runner, attr } ]"
required: true
type: string
timeout:
@ -22,13 +17,16 @@ on:
jobs:
build:
name: ${{ inputs.name }}
name: ${{ inputs.name }} (${{ matrix.attr }})
runs-on:
- ${{ inputs.os }}
- ${{ matrix.runner }}
strategy:
fail-fast: false
matrix: ${{ fromJSON(inputs.builds) }}
timeout-minutes: ${{ inputs.timeout }}
steps:
- name: Free disk space
if: endsWith( '-linux', inputs.system )
if: endsWith( '-linux', matrix.system )
uses: wimpysworld/nothing-but-nix@main
with:
# Options: holster, carve, cleave (default), rampage
@ -42,9 +40,9 @@ jobs:
with:
name: nix-community
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Build ${{ inputs.attr }}
- name: Build ${{ matrix.attr }}
env:
attr: ${{ inputs.attr }}
attr: ${{ matrix.attr }}
run: |
nix build ".#$attr" \
--abort-on-warn \

View file

@ -39,7 +39,5 @@ jobs:
matrix: ${{ fromJSON(needs.prepare.outputs.matrix) }}
secrets: inherit
with:
name: ${{ matrix.name }} (${{ matrix.system }})
system: ${{ matrix.system }}
os: ${{ join( matrix.os, ' ' ) }} # FIXME: os is an array!
attr: ${{ matrix.attr }}
name: ${{ matrix.name }}
builds: ${{ toJSON(matrix.builds) }}

View file

@ -15,24 +15,71 @@
};
# Output a build matrix for CI
flake.githubActions = inputs.nix-github-actions.lib.mkGithubMatrix {
checks = builtins.mapAttrs (
system: lib.filterAttrs (name: v: !lib.strings.hasPrefix "test-" name)
# lib.flip lib.pipe [
# lib.attrsToList
# # Group the "test-N" tests back into one drv
# # FIXME: drop the entire test-grouping system
# (builtins.groupBy ({ name, value }: if lib.strings.hasPrefix "test-" name then "test" else name))
# (builtins.mapAttrs (
# group: tests:
# let
# pkgs = inputs.nixpkgs.legacyPackages.${system};
# singleton = (builtins.head tests).value;
# joined = pkgs.linkFarm group (builtins.listToAttrs tests);
# in
# if builtins.length tests > 1 then joined else singleton
# ))
# ]
) self.checks;
};
flake.githubActions.matrix =
let
systemsByPrio = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
githubPlatforms = {
"x86_64-linux" = "ubuntu-24.04";
"x86_64-darwin" = "macos-13";
"aarch64-darwin" = "macos-14";
"aarch64-linux" = "ubuntu-24.04-arm";
};
toGithubBuild = system: {
inherit system;
runner = githubPlatforms.${system} or (throw "System not supported by GitHub Actions: ${system}");
};
getPrimaryBuild =
platforms:
let
systems = builtins.catAttrs "system" platforms;
system = lib.lists.findFirst (
system: builtins.elem system systems
) (throw "No supported system found!") systemsByPrio;
in
toGithubBuild system;
in
lib.pipe self.checks [
(lib.mapAttrsRecursiveCond (x: !lib.isDerivation x) (
loc: _: {
_type = "check";
build = toGithubBuild (builtins.head loc);
name = lib.attrsets.showAttrPath (builtins.tail loc);
}
))
(lib.collect (lib.isType "check"))
(lib.groupBy' (acc: x: acc ++ [ x.build ]) [ ] (x: x.attr))
(lib.mapAttrsToList (attr: builds: { inherit attr builds; }))
# Only build one one system for non-test attrs
# TODO: this is very heavy handed, maybe we want some exceptions?
(map (
matrix:
matrix
// lib.optionalAttrs (!lib.strings.hasPrefix "test-" matrix.name) {
builds = [
(getPrimaryBuild matrix.builds)
];
}
))
# Inject per-system attr
(map (
matrix:
matrix
// {
builds = map (
build:
build
// {
attr = "checks.${build.system}.${matrix.name}";
}
) matrix.builds;
}
))
];
}