Skip to content

Commit ed550d6

Browse files
Implement --matrix-extra for more matrix dimensions
Sometimes you need to test your project along more dimensions than just GHC version. This is particularly important for programs/libraries that use FFI to bind to libraries - they might need to be tested against a range of library versions. In general, you want to test all the combinations of GHC versions and other properties, i.e. the cartesian product. It is burdensome for maintainers that need such a strategy to manually adjust the matrix after every (re)generation of the CI script/spec. Better tool support for this scenario is warranted. This commit implements a new --matrix-extra option, which adds additional matrix dimensions. The option value format is: --matrix-extra libfoo:2.6,3.0;libbar:0.1,0.2 haskell-ci adds all the combinations of GHC version and the --matrix-extra fields to the matrix. Corresponding build/test steps can be introduced via --github-patches (or --travis-patches). This commit implements this feature for GitHub actions only. It can be implemented for Travis in a subsequent commit, if desired.
1 parent c76a268 commit ed550d6

File tree

3 files changed

+55
-12
lines changed

3 files changed

+55
-12
lines changed

src/HaskellCI/Config.hs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ data Config = Config
7676
, cfgPostgres :: !Bool
7777
, cfgGoogleChrome :: !Bool
7878
, cfgEnv :: M.Map Version String
79+
, cfgMatrixExtra :: M.Map String (S.Set String)
7980
, cfgAllowFailures :: !VersionRange
8081
, cfgLastInSeries :: !Bool
8182
, cfgOsx :: S.Set Version
@@ -134,6 +135,7 @@ emptyConfig = Config
134135
, cfgPostgres = False
135136
, cfgGoogleChrome = False
136137
, cfgEnv = M.empty
138+
, cfgMatrixExtra = M.empty
137139
, cfgAllowFailures = noVersion
138140
, cfgLastInSeries = False
139141
, cfgOsx = S.empty
@@ -159,7 +161,7 @@ configGrammar
159161
, c (Identity Ubuntu)
160162
, c (Identity Jobs)
161163
, c (Identity CopyFields)
162-
, c Env, c Folds, c CopyFields, c HeadVersion
164+
, c Env, c MatrixExtra, c Folds, c CopyFields, c HeadVersion
163165
, c (C.List C.FSep (Identity Installed) Installed)
164166
, Applicative (g DoctestConfig)
165167
, Applicative (g DocspecConfig)
@@ -228,6 +230,8 @@ configGrammar = Config
228230
^^^ help "Add google-chrome service"
229231
<*> C.monoidalFieldAla "env" Env (field @"cfgEnv")
230232
^^^ metahelp "ENV" "Environment variables per job (e.g. `8.0.2:HADDOCK=false`)"
233+
<*> C.monoidalFieldAla "matrix-extra" MatrixExtra (field @"cfgMatrixExtra")
234+
^^^ metahelp "MATRIX" "Extra matrix dimensions (e.g. `libfoo:2.6,3.0,git`)"
231235
<*> C.optionalFieldDefAla "allow-failures" Range (field @"cfgAllowFailures") noVersion
232236
^^^ metahelp "JOB" "Allow failures of particular GHC version"
233237
<*> C.booleanFieldDef "last-in-series" (field @"cfgLastInSeries") False
@@ -302,6 +306,28 @@ instance C.Pretty Env where
302306
pretty (Env m) = PP.fsep . PP.punctuate PP.comma . map p . M.toList $ m where
303307
p (v, s) = C.pretty v PP.<> PP.colon PP.<> PP.text s
304308

309+
310+
-------------------------------------------------------------------------------
311+
-- MatrixExtra
312+
-------------------------------------------------------------------------------
313+
314+
newtype MatrixExtra = MatrixExtra (M.Map String (S.Set String))
315+
deriving anyclass (C.Newtype (M.Map String (S.Set String)))
316+
317+
instance C.Parsec MatrixExtra where
318+
parsec = MatrixExtra . M.fromList . toList <$> C.sepByNonEmpty p (C.char ';')
319+
where
320+
p = do
321+
k <- C.munch1 (/= ':')
322+
_ <- C.char ':'
323+
v <- foldMap S.singleton <$> C.sepByNonEmpty (C.munch1 (`notElem` [',', ';'])) (C.char ',')
324+
pure (k, v)
325+
326+
instance C.Pretty MatrixExtra where
327+
pretty (MatrixExtra m) = PP.fsep . PP.punctuate PP.semi . map p . M.toList $ m where
328+
p (k, v) = PP.text k PP.<> PP.colon PP.<> PP.fsep (PP.punctuate PP.comma (map PP.text (toList v)))
329+
330+
305331
-------------------------------------------------------------------------------
306332
-- From Cabal
307333
-------------------------------------------------------------------------------

src/HaskellCI/GitHub.hs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -462,15 +462,7 @@ makeGitHub _argv config@Config {..} gitconfig prj jobs@JobVersions {..} = do
462462
, ghjContinueOnError = Just "${{ matrix.allow-failure }}"
463463
, ghjServices = mconcat
464464
[ Map.singleton "postgres" postgresService | cfgPostgres ]
465-
, ghjMatrix =
466-
[ GitHubMatrixEntry
467-
{ ghmeGhcVersion = v
468-
, ghmeAllowFailure =
469-
previewGHC cfgHeadHackage compiler
470-
|| maybeGHC False (`C.withinRange` cfgAllowFailures) compiler
471-
}
472-
| compiler@(GHC v) <- reverse $ toList versions
473-
]
465+
, ghjMatrix = matrix
474466
})
475467
unless (null cfgIrcChannels) $
476468
ircJob actionName mainJobName projectName config gitconfig
@@ -487,6 +479,30 @@ makeGitHub _argv config@Config {..} gitconfig prj jobs@JobVersions {..} = do
487479
headGhcVers :: Set CompilerVersion
488480
headGhcVers = S.filter (previewGHC cfgHeadHackage) versions
489481

482+
-- extra matrix fields
483+
matrixExtra :: [[(String, String)]]
484+
matrixExtra =
485+
sequence
486+
$ (\(k, vs) -> fmap (\v -> (k, v)) (toList vs))
487+
<$> Map.toList cfgMatrixExtra
488+
489+
mkMatrixEntries :: [(String, String)] -> [GitHubMatrixEntry]
490+
mkMatrixEntries extra =
491+
[ GitHubMatrixEntry
492+
{ ghmeGhcVersion = v
493+
, ghmeAllowFailure =
494+
previewGHC cfgHeadHackage compiler
495+
|| maybeGHC False (`C.withinRange` cfgAllowFailures) compiler
496+
, ghmeMatrixExtra = extra
497+
}
498+
| compiler@(GHC v) <- reverse $ toList versions
499+
]
500+
501+
matrix :: [GitHubMatrixEntry]
502+
matrix = case matrixExtra of
503+
[] -> mkMatrixEntries []
504+
xs -> xs >>= mkMatrixEntries
505+
490506
-- step primitives
491507
githubRun' :: String -> Map.Map String String -> ShM () -> ListBuilder (Either ShError GitHubStep) ()
492508
githubRun' name env shm = item $ do

src/HaskellCI/GitHub/Yaml.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ data GitHubJob = GitHubJob
4343
data GitHubMatrixEntry = GitHubMatrixEntry
4444
{ ghmeGhcVersion :: Version
4545
, ghmeAllowFailure :: Bool
46+
, ghmeMatrixExtra :: [(String, String)]
4647
}
4748
deriving (Show)
4849

@@ -123,10 +124,10 @@ instance ToYaml GitHubJob where
123124
item $ "steps" ~> ylistFilt [] (map toYaml $ filter notEmptyStep ghjSteps)
124125

125126
instance ToYaml GitHubMatrixEntry where
126-
toYaml GitHubMatrixEntry {..} = ykeyValuesFilt []
127+
toYaml GitHubMatrixEntry {..} = ykeyValuesFilt [] $
127128
[ "ghc" ~> fromString (prettyShow ghmeGhcVersion)
128129
, "allow-failure" ~> toYaml ghmeAllowFailure
129-
]
130+
] ++ fmap (\(k, v) -> k ~> fromString v) ghmeMatrixExtra
130131

131132
instance ToYaml GitHubStep where
132133
toYaml GitHubStep {..} = ykeyValuesFilt [] $

0 commit comments

Comments
 (0)