Prepare to switch GITHUB_ACTION to use ContextName instead of refname (#593)

This PR changes GITHUB_ACTION to use the step ContextName, instead of refname. The behavior is behind a feature flag. Refname is an otherwise deprecated property.

Primary motivation: For composite actions, we need a distinct GITHUB_ACTION for each nested step. This PR adds code to generate a default context name for nested steps.

For nested steps, GITHUB_ACTION will be set to "{ScopeName}.{ContextName}" to ensure no collisions.

A corresponding change will be made on the server so context name is never empty. Generated context names will start with "__".

A follow-up PR is required to avoid tracking "step" context values (outputs/conclusion/result) for generated context names. Waiting on telemetry from the server to confirm it's safe to assume leading "__" is a generate context name.
This commit is contained in:
eric sciple
2020-07-19 17:19:13 -04:00
committed by GitHub
parent f9dca15c63
commit 1cc3c08cf2
20 changed files with 288 additions and 745 deletions

View File

@@ -55,7 +55,7 @@ namespace GitHub.Runner.Worker
public ActionDefinitionData Load(IExecutionContext executionContext, string manifestFile)
{
var templateContext = CreateContext(executionContext);
var templateContext = CreateTemplateContext(executionContext);
ActionDefinitionData actionDefinition = new ActionDefinitionData();
// Clean up file name real quick
@@ -118,7 +118,7 @@ namespace GitHub.Runner.Worker
break;
case "inputs":
ConvertInputs(templateContext, actionPair.Value, actionDefinition);
ConvertInputs(actionPair.Value, actionDefinition);
break;
case "runs":
@@ -177,19 +177,19 @@ namespace GitHub.Runner.Worker
if (token != null)
{
var context = CreateContext(executionContext, extraExpressionValues);
var templateContext = CreateTemplateContext(executionContext, extraExpressionValues);
try
{
token = TemplateEvaluator.Evaluate(context, "outputs", token, 0, null, omitHeader: true);
context.Errors.Check();
token = TemplateEvaluator.Evaluate(templateContext, "outputs", token, 0, null, omitHeader: true);
templateContext.Errors.Check();
result = token.ToContextData().AssertDictionary("composite outputs");
}
catch (Exception ex) when (!(ex is TemplateValidationException))
{
context.Errors.Add(ex);
templateContext.Errors.Add(ex);
}
context.Errors.Check();
templateContext.Errors.Check();
}
return result ?? new DictionaryContextData();
@@ -204,11 +204,11 @@ namespace GitHub.Runner.Worker
if (token != null)
{
var context = CreateContext(executionContext, extraExpressionValues);
var templateContext = CreateTemplateContext(executionContext, extraExpressionValues);
try
{
var evaluateResult = TemplateEvaluator.Evaluate(context, "container-runs-args", token, 0, null, omitHeader: true);
context.Errors.Check();
var evaluateResult = TemplateEvaluator.Evaluate(templateContext, "container-runs-args", token, 0, null, omitHeader: true);
templateContext.Errors.Check();
Trace.Info($"Arguments evaluate result: {StringUtil.ConvertToJson(evaluateResult)}");
@@ -225,10 +225,10 @@ namespace GitHub.Runner.Worker
catch (Exception ex) when (!(ex is TemplateValidationException))
{
Trace.Error(ex);
context.Errors.Add(ex);
templateContext.Errors.Add(ex);
}
context.Errors.Check();
templateContext.Errors.Check();
}
return result;
@@ -243,11 +243,11 @@ namespace GitHub.Runner.Worker
if (token != null)
{
var context = CreateContext(executionContext, extraExpressionValues);
var templateContext = CreateTemplateContext(executionContext, extraExpressionValues);
try
{
var evaluateResult = TemplateEvaluator.Evaluate(context, "container-runs-env", token, 0, null, omitHeader: true);
context.Errors.Check();
var evaluateResult = TemplateEvaluator.Evaluate(templateContext, "container-runs-env", token, 0, null, omitHeader: true);
templateContext.Errors.Check();
Trace.Info($"Environments evaluate result: {StringUtil.ConvertToJson(evaluateResult)}");
@@ -269,10 +269,10 @@ namespace GitHub.Runner.Worker
catch (Exception ex) when (!(ex is TemplateValidationException))
{
Trace.Error(ex);
context.Errors.Add(ex);
templateContext.Errors.Add(ex);
}
context.Errors.Check();
templateContext.Errors.Check();
}
return result;
@@ -286,11 +286,11 @@ namespace GitHub.Runner.Worker
string result = "";
if (token != null)
{
var context = CreateContext(executionContext);
var templateContext = CreateTemplateContext(executionContext);
try
{
var evaluateResult = TemplateEvaluator.Evaluate(context, "input-default-context", token, 0, null, omitHeader: true);
context.Errors.Check();
var evaluateResult = TemplateEvaluator.Evaluate(templateContext, "input-default-context", token, 0, null, omitHeader: true);
templateContext.Errors.Check();
Trace.Info($"Input '{inputName}': default value evaluate result: {StringUtil.ConvertToJson(evaluateResult)}");
@@ -300,16 +300,16 @@ namespace GitHub.Runner.Worker
catch (Exception ex) when (!(ex is TemplateValidationException))
{
Trace.Error(ex);
context.Errors.Add(ex);
templateContext.Errors.Add(ex);
}
context.Errors.Check();
templateContext.Errors.Check();
}
return result;
}
private TemplateContext CreateContext(
private TemplateContext CreateTemplateContext(
IExecutionContext executionContext,
IDictionary<string, PipelineContextData> extraExpressionValues = null)
{
@@ -357,7 +357,7 @@ namespace GitHub.Runner.Worker
private ActionExecutionData ConvertRuns(
IExecutionContext executionContext,
TemplateContext context,
TemplateContext templateContext,
TemplateToken inputsToken,
MappingToken outputs = null)
{
@@ -375,7 +375,7 @@ namespace GitHub.Runner.Worker
var postToken = default(StringToken);
var postEntrypointToken = default(StringToken);
var postIfToken = default(StringToken);
var stepsLoaded = default(List<Pipelines.ActionStep>);
var steps = default(List<Pipelines.Step>);
foreach (var run in runsMapping)
{
@@ -424,9 +424,9 @@ namespace GitHub.Runner.Worker
case "steps":
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TESTING_COMPOSITE_ACTIONS_ALPHA")))
{
var steps = run.Value.AssertSequence("steps");
var evaluator = executionContext.ToPipelineTemplateEvaluator();
stepsLoaded = evaluator.LoadCompositeSteps(steps);
var stepsToken = run.Value.AssertSequence("steps");
steps = PipelineTemplateConverter.ConvertToSteps(templateContext, stepsToken);
templateContext.Errors.Check();
break;
}
throw new Exception("You aren't supposed to be using Composite Actions yet!");
@@ -479,7 +479,7 @@ namespace GitHub.Runner.Worker
}
else if (string.Equals(usingToken.Value, "composite", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TESTING_COMPOSITE_ACTIONS_ALPHA")))
{
if (stepsLoaded == null)
if (steps == null)
{
// TODO: Add a more helpful error message + including file name, etc. to show user that it's because of their yaml file
throw new ArgumentNullException($"No steps provided.");
@@ -488,7 +488,7 @@ namespace GitHub.Runner.Worker
{
return new CompositeActionExecutionData()
{
Steps = stepsLoaded,
Steps = steps.Cast<Pipelines.ActionStep>().ToList(),
Outputs = outputs
};
}
@@ -510,7 +510,6 @@ namespace GitHub.Runner.Worker
}
private void ConvertInputs(
TemplateContext context,
TemplateToken inputsToken,
ActionDefinitionData actionDefinition)
{