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

-- |
-- Module      : Language.Github.Actions.Job
-- Description : GitHub Actions job definition and serialization
-- Copyright   : (c) 2025 Bellroy Pty Ltd
-- License     : BSD-3-Clause
-- Maintainer  : Bellroy Tech Team <haskell@bellroy.com>
--
-- This module provides the 'Job' type for representing individual jobs within GitHub Actions workflows.
-- Jobs are collections of steps that execute on the same runner.
--
-- A job defines the environment, dependencies, and steps that should be executed as part of a workflow.
-- Jobs can run in parallel or be configured to depend on other jobs.
--
-- For more information about GitHub Actions job syntax, see:
-- <https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobs>
module Language.Github.Actions.Job
  ( Job (..),
    gen,
    new,
  )
where

import Data.Aeson (FromJSON, ToJSON (..), (.!=), (.:?), (.=))
import qualified Data.Aeson as Aeson
import Data.List.NonEmpty (NonEmpty (..))
import Data.Map (Map)
import Data.Maybe (catMaybes)
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.Container (JobContainer)
import qualified Language.Github.Actions.Job.Container as JobContainer
import Language.Github.Actions.Job.Environment (JobEnvironment)
import qualified Language.Github.Actions.Job.Environment as JobEnvironment
import Language.Github.Actions.Job.Needs (JobNeeds)
import qualified Language.Github.Actions.Job.Needs as JobNeeds
import Language.Github.Actions.Job.Strategy (JobStrategy)
import qualified Language.Github.Actions.Job.Strategy as JobStrategy
import Language.Github.Actions.Permissions (Permissions)
import qualified Language.Github.Actions.Permissions as Permissions
import Language.Github.Actions.RunIf (RunIf)
import qualified Language.Github.Actions.RunIf as RunIf
import Language.Github.Actions.Service (Service)
import qualified Language.Github.Actions.Service as Service
import Language.Github.Actions.Service.Id (ServiceId)
import qualified Language.Github.Actions.Service.Id as ServiceId
import Language.Github.Actions.Step (Step)
import qualified Language.Github.Actions.Step as Step

-- | A job within a GitHub Actions workflow.
--
-- A job is a set of steps that execute on the same runner. Jobs can run in parallel
-- or sequentially depending on their dependencies. Each job runs in its own virtual
-- environment specified by the runner.
--
-- Example usage:
--
-- @
-- import Language.Github.Actions.Job
-- import qualified Language.Github.Actions.Step as Step
--
-- myJob :: Job
-- myJob = new
--  { jobName = Just "Build and Test"
--  , runsOn = Just "ubuntu-latest"
--  , steps = Just $ Step.new :| []
--  }
-- @
--
-- For more details, see: <https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobs>
data Job = Job
  { -- | Concurrency settings for this job
    Job -> Maybe Concurrency
concurrency :: Maybe Concurrency,
    -- | Container to run the job in
    Job -> Maybe JobContainer
container :: Maybe JobContainer,
    -- | Whether to continue on step failure
    Job -> Maybe Bool
continueOnError :: Maybe Bool,
    -- | Default settings for steps in this job
    Job -> Maybe Defaults
defaults :: Maybe Defaults,
    -- | Environment variables for this job
    Job -> Map Text Text
env :: Map Text Text,
    -- | Deployment environment settings
    Job -> Maybe JobEnvironment
environment :: Maybe JobEnvironment,
    -- | Display name for the job
    Job -> Maybe Text
jobName :: Maybe Text,
    -- | Jobs this job depends on
    Job -> Maybe JobNeeds
needs :: Maybe JobNeeds,
    -- | Outputs from this job
    Job -> Map Text Text
outputs :: Map Text Text,
    -- | Permissions for this job
    Job -> Maybe Permissions
permissions :: Maybe Permissions,
    -- | Condition for running this job
    Job -> Maybe RunIf
runIf :: Maybe RunIf,
    -- | Runner type (e.g., "ubuntu-latest")
    Job -> Maybe Text
runsOn :: Maybe Text,
    -- | Secrets available to this job
    Job -> Map Text Text
secrets :: Map Text Text,
    -- | Services to run alongside this job
    Job -> Map ServiceId Service
services :: Map ServiceId Service,
    -- | Steps to execute in this job
    Job -> Maybe (NonEmpty Step)
steps :: Maybe (NonEmpty Step),
    -- | Matrix strategy for this job
    Job -> Maybe JobStrategy
strategy :: Maybe JobStrategy,
    -- | Timeout for the job in minutes
    Job -> Maybe Int
timeoutMinutes :: Maybe Int,
    -- | Reusable workflow to call
    Job -> Maybe Text
uses :: Maybe Text,
    -- | Inputs for reusable workflows
    Job -> Map Text Text
with :: Map Text Text
  }
  deriving stock (Job -> Job -> Bool
(Job -> Job -> Bool) -> (Job -> Job -> Bool) -> Eq Job
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Job -> Job -> Bool
== :: Job -> Job -> Bool
$c/= :: Job -> Job -> Bool
/= :: Job -> Job -> Bool
Eq, (forall x. Job -> Rep Job x)
-> (forall x. Rep Job x -> Job) -> Generic Job
forall x. Rep Job x -> Job
forall x. Job -> Rep Job x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Job -> Rep Job x
from :: forall x. Job -> Rep Job x
$cto :: forall x. Rep Job x -> Job
to :: forall x. Rep Job x -> Job
Generic, Eq Job
Eq Job =>
(Job -> Job -> Ordering)
-> (Job -> Job -> Bool)
-> (Job -> Job -> Bool)
-> (Job -> Job -> Bool)
-> (Job -> Job -> Bool)
-> (Job -> Job -> Job)
-> (Job -> Job -> Job)
-> Ord Job
Job -> Job -> Bool
Job -> Job -> Ordering
Job -> Job -> Job
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 :: Job -> Job -> Ordering
compare :: Job -> Job -> Ordering
$c< :: Job -> Job -> Bool
< :: Job -> Job -> Bool
$c<= :: Job -> Job -> Bool
<= :: Job -> Job -> Bool
$c> :: Job -> Job -> Bool
> :: Job -> Job -> Bool
$c>= :: Job -> Job -> Bool
>= :: Job -> Job -> Bool
$cmax :: Job -> Job -> Job
max :: Job -> Job -> Job
$cmin :: Job -> Job -> Job
min :: Job -> Job -> Job
Ord, Int -> Job -> ShowS
[Job] -> ShowS
Job -> String
(Int -> Job -> ShowS)
-> (Job -> String) -> ([Job] -> ShowS) -> Show Job
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Job -> ShowS
showsPrec :: Int -> Job -> ShowS
$cshow :: Job -> String
show :: Job -> String
$cshowList :: [Job] -> ShowS
showList :: [Job] -> ShowS
Show)

instance FromJSON Job where
  parseJSON :: Value -> Parser Job
parseJSON = String -> (Object -> Parser Job) -> Value -> Parser Job
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"Job" ((Object -> Parser Job) -> Value -> Parser Job)
-> (Object -> Parser Job) -> Value -> Parser Job
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 JobContainer
container <- Object
o Object -> Key -> Parser (Maybe JobContainer)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"container"
    Maybe Bool
continueOnError <- Object
o Object -> Key -> Parser (Maybe Bool)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"continue-on-error"
    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
    Maybe JobEnvironment
environment <- Object
o Object -> Key -> Parser (Maybe JobEnvironment)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"environment"
    Maybe Text
jobName <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"name"
    Maybe JobNeeds
needs <- Object
o Object -> Key -> Parser (Maybe JobNeeds)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"needs"
    Map Text Text
outputs <- Object
o Object -> Key -> Parser (Maybe (Map Text Text))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"outputs" 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
    Maybe Permissions
permissions <- Object
o Object -> Key -> Parser (Maybe Permissions)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"permissions"
    Maybe RunIf
runIf <- Object
o Object -> Key -> Parser (Maybe RunIf)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"if"
    Maybe Text
runsOn <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"runs-on"
    Map Text Text
secrets <- Object
o Object -> Key -> Parser (Maybe (Map Text Text))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"secrets" 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 ServiceId Service
services <- Object
o Object -> Key -> Parser (Maybe (Map ServiceId Service))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"services" Parser (Maybe (Map ServiceId Service))
-> Map ServiceId Service -> Parser (Map ServiceId Service)
forall a. Parser (Maybe a) -> a -> Parser a
.!= Map ServiceId Service
forall a. Monoid a => a
mempty
    Maybe (NonEmpty Step)
steps <- Object
o Object -> Key -> Parser (Maybe (NonEmpty Step))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"steps"
    Maybe JobStrategy
strategy <- Object
o Object -> Key -> Parser (Maybe JobStrategy)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"strategy"
    Maybe Int
timeoutMinutes <- Object
o Object -> Key -> Parser (Maybe Int)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"timeout-minutes"
    Maybe Text
uses <- Object
o Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"uses"
    Map Text Text
with <- Object
o Object -> Key -> Parser (Maybe (Map Text Text))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"with" 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
    Job -> Parser Job
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Job {Maybe Bool
Maybe Int
Maybe (NonEmpty Step)
Maybe Text
Maybe Concurrency
Maybe JobContainer
Maybe JobEnvironment
Maybe JobNeeds
Maybe JobStrategy
Maybe Permissions
Maybe RunIf
Maybe Defaults
Map Text Text
Map ServiceId Service
concurrency :: Maybe Concurrency
container :: Maybe JobContainer
continueOnError :: Maybe Bool
defaults :: Maybe Defaults
env :: Map Text Text
environment :: Maybe JobEnvironment
jobName :: Maybe Text
needs :: Maybe JobNeeds
outputs :: Map Text Text
permissions :: Maybe Permissions
runIf :: Maybe RunIf
runsOn :: Maybe Text
secrets :: Map Text Text
services :: Map ServiceId Service
steps :: Maybe (NonEmpty Step)
strategy :: Maybe JobStrategy
timeoutMinutes :: Maybe Int
uses :: Maybe Text
with :: Map Text Text
concurrency :: Maybe Concurrency
container :: Maybe JobContainer
continueOnError :: Maybe Bool
defaults :: Maybe Defaults
env :: Map Text Text
environment :: Maybe JobEnvironment
jobName :: Maybe Text
needs :: Maybe JobNeeds
outputs :: Map Text Text
permissions :: Maybe Permissions
runIf :: Maybe RunIf
runsOn :: Maybe Text
secrets :: Map Text Text
services :: Map ServiceId Service
steps :: Maybe (NonEmpty Step)
strategy :: Maybe JobStrategy
timeoutMinutes :: Maybe Int
uses :: Maybe Text
with :: Map Text Text
..}

instance ToJSON Job where
  toJSON :: Job -> Value
toJSON Job {Maybe Bool
Maybe Int
Maybe (NonEmpty Step)
Maybe Text
Maybe Concurrency
Maybe JobContainer
Maybe JobEnvironment
Maybe JobNeeds
Maybe JobStrategy
Maybe Permissions
Maybe RunIf
Maybe Defaults
Map Text Text
Map ServiceId Service
concurrency :: Job -> Maybe Concurrency
container :: Job -> Maybe JobContainer
continueOnError :: Job -> Maybe Bool
defaults :: Job -> Maybe Defaults
env :: Job -> Map Text Text
environment :: Job -> Maybe JobEnvironment
jobName :: Job -> Maybe Text
needs :: Job -> Maybe JobNeeds
outputs :: Job -> Map Text Text
permissions :: Job -> Maybe Permissions
runIf :: Job -> Maybe RunIf
runsOn :: Job -> Maybe Text
secrets :: Job -> Map Text Text
services :: Job -> Map ServiceId Service
steps :: Job -> Maybe (NonEmpty Step)
strategy :: Job -> Maybe JobStrategy
timeoutMinutes :: Job -> Maybe Int
uses :: Job -> Maybe Text
with :: Job -> Map Text Text
concurrency :: Maybe Concurrency
container :: Maybe JobContainer
continueOnError :: Maybe Bool
defaults :: Maybe Defaults
env :: Map Text Text
environment :: Maybe JobEnvironment
jobName :: Maybe Text
needs :: Maybe JobNeeds
outputs :: Map Text Text
permissions :: Maybe Permissions
runIf :: Maybe RunIf
runsOn :: Maybe Text
secrets :: Map Text Text
services :: Map ServiceId Service
steps :: Maybe (NonEmpty Step)
strategy :: Maybe JobStrategy
timeoutMinutes :: Maybe Int
uses :: Maybe Text
with :: Map Text Text
..} =
    [Pair] -> Value
Aeson.object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$
      [Maybe Pair] -> [Pair]
forall a. [Maybe a] -> [a]
catMaybes
        [ (Key
"concurrency" Key -> Concurrency -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Concurrency -> Pair) -> Maybe Concurrency -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Concurrency
concurrency,
          (Key
"container" Key -> JobContainer -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (JobContainer -> Pair) -> Maybe JobContainer -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe JobContainer
container,
          (Key
"continue-on-error" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Bool -> Pair) -> Maybe Bool -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Bool
continueOnError,
          (Key
"defaults" Key -> Defaults -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Defaults -> Pair) -> Maybe Defaults -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Defaults
defaults,
          (Key
"env" Key -> Map Text Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Map Text Text -> Pair) -> Maybe (Map Text Text) -> Maybe Pair
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
"environment" Key -> JobEnvironment -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (JobEnvironment -> Pair) -> Maybe JobEnvironment -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe JobEnvironment
environment,
          (Key
"if" Key -> RunIf -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (RunIf -> Pair) -> Maybe RunIf -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe RunIf
runIf,
          (Key
"name" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Text -> Pair) -> Maybe Text -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
jobName,
          (Key
"needs" Key -> JobNeeds -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (JobNeeds -> Pair) -> Maybe JobNeeds -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe JobNeeds
needs,
          (Key
"outputs" Key -> Map Text Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Map Text Text -> Pair) -> Maybe (Map Text Text) -> Maybe Pair
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
outputs,
          (Key
"permissions" Key -> Permissions -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Permissions -> Pair) -> Maybe Permissions -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Permissions
permissions,
          (Key
"runs-on" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Text -> Pair) -> Maybe Text -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
runsOn,
          (Key
"secrets" Key -> Map Text Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Map Text Text -> Pair) -> Maybe (Map Text Text) -> Maybe Pair
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
secrets,
          (Key
"services" Key -> Map ServiceId Service -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Map ServiceId Service -> Pair)
-> Maybe (Map ServiceId Service) -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map ServiceId Service -> Maybe (Map ServiceId Service)
forall a. (Eq a, Monoid a) => a -> Maybe a
monoidToMaybe Map ServiceId Service
services,
          (Key
"steps" Key -> NonEmpty Step -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (NonEmpty Step -> Pair) -> Maybe (NonEmpty Step) -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (NonEmpty Step)
steps,
          (Key
"strategy" Key -> JobStrategy -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (JobStrategy -> Pair) -> Maybe JobStrategy -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe JobStrategy
strategy,
          (Key
"timeout-minutes" Key -> Int -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Int -> Pair) -> Maybe Int -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Int
timeoutMinutes,
          (Key
"uses" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Text -> Pair) -> Maybe Text -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
uses,
          (Key
"with" Key -> Map Text Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.=) (Map Text Text -> Pair) -> Maybe (Map Text Text) -> Maybe Pair
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
with
        ]
    where
      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 Job
gen :: forall (m :: * -> *). MonadGen m => m Job
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 JobContainer
container <- m JobContainer -> m (Maybe JobContainer)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m JobContainer
forall (m :: * -> *). MonadGen m => m JobContainer
JobContainer.gen
  Maybe Bool
continueOnError <- m Bool -> m (Maybe Bool)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m Bool
forall (m :: * -> *). MonadGen m => m Bool
Gen.bool
  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
  Maybe JobEnvironment
environment <- m JobEnvironment -> m (Maybe JobEnvironment)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m JobEnvironment
forall (m :: * -> *). MonadGen m => m JobEnvironment
JobEnvironment.gen
  Maybe Text
jobName <- m Text -> m (Maybe Text)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m Text
genText
  Maybe JobNeeds
needs <- m JobNeeds -> m (Maybe JobNeeds)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m JobNeeds
forall (m :: * -> *). MonadGen m => m JobNeeds
JobNeeds.gen
  Map Text Text
outputs <- m (Map Text Text)
genTextMap
  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 RunIf
runIf <- m RunIf -> m (Maybe RunIf)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m RunIf
forall (m :: * -> *). MonadGen m => m RunIf
RunIf.gen
  Maybe Text
runsOn <- m Text -> m (Maybe Text)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m Text
genText
  Map Text Text
secrets <- m (Map Text Text)
genTextMap
  Map ServiceId Service
services <- Range Int -> m (ServiceId, Service) -> m (Map ServiceId Service)
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 (ServiceId, Service) -> m (Map ServiceId Service))
-> m (ServiceId, Service) -> m (Map ServiceId Service)
forall a b. (a -> b) -> a -> b
$ (ServiceId -> Service -> (ServiceId, Service))
-> m ServiceId -> m Service -> m (ServiceId, Service)
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 ServiceId
forall (m :: * -> *). MonadGen m => m ServiceId
ServiceId.gen m Service
forall (m :: * -> *). MonadGen m => m Service
Service.gen
  Maybe (NonEmpty Step)
steps <- m (NonEmpty Step) -> m (Maybe (NonEmpty Step))
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe (Range Int -> m Step -> m (NonEmpty Step)
forall (m :: * -> *) a.
MonadGen m =>
Range Int -> m a -> m (NonEmpty a)
Gen.nonEmpty (Int -> Int -> Range Int
forall a. Integral a => a -> a -> Range a
Range.linear Int
1 Int
20) m Step
forall (m :: * -> *). MonadGen m => m Step
Step.gen)
  Maybe JobStrategy
strategy <- m JobStrategy -> m (Maybe JobStrategy)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m JobStrategy
forall (m :: * -> *). MonadGen m => m JobStrategy
JobStrategy.gen
  Maybe Int
timeoutMinutes <- m Int -> m (Maybe Int)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe (m Int -> m (Maybe Int)) -> m Int -> m (Maybe Int)
forall a b. (a -> b) -> a -> b
$ Range Int -> m Int
forall (m :: * -> *). MonadGen m => Range Int -> m Int
Gen.int (Int -> Int -> Range Int
forall a. Integral a => a -> a -> Range a
Range.linear Int
1 Int
120)
  Maybe Text
uses <- m Text -> m (Maybe Text)
forall (m :: * -> *) a. MonadGen m => m a -> m (Maybe a)
Gen.maybe m Text
genText
  Map Text Text
with <- m (Map Text Text)
genTextMap
  Job -> m Job
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Job {Maybe Bool
Maybe Int
Maybe (NonEmpty Step)
Maybe Text
Maybe Concurrency
Maybe JobContainer
Maybe JobEnvironment
Maybe JobNeeds
Maybe JobStrategy
Maybe Permissions
Maybe RunIf
Maybe Defaults
Map Text Text
Map ServiceId Service
concurrency :: Maybe Concurrency
container :: Maybe JobContainer
continueOnError :: Maybe Bool
defaults :: Maybe Defaults
env :: Map Text Text
environment :: Maybe JobEnvironment
jobName :: Maybe Text
needs :: Maybe JobNeeds
outputs :: Map Text Text
permissions :: Maybe Permissions
runIf :: Maybe RunIf
runsOn :: Maybe Text
secrets :: Map Text Text
services :: Map ServiceId Service
steps :: Maybe (NonEmpty Step)
strategy :: Maybe JobStrategy
timeoutMinutes :: Maybe Int
uses :: Maybe Text
with :: Map Text Text
concurrency :: Maybe Concurrency
container :: Maybe JobContainer
continueOnError :: Maybe Bool
defaults :: Maybe Defaults
env :: Map Text Text
environment :: Maybe JobEnvironment
jobName :: Maybe Text
needs :: Maybe JobNeeds
outputs :: Map Text Text
permissions :: Maybe Permissions
runIf :: Maybe RunIf
runsOn :: Maybe Text
secrets :: Map Text Text
services :: Map ServiceId Service
steps :: Maybe (NonEmpty Step)
strategy :: Maybe JobStrategy
timeoutMinutes :: Maybe Int
uses :: Maybe Text
with :: Map Text Text
..}
  where
    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 'Job' with default values.
--
-- This provides a minimal job that can be extended with specific steps,
-- runner configuration, and other settings.
--
-- Example:
--
-- @
-- buildJob = new
--   { jobName = Just "Build"
--   , runsOn = Just "ubuntu-latest"
--   , steps = Just $ checkoutStep :| [buildStep]
--   }
-- @
new :: Job
new :: Job
new =
  Job
    { concurrency :: Maybe Concurrency
concurrency = Maybe Concurrency
forall a. Maybe a
Nothing,
      container :: Maybe JobContainer
container = Maybe JobContainer
forall a. Maybe a
Nothing,
      continueOnError :: Maybe Bool
continueOnError = Maybe Bool
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,
      environment :: Maybe JobEnvironment
environment = Maybe JobEnvironment
forall a. Maybe a
Nothing,
      jobName :: Maybe Text
jobName = Maybe Text
forall a. Maybe a
Nothing,
      needs :: Maybe JobNeeds
needs = Maybe JobNeeds
forall a. Maybe a
Nothing,
      outputs :: Map Text Text
outputs = Map Text Text
forall a. Monoid a => a
mempty,
      permissions :: Maybe Permissions
permissions = Maybe Permissions
forall a. Maybe a
Nothing,
      runIf :: Maybe RunIf
runIf = Maybe RunIf
forall a. Maybe a
Nothing,
      runsOn :: Maybe Text
runsOn = Maybe Text
forall a. Maybe a
Nothing,
      secrets :: Map Text Text
secrets = Map Text Text
forall a. Monoid a => a
mempty,
      services :: Map ServiceId Service
services = Map ServiceId Service
forall a. Monoid a => a
mempty,
      steps :: Maybe (NonEmpty Step)
steps = Maybe (NonEmpty Step)
forall a. Maybe a
Nothing,
      strategy :: Maybe JobStrategy
strategy = Maybe JobStrategy
forall a. Maybe a
Nothing,
      timeoutMinutes :: Maybe Int
timeoutMinutes = Maybe Int
forall a. Maybe a
Nothing,
      uses :: Maybe Text
uses = Maybe Text
forall a. Maybe a
Nothing,
      with :: Map Text Text
with = Map Text Text
forall a. Monoid a => a
mempty
    }