diff --git a/ci.nix b/ci.nix index 9dcc8f1b..8e4bd9be 100644 --- a/ci.nix +++ b/ci.nix @@ -3,66 +3,42 @@ # - https://github.com/NixOS/nixpkgs/pull/68398 let + inherit (import ./dimension.nix) dimension; nixpkgsVersions = { # "release-18.09" = builtins.fetchTarball "https://github.com/input-output-hk/nixpkgs/archive/7e4dcacbf066a8e2d12693a9de1fb30c77081c5d.tar.gz"; "release-19.03" = builtins.fetchTarball "https://github.com/input-output-hk/nixpkgs/archive/a8f81dc037a5977414a356dd068f2621b3c89b60.tar.gz"; # "release-19.09" = builtins.fetchTarball "https://github.com/input-output-hk/nixpkgs/archive/3d623a406cec9052ae0a16a79ce3ce9de11236bb.tar.gz"; }; + systems = { + "x86_64-linux" = {}; + }; + crossSystems = { + "x86_64-pc-mingw32" = {}; + }; haskellNixArgs = import ./.; - defaultNixpkgs = import (nixpkgsVersions."release-19.03") {}; - recRecurseIntoAttrs = with defaultNixpkgs; pred: x: if pred x then recurseIntoAttrs (lib.mapAttrs (n: v: if n == "buildPackages" then v else recRecurseIntoAttrs pred v) x) else x; in - recRecurseIntoAttrs (x: with defaultNixpkgs; lib.isAttrs x && !lib.isDerivation x) ( - builtins.mapAttrs (nixpkgsName: nixpkgsSrc: with (import nixpkgsSrc {}); { - x86_64-linux = { - hello = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-linux"; })); - (haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2";}).components.exes.hello; - x86_64-pc-mingw32-hello = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-linux"; crossSystem.config = "x86_64-pc-mingw32"; })); - (haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2";}).components.exes.hello; +dimension "Nixpkgs version" nixpkgsVersions (nixpkgsName: nixpkgsSrc: + dimension "System" systems (system: _: + # Native builds + # TODO: can we merge this into the general case by picking an appropriate "cross system" to mean native? + let pkgs = import nixpkgsSrc (haskellNixArgs // { inherit system; }); + in pkgs.recurseIntoAttrs { + hello = (pkgs.haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2";}).components.exes.hello; + iserv-proxy = pkgs.ghc-extra-packages.ghc865.iserv-proxy.components.exes.iserv-proxy; + ghc = pkgs.recurseIntoAttrs pkgs.haskell-nix.compiler; + tests = pkgs.lib.optionalAttrs (system == "x86_64-linux") (import ./test { inherit pkgs; }); + } + // + dimension "Cross system" crossSystems (crossSystem: _: + # Cross builds + let pkgs = import nixpkgsSrc (haskellNixArgs // { inherit system; crossSystem.config = crossSystem; }); + in pkgs.recurseIntoAttrs { + hello = (pkgs.haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2";}).components.exes.hello; - iserv-proxy = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-linux"; })); - (ghc-extra-packages.ghc865.iserv-proxy.components.exes).iserv-proxy; + iserv-proxy = pkgs.ghc-extra-packages.ghc865.iserv-proxy.components.exes.iserv-proxy; - x86_64-pc-mingw32-iserv-proxy = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-linux"; crossSystem.config = "x86_64-pc-mingw32"; })); - (buildPackages.ghc-extra-packages.ghc865.iserv-proxy.components.exes).iserv-proxy; - - x86_64-pc-mingw32-remote-iserv = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-linux"; crossSystem.config = "x86_64-pc-mingw32"; })); - (ghc-extra-packages.ghc865.remote-iserv.components.exes).remote-iserv; - - }; - x86_64-darwin = { - hello = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-darwin"; })); - (haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2";}).components.exes.hello; - x86_64-pc-mingw32-hello = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-darwin"; crossSystem.config = "x86_64-pc-mingw32"; })); - (haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2";}).components.exes.hello; - - iserv-proxy = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-darwin"; })); - (ghc-extra-packages.ghc865.iserv-proxy.components.exes).iserv-proxy; - - x86_64-pc-mingw32-iserv-proxy = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-darwin"; crossSystem.config = "x86_64-pc-mingw32"; })); - (buildPackages.ghc-extra-packages.ghc865.iserv-proxy.components.exes).iserv-proxy; - - x86_64-pc-mingw32-remote-iserv = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-darwin"; crossSystem.config = "x86_64-pc-mingw32"; })); - (ghc-extra-packages.ghc865.remote-iserv.components.exes).remote-iserv; - - }; - haskell-nix.compiler = { - x86_64-linux = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-linux"; })); - haskell-nix.compiler; - x86_64-darwin = with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-darwin";})); - haskell-nix.compiler; - }; - tests = { - x86_64-linux = (import ./test { nixpkgs = nixpkgsSrc; nixpkgsArgs = { system = "x86_64-linux"; }; }); - # x86_64-darwin = (import ./test { nixpkgs = nixpkgsSrc; nixpkgsArgs = { system = "x86_64-darwin"; }; }); - }; - -# Don't build (all of) stackage on linux for now. -# stackage = { -# x86_64-linux = (with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-linux"; })); -# haskell-nix.snapshots."lts-13.29"); -# # x86_64-darwin = (with (import nixpkgsSrc (haskellNixArgs // { system = "x86_64-darwin"; })); -# # haskell-nix.snapshots."lts-13.29"); -# }; - -}) nixpkgsVersions) + remote-iserv = pkgs.ghc-extra-packages.ghc865.remote-iserv.components.exes.remote-iserv; + } + ) + ) +) diff --git a/dimension.nix b/dimension.nix new file mode 100644 index 00000000..2594e912 --- /dev/null +++ b/dimension.nix @@ -0,0 +1,114 @@ +# Borrowed from https://github.com/cachix/ghcide-nix/pull/4/files#diff-70bfff902f4dec33e545cac10ee5844d +# Tweaked to use builtins.mapAttrs instead of needing the one from nixpkgs lib +{ + /* + dimension: name -> attrs -> function -> attrs + where + function: keyText -> value -> attrsOf package + + WARNING: Attribute names must not contain periods ("."). + See https://github.com/NixOS/nix/issues/3088 + + NOTE: The dimension name will be picked up by agent and web ui soon. + + Specifies a dimension of the build matrix. For example + + dimension "Example" { + withP = { p = true; } + withoutP = { p = false; } + } (key: # either "withP" or "withoutP" + { p }: # either p = true or p = false + myProject p + ) + + evaluates roughly to + + { + withP = myProject true; + withoutP = myProject false; + } + + Use nested calls for multiple dimensions. + + Example: + + dimension "System" { + "x86_64-linux" = {}; + # ... + }: (system: {}: + + dimension "Nixpkgs release" ( + { + "nixpkgs-19_03".nixpkgs = someSource + } // optionalAttrs (system != "...") { + "nixpkgs-unstable".nixpkgs = someOtherSource + } + ) (_key: { nixpkgs }: + + myProject system nixpkgs + + ) + ) + + evaluates roughly to + + { + x86_64-linux.nixpkgs-19_03 = myProject "x86_64-linux" someSource; + x86_64-linux.nixpkgs-unstable = myProject "x86_64-linux" someOtherSource; + ... + } + + If you need to make references across attributes, you can do so by binding + the result. Wherever you write + + dimension "My dimension" {} (key: value: f1 key value) + + You can also write + + let + myDimension = dimension "My dimension" {} (key: value: f2 key value myDimension) + in + myDimension + + This example builds a single test runner to reuse across releases: + + let + overlay = + testRunnerPkgs: self: super: { + # ... + }; + myProject = + { nixpkgs, + pkgs ? import nixpkgs { overlays = [ overlay ]; }, + testRunnerPkgs ? pkgs + }: pkgs; + in + + let + latest = "nixpkgs-19_03"; + releases = + dimension "Nixpkgs release" + { + nixpkgs-18_09.nixpkgs = someSource + nixpkgs-19_03.nixpkgs = someOtherSource + } + (_key: { nixpkgs }: + + myProject { + inherit nixpkgs; + testRunnerPkgs = releases."${latest}"; + } + + ); + in releases; + + */ + dimension = name: attrs: f: + builtins.mapAttrs + (k: v: + let o = f k v; + in o // { recurseForDerivations = o.recurseForDerivations or true; } + ) + attrs + // { meta.dimension.name = name; }; +}