wip
This commit is contained in:
@@ -30,15 +30,15 @@ type PipelineModifier<'Agent> =
|
||||
agent + envVars + workingDir
|
||||
|
||||
|
||||
type AgentIsSet =
|
||||
type NewAgent =
|
||||
private
|
||||
| AgentIsSet of image : string Comp
|
||||
| NewAgent of image : string Comp
|
||||
override this.ToString () =
|
||||
match this with
|
||||
| AgentIsSet comp -> "Image: " + Comp.force comp
|
||||
| NewAgent comp -> "Image: " + Comp.force comp
|
||||
|
||||
type AgentUnset =
|
||||
private | AgentUnset
|
||||
type SameAgent =
|
||||
private | SameAgent
|
||||
override this.ToString () =
|
||||
"<no image specified>"
|
||||
|
||||
@@ -47,7 +47,8 @@ type Pipeline<'Agent> =
|
||||
| ShellScript of script : string * andThen : Pipeline<'Agent>
|
||||
| ShellScriptBind of script : string * consumeStdout : (Stdout -> Pipeline<'Agent>)
|
||||
| WithModifier of Pipeline<'Agent> * PipelineModifier<'Agent>
|
||||
| Sequence of first : Pipeline<AgentUnset> * second : Pipeline<'Agent>
|
||||
| Sequence of first : Pipeline<SameAgent> * second : Pipeline<'Agent>
|
||||
| ChangeAgent of first : Pipeline<NewAgent> * second : Pipeline<NewAgent>
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module Pipeline =
|
||||
@@ -67,11 +68,11 @@ module Pipeline =
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module private PipelineModifier =
|
||||
let empty : PipelineModifier<AgentUnset> =
|
||||
let empty : PipelineModifier<SameAgent> =
|
||||
{
|
||||
EnvVars = []
|
||||
WorkingDir = None
|
||||
Agent = AgentUnset
|
||||
Agent = SameAgent
|
||||
}
|
||||
|
||||
[<Sealed ; Class>]
|
||||
@@ -88,7 +89,7 @@ type PipelineBuilder<'plat, 'agentFinal> () =
|
||||
[<CustomOperation "withEnv">]
|
||||
member _.WithEnv
|
||||
(() : unit, (key : string, value : string Comp))
|
||||
: PipelineModifier<AgentUnset>
|
||||
: PipelineModifier<SameAgent>
|
||||
=
|
||||
{ PipelineModifier.empty with
|
||||
EnvVars = [key, value]
|
||||
@@ -106,7 +107,7 @@ type PipelineBuilder<'plat, 'agentFinal> () =
|
||||
[<CustomOperation "workingDir">]
|
||||
member _.WorkingDir
|
||||
(() : unit, dir : DirectoryInfo Comp)
|
||||
: PipelineModifier<AgentUnset>
|
||||
: PipelineModifier<SameAgent>
|
||||
=
|
||||
{ PipelineModifier.empty with
|
||||
WorkingDir = Some dir
|
||||
@@ -115,26 +116,26 @@ type PipelineBuilder<'plat, 'agentFinal> () =
|
||||
[<CustomOperation "remote">]
|
||||
member _.Remote
|
||||
(() : unit, image : string Comp)
|
||||
: PipelineModifier<AgentIsSet>
|
||||
: PipelineModifier<NewAgent>
|
||||
=
|
||||
{
|
||||
EnvVars = []
|
||||
WorkingDir = None
|
||||
Agent = AgentIsSet image
|
||||
Agent = NewAgent image
|
||||
}
|
||||
|
||||
[<CustomOperation "remote">]
|
||||
member _.Remote
|
||||
(mods : PipelineModifier<AgentUnset>, image : string Comp)
|
||||
: PipelineModifier<AgentIsSet>
|
||||
(mods : PipelineModifier<SameAgent>, image : string Comp)
|
||||
: PipelineModifier<NewAgent>
|
||||
=
|
||||
{
|
||||
EnvVars = mods.EnvVars
|
||||
WorkingDir = mods.WorkingDir
|
||||
Agent = AgentIsSet image
|
||||
Agent = NewAgent image
|
||||
}
|
||||
|
||||
member _.Return (() : unit) = Pipeline.Empty
|
||||
member _.Return<'Agent> (() : unit) = Pipeline<'Agent>.Empty
|
||||
|
||||
/// For running a script, capturing stdout
|
||||
member _.Bind (toRun : string, cont : Stdout -> Pipeline<'Agent>) : Pipeline<'Agent> =
|
||||
@@ -142,34 +143,40 @@ type PipelineBuilder<'plat, 'agentFinal> () =
|
||||
/// For running a script, without capturing stdout
|
||||
member _.Bind (toRun : string, cont : unit -> Pipeline<'Agent>) : Pipeline<'Agent> =
|
||||
Pipeline.ShellScript (toRun, cont ())
|
||||
/// We can bind any pipeline which doesn't say where it's going to run; the interpretation is that it'll
|
||||
/// run wherever the parent runs.
|
||||
member _.Bind (p : Pipeline<AgentUnset>, cont : unit -> Pipeline<'Agent>) : Pipeline<'Agent> =
|
||||
/// We can bind any pipeline which runs on the "same agent".
|
||||
member _.Bind (p : Pipeline<SameAgent>, cont : unit -> Pipeline<'Agent>) : Pipeline<'Agent> =
|
||||
Pipeline.Sequence (p, cont ())
|
||||
// TODO: we could allow binding in running on the same agent as the parent, interpreting that as "run on the parent",
|
||||
// or binding in running on a different agent from the parent, interpreting that as "run in a new agent".
|
||||
// Seems a bit magic.
|
||||
/// We can also bind in any pipeline to run on a different agent.
|
||||
member _.Bind (p : Pipeline<NewAgent>, cont : unit -> Pipeline<NewAgent>) : Pipeline<'Agent> =
|
||||
Pipeline.ChangeAgent (p, cont ())
|
||||
member _.Yield (() : unit) : unit = ()
|
||||
member _.For (expr : PipelineModifier<'Agent>, cont : unit -> Pipeline<'Agent>) : Pipeline<'Agent> =
|
||||
Pipeline.WithModifier (cont (), expr)
|
||||
|
||||
[<AutoOpen>]
|
||||
module PipelineBuilder =
|
||||
let pipeline<'plat, 'agent> = PipelineBuilder<'plat, 'agent> ()
|
||||
let pipeline<'agent> = PipelineBuilder<unit, 'agent> ()
|
||||
let toStepDag<'Agent> (p : Pipeline<'Agent>) : SealedStepDag<unit, unit> = failwith $"TODO\n%s{Pipeline.toString p}"
|
||||
|
||||
let foo () : SealedStepDag<unit, unit> =
|
||||
pipeline {
|
||||
remote (Comp.make "some-image")
|
||||
withEnv ("hi", Comp.make "bye")
|
||||
workingDir (Comp.make (DirectoryInfo "code root here"))
|
||||
withEnv ("foo", Comp.make "bar")
|
||||
withEnv ("hi", Comp.make "bye")
|
||||
let! (Stdout stdout) = "sh script here"
|
||||
do! pipeline {
|
||||
// type annotation is not necessary here but makes the location explicit
|
||||
do! pipeline<SameAgent> {
|
||||
withEnv ("foo", stdout)
|
||||
do! "git config --foo"
|
||||
return ()
|
||||
}
|
||||
// again, type annotation is not necessary here but makes it explicit that this is running somewhere
|
||||
// else
|
||||
do! pipeline {
|
||||
// remote (Comp.make "another-image")
|
||||
return ()
|
||||
}
|
||||
do! "a shell script"
|
||||
return ()
|
||||
}
|
||||
|
Reference in New Issue
Block a user