{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}

-- |
-- Module      : Language.Github.Actions.Workflow
-- Description : GitHub Actions workflow definition and serialization
-- Copyright   : (c) 2025 Bellroy Pty Ltd
-- License     : BSD-3-Clause
-- Maintainer  : Bellroy Tech Team <haskell@bellroy.com>
--
-- This module provides the core 'Workflow' type for representing GitHub Actions workflows,
-- along with JSON serialization/deserialization and generation utilities.
--
-- GitHub Actions workflows are defined in YAML files that specify automated processes
-- triggered by events in a GitHub repository. This module provides a type-safe way to
-- construct and serialize these workflows.
--
-- For more information about GitHub Actions workflow syntax, see:
-- <https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions>
module Language.Github.Actions.Workflow
  ( Workflow (..),
    gen,
    new,
  )
where

import Data.Aeson (FromJSON, ToJSON (..), (.!=), (.:), (.:?), (.=))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.KeyMap as AesonKeyMap
import Data.Map (Map)
import Data.Maybe (catMaybes)
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Text (Text)
import GHC.Generics (Generic)
import Hedgehog (MonadGen)
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Language.Github.Actions.Concurrency (Concurrency)
import qualified Language.Github.Actions.Concurrency as Concurrency
import Language.Github.Actions.Defaults (Defaults)
import qualified Language.Github.Actions.Defaults as Defaults
import Language.Github.Actions.Job (Job)
import qualified Language.Github.Actions.Job as Job
import Language.Github.Actions.Job.Id (JobId)
import qualified Language.Github.Actions.Job.Id as JobId
import Language.Github.Actions.Permissions (Permissions)
import qualified Language.Github.Actions.Permissions as Permissions
import Language.Github.Actions.Workflow.Trigger (WorkflowTrigger)
import qualified Language.Github.Actions.Workflow.Trigger as WorkflowTrigger

-- | Internal type for workflow job steps (used in JSON parsing)
data WorkflowJobStep = WorkflowJobStep
  { -- | Optional step name
    WorkflowJobStep -> Maybe Text
name :: Maybe Text,
    -- | Optional run command
    WorkflowJobStep -> Maybe Text
run :: Maybe Text
  }
  deriving stock (WorkflowJobStep -> WorkflowJobStep -> Bool
(WorkflowJobStep -> WorkflowJobStep -> Bool)
-> (WorkflowJobStep -> WorkflowJobStep -> Bool)
-> Eq WorkflowJobStep
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: WorkflowJobStep -> WorkflowJobStep -> Bool
== :: WorkflowJobStep -> WorkflowJobStep -> Bool
$c/= :: WorkflowJobStep -> WorkflowJobStep -> Bool
/= :: WorkflowJobStep -> WorkflowJobStep -> Bool
Eq, (forall x. WorkflowJobStep -> Rep WorkflowJobStep x)
-> (forall x. Rep WorkflowJobStep x -> WorkflowJobStep)
-> Generic WorkflowJobStep
forall x. Rep WorkflowJobStep x -> WorkflowJobStep
forall x. WorkflowJobStep -> Rep WorkflowJobStep x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. WorkflowJobStep -> Rep WorkflowJobStep x
from :: forall x. WorkflowJobStep -> Rep WorkflowJobStep x
$cto :: forall x. Rep WorkflowJobStep x -> WorkflowJobStep
to :: forall x. Rep WorkflowJobStep x -> WorkflowJobStep
Generic, Eq WorkflowJobStep
Eq WorkflowJobStep =>
(WorkflowJobStep -> WorkflowJobStep -> Ordering)
-> (WorkflowJobStep -> WorkflowJobStep -> Bool)
-> (WorkflowJobStep -> WorkflowJobStep -> Bool)
-> (WorkflowJobStep -> WorkflowJobStep -> Bool)
-> (WorkflowJobStep -> WorkflowJobStep -> Bool)
-> (WorkflowJobStep -> WorkflowJobStep -> WorkflowJobStep)
-> (WorkflowJobStep -> WorkflowJobStep -> WorkflowJobStep)
-> Ord WorkflowJobStep
WorkflowJobStep -> WorkflowJobStep -> Bool
WorkflowJobStep -> WorkflowJobStep -> Ordering
WorkflowJobStep -> WorkflowJobStep -> WorkflowJobStep
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: WorkflowJobStep -> WorkflowJobStep -> Ordering
compare :: WorkflowJobStep -> WorkflowJobStep -> Ordering
$c< :: WorkflowJobStep -> WorkflowJobStep -> Bool
< :: WorkflowJobStep -> WorkflowJobStep -> Bool
$c<= :: WorkflowJobStep -> WorkflowJobStep -> Bool
<= :: WorkflowJobStep -> WorkflowJobStep -> Bool
$c> :: WorkflowJobStep -> WorkflowJobStep -> Bool
> :: WorkflowJobStep -> WorkflowJobStep -> Bool
$c>= :: WorkflowJobStep -> WorkflowJobStep -> Bool
>= :: WorkflowJobStep -> WorkflowJobStep -> Bool
$cmax :: WorkflowJobStep -> WorkflowJobStep -> WorkflowJobStep
max :: WorkflowJobStep -> WorkflowJobStep -> WorkflowJobStep
$cmin :: WorkflowJobStep -> WorkflowJobStep -> WorkflowJobStep
min :: WorkflowJobStep -> WorkflowJobStep -> WorkflowJobStep
Ord, Int -> WorkflowJobStep -> ShowS
[WorkflowJobStep] -> ShowS
WorkflowJobStep -> String
(Int -> WorkflowJobStep -> ShowS)
-> (WorkflowJobStep -> String)
-> ([WorkflowJobStep] -> ShowS)
-> Show WorkflowJobStep
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> WorkflowJobStep -> ShowS
showsPrec :: Int -> WorkflowJobStep -> ShowS
$cshow :: WorkflowJobStep -> String
show :: WorkflowJobStep -> String
$cshowList :: [WorkflowJobStep] -> ShowS
showList :: [WorkflowJobStep] -> ShowS
Show)

-- | A GitHub Actions workflow definition.
--
-- A workflow defines automated processes that run in response to events in your repository.
-- Workflows are defined in YAML files stored in the @.github\/workflows@ directory.
--
-- Example usage:
--
-- @
-- import Language.Github.Actions.Workflow
-- import qualified Language.Github.Actions.Job as Job
-- import qualified Language.Github.Actions.Job.Id as JobId
--
-- myWorkflow :: Workflow
-- myWorkflow = new
--  { workflowName = Just "CI"
--  , jobs = Map.singleton (JobId "build") Job.new
--  , on = Set.singleton pushTrigger
--  }
-- @
--
-- For more details, see: <https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions>
data Workflow = Workflow
  { -- | Concurrency settings to limit workflow runs
    Workflow -> Maybe Concurrency
concurrency :: Maybe Concurrency,
    -- | Default settings for all jobs in the workflow
    Workflow -> Maybe Defaults
defaults :: Maybe Defaults,
    -- | Environment variables available to all jobs
    Workflow -> Map Text Text
env :: Map Text Text,
    -- | The jobs that make up the workflow
    Workflow -> Map JobId Job
jobs :: Map JobId Job,
    -- | Events that trigger the workflow
    Workflow -> Set WorkflowTrigger
on :: Set WorkflowTrigger,
    -- | Permissions granted to the workflow
    Workflow -> Maybe Permissions
permissions :: Maybe Permissions,
    -- | Name for workflow runs
    Workflow -> Maybe Text
runName :: Maybe Text,
    -- | Name of the workflow
    Workflow -> Maybe Text
workflowName :: Maybe Text
  }
  deriving stock (Workflow -> Workflow -> Bool
(Workflow -> Workflow -> Bool)
-> (Workflow -> Workflow -> Bool) -> Eq Workflow
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Workflow -> Workflow -> Bool
== :: Workflow -> Workflow -> Bool
$c/= :: Workflow -> Workflow -> Bool
/= :: Workflow -> Workflow -> Bool
Eq, (forall x. Workflow -> Rep Workflow x)
-> (forall x. Rep Workflow x -> Workflow) -> Generic Workflow
forall x. Rep Workflow x -> Workflow
forall x. Workflow -> Rep Workflow x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Workflow -> Rep Workflow x
from :: forall x. Workflow -> Rep Workflow x
$cto :: forall x. Rep Workflow x -> Workflow
to :: forall x. Rep Workflow x -> Workflow
Generic, Eq Workflow
Eq Workflow =>
(Workflow -> Workflow -> Ordering)
-> (Workflow -> Workflow -> Bool)
-> (Workflow -> Workflow -> Bool)
-> (Workflow -> Workflow -> Bool)
-> (Workflow -> Workflow -> Bool)
-> (Workflow -> Workflow -> Workflow)
-> (Workflow -> Workflow -> Workflow)
-> Ord Workflow
Workflow -> Workflow -> Bool
Workflow -> Workflow -> Ordering
Workflow -> Workflow -> Workflow
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Workflow -> Workflow -> Ordering
compare :: Workflow -> Workflow -> Ordering
$c< :: Workflow -> Workflow -> Bool
< :: Workflow -> Workflow -> Bool
$c<= :: Workflow -> Workflow -> Bool
<= :: Workflow -> Workflow -> Bool
$c> :: Workflow -> Workflow -> Bool
> :: Workflow -> Workflow -> Bool
$c>= :: Workflow -> Workflow -> Bool
>= :: Workflow -> Workflow -> Bool
$cmax :: Workflow -> Workflow -> Workflow
max :: Workflow -> Workflow -> Workflow
$cmin :: Workflow -> Workflow -> Workflow
min :: Workflow -> Workflow -> Workflow
Ord, Int -> Workflow -> ShowS
[Workflow] -> ShowS
Workflow -> String
(Int -> Workflow -> ShowS)
-> (Workflow -> String) -> ([Workflow] -> ShowS) -> Show Workflow
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Workflow -> ShowS
showsPrec :: Int -> Workflow -> ShowS
$cshow :: Workflow -> String
show :: Workflow -> String
$cshowList :: [Workflow] -> ShowS
showList :: [Workflow] -> ShowS
Show)

instance FromJSON Workflow where
  parseJSON :: Value -> Parser Workflow
parseJSON = String -> (Object -> Parser Workflow) -> Value -> Parser Workflow
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"Workflow" ((Object -> Parser Workflow) -> Value -> Parser Workflow)
-> (Object -> Parser Workflow) -> Value -> Parser Workflow
forall a b. (a -> b) -> a -> b
$ \Object
o -> do
    Maybe Concurrency
concurrency <- Object
o Object -> Key -> Parser (Maybe Concurrency)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"concurrency"
    Maybe Defaults
defaults <- Object
o Object -> Key -> Parser (Maybe Defaults)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"defaults"
    Map Text Text
env <- Object
o Object -> Key -> Parser (Maybe (Map Text Text))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"env" Parser (Maybe (Map Text Text))
-> Map Text Text -> Parser (Map Text Text)
forall a. Parser (Maybe a) -> a -> Parser a
.!= Map Text Text
forall a. Monoid a => a
mempty
    Map JobId Job
jobs <- Object
o Object -> Key -> Parser (Map JobId Job)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"jobs"
    Aeson.Object Object
onObject <- Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"on"
    [WorkflowTrigger]
triggers <-
      ((Key, Value) -> Parser WorkflowTrigger)
-> [(Key, Value)] -> Parser [WorkflowTrigger]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse
        ( Value -> Parser WorkflowTrigger
forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON
            (Value -> Parser WorkflowTrigger)
-> ((Key, Value) -> Value)
-> (Key, Value)
-> Parser WorkflowTrigger
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Object -> Value
Aeson.Object
            (Object -> Value)
-> ((Key, Value) -> Object) -> (Key, Value) -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Key -> Value -> Object) -> (Key, Value) -> Object
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Key -> Value -> Object
forall v. Key -> v -> KeyMap v
AesonKeyMap.singleton
        )
        ([(Key, Value)] -> Parser [WorkflowTrigger])
-> [(Key, Value)] -> Parser [WorkflowTrigger]
forall a b. (a -> b) -> a -> b
$ Object -> [(Key, Value)]
forall v. KeyMap v -> [(Key, v)]
AesonKeyMap.toList Object
onObject
    let on :: Set WorkflowTrigger
on = [WorkflowTrigger] -> Set WorkflowTrigger
forall a. Ord a => [a] -> Set a
Set.fromList [WorkflowTrigger]
triggers
    Maybe Permissions
permissions <- Object
o Object -> Key -> Parser (Maybe Permissions)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"permissions"
    Maybe Text
runName <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"run-name"
    Maybe Text
workflowName <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"name"
    Workflow -> Parser Workflow
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Workflow {Maybe Text
Maybe Concurrency
Maybe Permissions
Maybe Defaults
Map Text Text
Map JobId Job
Set WorkflowTrigger
concurrency :: Maybe Concurrency
defaults :: Maybe Defaults
env :: Map Text Text
jobs :: Map JobId Job
on :: Set WorkflowTrigger
permissions :: Maybe Permissions
runName :: Maybe Text
workflowName :: Maybe Text
concurrency :: Maybe Concurrency
defaults :: Maybe Defaults
env :: Map Text Text
jobs :: Map JobId Job
on :: Set WorkflowTrigger
permissions :: Maybe Permissions
runName :: Maybe Text
workflowName :: Maybe Text
..}

instance ToJSON Workflow where
  toJSON :: Workflow -> Value
toJSON Workflow {Maybe Text
Maybe Concurrency
Maybe Permissions
Maybe Defaults
Map Text Text
Map JobId Job
Set WorkflowTrigger
concurrency :: Workflow -> Maybe Concurrency
defaults :: Workflow -> Maybe Defaults
env :: Workflow -> Map Text Text
jobs :: Workflow -> Map JobId Job
on :: Workflow -> Set WorkflowTrigger
permissions :: Workflow -> Maybe Permissions
runName :: Workflow -> Maybe Text
workflowName :: Workflow -> Maybe Text
concurrency :: Maybe Concurrency
defaults :: Maybe Defaults
env :: Map Text Text
jobs :: Map JobId Job
on :: Set WorkflowTrigger
permissions :: Maybe Permissions
runName :: Maybe Text
workflowName :: Maybe Text
..} =
    [(Key, Value)] -> Value
Aeson.object ([(Key, Value)] -> Value) -> [(Key, Value)] -> Value
forall a b. (a -> b) -> a -> b
$
      [Maybe (Key, Value)] -> [(Key, Value)]
forall a. [Maybe a] -> [a]
catMaybes
        [ (Key
"concurrency" Key -> Concurrency -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Concurrency -> (Key, Value))
-> Maybe Concurrency -> Maybe (Key, Value)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Concurrency
concurrency,
          (Key
"defaults" Key -> Defaults -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Defaults -> (Key, Value)) -> Maybe Defaults -> Maybe (Key, Value)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Defaults
defaults,
          (Key
"env" Key -> Map Text Text -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Map Text Text -> (Key, Value))
-> Maybe (Map Text Text) -> Maybe (Key, Value)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Text Text -> Maybe (Map Text Text)
forall a. (Eq a, Monoid a) => a -> Maybe a
monoidToMaybe Map Text Text
env,
          (Key, Value) -> Maybe (Key, Value)
forall a. a -> Maybe a
Just ((Key, Value) -> Maybe (Key, Value))
-> (Key, Value) -> Maybe (Key, Value)
forall a b. (a -> b) -> a -> b
$ Key
"jobs" Key -> Map JobId Job -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Map JobId Job
jobs,
          (Key
"name" Key -> Text -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Text -> (Key, Value)) -> Maybe Text -> Maybe (Key, Value)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
workflowName,
          (Key, Value) -> Maybe (Key, Value)
forall a. a -> Maybe a
Just ((Key, Value) -> Maybe (Key, Value))
-> (Key, Value) -> Maybe (Key, Value)
forall a b. (a -> b) -> a -> b
$ Key
"on" Key -> Value -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Object -> Value
Aeson.Object ([Object] -> Object
forall a. Monoid a => [a] -> a
mconcat (Value -> Object
forceToJSONObject (Value -> Object)
-> (WorkflowTrigger -> Value) -> WorkflowTrigger -> Object
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WorkflowTrigger -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (WorkflowTrigger -> Object) -> [WorkflowTrigger] -> [Object]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set WorkflowTrigger -> [WorkflowTrigger]
forall a. Set a -> [a]
Set.toList Set WorkflowTrigger
on)),
          (Key
"permissions" Key -> Permissions -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Permissions -> (Key, Value))
-> Maybe Permissions -> Maybe (Key, Value)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Permissions
permissions,
          (Key
"run-name" Key -> Text -> (Key, Value)
forall v. ToJSON v => Key -> v -> (Key, Value)
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Text -> (Key, Value)) -> Maybe Text -> Maybe (Key, Value)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
runName
        ]
    where
      forceToJSONObject :: Aeson.Value -> Aeson.Object
      forceToJSONObject :: Value -> Object
forceToJSONObject (Aeson.Object Object
o) = Object
o
      forceToJSONObject Value
_ = String -> Object
forall a. HasCallStack => String -> a
error String
"Expected Aeson.Object"

      monoidToMaybe :: (Eq a, Monoid a) => a -> Maybe a
      monoidToMaybe :: forall a. (Eq a, Monoid a) => a -> Maybe a
monoidToMaybe a
a = if a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Monoid a => a
mempty then Maybe a
forall a. Maybe a
Nothing else a -> Maybe a
forall a. a -> Maybe a
Just a
a

gen :: (MonadGen m) => m Workflow
gen :: forall (m :: * -> *). MonadGen m => m Workflow
gen = do
  Maybe Concurrency
concurrency <- m Concurrency -> m (Maybe Concurrency)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m Concurrency
forall (m :: * -> *). MonadGen m => m Concurrency
Concurrency.gen
  Maybe Defaults
defaults <- m Defaults -> m (Maybe Defaults)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m Defaults
forall (m :: * -> *). MonadGen m => m Defaults
Defaults.gen
  Map Text Text
env <- m (Map Text Text)
genTextMap
  Map JobId Job
jobs <-
    Range Int -> m (JobId, Job) -> m (Map JobId Job)
forall (m :: * -> *) k v.
(MonadGen m, Ord k) =>
Range Int -> m (k, v) -> m (Map k v)
Gen.map (Int -> Int -> Range Int
forall a. Integral a => a -> a -> Range a
Range.linear Int
1 Int
5) ((JobId -> Job -> (JobId, Job))
-> m JobId -> m Job -> m (JobId, Job)
forall a b c. (a -> b -> c) -> m a -> m b -> m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) m JobId
forall (m :: * -> *). MonadGen m => m JobId
JobId.gen m Job
forall (m :: * -> *). MonadGen m => m Job
Job.gen)
  Set WorkflowTrigger
on <-
    [WorkflowTrigger] -> Set WorkflowTrigger
forall a. Ord a => [a] -> Set a
Set.fromList
      ([WorkflowTrigger] -> Set WorkflowTrigger)
-> ([WorkflowTrigger] -> [WorkflowTrigger])
-> [WorkflowTrigger]
-> Set WorkflowTrigger
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Key], [WorkflowTrigger]) -> [WorkflowTrigger]
forall a b. (a, b) -> b
snd
      (([Key], [WorkflowTrigger]) -> [WorkflowTrigger])
-> ([WorkflowTrigger] -> ([Key], [WorkflowTrigger]))
-> [WorkflowTrigger]
-> [WorkflowTrigger]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (WorkflowTrigger
 -> ([Key], [WorkflowTrigger]) -> ([Key], [WorkflowTrigger]))
-> ([Key], [WorkflowTrigger])
-> [WorkflowTrigger]
-> ([Key], [WorkflowTrigger])
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr WorkflowTrigger
-> ([Key], [WorkflowTrigger]) -> ([Key], [WorkflowTrigger])
onlyAddIfJsonKeyNotAlreadyPresent ([], [])
      ([WorkflowTrigger] -> Set WorkflowTrigger)
-> m [WorkflowTrigger] -> m (Set WorkflowTrigger)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Range Int -> m WorkflowTrigger -> m [WorkflowTrigger]
forall (m :: * -> *) a. MonadGen m => Range Int -> m a -> m [a]
Gen.list (Int -> Int -> Range Int
forall a. Integral a => a -> a -> Range a
Range.linear Int
1 Int
5) m WorkflowTrigger
forall (m :: * -> *). MonadGen m => m WorkflowTrigger
WorkflowTrigger.gen

  Maybe Permissions
permissions <- m Permissions -> m (Maybe Permissions)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m Permissions
forall (m :: * -> *). MonadGen m => m Permissions
Permissions.gen
  Maybe Text
runName <- m Text -> m (Maybe Text)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m Text
genText
  Maybe Text
workflowName <- m Text -> m (Maybe Text)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m Text
genText
  Workflow -> m Workflow
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Workflow {Maybe Text
Maybe Concurrency
Maybe Permissions
Maybe Defaults
Map Text Text
Map JobId Job
Set WorkflowTrigger
concurrency :: Maybe Concurrency
defaults :: Maybe Defaults
env :: Map Text Text
jobs :: Map JobId Job
on :: Set WorkflowTrigger
permissions :: Maybe Permissions
runName :: Maybe Text
workflowName :: Maybe Text
concurrency :: Maybe Concurrency
defaults :: Maybe Defaults
env :: Map Text Text
jobs :: Map JobId Job
on :: Set WorkflowTrigger
permissions :: Maybe Permissions
runName :: Maybe Text
workflowName :: Maybe Text
..}
  where
    onlyAddIfJsonKeyNotAlreadyPresent ::
      WorkflowTrigger ->
      ([AesonKeyMap.Key], [WorkflowTrigger]) ->
      ([AesonKeyMap.Key], [WorkflowTrigger])
    onlyAddIfJsonKeyNotAlreadyPresent :: WorkflowTrigger
-> ([Key], [WorkflowTrigger]) -> ([Key], [WorkflowTrigger])
onlyAddIfJsonKeyNotAlreadyPresent WorkflowTrigger
trigger ([Key]
keys, [WorkflowTrigger]
triggers) =
      let key :: Key
key = case ToJSONKeyFunction WorkflowTrigger
forall a. ToJSONKey a => ToJSONKeyFunction a
Aeson.toJSONKey of
            Aeson.ToJSONKeyText WorkflowTrigger -> Key
f WorkflowTrigger -> Encoding' Key
_ -> WorkflowTrigger -> Key
f WorkflowTrigger
trigger
            ToJSONKeyFunction WorkflowTrigger
_ -> String -> Key
forall a. HasCallStack => String -> a
error String
"Expected Aeson.ToJSONKeyText"
       in if Key
key Key -> [Key] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Key]
keys
            then ([Key]
keys, [WorkflowTrigger]
triggers)
            else (Key
key Key -> [Key] -> [Key]
forall a. a -> [a] -> [a]
: [Key]
keys, WorkflowTrigger
trigger WorkflowTrigger -> [WorkflowTrigger] -> [WorkflowTrigger]
forall a. a -> [a] -> [a]
: [WorkflowTrigger]
triggers)

    genText :: m Text
genText = Range Int -> m Char -> m Text
forall (m :: * -> *). MonadGen m => Range Int -> m Char -> m Text
Gen.text (Int -> Int -> Range Int
forall a. Integral a => a -> a -> Range a
Range.linear Int
1 Int
5) m Char
forall (m :: * -> *). MonadGen m => m Char
Gen.alphaNum
    genTextMap :: m (Map Text Text)
genTextMap = Range Int -> m (Text, Text) -> m (Map Text Text)
forall (m :: * -> *) k v.
(MonadGen m, Ord k) =>
Range Int -> m (k, v) -> m (Map k v)
Gen.map (Int -> Int -> Range Int
forall a. Integral a => a -> a -> Range a
Range.linear Int
1 Int
5) (m (Text, Text) -> m (Map Text Text))
-> m (Text, Text) -> m (Map Text Text)
forall a b. (a -> b) -> a -> b
$ (Text -> Text -> (Text, Text))
-> m Text -> m Text -> m (Text, Text)
forall a b c. (a -> b -> c) -> m a -> m b -> m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) m Text
genText m Text
genText

-- | Create a new empty 'Workflow' with default values.
--
-- This provides a minimal workflow that can be extended with specific jobs,
-- triggers, and other configuration.
--
-- Example:
--
-- @
-- myWorkflow = new
--   { workflowName = Just "My Workflow"
--   , jobs = Map.singleton (JobId "test") Job.new
--   , on = Set.singleton (PushTrigger pushTriggerDefaults)
--   }
-- @
new :: Workflow
new :: Workflow
new =
  Workflow
    { concurrency :: Maybe Concurrency
concurrency = Maybe Concurrency
forall a. Maybe a
Nothing,
      defaults :: Maybe Defaults
defaults = Maybe Defaults
forall a. Maybe a
Nothing,
      env :: Map Text Text
env = Map Text Text
forall a. Monoid a => a
mempty,
      jobs :: Map JobId Job
jobs = Map JobId Job
forall a. Monoid a => a
mempty,
      on :: Set WorkflowTrigger
on = Set WorkflowTrigger
forall a. Monoid a => a
mempty,
      permissions :: Maybe Permissions
permissions = Maybe Permissions
forall a. Maybe a
Nothing,
      runName :: Maybe Text
runName = Maybe Text
forall a. Maybe a
Nothing,
      workflowName :: Maybe Text
workflowName = Maybe Text
forall a. Maybe a
Nothing
    }