Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(In Progress) Composing Actions Within Actions Proof of Concept #612

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
645ba09
Explicitly define what is allowed for an action
ethanchewy Jul 20, 2020
220793d
Add step-env
ethanchewy Jul 20, 2020
89412f3
Remove secrets + defaults
ethanchewy Jul 21, 2020
6602117
new line
ethanchewy Jul 21, 2020
aeae15d
Add safety check to prevent from checking defaults in ScriptHandler f…
ethanchewy Jul 21, 2020
a22fcbc
Revert "Add safety check to prevent from checking defaults in ScriptH…
ethanchewy Jul 21, 2020
3381b95
Need to explictly use ActionStep type since we need the .Inputs attri…
ethanchewy Jul 21, 2020
2bfa135
Fix ActionManifestManager
ethanchewy Jul 21, 2020
522fbd0
Remove todos
ethanchewy Jul 21, 2020
143266b
Revert "Revert "Add safety check to prevent from checking defaults in…
ethanchewy Jul 21, 2020
5dfb2cc
revert
ethanchewy Jul 21, 2020
a24e33b
Remove needs in env
ethanchewy Jul 22, 2020
e9dcc05
Merge branch 'users/ethanchewy/compositeRestrictUnknownBehavior' of h…
ethanchewy Jul 23, 2020
cc8e273
Add 'uses' and 'with' to action yaml and change names to be consisten…
ethanchewy Jul 23, 2020
80540ed
Fix templating errors
ethanchewy Jul 23, 2020
6a46ef1
Make shell required + add inputs
ethanchewy Jul 27, 2020
49893b6
Merge branch 'main' of https://github.com/actions/runner into users/e…
ethanchewy Jul 27, 2020
e0d4270
Remove passing context to all composite steps attribuyte
ethanchewy Jul 27, 2020
1ce75f1
Merge branch 'main' of https://github.com/actions/runner into composi…
ethanchewy Jul 27, 2020
e927bac
revert
ethanchewy Jul 27, 2020
992ce4b
add new changes
ethanchewy Jul 27, 2020
3d36af4
Experimentation with evaluating inputs in the context
ethanchewy Jul 27, 2020
4c02d0a
new function for inputs within a composite action
ethanchewy Jul 28, 2020
7ab3d5a
progress...
ethanchewy Jul 28, 2020
45345dc
testing...
ethanchewy Jul 31, 2020
46245a1
Resolve Template Error by Adding ExpressionFunctions
ethanchewy Aug 3, 2020
abfc04c
Download action repos into directory
ethanchewy Aug 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
82 changes: 82 additions & 0 deletions src/Runner.Worker/ActionManifestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public interface IActionManifestManager : IRunnerService
Dictionary<string, string> EvaluateContainerEnvironment(IExecutionContext executionContext, MappingToken token, IDictionary<string, PipelineContextData> extraExpressionValues);

string EvaluateDefaultInput(IExecutionContext executionContext, string inputName, TemplateToken token);

// string EvaluateDefaultInputInsideComposite(IExecutionContext executionContext, string inputName, TemplateToken token);
}

public sealed class ActionManifestManager : RunnerService, IActionManifestManager
Expand Down Expand Up @@ -282,6 +284,9 @@ public ActionDefinitionData Load(IExecutionContext executionContext, string mani
if (token != null)
{
var templateContext = CreateTemplateContext(executionContext);
Trace.Info($"Template context GitHub: {StringUtil.ConvertToJson(templateContext.ExpressionValues["github"])}");

Trace.Info($"Template context keys: {StringUtil.ConvertToJson(templateContext.ExpressionValues.Keys)}");
try
{
var evaluateResult = TemplateEvaluator.Evaluate(templateContext, "input-default-context", token, 0, null, omitHeader: true);
Expand All @@ -304,6 +309,83 @@ public ActionDefinitionData Load(IExecutionContext executionContext, string mani
return result;
}

// public string EvaluateDefaultInputInsideComposite(
// IExecutionContext executionContext,
// string inputName,
// TemplateToken token)
// {
// string result = "";
// if (token != null)
// {
// // Add GitHub Expression Values
// var githubContext = executionContext.ExpressionValues["github"];
// Trace.Info($"GitHub Context EvaluateDefaultInputInsideComposite: {StringUtil.ConvertToJson(githubContext)}");

// var temp = new Dictionary<string, PipelineContextData>();
// temp["github"] = githubContext;

// // Trace.Info($"Token: {StringUtil.ConvertToJson(token)}");

// var templateContext = CreateTemplateContext(executionContext, temp);
// try
// {

// var evaluateResult = TemplateEvaluator.Evaluate(templateContext, "uses-input", token, 0, null, omitHeader: true);

// Trace.Info($"Input '{inputName}': default value evaluate result: {StringUtil.ConvertToJson(evaluateResult)}");
// templateContext.Errors.Check();

// // Can't evaluate the default github.respository, etc.


// // TODO: restrict to only be used for composite "uses" steps
// // Find better way to isolate only
// // We could create a whitelist for just checkout?
// // (ex: "repo", "token", etc.)
// // if (evaluateResult is BasicExpressionToken)
// // {


// // // var evaluateResult2 = TemplateEvaluator.Evaluate(templateContext, "step-with", token, 0, null, omitHeader: true);
// // // templateContext.Errors.Check();

// // // Trace.Info($"Test2 Input '{inputName}': default value evaluate result: {StringUtil.ConvertToJson(evaluateResult2)}");
// // // var result2 = evaluateResult2.AssertString($"default value for input '{inputName}'").Value;

// // // TODO 6/28 => Try just getting it from the getgithubcontext lmao.

// // // Trace.Info($"Basic expr token: {evaluateResult}");

// // var stringVersion = evaluateResult.AssertString($"default value for input '{inputName}'").Value;

// // // no we have to use the template evaluator since it's a

// // // var githubTokenSplit =

// // // // Evaluate it
// // // var evaluateResult = executionContext.GetGitHubContext("");

// // return result2;
// // }

// // Trace.Info($"Input '{inputName}': default value evaluate result: {StringUtil.ConvertToJson(evaluateResult)}");

// // String
// result = evaluateResult.AssertString($"default value for input '{inputName}'").Value;
// }
// catch (Exception ex) when (!(ex is TemplateValidationException))
// {
// Trace.Error(ex);
// templateContext.Errors.Add(ex);
// }

// templateContext.Errors.Check();
// }

// return result;

// }

private TemplateContext CreateTemplateContext(
IExecutionContext executionContext,
IDictionary<string, PipelineContextData> extraExpressionValues = null)
Expand Down
29 changes: 29 additions & 0 deletions src/Runner.Worker/ActionRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,25 @@ public async Task RunAsync()
validInputs.Add("entryPoint");
validInputs.Add("args");
}

Trace.Info($"Repo: {ExecutionContext.GetGitHubContext("repository")}");

// Since we don't pass the GitHub Context attributes to the composite action,
// We need to explitly set the default values of certain things we need like the
// default repository

// if (ExecutionContext.GetGitHubContext("repository") == null)
// {
// ExecutionContext.SetGitHubContext("repository", definition.Directory);
// }

// var githubContext = ExecutionContext.ExpressionValues["github"] as GitHubContext;

// foreach (var pair in githubContext)
// {
// ExecutionContext.SetGitHubContext(pair.Key, pair.Value as StringContextData);
// }

// Merge the default inputs from the definition
if (definition.Data?.Inputs != null)
{
Expand All @@ -179,7 +198,17 @@ public async Task RunAsync()
validInputs.Add(key);
if (!inputs.ContainsKey(key))
{
Trace.Info($"Definition Input Key: {key}");
// if (ExecutionContext.InsideComposite)
// {
// inputs[key] = manifestManager.EvaluateDefaultInputInsideComposite(ExecutionContext, key, input.Value);
// }
// else
// {
// inputs[key] = manifestManager.EvaluateDefaultInput(ExecutionContext, key, input.Value);
// }
inputs[key] = manifestManager.EvaluateDefaultInput(ExecutionContext, key, input.Value);
Trace.Info($"Definition Input Value: {inputs[key]}");
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/Runner.Worker/Handlers/CompositeActionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using GitHub.DistributedTask.Expressions2;
using GitHub.DistributedTask.ObjectTemplating.Tokens;
using GitHub.DistributedTask.Pipelines.ContextData;
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
using GitHub.DistributedTask.WebApi;
using GitHub.Runner.Common;
using GitHub.Runner.Sdk;
using GitHub.Runner.Worker.Expressions;
using Pipelines = GitHub.DistributedTask.Pipelines;


Expand All @@ -35,6 +38,8 @@ public async Task RunAsync(ActionRunStage stage)
var githubContext = ExecutionContext.ExpressionValues["github"] as GitHubContext;
ArgUtil.NotNull(githubContext, nameof(githubContext));

// Trace.Info($"Github Context: {StringUtil.ConvertToJson(githubContext)}");

// Resolve action steps
var actionSteps = Data.Steps;

Expand All @@ -45,6 +50,8 @@ public async Task RunAsync(ActionRunStage stage)
inputsData[i.Key] = new StringContextData(i.Value);
}

Trace.Info($"Composite Actions Inputs {StringUtil.ConvertToJson(inputsData)}");

// Initialize Composite Steps List of Steps
var compositeSteps = new List<IStep>();

Expand All @@ -64,6 +71,10 @@ public async Task RunAsync(ActionRunStage stage)
compositeGitHubContext[pair.Key] = pair.Value;
}

// Download all data
var actionManager = HostContext.GetService<IActionManager>();
await actionManager.PrepareActionsAsync(ExecutionContext, actionSteps);

foreach (Pipelines.ActionStep actionStep in actionSteps)
{
var actionRunner = HostContext.CreateService<IActionRunner>();
Expand All @@ -76,6 +87,7 @@ public async Task RunAsync(ActionRunStage stage)
// Set GITHUB_ACTION_PATH
step.ExecutionContext.ExpressionValues["github"] = compositeGitHubContext;
step.ExecutionContext.SetGitHubContext("action_path", ActionDirectory);
step.ExecutionContext.ExpressionFunctions.Add(new FunctionInfo<HashFilesFunction>(PipelineTemplateConstants.HashFiles, 1, byte.MaxValue));

compositeSteps.Add(step);
}
Expand Down Expand Up @@ -150,6 +162,7 @@ private async Task RunStepsAsync(List<IStep> compositeSteps)
{
ArgUtil.NotNull(compositeSteps, nameof(compositeSteps));


// The parent StepsRunner of the whole Composite Action Step handles the cancellation stuff already.
foreach (IStep step in compositeSteps)
{
Expand Down
55 changes: 53 additions & 2 deletions src/Runner.Worker/action_yaml.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,15 @@
},
"composite-steps": {
"sequence": {
"item-type": "composite-step"
"item-type": "composite-step-types"
}
},
"composite-step-types": {
"one-of": [
"composite-step",
"uses-step"
]
},
"composite-step": {
"mapping": {
"properties": {
Expand All @@ -130,6 +136,20 @@
}
}
},
"uses-step": {
"mapping": {
"properties": {
"name": "string-steps-context",
"id": "non-empty-string",
"uses": {
"type": "non-empty-string",
"required": true
},
"with": "step-with",
"env": "step-env"
}
}
},
"container-runs-context": {
"context": [
"inputs"
Expand Down Expand Up @@ -195,6 +215,37 @@
"loose-key-type": "non-empty-string",
"loose-value-type": "string"
}
},
"step-with": {
"context": [
"github",
"inputs",
"strategy",
"matrix",
"steps",
"job",
"runner",
"env",
"hashFiles(1,255)"
],
"mapping": {
"loose-key-type": "non-empty-string",
"loose-value-type": "string"
}
},
"uses-input": {
"context": [
"github",
"inputs",
"strategy",
"matrix",
"steps",
"job",
"runner",
"env",
"hashFiles(1,255)"
],
"string": {}
}
}
}
}
2 changes: 1 addition & 1 deletion src/runnerversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.272.0
2.274.0