Compare commits

...

3 Commits

Author SHA1 Message Date
Ethan Chiu
9bbed7d3c2 Draft framework and model for refactoring composite actions 2020-07-13 10:55:33 -04:00
Ethan Chiu
a4cc13e36f Starting framework 2020-07-10 14:33:12 -04:00
Ethan Chiu
747addfca6 notes on todo tasks for refactoring to support different types of steps 2020-07-10 13:51:36 -04:00
4 changed files with 95 additions and 49 deletions

View File

@@ -325,7 +325,7 @@ namespace GitHub.Runner.Worker
var postToken = default(StringToken);
var postEntrypointToken = default(StringToken);
var postIfToken = default(StringToken);
var stepsLoaded = default(List<Pipelines.ActionStep>);
var stepsLoaded = default(List<Pipelines.Step>);
foreach (var run in runsMapping)
{
@@ -376,6 +376,7 @@ namespace GitHub.Runner.Worker
{
var steps = run.Value.AssertSequence("steps");
var evaluator = executionContext.ToPipelineTemplateEvaluator();
// TODO: Change this so that we process each type of step
stepsLoaded = evaluator.LoadCompositeSteps(steps);
break;
}

View File

@@ -35,9 +35,6 @@ namespace GitHub.Runner.Worker.Handlers
var tempDirectory = HostContext.GetDirectory(WellKnownDirectory.Temp);
// Resolve action steps
var actionSteps = Data.Steps;
// Create Context Data to reuse for each composite action step
var inputsData = new DictionaryContextData();
foreach (var i in Inputs)
@@ -47,48 +44,96 @@ namespace GitHub.Runner.Worker.Handlers
// Add each composite action step to the front of the queue
int location = 0;
foreach (Pipelines.ActionStep aStep in actionSteps)
// Resolve action steps
var compositeSteps = Data.Steps;
// TODO: Assume that each step is not an actionStep
// How do we handle all types of steps?????
// While loop till we have reached the last layer?
List<Pipelines.Step> stepsToAppend = new List<Pipelines.Step>();
// First put each step in stepsToAppend
foreach (var step in compositeSteps)
{
// Ex:
// runs:
// using: "composite"
// steps:
// - uses: example/test-composite@v2 (a)
// - run echo hello world (b)
// - run echo hello world 2 (c)
//
// ethanchewy/test-composite/action.yaml
// runs:
// using: "composite"
// steps:
// - run echo hello world 3 (d)
// - run echo hello world 4 (e)
//
// Steps processed as follow:
// | a |
// | a | => | d |
// (Run step d)
// | a |
// | a | => | e |
// (Run step e)
// | a |
// (Run step a)
// | b |
// (Run step b)
// | c |
// (Run step c)
// Done.
var actionRunner = HostContext.CreateService<IActionRunner>();
actionRunner.Action = aStep;
actionRunner.Stage = stage;
actionRunner.Condition = aStep.Condition;
actionRunner.DisplayName = aStep.DisplayName;
ExecutionContext.RegisterNestedStep(actionRunner, inputsData, location, Environment);
location++;
stepsToAppend.Append(step);
}
// We go through each step and push to the top of the stack its children.
// That way, we go through each steps, steps of steps in order
// This is an ITERATIVE approach. While a recursive approach may be more elegant,
// that would use a lot more memory in the call stack.
// Ex:
// Let's say we have 4 composite steps with the first step that has 3 children
// A (composite step)=> a1, a2, a3
// B (non composite)
// C (non composite)
// D (non composite)
// It would be executed in this order => a1, a2, a3, A (steps within A), B, C, D
while (stepsToAppend != null)
{
var currentStep = stepsToAppend[0];
// TODO: Create another StepsContext?
// In the original StepsRunner, we could lock the thread and only proceed after we finish processing these steps
// Then, we invoke the CompositeStepsRunner class?
// TODO: We have to create another Execution Context for Composite Actions
// See below
// TODO: Append to StepsRunner
// by invoking a RegisterNestedStep on the Composite Action Exeuction Context for Composite Action Steps
}
// foreach (Pipelines.Step aStep in actionSteps)
// {
// // Ex:
// // runs:
// // using: "composite"
// // steps:
// // - uses: example/test-composite@v2 (a)
// // - run echo hello world (b)
// // - run echo hello world 2 (c)
// //
// // ethanchewy/test-composite/action.yaml
// // runs:
// // using: "composite"
// // steps:
// // - run echo hello world 3 (d)
// // - run echo hello world 4 (e)
// //
// // Steps processed as follow:
// // | a |
// // | a | => | d |
// // (Run step d)
// // | a |
// // | a | => | e |
// // (Run step e)
// // | a |
// // (Run step a)
// // | b |
// // (Run step b)
// // | c |
// // (Run step c)
// // Done.
// // TODO: how are we going to order each step?
// // How is this going to look in the UI (will we have a bunch of nesting)
// // ^ We need to focus on how we are going to get the steps to run in the right order.
// var actionRunner = HostContext.CreateService<IActionRunner>();
// actionRunner.Action = aStep;
// actionRunner.Stage = stage;
// actionRunner.Condition = aStep.Condition;
// actionRunner.DisplayName = aStep.DisplayName;
// ExecutionContext.RegisterNestedStep(actionRunner, inputsData, location, Environment);
// location++;
// }
return Task.CompletedTask;
}

View File

@@ -264,14 +264,13 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
return result;
}
//Note: originally was List<Step> but we need to change to List<ActionStep> to use the "Inputs" attribute
internal static List<ActionStep> ConvertToSteps(
internal static List<Step> ConvertToSteps(
TemplateContext context,
TemplateToken steps)
{
var stepsSequence = steps.AssertSequence($"job {PipelineTemplateConstants.Steps}");
var result = new List<ActionStep>();
var result = new List<Step>();
foreach (var stepsItem in stepsSequence)
{
var step = ConvertToStep(context, stepsItem);
@@ -287,7 +286,7 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
return result;
}
private static ActionStep ConvertToStep(
private static Step ConvertToStep(
TemplateContext context,
TemplateToken stepsItem)
{

View File

@@ -159,10 +159,11 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
return result;
}
public List<ActionStep> LoadCompositeSteps(
// TODO: Change to return a variety of steps.
public List<Step> LoadCompositeSteps(
TemplateToken token)
{
var result = default(List<ActionStep>);
var result = default(List<Step>);
if (token != null && token.Type != TokenType.Null)
{
var context = CreateContext(null, null, setMissingContext: false);