Compare commits

..

1 Commits

Author SHA1 Message Date
eric sciple
8770849c3b add set-workspace command 2019-10-30 22:16:31 -04:00
11 changed files with 126 additions and 76 deletions

View File

@@ -2,10 +2,11 @@
- N/A
## Bugs
- Fixed an issue with Strong Name Validation when running as a service on Windows (#185)
- Reverted removal of additional fields error and warning fields (#147)
- Actions cache would incorrectly cache the action if the tag was updated (#148)
## Misc
- N/A
- Updated to .NET Core 3.0 (#127)
## Agent Downloads

View File

@@ -42,6 +42,7 @@ namespace GitHub.Runner.Common
// Action command extensions.
case "GitHub.Runner.Worker.IActionCommandExtension":
Add<T>(extensions, "GitHub.Runner.Worker.InternalPluginSetRepoPathCommandExtension, Runner.Worker");
Add<T>(extensions, "GitHub.Runner.Worker.SetWorkspaceCommandExtension, Runner.Worker");
Add<T>(extensions, "GitHub.Runner.Worker.SetEnvCommandExtension, Runner.Worker");
Add<T>(extensions, "GitHub.Runner.Worker.SetOutputCommandExtension, Runner.Worker");
Add<T>(extensions, "GitHub.Runner.Worker.SaveStateCommandExtension, Runner.Worker");

Binary file not shown.

View File

@@ -9,8 +9,9 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>RunnerService</RootNamespace>
<AssemblyName>RunnerService</AssemblyName>
<SignAssembly>false</SignAssembly>
<DelaySign>false</DelaySign>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>FinalPublicKey.snk</AssemblyOriginatorKeyFile>
<DelaySign>true</DelaySign>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
@@ -63,6 +64,7 @@
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="FinalPublicKey.snk" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resource.resx">

View File

@@ -73,7 +73,7 @@ namespace GitHub.Runner.Worker
return false;
}
// process action command in serialize order.
// process action command in serialize oreder.
lock (_commandSerializeLock)
{
if (_stopProcessCommand)
@@ -107,19 +107,32 @@ namespace GitHub.Runner.Worker
}
else if (_commandExtensions.TryGetValue(actionCommand.Command, out IActionCommandExtension extension))
{
if (context.EchoOnActionCommand && !extension.OmitEcho)
{
context.Output(input);
}
bool commandHasBeenOutput = false;
try
{
if (context.EchoOnActionCommand)
{
context.Output(input);
context.Debug($"Processing command '{actionCommand.Command}'");
commandHasBeenOutput = true;
}
extension.ProcessCommand(context, input, actionCommand);
if (context.EchoOnActionCommand)
{
context.Debug($"Processed command '{actionCommand.Command}' successfully");
}
}
catch (Exception ex)
{
var commandInformation = extension.OmitEcho ? extension.Command : input;
context.Error($"Unable to process command '{commandInformation}' successfully.");
if (!commandHasBeenOutput)
{
context.Output(input);
}
context.Error($"Unable to process command '{input}' successfully.");
context.Error(ex);
context.CommandResult = TaskResult.Failed;
}
@@ -138,7 +151,6 @@ namespace GitHub.Runner.Worker
public interface IActionCommandExtension : IExtension
{
string Command { get; }
bool OmitEcho { get; }
void ProcessCommand(IExecutionContext context, string line, ActionCommand command);
}
@@ -146,7 +158,6 @@ namespace GitHub.Runner.Worker
public sealed class InternalPluginSetRepoPathCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "internal-set-repo-path";
public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -173,10 +184,43 @@ namespace GitHub.Runner.Worker
}
}
public sealed class SetWorkspaceCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "set-workspace";
public Type ExtensionType => typeof(IActionCommandExtension);
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
{
string path = command.Data;
if (string.IsNullOrWhiteSpace(path))
{
throw new Exception("Path not specified");
}
if (!Path.IsPathRooted(path))
{
throw new Exception("Expected a rooted path");
}
string runnerWorkspace = context.GetRunnerContext("workspace");
ArgUtil.Directory(runnerWorkspace, nameof(runnerWorkspace));
// Must be under runner workspace
path = Path.GetFullPath(path); // remove relative pathing and normalize slashes
if (!path.StartsWith(runnerWorkspace + Path.DirectorySeparatorChar, IOUtil.FilePathStringComparison))
{
throw new Exception($"Expected path to be under {runnerWorkspace}");
}
Trace.Info($"Setting GitHub workspace to '{path}'");
context.SetGitHubContext("workspace", path);
}
}
public sealed class SetEnvCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "set-env";
public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -201,7 +245,6 @@ namespace GitHub.Runner.Worker
public sealed class SetOutputCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "set-output";
public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -225,7 +268,6 @@ namespace GitHub.Runner.Worker
public sealed class SaveStateCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "save-state";
public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -249,7 +291,6 @@ namespace GitHub.Runner.Worker
public sealed class AddMaskCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "add-mask";
public bool OmitEcho => true;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -261,11 +302,6 @@ namespace GitHub.Runner.Worker
}
else
{
if (context.EchoOnActionCommand)
{
context.Output($"::{Command}::***");
}
HostContext.SecretMasker.AddValue(command.Data);
Trace.Info($"Add new secret mask with length of {command.Data.Length}");
}
@@ -275,7 +311,6 @@ namespace GitHub.Runner.Worker
public sealed class AddPathCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "add-path";
public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -290,7 +325,6 @@ namespace GitHub.Runner.Worker
public sealed class AddMatcherCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "add-matcher";
public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -337,7 +371,6 @@ namespace GitHub.Runner.Worker
public sealed class RemoveMatcherCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "remove-matcher";
public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -405,7 +438,6 @@ namespace GitHub.Runner.Worker
public sealed class DebugCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "debug";
public bool OmitEcho => true;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -433,7 +465,6 @@ namespace GitHub.Runner.Worker
{
public abstract IssueType Type { get; }
public abstract string Command { get; }
public bool OmitEcho => true;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -513,8 +544,6 @@ namespace GitHub.Runner.Worker
public abstract class GroupingCommandExtension : RunnerService, IActionCommandExtension
{
public abstract string Command { get; }
public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
@@ -527,7 +556,6 @@ namespace GitHub.Runner.Worker
public sealed class EchoCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "echo";
public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);

View File

@@ -94,21 +94,7 @@ namespace GitHub.Runner.Worker
{
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);
ExecutionContext.RegisterPostJobAction(postDisplayName, handlerData.CleanupCondition, Action);
}
IStepHost stepHost = HostContext.CreateService<IDefaultStepHost>();

View File

@@ -11,7 +11,6 @@ using GitHub.Runner.Common;
using GitHub.Runner.Sdk;
using GitHub.DistributedTask.Pipelines.ContextData;
using Microsoft.Win32;
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
namespace GitHub.Runner.Worker
{
@@ -39,14 +38,6 @@ namespace GitHub.Runner.Worker
List<ContainerInfo> containers = data as List<ContainerInfo>;
ArgUtil.NotNull(containers, nameof(containers));
var postJobStep = new JobExtensionRunner(runAsync: this.StopContainersAsync,
condition: $"{PipelineTemplateConstants.Always}()",
displayName: "Stop containers",
data: data);
executionContext.Debug($"Register post job cleanup for stoping/deleting containers.");
executionContext.RegisterPostJobStep(nameof(StopContainersAsync), postJobStep);
// Check whether we are inside a container.
// Our container feature requires to map working directory from host to the container.
// If we are already inside a container, we will not able to find out the real working direcotry path on the host.

View File

@@ -78,6 +78,7 @@ namespace GitHub.Runner.Worker
void Start(string currentOperation = null);
TaskResult Complete(TaskResult? result = null, string currentOperation = null, string resultCode = null);
void SetEnvContext(string name, string value);
string GetRunnerContext(string name);
void SetRunnerContext(string name, string value);
string GetGitHubContext(string name);
void SetGitHubContext(string name, string value);
@@ -98,7 +99,7 @@ namespace GitHub.Runner.Worker
// others
void ForceTaskComplete();
void RegisterPostJobStep(string refName, IStep step);
void RegisterPostJobAction(string displayName, string condition, Pipelines.ActionStep action);
}
public sealed class ExecutionContext : RunnerService, IExecutionContext
@@ -240,10 +241,27 @@ namespace GitHub.Runner.Worker
});
}
public void RegisterPostJobStep(string refName, IStep step)
public void RegisterPostJobAction(string displayName, string condition, Pipelines.ActionStep action)
{
step.ExecutionContext = Root.CreatePostChild(step.DisplayName, refName, IntraActionState);
Root.PostJobSteps.Push(step);
if (action.Reference.Type != ActionSourceType.Repository)
{
throw new NotSupportedException("Only action that has `action.yml` can define post job execution.");
}
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}";
this.Debug($"Register post job cleanup for action: {repoString}");
var actionRunner = HostContext.CreateService<IActionRunner>();
actionRunner.Action = action;
actionRunner.Stage = ActionRunStage.Post;
actionRunner.Condition = condition;
actionRunner.DisplayName = displayName;
actionRunner.ExecutionContext = Root.CreatePostChild(displayName, $"{actionRunner.Action.Name}_post", IntraActionState);
Root.PostJobSteps.Push(actionRunner);
}
public IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, Dictionary<string, string> intraActionState = null, int? recordOrder = null)
@@ -348,6 +366,13 @@ namespace GitHub.Runner.Worker
return Result.Value;
}
public string GetRunnerContext(string name)
{
ArgUtil.NotNullOrEmpty(name, nameof(name));
var runnerContext = ExpressionValues["runner"] as RunnerContext;
return runnerContext[name].AssertString($"runner[{name}]");
}
public void SetRunnerContext(string name, string value)
{
ArgUtil.NotNullOrEmpty(name, nameof(name));

View File

@@ -110,7 +110,9 @@ namespace GitHub.Runner.Worker
}
}
// Build up 2 lists of steps, pre-job, job
// Build up 3 lists of steps, pre-job, job, post-job
var postJobStepsBuilder = new Stack<IStep>();
// Download actions not already in the cache
Trace.Info("Downloading actions");
var actionManager = HostContext.GetService<IActionManager>();
@@ -132,6 +134,10 @@ namespace GitHub.Runner.Worker
condition: $"{PipelineTemplateConstants.Success}()",
displayName: "Initialize containers",
data: (object)containers));
postJobStepsBuilder.Push(new JobExtensionRunner(runAsync: containerProvider.StopContainersAsync,
condition: $"{PipelineTemplateConstants.Always}()",
displayName: "Stop containers",
data: (object)containers));
}
// Add action steps
@@ -181,9 +187,33 @@ namespace GitHub.Runner.Worker
}
}
// Add post-job steps
Trace.Info("Adding post-job steps");
while (postJobStepsBuilder.Count > 0)
{
postJobSteps.Add(postJobStepsBuilder.Pop());
}
// Create execution context for post-job steps
foreach (var step in postJobSteps)
{
if (step is JobExtensionRunner)
{
JobExtensionRunner extensionStep = step as JobExtensionRunner;
ArgUtil.NotNull(extensionStep, extensionStep.DisplayName);
Guid stepId = Guid.NewGuid();
extensionStep.ExecutionContext = jobContext.CreateChild(stepId, extensionStep.DisplayName, stepId.ToString("N"), null, null);
}
}
List<IStep> steps = new List<IStep>();
steps.AddRange(preJobSteps);
steps.AddRange(jobSteps);
steps.AddRange(postJobSteps);
// Start agent log plugin host process
// var logPlugin = HostContext.GetService<IAgentLogPlugin>();
// await logPlugin.StartAsync(context, steps, jobContext.CancellationToken);
// Prepare for orphan process cleanup
_processCleanup = jobContext.Variables.GetBoolean("process.clean") ?? true;

View File

@@ -206,22 +206,8 @@ namespace GitHub.Runner.Common.Tests.Worker
var action2 = jobContext.CreateChild(Guid.NewGuid(), "action_2", "action_2", null, null);
action2.IntraActionState["state"] = "2";
var postRunner1 = hc.CreateService<IActionRunner>();
postRunner1.Action = new Pipelines.ActionStep() { Name = "post1", DisplayName = "Test 1", Reference = new Pipelines.RepositoryPathReference() { Name = "actions/action" } };
postRunner1.Stage = ActionRunStage.Post;
postRunner1.Condition = "always()";
postRunner1.DisplayName = "post1";
var postRunner2 = hc.CreateService<IActionRunner>();
postRunner2.Action = new Pipelines.ActionStep() { Name = "post2", DisplayName = "Test 2", Reference = new Pipelines.RepositoryPathReference() { Name = "actions/action" } };
postRunner2.Stage = ActionRunStage.Post;
postRunner2.Condition = "always()";
postRunner2.DisplayName = "post2";
action1.RegisterPostJobStep("post1", postRunner1);
action2.RegisterPostJobStep("post2", postRunner2);
action1.RegisterPostJobAction("post1", "always()", new Pipelines.ActionStep() { Name = "post1", DisplayName = "Test 1", Reference = new Pipelines.RepositoryPathReference() { Name = "actions/action" } });
action2.RegisterPostJobAction("post2", "always()", new Pipelines.ActionStep() { Name = "post2", DisplayName = "Test 2", Reference = new Pipelines.RepositoryPathReference() { Name = "actions/action" } });
Assert.NotNull(jobContext.JobSteps);
Assert.NotNull(jobContext.PostJobSteps);

View File

@@ -1 +1 @@
2.160.2
2.160.0