Env Flow => Able to get env variables and overwrite current env variables => but it doesn't 'stick'

This commit is contained in:
Ethan Chiu
2020-06-18 15:34:48 -04:00
parent 038e5e2c2e
commit e56b2439b9
7 changed files with 111 additions and 3 deletions

View File

@@ -1283,6 +1283,7 @@ namespace GitHub.Runner.Worker
public override bool HasPre => false; public override bool HasPre => false;
public override bool HasPost => false; public override bool HasPost => false;
public List<Pipelines.ActionStep> Steps { get; set; } public List<Pipelines.ActionStep> Steps { get; set; }
public MappingToken Environment { get; set; }
} }
public abstract class ActionExecutionData public abstract class ActionExecutionData

View File

@@ -27,6 +27,7 @@ namespace GitHub.Runner.Worker
Dictionary<string, string> EvaluateContainerEnvironment(IExecutionContext executionContext, MappingToken token, IDictionary<string, PipelineContextData> extraExpressionValues); Dictionary<string, string> EvaluateContainerEnvironment(IExecutionContext executionContext, MappingToken token, IDictionary<string, PipelineContextData> extraExpressionValues);
public Dictionary<string, string> EvaluateCompositeActionEnvironment(IExecutionContext executionContext, MappingToken token, IDictionary<string, PipelineContextData> extraExpressionValues);
string EvaluateDefaultInput(IExecutionContext executionContext, string inputName, TemplateToken token); string EvaluateDefaultInput(IExecutionContext executionContext, string inputName, TemplateToken token);
} }
@@ -214,6 +215,65 @@ namespace GitHub.Runner.Worker
return result; return result;
} }
// TODO: Add Evaluate Composite Action Env Function Here
// Steps will be evaluated already in StepsRunner
public Dictionary<string, string> EvaluateCompositeActionEnvironment(
IExecutionContext executionContext,
MappingToken token,
IDictionary<string, PipelineContextData> extraExpressionValues)
{
var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
if (token != null)
{
var context = CreateContext(executionContext, extraExpressionValues);
try
{
var evaluateResult = TemplateEvaluator.Evaluate(context, "container-runs-env", token, 0, null, omitHeader: true);
context.Errors.Check();
if (evaluateResult != null) {
Trace.Info($"EvaluateCompositeActionEnvironment evaluateResult {evaluateResult}");
} else {
Trace.Info($"EvaluateCompositeActionEnvironment evaluateResult is null");
}
Trace.Info($"Composite Action Environments evaluate result: {StringUtil.ConvertToJson(evaluateResult)}");
// Mapping
var mapping = evaluateResult.AssertMapping("composite env");
if (mapping != null) {
Trace.Info($"EvaluateCompositeActionEnvironment Mapping {mapping}");
} else {
Trace.Info($"EvaluateCompositeActionEnvironment Mapping is null");
}
foreach (var pair in mapping)
{
// Literal key
var key = pair.Key.AssertString("composite env key");
Trace.Info($"EvaluateCompositeActionEnvironment Key{key.Value}");
// Literal value
var value = pair.Value.AssertString("composite env value");
Trace.Info($"EvaluateCompositeActionEnvironment Value{value.Value}");
result[key.Value] = value.Value;
Trace.Info($"Add env {key} = {value}");
}
}
catch (Exception ex) when (!(ex is TemplateValidationException))
{
Trace.Error(ex);
context.Errors.Add(ex);
}
context.Errors.Check();
}
return result;
}
public string EvaluateDefaultInput( public string EvaluateDefaultInput(
IExecutionContext executionContext, IExecutionContext executionContext,
string inputName, string inputName,
@@ -426,6 +486,7 @@ namespace GitHub.Runner.Worker
return new CompositeActionExecutionData() return new CompositeActionExecutionData()
{ {
Steps = stepsLoaded, Steps = stepsLoaded,
Environment = envToken
}; };
} }
} }

View File

@@ -105,8 +105,9 @@ namespace GitHub.Runner.Worker
// others // others
void ForceTaskComplete(); void ForceTaskComplete();
void RegisterPostJobStep(IStep step); void RegisterPostJobStep(IStep step);
IStep RegisterCompositeStep(IStep step, DictionaryContextData inputsData); IStep RegisterCompositeStep(IStep step, DictionaryContextData inputsData, PipelineContextData envData);
void EnqueueAllCompositeSteps(Queue<IStep> steps); void EnqueueAllCompositeSteps(Queue<IStep> steps);
ExecutionContext getParentExecutionContext();
} }
public sealed class ExecutionContext : RunnerService, IExecutionContext public sealed class ExecutionContext : RunnerService, IExecutionContext
@@ -271,7 +272,7 @@ namespace GitHub.Runner.Worker
RegisterCompositeStep is a helper function used in CompositeActionHandler::RunAsync to RegisterCompositeStep is a helper function used in CompositeActionHandler::RunAsync to
add a child node, aka a step, to the current job to the front of the queue for processing. add a child node, aka a step, to the current job to the front of the queue for processing.
*/ */
public IStep RegisterCompositeStep(IStep step, DictionaryContextData inputsData) public IStep RegisterCompositeStep(IStep step, DictionaryContextData inputsData, PipelineContextData envData)
{ {
// ~Brute Force Method~ // ~Brute Force Method~
// There is no way to put this current job in front of the queue in < O(n) time where n = # of elements in JobSteps // There is no way to put this current job in front of the queue in < O(n) time where n = # of elements in JobSteps
@@ -296,6 +297,10 @@ namespace GitHub.Runner.Worker
var newGuid = Guid.NewGuid(); var newGuid = Guid.NewGuid();
step.ExecutionContext = Root.CreateChild(newGuid, step.DisplayName, newGuid.ToString("N"), null, null); step.ExecutionContext = Root.CreateChild(newGuid, step.DisplayName, newGuid.ToString("N"), null, null);
step.ExecutionContext.ExpressionValues["inputs"] = inputsData; step.ExecutionContext.ExpressionValues["inputs"] = inputsData;
step.ExecutionContext.ExpressionValues["env"] = envData;
// TODO add environment variables for individual composite action steps
return step; return step;
} }
@@ -329,6 +334,11 @@ namespace GitHub.Runner.Worker
} }
} }
public ExecutionContext getParentExecutionContext()
{
return _parentExecutionContext;
}
public IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, Dictionary<string, string> intraActionState = null, int? recordOrder = null) public IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, Dictionary<string, string> intraActionState = null, int? recordOrder = null)
{ {
Trace.Entering(); Trace.Entering();

View File

@@ -52,6 +52,32 @@ namespace GitHub.Runner.Worker.Handlers
inputsData[i.Key] = new StringContextData(i.Value); inputsData[i.Key] = new StringContextData(i.Value);
} }
// Set up parent's environment data and then add on composite action environment data
#if OS_WINDOWS
var envData = ExecutionContext.ExpressionValues["env"].Clone() as DictionaryContextData;
#else
var envData = ExecutionContext.ExpressionValues["env"].Clone() as CaseSensitiveDictionaryContextData;
#endif
// Composite action will have already inherited the root env attributes.
// We evaluated the env simimilar to how ContainerActionHandler does it.
if (Data.Environment == null) {
Trace.Info($"Composite Env Mapping Token is null");
} else {
Trace.Info($"Composite Env Mapping Token {Data.Environment}");
}
var extraExpressionValues = new Dictionary<string, PipelineContextData>(StringComparer.OrdinalIgnoreCase);
extraExpressionValues["inputs"] = inputsData;
var manifestManager = HostContext.GetService<IActionManifestManager>();
var evaluatedEnv = manifestManager.EvaluateCompositeActionEnvironment(ExecutionContext, Data.Environment, extraExpressionValues);
foreach (var e in evaluatedEnv)
{
// How to add to EnvironmentContextData
// We need to use IEnvironmentContextData because ScriptHandler uses this type for environment variables
Trace.Info($"Composite Action Env Key: {e.Key}");
Trace.Info($"Composite Action Env Value: {e.Value}");
envData[e.Key] = new StringContextData(e.Value);
}
// Add each composite action step to the front of the queue // Add each composite action step to the front of the queue
var compositeActionSteps = new Queue<IStep>(); var compositeActionSteps = new Queue<IStep>();
foreach (Pipelines.ActionStep aStep in actionSteps) foreach (Pipelines.ActionStep aStep in actionSteps)
@@ -94,7 +120,7 @@ namespace GitHub.Runner.Worker.Handlers
// TODO: Do we need to add any context data from the job message? // TODO: Do we need to add any context data from the job message?
// (See JobExtension.cs ~line 236) // (See JobExtension.cs ~line 236)
compositeActionSteps.Enqueue(ExecutionContext.RegisterCompositeStep(actionRunner, inputsData)); compositeActionSteps.Enqueue(ExecutionContext.RegisterCompositeStep(actionRunner, inputsData, envData));
} }
ExecutionContext.EnqueueAllCompositeSteps(compositeActionSteps); ExecutionContext.EnqueueAllCompositeSteps(compositeActionSteps);

View File

@@ -255,6 +255,14 @@ namespace GitHub.Runner.Worker.Handlers
Environment[env.Key] = env.Value; Environment[env.Key] = env.Value;
} }
} }
// if (context.Key == "env" && context.Value != null && !String.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("TESTING_COMPOSITE_ACTIONS_ALPHA")))
// {
// foreach (var env in context.Value as DictionaryContextData)
// {
// Environment[env.Key] = env.Value as StringContextData;
// }
// }
} }
// dump out the command // dump out the command

View File

@@ -90,6 +90,7 @@ namespace GitHub.Runner.Worker
// Initialize scope // Initialize scope
if (InitializeScope(step, scopeInputs)) if (InitializeScope(step, scopeInputs))
{ {
// TODO Check if this adds env context to each composite action step
// Populate env context for each step // Populate env context for each step
Trace.Info("Initialize Env context for step"); Trace.Info("Initialize Env context for step");
#if OS_WINDOWS #if OS_WINDOWS

View File

@@ -88,6 +88,7 @@
"mapping": { "mapping": {
"properties": { "properties": {
"using": "non-empty-string", "using": "non-empty-string",
"env": "container-runs-env",
"steps": "composite-steps" "steps": "composite-steps"
} }
} }