github-actions 0.2.0.0 → 0.3.0.0
raw patch · 6 files changed
+100/−11 lines, 6 filesdep ~aesonPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: aeson
API changes (from Hackage documentation)
+ Language.Github.Actions.Job.RunsOn: RunsOnArray :: NonEmpty Text -> RunsOn
+ Language.Github.Actions.Job.RunsOn: RunsOnString :: Text -> RunsOn
+ Language.Github.Actions.Job.RunsOn: data RunsOn
+ Language.Github.Actions.Job.RunsOn: gen :: MonadGen m => m RunsOn
+ Language.Github.Actions.Job.RunsOn: instance Data.Aeson.Types.FromJSON.FromJSON Language.Github.Actions.Job.RunsOn.RunsOn
+ Language.Github.Actions.Job.RunsOn: instance Data.Aeson.Types.ToJSON.ToJSON Language.Github.Actions.Job.RunsOn.RunsOn
+ Language.Github.Actions.Job.RunsOn: instance GHC.Classes.Eq Language.Github.Actions.Job.RunsOn.RunsOn
+ Language.Github.Actions.Job.RunsOn: instance GHC.Classes.Ord Language.Github.Actions.Job.RunsOn.RunsOn
+ Language.Github.Actions.Job.RunsOn: instance GHC.Generics.Generic Language.Github.Actions.Job.RunsOn.RunsOn
+ Language.Github.Actions.Job.RunsOn: instance GHC.Show.Show Language.Github.Actions.Job.RunsOn.RunsOn
- Language.Github.Actions.Job: Job :: Maybe Concurrency -> Maybe JobContainer -> Maybe Bool -> Maybe Defaults -> Map Text Text -> Maybe JobEnvironment -> Maybe Text -> Maybe JobNeeds -> Map Text Text -> Maybe Permissions -> Maybe RunIf -> Maybe Text -> Map Text Text -> Map ServiceId Service -> Maybe (NonEmpty Step) -> Maybe JobStrategy -> Maybe Int -> Maybe Text -> Map Text Text -> Job
+ Language.Github.Actions.Job: Job :: Maybe Concurrency -> Maybe JobContainer -> Maybe Bool -> Maybe Defaults -> Map Text Text -> Maybe JobEnvironment -> Maybe Text -> Maybe JobNeeds -> Map Text Text -> Maybe Permissions -> Maybe RunIf -> Maybe RunsOn -> Map Text Text -> Map ServiceId Service -> Maybe (NonEmpty Step) -> Maybe JobStrategy -> Maybe Int -> Maybe Text -> Map Text Text -> Job
- Language.Github.Actions.Job: [runsOn] :: Job -> Maybe Text
+ Language.Github.Actions.Job: [runsOn] :: Job -> Maybe RunsOn
Files
- CHANGELOG.md +6/−0
- README.md +2/−1
- github-actions.cabal +4/−3
- src/Language/Github/Actions/Job.hs +7/−5
- src/Language/Github/Actions/Job/RunsOn.hs +79/−0
- test/golden/configuration-main.hs.txt +2/−2
CHANGELOG.md view
@@ -1,5 +1,11 @@ # CHANGELOG +## Version 0.3.0.0++- Changed `runsOn` from `Maybe Text` to `Maybe RunsOn` to support GitHub Actions+ runner label lists (e.g. `runs-on: [self-hosted, linux]`), while preserving+ the original YAML representation during round-trip serialization+ ## Version 0.2.0 (2025-07-21) - Changed `cancelInProgress` from `Maybe Bool` to `Maybe Text` to support GitHub Actions expressions
README.md view
@@ -24,6 +24,7 @@ import Language.Github.Actions.Workflow import qualified Language.Github.Actions.Job as Job import qualified Language.Github.Actions.Job.Id as JobId+import qualified Language.Github.Actions.Job.RunsOn as RunsOn import qualified Language.Github.Actions.Step as Step import qualified Language.Github.Actions.Workflow.Trigger as Trigger @@ -38,7 +39,7 @@ buildJob :: Job.Job buildJob = Job.new { Job.jobName = Just "Build and Test"- , Job.runsOn = Just "ubuntu-latest"+ , Job.runsOn = Just (RunsOn.RunsOnString "ubuntu-latest") , Job.steps = Just $ checkoutStep :| [buildStep, testStep] }
github-actions.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: github-actions-version: 0.2.0.0+version: 0.3.0.0 synopsis: Github Actions description: This library provides types and instances for serializing and deserializing@@ -24,7 +24,7 @@ test/golden/configuration-main.hs.txt test/golden/configuration-main.yml -tested-with: GHC ==9.6.7 || ==9.8.4 || ==9.10.3 || ==9.12.4+tested-with: GHC ==9.6.7 || ==9.8.4 || ==9.10.3 || ==9.12.4 || ==9.14.1 common opts default-language: Haskell2010@@ -37,7 +37,7 @@ common deps build-depends:- , aeson ^>=2.2.3.0+ , aeson ^>=2.3.0.0 , base >=4.14 && <4.23 , containers ^>=0.6.7 || ^>=0.7 || ^>=0.8 , hedgehog ^>=1.5 || ^>=1.6 || ^>=1.7@@ -60,6 +60,7 @@ Language.Github.Actions.Job.Environment Language.Github.Actions.Job.Id Language.Github.Actions.Job.Needs+ Language.Github.Actions.Job.RunsOn Language.Github.Actions.Job.Strategy Language.Github.Actions.Permissions Language.Github.Actions.RunIf
src/Language/Github/Actions/Job.hs view
@@ -45,6 +45,8 @@ 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.RunsOn (RunsOn)+import qualified Language.Github.Actions.Job.RunsOn as RunsOn import Language.Github.Actions.Job.Strategy (JobStrategy) import qualified Language.Github.Actions.Job.Strategy as JobStrategy import Language.Github.Actions.Permissions (Permissions)@@ -73,7 +75,7 @@ -- myJob :: Job -- myJob = new -- { jobName = Just "Build and Test"--- , runsOn = Just "ubuntu-latest"+-- , runsOn = Just (RunsOn.RunsOnString "ubuntu-latest") -- , steps = Just $ Step.new :| [] -- } -- @@@ -102,8 +104,8 @@ permissions :: Maybe Permissions, -- | Condition for running this job runIf :: Maybe RunIf,- -- | Runner type (e.g., "ubuntu-latest")- runsOn :: Maybe Text,+ -- | Runner type (e.g., "ubuntu-latest") or a list of runner labels+ runsOn :: Maybe RunsOn, -- | Secrets available to this job secrets :: Map Text Text, -- | Services to run alongside this job@@ -185,7 +187,7 @@ outputs <- genTextMap permissions <- Gen.maybe Permissions.gen runIf <- Gen.maybe RunIf.gen- runsOn <- Gen.maybe genText+ runsOn <- Gen.maybe RunsOn.gen secrets <- genTextMap services <- Gen.map (Range.linear 1 5) $ liftA2 (,) ServiceId.gen Service.gen steps <- Gen.maybe (Gen.nonEmpty (Range.linear 1 20) Step.gen)@@ -208,7 +210,7 @@ -- @ -- buildJob = new -- { jobName = Just "Build"--- , runsOn = Just "ubuntu-latest"+-- , runsOn = Just (RunsOn.RunsOnString "ubuntu-latest") -- , steps = Just $ checkoutStep :| [buildStep] -- } -- @
+ src/Language/Github/Actions/Job/RunsOn.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingStrategies #-}++-- |+-- Module : Language.Github.Actions.Job.RunsOn+-- Description : Runner specification for GitHub Actions jobs+-- Copyright : (c) 2025 Bellroy Pty Ltd+-- License : BSD-3-Clause+-- Maintainer : Bellroy Tech Team <haskell@bellroy.com>+--+-- This module provides the 'RunsOn' type for representing the runner+-- configuration of a GitHub Actions job. GitHub Actions allows both strings+-- and lists of strings for the 'runs-on' field.+--+-- Examples of valid 'runs-on' specifications:+-- * @runs-on: ubuntu-latest@ - A single runner specified as a string+-- * @runs-on: [self-hosted, linux]@ - A runner specified as a list of labels+-- * @runs-on: [self-hosted, linux, x64]@ - A runner specified as a list of labels+--+-- For more information about GitHub Actions runner selection, see:+-- <https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on>+module Language.Github.Actions.Job.RunsOn+ ( RunsOn (..),+ gen,+ )+where++import Data.Aeson (FromJSON, ToJSON (..), Value (..))+import qualified Data.Aeson as Aeson+import Data.List.NonEmpty (NonEmpty)+import Data.Text (Text)+import GHC.Generics (Generic)+import Hedgehog (MonadGen)+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range++-- | Runner specification that preserves YAML representation.+--+-- GitHub Actions supports flexible runner specification:+--+-- * 'RunsOnString' - A single runner label as a string like @runs-on: ubuntu-latest@+-- * 'RunsOnArray' - A list of runner labels like @runs-on: [self-hosted, linux]@+--+-- Examples:+--+-- @+-- -- Single runner label (string form)+-- stringRunner :: RunsOn+-- stringRunner = RunsOnString "ubuntu-latest"+--+-- -- Multiple runner labels (array form)+-- arrayRunner :: RunsOn+-- arrayRunner = RunsOnArray ("self-hosted" :| ["linux", "x64"])+-- @+--+-- The type preserves the original YAML format during round-trip serialization.+-- A string input will serialize back to a string, and an array input will+-- serialize back to an array, preventing information loss.+data RunsOn+ = RunsOnString Text+ | RunsOnArray (NonEmpty Text)+ deriving stock (Eq, Generic, Ord, Show)++instance FromJSON RunsOn where+ parseJSON v@(Array _) = RunsOnArray <$> Aeson.parseJSON v+ parseJSON v = RunsOnString <$> Aeson.parseJSON v++instance ToJSON RunsOn where+ toJSON (RunsOnString label) = toJSON label+ toJSON (RunsOnArray labels) = toJSON labels++gen :: (MonadGen m) => m RunsOn+gen =+ Gen.choice+ [ RunsOnString <$> genText,+ RunsOnArray <$> Gen.nonEmpty (Range.linear 1 5) genText+ ]+ where+ genText = Gen.text (Range.linear 1 5) Gen.alphaNum
test/golden/configuration-main.hs.txt view
@@ -22,7 +22,7 @@ , outputs = fromList [] , permissions = Nothing , runIf = Nothing- , runsOn = Just "ubuntu-20.04"+ , runsOn = Just (RunsOnString "ubuntu-20.04") , secrets = fromList [] , services = fromList [] , steps =@@ -871,7 +871,7 @@ , outputs = fromList [] , permissions = Nothing , runIf = Nothing- , runsOn = Just "ubuntu-20.04"+ , runsOn = Just (RunsOnString "ubuntu-20.04") , secrets = fromList [] , services = fromList [] , steps =