mirror of
https://github.com/actions/runner.git
synced 2025-12-11 04:46:58 +00:00
committed by
TingluoHuang
parent
593673ba9e
commit
0fcd63d171
@@ -56,6 +56,10 @@ namespace GitHub.Runner.Common
|
||||
Add<T>(extensions, "GitHub.Runner.Worker.EndGroupCommandExtension, Runner.Worker");
|
||||
Add<T>(extensions, "GitHub.Runner.Worker.EchoCommandExtension, Runner.Worker");
|
||||
break;
|
||||
case "GitHub.Runner.Worker.IFileCommandExtension":
|
||||
Add<T>(extensions, "GitHub.Runner.Worker.AddPathFileCommand, Runner.Worker");
|
||||
Add<T>(extensions, "GitHub.Runner.Worker.SetEnvFileCommand, Runner.Worker");
|
||||
break;
|
||||
default:
|
||||
// This should never happen.
|
||||
throw new NotSupportedException($"Unexpected extension type: '{typeof(T).FullName}'");
|
||||
|
||||
@@ -145,6 +145,12 @@ namespace GitHub.Runner.Worker
|
||||
stepHost = containerStepHost;
|
||||
}
|
||||
|
||||
// Setup File Command Manager
|
||||
var fileCommandManager = HostContext.CreateService<IFileCommandManager>();
|
||||
// Container Action Handler will handle the conversion for Container Actions
|
||||
var container = handlerData.ExecutionType == ActionExecutionType.Container ? null : ExecutionContext.Global.Container;
|
||||
fileCommandManager.InitializeFiles(ExecutionContext, container);
|
||||
|
||||
// Load the inputs.
|
||||
ExecutionContext.Debug("Loading inputs");
|
||||
var templateEvaluator = ExecutionContext.ToPipelineTemplateEvaluator();
|
||||
@@ -239,6 +245,8 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
// Run the task.
|
||||
await handler.RunAsync(Stage);
|
||||
fileCommandManager.TryProcessFiles(ExecutionContext, ExecutionContext.Global.Container);
|
||||
|
||||
}
|
||||
|
||||
public bool TryEvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context)
|
||||
|
||||
140
src/Runner.Worker/FileCommandManager.cs
Normal file
140
src/Runner.Worker/FileCommandManager.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using GitHub.Runner.Worker.Container;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using GitHub.Runner.Common;
|
||||
using GitHub.Runner.Sdk;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GitHub.Runner.Worker
|
||||
{
|
||||
[ServiceLocator(Default = typeof(FileCommandManager))]
|
||||
public interface IFileCommandManager : IRunnerService
|
||||
{
|
||||
void InitializeFiles(IExecutionContext context, ContainerInfo container);
|
||||
void TryProcessFiles(IExecutionContext context, ContainerInfo container);
|
||||
|
||||
}
|
||||
|
||||
public sealed class FileCommandManager : RunnerService, IFileCommandManager
|
||||
{
|
||||
private const string _folderName = "_runner_file_commands";
|
||||
private List<IFileCommandExtension> _commandExtensions;
|
||||
private string _fileSuffix = String.Empty;
|
||||
private string _fileCommandDirectory;
|
||||
private Tracing _trace;
|
||||
|
||||
public override void Initialize(IHostContext hostContext)
|
||||
{
|
||||
base.Initialize(hostContext);
|
||||
_trace = HostContext.GetTrace(nameof(FileCommandManager));
|
||||
|
||||
_fileCommandDirectory = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Temp), _folderName);
|
||||
if (!Directory.Exists(_fileCommandDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(_fileCommandDirectory);
|
||||
}
|
||||
|
||||
var extensionManager = hostContext.GetService<IExtensionManager>();
|
||||
_commandExtensions = extensionManager.GetExtensions<IFileCommandExtension>() ?? new List<IFileCommandExtension>();
|
||||
|
||||
}
|
||||
|
||||
public void InitializeFiles(IExecutionContext context, ContainerInfo container)
|
||||
{
|
||||
var oldSuffix = _fileSuffix;
|
||||
_fileSuffix = Guid.NewGuid().ToString();
|
||||
foreach (var fileCommand in _commandExtensions)
|
||||
{
|
||||
var oldPath = Path.Combine(_fileCommandDirectory, fileCommand.FileName + oldSuffix);
|
||||
if (oldSuffix != String.Empty && File.Exists(oldPath))
|
||||
{
|
||||
TryDeleteFile(oldPath);
|
||||
}
|
||||
|
||||
var newPath = Path.Combine(_fileCommandDirectory, fileCommand.FileName + _fileSuffix);
|
||||
TryDeleteFile(newPath);
|
||||
File.Create(newPath).Dispose();
|
||||
|
||||
var pathToSet = container != null ? container.TranslateToContainerPath(newPath) : newPath;
|
||||
context.SetGitHubContext(fileCommand.ContextName, pathToSet);
|
||||
}
|
||||
}
|
||||
|
||||
public void TryProcessFiles(IExecutionContext context, ContainerInfo container)
|
||||
{
|
||||
foreach (var fileCommand in _commandExtensions)
|
||||
{
|
||||
fileCommand.ProcessCommand(context, Path.Combine(_fileCommandDirectory, fileCommand.FileName + _fileSuffix),container);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryDeleteFile(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
try
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_trace.Warning($"Unable to delete file {path} for reason: {e.ToString()}");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IFileCommandExtension : IExtension
|
||||
{
|
||||
string ContextName { get; }
|
||||
string FileName { get; }
|
||||
|
||||
void ProcessCommand(IExecutionContext context, string filePath, ContainerInfo container);
|
||||
}
|
||||
|
||||
public sealed class AddPathFileCommand : RunnerService, IFileCommandExtension
|
||||
{
|
||||
public string ContextName => "path";
|
||||
public string FileName => "add_path_";
|
||||
|
||||
public Type ExtensionType => typeof(IFileCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string filePath, ContainerInfo container)
|
||||
{
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
var lines = File.ReadAllLines(filePath, Encoding.UTF8);
|
||||
foreach(var line in lines)
|
||||
{
|
||||
if (line == string.Empty)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
context.Global.PrependPath.RemoveAll(x => string.Equals(x, line, StringComparison.CurrentCulture));
|
||||
context.Global.PrependPath.Add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SetEnvFileCommand : RunnerService, IFileCommandExtension
|
||||
{
|
||||
public string ContextName => "env";
|
||||
public string FileName => "set_env_";
|
||||
|
||||
public Type ExtensionType => typeof(IFileCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string filePath, ContainerInfo container)
|
||||
{
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
// TODO Process this file
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,13 @@ namespace GitHub.Runner.Worker
|
||||
"actor",
|
||||
"api_url",
|
||||
"base_ref",
|
||||
"env",
|
||||
"event_name",
|
||||
"event_path",
|
||||
"graphql_url",
|
||||
"head_ref",
|
||||
"job",
|
||||
"path",
|
||||
"ref",
|
||||
"repository",
|
||||
"repository_owner",
|
||||
|
||||
@@ -161,16 +161,21 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
Directory.CreateDirectory(tempHomeDirectory);
|
||||
this.Environment["HOME"] = tempHomeDirectory;
|
||||
|
||||
var tempFileCommandDirectory = Path.Combine(tempDirectory, "_runner_file_commands");
|
||||
ArgUtil.Directory(tempFileCommandDirectory, nameof(tempFileCommandDirectory));
|
||||
|
||||
var tempWorkflowDirectory = Path.Combine(tempDirectory, "_github_workflow");
|
||||
ArgUtil.Directory(tempWorkflowDirectory, nameof(tempWorkflowDirectory));
|
||||
|
||||
container.MountVolumes.Add(new MountVolume("/var/run/docker.sock", "/var/run/docker.sock"));
|
||||
container.MountVolumes.Add(new MountVolume(tempHomeDirectory, "/github/home"));
|
||||
container.MountVolumes.Add(new MountVolume(tempWorkflowDirectory, "/github/workflow"));
|
||||
container.MountVolumes.Add(new MountVolume(tempFileCommandDirectory, "/github/file_commands"));
|
||||
container.MountVolumes.Add(new MountVolume(defaultWorkingDirectory, "/github/workspace"));
|
||||
|
||||
container.AddPathTranslateMapping(tempHomeDirectory, "/github/home");
|
||||
container.AddPathTranslateMapping(tempWorkflowDirectory, "/github/workflow");
|
||||
container.AddPathTranslateMapping(tempFileCommandDirectory, "/github/file_commands");
|
||||
container.AddPathTranslateMapping(defaultWorkingDirectory, "/github/workspace");
|
||||
|
||||
container.ContainerWorkDirectory = "/github/workspace";
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace GitHub.Runner.Common.Tests
|
||||
{
|
||||
typeof(IActionCommandExtension),
|
||||
typeof(IExecutionContext),
|
||||
typeof(IFileCommandExtension),
|
||||
typeof(IHandler),
|
||||
typeof(IJobExtension),
|
||||
typeof(IStep),
|
||||
|
||||
@@ -32,6 +32,8 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
private TestHostContext _hc;
|
||||
private ActionRunner _actionRunner;
|
||||
private IActionManifestManager _actionManifestManager;
|
||||
private Mock<IFileCommandManager> _fileCommandManager;
|
||||
|
||||
private DictionaryContextData _context = new DictionaryContextData();
|
||||
|
||||
[Fact]
|
||||
@@ -362,6 +364,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
_handlerFactory = new Mock<IHandlerFactory>();
|
||||
_defaultStepHost = new Mock<IDefaultStepHost>();
|
||||
_actionManifestManager = new ActionManifestManager();
|
||||
_fileCommandManager = new Mock<IFileCommandManager>();
|
||||
_actionManifestManager.Initialize(_hc);
|
||||
|
||||
var githubContext = new GitHubContext();
|
||||
@@ -394,6 +397,8 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
|
||||
_hc.EnqueueInstance<IDefaultStepHost>(_defaultStepHost.Object);
|
||||
|
||||
_hc.EnqueueInstance(_fileCommandManager.Object);
|
||||
|
||||
// Instance to test.
|
||||
_actionRunner = new ActionRunner();
|
||||
_actionRunner.Initialize(_hc);
|
||||
|
||||
Reference in New Issue
Block a user