public async Task RunAsync() { // Validate args. Trace.Entering(); ArgUtil.NotNull(ExecutionContext, nameof(ExecutionContext)); ArgUtil.NotNull(Action, nameof(Action)); var taskManager = HostContext.GetService <IActionManager>(); var handlerFactory = HostContext.GetService <IHandlerFactory>(); // Load the task definition and choose the handler. Definition definition = taskManager.LoadAction(ExecutionContext, Action); ArgUtil.NotNull(definition, nameof(definition)); ActionExecutionData handlerData = definition.Data?.Execution; ArgUtil.NotNull(handlerData, nameof(handlerData)); // The action has post cleanup defined. // we need to create timeline record for them and add them to the step list that StepRunner is using if (handlerData.HasCleanup && Stage == ActionRunStage.Main) { string postDisplayName = null; if (this.DisplayName.StartsWith(PipelineTemplateConstants.RunDisplayPrefix)) { postDisplayName = $"Post {this.DisplayName.Substring(PipelineTemplateConstants.RunDisplayPrefix.Length)}"; } else { postDisplayName = $"Post {this.DisplayName}"; } var repositoryReference = Action.Reference as RepositoryPathReference; var pathString = string.IsNullOrEmpty(repositoryReference.Path) ? string.Empty : $"/{repositoryReference.Path}"; var repoString = string.IsNullOrEmpty(repositoryReference.Ref) ? $"{repositoryReference.Name}{pathString}" : $"{repositoryReference.Name}{pathString}@{repositoryReference.Ref}"; ExecutionContext.Debug($"Register post job cleanup for action: {repoString}"); var actionRunner = HostContext.CreateService <IActionRunner>(); actionRunner.Action = Action; actionRunner.Stage = ActionRunStage.Post; actionRunner.Condition = handlerData.CleanupCondition; actionRunner.DisplayName = postDisplayName; ExecutionContext.RegisterPostJobStep($"{actionRunner.Action.Name}_post", actionRunner); } IStepHost stepHost = HostContext.CreateService <IDefaultStepHost>(); // Makes directory for event_path data var tempDirectory = HostContext.GetDirectory(WellKnownDirectory.Temp); var workflowDirectory = Path.Combine(tempDirectory, "_github_workflow"); Directory.CreateDirectory(workflowDirectory); var gitHubEvent = ExecutionContext.GetGitHubContext("event"); // adds the GitHub event path/file if the event exists if (gitHubEvent != null) { var workflowFile = Path.Combine(workflowDirectory, "event.json"); Trace.Info($"Write event payload to {workflowFile}"); File.WriteAllText(workflowFile, gitHubEvent, new UTF8Encoding(false)); ExecutionContext.SetGitHubContext("event_path", workflowFile); } // Setup container stephost for running inside the container. if (ExecutionContext.Container != null) { // Make sure required container is already created. ArgUtil.NotNullOrEmpty(ExecutionContext.Container.ContainerId, nameof(ExecutionContext.Container.ContainerId)); var containerStepHost = HostContext.CreateService <IContainerStepHost>(); containerStepHost.Container = ExecutionContext.Container; stepHost = containerStepHost; } // Load the inputs. ExecutionContext.Debug("Loading inputs"); var templateEvaluator = ExecutionContext.ToPipelineTemplateEvaluator(); var inputs = templateEvaluator.EvaluateStepInputs(Action.Inputs, ExecutionContext.ExpressionValues, ExecutionContext.ExpressionFunctions); foreach (KeyValuePair <string, string> input in inputs) { string message = ""; if (definition.Data?.Deprecated?.TryGetValue(input.Key, out message) == true) { ExecutionContext.Warning(String.Format("Input '{0}' has been deprecated with message: {1}", input.Key, message)); } } // Merge the default inputs from the definition if (definition.Data?.Inputs != null) { var manifestManager = HostContext.GetService <IActionManifestManager>(); foreach (var input in (definition.Data?.Inputs)) { string key = input.Key.AssertString("action input name").Value; if (!inputs.ContainsKey(key)) { inputs[key] = manifestManager.EvaluateDefaultInput(ExecutionContext, key, input.Value); } } } // Load the action environment. ExecutionContext.Debug("Loading env"); var environment = new Dictionary <String, String>(VarUtil.EnvironmentVariableKeyComparer); #if OS_WINDOWS var envContext = ExecutionContext.ExpressionValues["env"] as DictionaryContextData; #else var envContext = ExecutionContext.ExpressionValues["env"] as CaseSensitiveDictionaryContextData; #endif // Apply environment from env context, env context contains job level env and action's evn block foreach (var env in envContext) { environment[env.Key] = env.Value.ToString(); } // Apply action's intra-action state at last foreach (var state in ExecutionContext.IntraActionState) { environment[$"STATE_{state.Key}"] = state.Value ?? string.Empty; } // Create the handler. IHandler handler = handlerFactory.Create( ExecutionContext, Action.Reference, stepHost, handlerData, inputs, environment, ExecutionContext.Variables, actionDirectory: definition.Directory); // Print out action details handler.PrintActionDetails(Stage); // Run the task. await handler.RunAsync(Stage); }