1/*
2 This is the Hydra jobset for the `haskell-updates` branch in Nixpkgs.
3 You can see the status of this jobset at
4 https://hydra.nixos.org/jobset/nixpkgs/haskell-updates.
5
6 To debug this expression you can use `hydra-eval-jobs` from
7 `pkgs.hydra` which prints the jobset description
8 to `stdout`:
9
10 $ hydra-eval-jobs -I . pkgs/top-level/release-haskell.nix
11*/
12{
13 supportedSystems ? builtins.fromJSON (builtins.readFile ../../ci/supportedSystems.json),
14}:
15
16let
17
18 releaseLib = import ./release-lib.nix {
19 inherit supportedSystems;
20 };
21
22 inherit (releaseLib)
23 lib
24 mapTestOn
25 packagePlatforms
26 pkgs
27 ;
28
29 # Helper function which traverses a (nested) set
30 # of derivations produced by mapTestOn and flattens
31 # it to a list of derivations suitable to be passed
32 # to `releaseTools.aggregate` as constituents.
33 # Removes all non derivations from the input jobList.
34 #
35 # accumulateDerivations :: [ Either Derivation AttrSet ] -> [ Derivation ]
36 #
37 # > accumulateDerivations [ drv1 "string" { foo = drv2; bar = { baz = drv3; }; } ]
38 # [ drv1 drv2 drv3 ]
39 accumulateDerivations =
40 jobList:
41 lib.concatMap (
42 attrs:
43 if lib.isDerivation attrs then
44 [ attrs ]
45 else
46 lib.optionals (lib.isAttrs attrs) (accumulateDerivations (lib.attrValues attrs))
47 ) jobList;
48
49 # names of all subsets of `pkgs.haskell.packages`
50 #
51 # compilerNames looks like the following:
52 #
53 # ```
54 # {
55 # ghc810 = "ghc810";
56 # ghc8107Binary = "ghc8107Binary";
57 # ghc8107 = "ghc8107";
58 # ghc924 = "ghc924";
59 # ...
60 # }
61 # ```
62 compilerNames = lib.mapAttrs (name: _: name) pkgs.haskell.packages;
63
64 # list of all compilers to test specific packages on
65 released = with compilerNames; [
66 ghc948
67 ghc963
68 ghc967
69 ghc984
70 ghc9101
71 ghc9102
72 # exclude ghc9121 due to severe miscompilation bug
73 ghc9122
74 ];
75
76 # packagePlatforms applied to `haskell.packages.*`
77 #
78 # This returns an attr set that looks like the following, where each Haskell
79 # package in the compiler attr set has its list of supported platforms as its
80 # value.
81 #
82 # ```
83 # {
84 # ghc810 = {
85 # conduit = [ ... ];
86 # lens = [ "i686-cygwin" "x86_64-cygwin" ... "x86_64-windows" "i686-windows" ]
87 # ...
88 # };
89 # ghc902 = { ... };
90 # ...
91 # }
92 # ```
93 compilerPlatforms = lib.mapAttrs (_: v: packagePlatforms v) pkgs.haskell.packages;
94
95 # This function lets you specify specific packages
96 # which are to be tested on a list of specific GHC
97 # versions and returns a job set for all specified
98 # combinations.
99 #
100 # You can call versionedCompilerJobs like the following:
101 #
102 # ```
103 # versionedCompilerJobs {
104 # ghc-tags = ["ghc902" "ghc924"];
105 # }
106 # ```
107 #
108 # This would produce an output like the following:
109 #
110 # ```
111 # {
112 # haskell.packages = {
113 # ghc884 = {};
114 # ghc810 = {};
115 # ghc902 = {
116 # ghc-tags = {
117 # aarch64-darwin = <derivation...>;
118 # aarch64-linux = <derivation...>;
119 # ...
120 # };
121 # };
122 # ghc924 = {
123 # ghc-tags = { ... };
124 # };
125 # ...
126 # };
127 # }
128 # ```
129 versionedCompilerJobs =
130 config:
131 mapTestOn {
132 haskell.packages =
133 let
134 # Mapping function that takes an attrset of jobs, and
135 # removes all jobs that are not specified in config.
136 #
137 # For example, imagine a call to onlyConfigJobs like:
138 #
139 # ```
140 # onlyConfigJobs
141 # "ghc902"
142 # {
143 # conduit = [ ... ];
144 # lens = [ "i686-cygwin" "x86_64-cygwin" ... "x86_64-windows" "i686-windows" ];
145 # }
146 # ```
147 #
148 # onlyConfigJobs pulls out only those jobs that are specified in config.
149 #
150 # For instance, if config is `{ lens = [ "ghc902" ]; }`, then the above
151 # example call to onlyConfigJobs will return:
152 #
153 # ```
154 # { lens = [ "i686-cygwin" "x86_64-cygwin" ... "x86_64-windows" "i686-windows" ]; }
155 # ```
156 #
157 # If config is `{ lens = [ "ghc8107" ]; }`, then the above example call
158 # to onlyConfigJobs returns `{}`.
159 #
160 # onlyConfigJobs will also remove all platforms from a job that are not
161 # supported by the GHC it is compiled with.
162 onlyConfigJobs =
163 ghc: jobs:
164 let
165 configFilteredJobset = lib.filterAttrs (
166 jobName: platforms: lib.elem ghc (config."${jobName}" or [ ])
167 ) jobs;
168
169 # Remove platforms from each job that are not supported by GHC.
170 # This is important so that we don't build jobs for platforms
171 # where GHC can't be compiled.
172 jobsetWithGHCPlatforms = lib.mapAttrs (
173 _: platforms: lib.intersectLists jobs.ghc platforms
174 ) configFilteredJobset;
175 in
176 jobsetWithGHCPlatforms;
177 in
178 lib.mapAttrs onlyConfigJobs compilerPlatforms;
179 };
180
181 # hydra jobs for `pkgs` of which we import a subset of
182 pkgsPlatforms = packagePlatforms pkgs;
183
184 # names of packages in an attribute set that are maintained
185 maintainedPkgNames =
186 set:
187 builtins.attrNames (lib.filterAttrs (_: v: builtins.length (v.meta.maintainers or [ ]) > 0) set);
188
189 recursiveUpdateMany = builtins.foldl' lib.recursiveUpdate { };
190
191 # Remove multiple elements from a list at once.
192 #
193 # removeMany
194 # :: [a] -- list of elements to remove
195 # -> [a] -- list of elements from which to remove
196 # -> [a]
197 #
198 # > removeMany ["aarch64-linux" "x86_64-darwin"] ["aarch64-linux" "x86_64-darwin" "x86_64-linux"]
199 # ["x86_64-linux"]
200 removeMany = itemsToRemove: list: lib.foldr lib.remove list itemsToRemove;
201
202 # Recursively remove platforms from the values in an attribute set.
203 #
204 # removePlatforms
205 # :: [String]
206 # -> AttrSet
207 # -> AttrSet
208 #
209 # > attrSet = {
210 # foo = ["aarch64-linux" "x86_64-darwin" "x86_64-linux"];
211 # bar.baz = ["aarch64-linux" "x86_64-linux"];
212 # bar.quux = ["aarch64-linux" "x86_64-darwin"];
213 # }
214 # > removePlatforms ["aarch64-linux" "x86_64-darwin"] attrSet
215 # {
216 # foo = ["x86_64-linux"];
217 # bar = {
218 # baz = ["x86_64-linux"];
219 # quux = [];
220 # };
221 # }
222 removePlatforms =
223 platformsToRemove: packageSet:
224 lib.mapAttrsRecursive (
225 _: val: if lib.isList val then removeMany platformsToRemove val else val
226 ) packageSet;
227
228 jobs = recursiveUpdateMany [
229 (mapTestOn {
230 haskellPackages = packagePlatforms pkgs.haskellPackages;
231 haskell.compiler = packagePlatforms pkgs.haskell.compiler;
232 tests.haskell = packagePlatforms pkgs.tests.haskell;
233
234 nixosTests = {
235 inherit (packagePlatforms pkgs.nixosTests)
236 agda
237 kmonad
238 xmonad
239 xmonad-xdg-autostart
240 ;
241 };
242
243 agdaPackages = packagePlatforms pkgs.agdaPackages;
244
245 # top-level packages that depend on haskellPackages
246 inherit (pkgsPlatforms)
247 agda
248 alex
249 arion
250 aws-spend-summary
251 bench
252 blucontrol
253 cabal-install
254 cabal2nix
255 cachix
256 # carp broken on 2024-04-09
257 changelog-d
258 cornelis
259 cedille
260 client-ip-echo
261 darcs
262 dconf2nix
263 dhall
264 dhall-bash
265 dhall-docs
266 dhall-lsp-server
267 dhall-json
268 dhall-nix
269 dhall-nixpkgs
270 dhall-yaml
271 diagrams-builder
272 echidna
273 elm2nix
274 emanote
275 fffuu
276 futhark
277 ghcid
278 git-annex
279 git-brunch
280 gitit
281 glirc
282 hadolint
283 happy
284 haskell-ci
285 haskell-language-server
286 hci
287 hercules-ci-agent
288 hinit
289 hedgewars
290 hledger
291 hledger-check-fancyassertions
292 hledger-iadd
293 hledger-interest
294 hledger-ui
295 hledger-web
296 hlint
297 hpack
298 hscolour
299 icepeak
300 ihaskell
301 jacinda
302 jl
303 json2yaml
304 koka
305 krank
306 lambdabot
307 lhs2tex
308 madlang
309 matterhorn
310 mkjson
311 mueval
312 naproche
313 niv
314 nix-delegate
315 nix-deploy
316 nix-diff
317 nix-output-monitor
318 nix-script
319 nix-tree
320 nixfmt-classic
321 nixfmt
322 nota
323 nvfetcher
324 oama
325 ormolu
326 pakcs
327 pandoc
328 place-cursor-at
329 pinboard-notes-backup
330 pretty-simple
331 purenix
332 shake
333 shellcheck
334 shellcheck-minimal
335 sourceAndTags
336 spacecookie
337 spago
338 specup
339 splot
340 stack
341 stack2nix
342 stutter
343 stylish-haskell
344 taffybar
345 tamarin-prover
346 termonad
347 tldr-hs
348 tweet-hs
349 update-nix-fetchgit
350 uusi
351 uqm
352 uuagc
353 # vaultenv: broken by connection on 2024-03-16
354 wstunnel
355 xmobar
356 xmonadctl
357 xmonad-with-packages
358 yi
359 ;
360
361 # Members of the elmPackages set that are Haskell derivations
362 elmPackages = {
363 inherit (pkgsPlatforms.elmPackages)
364 elm
365 elm-format
366 ;
367 };
368
369 # GHCs linked to musl.
370 pkgsMusl =
371 removePlatforms
372 [
373 # pkgsMusl is compiled natively with musl. It is not
374 # cross-compiled (unlike pkgsStatic). We can only
375 # natively bootstrap GHC with musl on x86_64-linux because
376 # upstream doesn't provide a musl bindist for aarch64.
377 "aarch64-linux"
378
379 # musl only supports linux, not darwin.
380 "x86_64-darwin"
381 "aarch64-darwin"
382 ]
383 {
384 haskell.compiler = packagePlatforms pkgs.pkgsMusl.haskell.compiler;
385
386 # Get some cache going for MUSL-enabled GHC.
387 haskellPackages = {
388 inherit (packagePlatforms pkgs.pkgsMusl.haskellPackages)
389 hello
390 lens
391 random
392 ;
393 };
394 };
395
396 # Test some statically linked packages to catch regressions
397 # and get some cache going for static compilation with GHC.
398 # Use native-bignum to avoid GMP linking problems (LGPL)
399 pkgsStatic =
400 removePlatforms
401 [
402 "aarch64-linux" # times out on Hydra
403
404 # Static doesn't work on darwin
405 "x86_64-darwin"
406 "aarch64-darwin"
407 ]
408 {
409 haskellPackages = {
410 inherit (packagePlatforms pkgs.pkgsStatic.haskellPackages)
411 hello
412 lens
413 random
414 QuickCheck
415 cabal2nix
416 terminfo # isn't bundled for cross
417 xhtml # isn't bundled for cross
418 postgrest
419 ;
420 };
421
422 haskell.packages.native-bignum.ghc948 = {
423 inherit (packagePlatforms pkgs.pkgsStatic.haskell.packages.native-bignum.ghc948)
424 hello
425 lens
426 random
427 QuickCheck
428 cabal2nix
429 terminfo # isn't bundled for cross
430 xhtml # isn't bundled for cross
431 postgrest
432 ;
433 };
434
435 haskell.packages.native-bignum.ghc984 = {
436 inherit (packagePlatforms pkgs.pkgsStatic.haskell.packages.native-bignum.ghc984)
437 hello
438 random
439 QuickCheck
440 terminfo # isn't bundled for cross
441 ;
442 };
443 };
444
445 pkgsCross = {
446 aarch64-android-prebuilt.pkgsStatic =
447 removePlatforms
448 [
449 # Android NDK package doesn't support building on
450 "aarch64-darwin"
451 "aarch64-linux"
452
453 "x86_64-darwin"
454 ]
455 {
456 haskell.packages.ghc912 = {
457 inherit
458 (packagePlatforms pkgs.pkgsCross.aarch64-android-prebuilt.pkgsStatic.haskell.packages.ghc912)
459 ghc
460 hello
461 microlens
462 ;
463 };
464 };
465
466 ghcjs =
467 removePlatforms
468 [
469 # Hydra output size of 3GB is exceeded
470 "aarch64-linux"
471 ]
472 {
473 haskellPackages = {
474 inherit (packagePlatforms pkgs.pkgsCross.ghcjs.haskellPackages)
475 ghc
476 hello
477 microlens
478 ;
479 };
480
481 haskell.packages.ghc98 = {
482 inherit (packagePlatforms pkgs.pkgsCross.ghcjs.haskell.packages.ghc98)
483 ghc
484 hello
485 microlens
486 ;
487 };
488
489 haskell.packages.ghc912 = {
490 inherit (packagePlatforms pkgs.pkgsCross.ghcjs.haskell.packages.ghc912)
491 ghc
492 hello
493 microlens
494 miso
495 reflex-dom
496 ;
497 };
498
499 haskell.packages.ghcHEAD = {
500 inherit (packagePlatforms pkgs.pkgsCross.ghcjs.haskell.packages.ghcHEAD)
501 ghc
502 hello
503 microlens
504 ;
505 };
506 };
507
508 ucrt64.haskell.packages.ghc912 = {
509 inherit (packagePlatforms pkgs.pkgsCross.ucrt64.haskell.packages.ghc912)
510 ghc
511 # hello # executables don't build yet
512 microlens
513 ;
514 };
515
516 riscv64 = {
517 # Cross compilation of GHC
518 haskell.compiler = {
519 inherit (packagePlatforms pkgs.pkgsCross.riscv64.haskell.compiler)
520 # Latest GHC we are able to cross-compile.
521 ghc948
522 ;
523 };
524 };
525
526 aarch64-multiplatform = {
527 # Cross compilation of GHC
528 haskell.compiler = {
529 inherit (packagePlatforms pkgs.pkgsCross.aarch64-multiplatform.haskell.compiler)
530 # Latest GHC we are able to cross-compile. Uses NCG backend.
531 ghc948
532 ;
533 };
534 };
535 };
536 })
537 (versionedCompilerJobs {
538 # Packages which should be checked on more than the
539 # default GHC version. This list can be used to test
540 # the state of the package set with newer compilers
541 # and to confirm that critical packages for the
542 # package sets (like Cabal, jailbreak-cabal) are
543 # working as expected.
544 cabal-install = lib.subtractLists [
545 # It is recommended to use pkgs.cabal-install instead of cabal-install
546 # from the package sets. Due to (transitively) requiring recent versions
547 # of core packages, it is not always reasonable to get cabal-install to
548 # work with older compilers.
549 compilerNames.ghc948
550 ] released;
551 Cabal_3_10_3_0 = lib.subtractLists [
552 # time < 1.13 conflicts with time == 1.14.*
553 compilerNames.ghc9121
554 compilerNames.ghc9122
555 ] released;
556 Cabal_3_12_1_0 = released;
557 Cabal_3_14_2_0 = released;
558 cabal2nix = released;
559 cabal2nix-unstable = released;
560 funcmp = released;
561 git-annex = [
562 # for 9.10, test that using filepath (instead of filepath-bytestring) works.
563 compilerNames.ghc9101
564 compilerNames.ghc9102
565 ];
566 haskell-language-server = released;
567 hoogle = released;
568 hlint = lib.subtractLists [
569 compilerNames.ghc9101
570 compilerNames.ghc9102
571 compilerNames.ghc9122
572 ] released;
573 hpack = released;
574 hsdns = released;
575 jailbreak-cabal = released;
576 language-nix = released;
577 nix-paths = released;
578 titlecase = released;
579 ghc-lib = released;
580 ghc-lib-parser = released;
581 ghc-lib-parser-ex = released;
582 ghc-source-gen = lib.subtractLists [
583 compilerNames.ghc9122
584 ] released;
585 ghc-tags = lib.subtractLists [
586 compilerNames.ghc9122
587 ] released;
588 hashable = released;
589 primitive = released;
590 semaphore-compat = [
591 # Compiler < 9.8 don't have the semaphore-compat core package, but
592 # requires unix >= 2.8.1.0 which implies GHC >= 9.6 for us.
593 compilerNames.ghc967
594 ];
595 weeder = lib.subtractLists [
596 compilerNames.ghc9101
597 compilerNames.ghc9102
598 compilerNames.ghc9122
599 ] released;
600 })
601 {
602 mergeable = pkgs.releaseTools.aggregate {
603 name = "haskell-updates-mergeable";
604 meta = {
605 description = ''
606 Critical haskell packages that should work at all times,
607 serves as minimum requirement for an update merge
608 '';
609 teams = [ lib.teams.haskell ];
610 };
611 constituents = accumulateDerivations [
612 # haskell specific tests
613 jobs.tests.haskell
614 # important top-level packages
615 jobs.cabal-install
616 jobs.cabal2nix
617 jobs.cachix
618 jobs.darcs
619 jobs.haskell-language-server
620 jobs.hledger
621 jobs.hledger-ui
622 jobs.hpack
623 jobs.niv
624 jobs.pandoc
625 jobs.stack
626 jobs.stylish-haskell
627 jobs.shellcheck
628 # important haskell (library) packages
629 jobs.haskellPackages.cabal-plan
630 jobs.haskellPackages.distribution-nixpkgs
631 jobs.haskellPackages.hackage-db
632 jobs.haskellPackages.xmonad
633 jobs.haskellPackages.xmonad-contrib
634 # haskell packages maintained by @peti
635 # imported from the old hydra jobset
636 jobs.haskellPackages.hopenssl
637 jobs.haskellPackages.hsemail
638 jobs.haskellPackages.hsyslog
639 ];
640 };
641 maintained = pkgs.releaseTools.aggregate {
642 name = "maintained-haskell-packages";
643 meta = {
644 description = "Aggregate jobset of all haskell packages with a maintainer";
645 teams = [ lib.teams.haskell ];
646 };
647 constituents = accumulateDerivations (
648 builtins.map (name: jobs.haskellPackages."${name}") (maintainedPkgNames pkgs.haskellPackages)
649 );
650 };
651
652 muslGHCs = pkgs.releaseTools.aggregate {
653 name = "haskell-pkgsMusl-ghcs";
654 meta = {
655 description = "GHCs built with musl";
656 maintainers = with lib.maintainers; [
657 nh2
658 ];
659 };
660 constituents = accumulateDerivations [
661 jobs.pkgsMusl.haskell.compiler.ghcHEAD
662 jobs.pkgsMusl.haskell.compiler.native-bignum.ghcHEAD
663 ];
664 };
665
666 staticHaskellPackages = pkgs.releaseTools.aggregate {
667 name = "static-haskell-packages";
668 meta = {
669 description = "Static haskell builds using the pkgsStatic infrastructure";
670 maintainers = [
671 lib.maintainers.sternenseemann
672 lib.maintainers.rnhmjoj
673 ];
674 };
675 constituents = accumulateDerivations [
676 jobs.pkgsStatic.haskell.packages.native-bignum.ghc948 # non-hadrian
677 jobs.pkgsStatic.haskellPackages
678 jobs.pkgsStatic.haskell.packages.native-bignum.ghc984
679 ];
680 };
681 }
682 ];
683
684in
685jobs