mirror of
https://github.com/actions/runner.git
synced 2026-01-16 08:42:55 +08:00
Compare commits
9 Commits
users/logo
...
releases/m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcf795d86d | ||
|
|
5d95befb0b | ||
|
|
ba544a1d9f | ||
|
|
f1aa949184 | ||
|
|
0d1d346078 | ||
|
|
2cf97ad42c | ||
|
|
2a3e64d335 | ||
|
|
004d2ececd | ||
|
|
659e8a3685 |
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@@ -43,6 +43,14 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
|
|
||||||
|
# Set Path workaround for https://github.com/actions/virtual-environments/issues/263
|
||||||
|
- run: |
|
||||||
|
echo "::add-path::C:\Program Files\Git\mingw64\bin"
|
||||||
|
echo "::add-path::C:\Program Files\Git\usr\bin"
|
||||||
|
echo "::add-path::C:\Program Files\Git\bin"
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
name: "Temp step to Set Path for Windows"
|
||||||
|
|
||||||
# Build runner layout
|
# Build runner layout
|
||||||
- name: Build & Layout Release
|
- name: Build & Layout Release
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@@ -70,7 +70,15 @@ jobs:
|
|||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
# Set Path workaround for https://github.com/actions/virtual-environments/issues/263
|
||||||
|
- run: |
|
||||||
|
echo "::add-path::C:\Program Files\Git\mingw64\bin"
|
||||||
|
echo "::add-path::C:\Program Files\Git\usr\bin"
|
||||||
|
echo "::add-path::C:\Program Files\Git\bin"
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
name: "Temp step to Set Path for Windows"
|
||||||
|
|
||||||
# Build runner layout
|
# Build runner layout
|
||||||
- name: Build & Layout Release
|
- name: Build & Layout Release
|
||||||
|
|||||||
@@ -17,14 +17,13 @@
|
|||||||
- Trace javascript action exit code to debug instead of user logs (#290)
|
- Trace javascript action exit code to debug instead of user logs (#290)
|
||||||
- Change prompt message when removing a runner to lines up with GitHub.com UI (#303)
|
- Change prompt message when removing a runner to lines up with GitHub.com UI (#303)
|
||||||
- Include step.env as part of env context. (#300)
|
- Include step.env as part of env context. (#300)
|
||||||
- Update Base64 Encoders to deal with suffixes (#284)
|
|
||||||
|
|
||||||
## Misc
|
## Misc
|
||||||
- Move .sln file under ./src (#238)
|
- Move .sln file under ./src (#238)
|
||||||
- Treat warnings as errors during compile (#249)
|
- Treat warnings as errors during compile (#249)
|
||||||
|
|
||||||
## Windows x64
|
## Windows x64
|
||||||
We recommend configuring the runner in a root folder of the Windows drive (e.g. "C:\actions-runner"). This will help avoid issues related to service identity folder permissions and long file path restrictions on Windows
|
We recommend configuring the runner under "<DRIVE>:\actions-runner". This will help avoid issues related to service identity folder permissions and long file path restrictions on Windows
|
||||||
```
|
```
|
||||||
// Create a folder under the drive root
|
// Create a folder under the drive root
|
||||||
mkdir \actions-runner ; cd \actions-runner
|
mkdir \actions-runner ; cd \actions-runner
|
||||||
@@ -32,7 +31,7 @@ mkdir \actions-runner ; cd \actions-runner
|
|||||||
Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-win-x64-<RUNNER_VERSION>.zip -OutFile actions-runner-win-x64-<RUNNER_VERSION>.zip
|
Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-win-x64-<RUNNER_VERSION>.zip -OutFile actions-runner-win-x64-<RUNNER_VERSION>.zip
|
||||||
// Extract the installer
|
// Extract the installer
|
||||||
Add-Type -AssemblyName System.IO.Compression.FileSystem ;
|
Add-Type -AssemblyName System.IO.Compression.FileSystem ;
|
||||||
[System.IO.Compression.ZipFile]::ExtractToDirectory("$PWD\actions-runner-win-x64-<RUNNER_VERSION>.zip", "$PWD")
|
[System.IO.Compression.ZipFile]::ExtractToDirectory("$HOME\Downloads\actions-runner-win-x64-<RUNNER_VERSION>.zip", "$PWD")
|
||||||
```
|
```
|
||||||
|
|
||||||
## OSX
|
## OSX
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.164.0
|
2.165.2
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using GitHub.Runner.Common;
|
|
||||||
using GitHub.Runner.Common.Util;
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
|
||||||
using GitHub.Services.Common;
|
using GitHub.Services.Common;
|
||||||
using GitHub.Services.OAuth;
|
using GitHub.Services.OAuth;
|
||||||
using GitHub.Services.WebApi;
|
using GitHub.Services.WebApi;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using GitHub.Runner.Common;
|
||||||
|
using GitHub.Runner.Sdk;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
|
||||||
namespace GitHub.Runner.Listener.Configuration
|
namespace GitHub.Runner.Listener.Configuration
|
||||||
{
|
{
|
||||||
@@ -276,15 +277,12 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
throw new NotSupportedException("Message queue listen OAuth token.");
|
throw new NotSupportedException("Message queue listen OAuth token.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testing agent connection, detect any potential connection issue, like local clock skew that cause OAuth token expired.
|
// Testing agent connection, detect any protential connection issue, like local clock skew that cause OAuth token expired.
|
||||||
var credMgr = HostContext.GetService<ICredentialManager>();
|
var credMgr = HostContext.GetService<ICredentialManager>();
|
||||||
VssCredentials credential = credMgr.LoadCredentials();
|
VssCredentials credential = credMgr.LoadCredentials();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _runnerServer.ConnectAsync(new Uri(runnerSettings.ServerUrl), credential);
|
await _runnerServer.ConnectAsync(new Uri(runnerSettings.ServerUrl), credential);
|
||||||
// ConnectAsync() hits _apis/connectionData which is an anonymous endpoint
|
|
||||||
// Need to hit an authenticate endpoint to trigger OAuth token exchange.
|
|
||||||
await _runnerServer.GetAgentPoolsAsync();
|
|
||||||
_term.WriteSuccessMessage("Runner connection is good");
|
_term.WriteSuccessMessage("Runner connection is good");
|
||||||
}
|
}
|
||||||
catch (VssOAuthTokenRequestException ex) when (ex.Message.Contains("Current server time is"))
|
catch (VssOAuthTokenRequestException ex) when (ex.Message.Contains("Current server time is"))
|
||||||
@@ -521,20 +519,15 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
|
|
||||||
private async Task<GitHubAuthResult> GetTenantCredential(string githubUrl, string githubToken)
|
private async Task<GitHubAuthResult> GetTenantCredential(string githubUrl, string githubToken)
|
||||||
{
|
{
|
||||||
var gitHubUrlBuilder = new UriBuilder(githubUrl);
|
var gitHubUrl = new UriBuilder(githubUrl);
|
||||||
var githubApiUrl = $"{gitHubUrlBuilder.Scheme}://api.{gitHubUrlBuilder.Host}/actions/runner-registration";
|
var githubApiUrl = $"https://api.{gitHubUrl.Host}/repos/{gitHubUrl.Path.Trim('/')}/actions-runners/registration";
|
||||||
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
|
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
|
||||||
using (var httpClient = new HttpClient(httpClientHandler))
|
using (var httpClient = new HttpClient(httpClientHandler))
|
||||||
{
|
{
|
||||||
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("RemoteAuth", githubToken);
|
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("RemoteAuth", githubToken);
|
||||||
httpClient.DefaultRequestHeaders.UserAgent.Add(HostContext.UserAgent);
|
httpClient.DefaultRequestHeaders.UserAgent.Add(HostContext.UserAgent);
|
||||||
|
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github.shuri-preview+json"));
|
||||||
var bodyObject = new Dictionary<string, string>()
|
var response = await httpClient.PostAsync(githubApiUrl, new StringContent("", null, "application/json"));
|
||||||
{
|
|
||||||
{"url", githubUrl}
|
|
||||||
};
|
|
||||||
|
|
||||||
var response = await httpClient.PostAsync(githubApiUrl, new StringContent(StringUtil.ConvertToJson(bodyObject), null, "application/json"));
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using GitHub.DistributedTask.Pipelines;
|
using GitHub.DistributedTask.Pipelines;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using GitHub.Runner.Common.Util;
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Worker.Container;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -16,14 +15,14 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
void EnablePluginInternalCommand();
|
void EnablePluginInternalCommand();
|
||||||
void DisablePluginInternalCommand();
|
void DisablePluginInternalCommand();
|
||||||
bool TryProcessCommand(IExecutionContext context, string input, ContainerInfo container);
|
bool TryProcessCommand(IExecutionContext context, string input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ActionCommandManager : RunnerService, IActionCommandManager
|
public sealed class ActionCommandManager : RunnerService, IActionCommandManager
|
||||||
{
|
{
|
||||||
private const string _stopCommand = "stop-commands";
|
private const string _stopCommand = "stop-commands";
|
||||||
private readonly Dictionary<string, IActionCommandExtension> _commandExtensions = new Dictionary<string, IActionCommandExtension>(StringComparer.OrdinalIgnoreCase);
|
private readonly Dictionary<string, IActionCommandExtension> _commandExtensions = new Dictionary<string, IActionCommandExtension>(StringComparer.OrdinalIgnoreCase);
|
||||||
private readonly HashSet<string> _registeredCommands = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
private HashSet<string> _registeredCommands = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private readonly object _commandSerializeLock = new object();
|
private readonly object _commandSerializeLock = new object();
|
||||||
private bool _stopProcessCommand = false;
|
private bool _stopProcessCommand = false;
|
||||||
private string _stopToken = null;
|
private string _stopToken = null;
|
||||||
@@ -59,7 +58,7 @@ namespace GitHub.Runner.Worker
|
|||||||
_registeredCommands.Remove("internal-set-repo-path");
|
_registeredCommands.Remove("internal-set-repo-path");
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryProcessCommand(IExecutionContext context, string input, ContainerInfo container)
|
public bool TryProcessCommand(IExecutionContext context, string input)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(input))
|
if (string.IsNullOrEmpty(input))
|
||||||
{
|
{
|
||||||
@@ -115,7 +114,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
extension.ProcessCommand(context, input, actionCommand, container);
|
extension.ProcessCommand(context, input, actionCommand);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -141,7 +140,7 @@ namespace GitHub.Runner.Worker
|
|||||||
string Command { get; }
|
string Command { get; }
|
||||||
bool OmitEcho { get; }
|
bool OmitEcho { get; }
|
||||||
|
|
||||||
void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container);
|
void ProcessCommand(IExecutionContext context, string line, ActionCommand command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class InternalPluginSetRepoPathCommandExtension : RunnerService, IActionCommandExtension
|
public sealed class InternalPluginSetRepoPathCommandExtension : RunnerService, IActionCommandExtension
|
||||||
@@ -151,7 +150,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||||
{
|
{
|
||||||
if (!command.Properties.TryGetValue(SetRepoPathCommandProperties.repoFullName, out string repoFullName) || string.IsNullOrEmpty(repoFullName))
|
if (!command.Properties.TryGetValue(SetRepoPathCommandProperties.repoFullName, out string repoFullName) || string.IsNullOrEmpty(repoFullName))
|
||||||
{
|
{
|
||||||
@@ -181,7 +180,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||||
{
|
{
|
||||||
if (!command.Properties.TryGetValue(SetEnvCommandProperties.Name, out string envName) || string.IsNullOrEmpty(envName))
|
if (!command.Properties.TryGetValue(SetEnvCommandProperties.Name, out string envName) || string.IsNullOrEmpty(envName))
|
||||||
{
|
{
|
||||||
@@ -206,7 +205,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||||
{
|
{
|
||||||
if (!command.Properties.TryGetValue(SetOutputCommandProperties.Name, out string outputName) || string.IsNullOrEmpty(outputName))
|
if (!command.Properties.TryGetValue(SetOutputCommandProperties.Name, out string outputName) || string.IsNullOrEmpty(outputName))
|
||||||
{
|
{
|
||||||
@@ -230,7 +229,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||||
{
|
{
|
||||||
if (!command.Properties.TryGetValue(SaveStateCommandProperties.Name, out string stateName) || string.IsNullOrEmpty(stateName))
|
if (!command.Properties.TryGetValue(SaveStateCommandProperties.Name, out string stateName) || string.IsNullOrEmpty(stateName))
|
||||||
{
|
{
|
||||||
@@ -254,7 +253,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(command.Data))
|
if (string.IsNullOrWhiteSpace(command.Data))
|
||||||
{
|
{
|
||||||
@@ -280,7 +279,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||||
{
|
{
|
||||||
ArgUtil.NotNullOrEmpty(command.Data, "path");
|
ArgUtil.NotNullOrEmpty(command.Data, "path");
|
||||||
context.PrependPath.RemoveAll(x => string.Equals(x, command.Data, StringComparison.CurrentCulture));
|
context.PrependPath.RemoveAll(x => string.Equals(x, command.Data, StringComparison.CurrentCulture));
|
||||||
@@ -295,7 +294,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||||
{
|
{
|
||||||
var file = command.Data;
|
var file = command.Data;
|
||||||
|
|
||||||
@@ -307,9 +306,9 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Translate file path back from container path
|
// Translate file path back from container path
|
||||||
if (container != null)
|
if (context.Container != null)
|
||||||
{
|
{
|
||||||
file = container.TranslateToHostPath(file);
|
file = context.Container.TranslateToHostPath(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Root the path
|
// Root the path
|
||||||
@@ -342,7 +341,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||||
{
|
{
|
||||||
command.Properties.TryGetValue(RemoveMatcherCommandProperties.Owner, out string owner);
|
command.Properties.TryGetValue(RemoveMatcherCommandProperties.Owner, out string owner);
|
||||||
var file = command.Data;
|
var file = command.Data;
|
||||||
@@ -370,9 +369,9 @@ namespace GitHub.Runner.Worker
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Translate file path back from container path
|
// Translate file path back from container path
|
||||||
if (container != null)
|
if (context.Container != null)
|
||||||
{
|
{
|
||||||
file = container.TranslateToHostPath(file);
|
file = context.Container.TranslateToHostPath(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Root the path
|
// Root the path
|
||||||
@@ -410,7 +409,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command)
|
||||||
{
|
{
|
||||||
context.Debug(command.Data);
|
context.Debug(command.Data);
|
||||||
}
|
}
|
||||||
@@ -438,7 +437,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command)
|
||||||
{
|
{
|
||||||
command.Properties.TryGetValue(IssueCommandProperties.File, out string file);
|
command.Properties.TryGetValue(IssueCommandProperties.File, out string file);
|
||||||
command.Properties.TryGetValue(IssueCommandProperties.Line, out string line);
|
command.Properties.TryGetValue(IssueCommandProperties.Line, out string line);
|
||||||
@@ -455,10 +454,10 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
issue.Category = "Code";
|
issue.Category = "Code";
|
||||||
|
|
||||||
if (container != null)
|
if (context.Container != null)
|
||||||
{
|
{
|
||||||
// Translate file path back from container path
|
// Translate file path back from container path
|
||||||
file = container.TranslateToHostPath(file);
|
file = context.Container.TranslateToHostPath(file);
|
||||||
command.Properties[IssueCommandProperties.File] = file;
|
command.Properties[IssueCommandProperties.File] = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,7 +517,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||||
{
|
{
|
||||||
var data = this is GroupCommandExtension ? command.Data : string.Empty;
|
var data = this is GroupCommandExtension ? command.Data : string.Empty;
|
||||||
context.Output($"##[{Command}]{data}");
|
context.Output($"##[{Command}]{data}");
|
||||||
@@ -532,7 +531,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||||
{
|
{
|
||||||
ArgUtil.NotNullOrEmpty(command.Data, "value");
|
ArgUtil.NotNullOrEmpty(command.Data, "value");
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
{
|
{
|
||||||
// This does not need to be inside of a critical section.
|
// This does not need to be inside of a critical section.
|
||||||
// The logging queues and command handlers are thread-safe.
|
// The logging queues and command handlers are thread-safe.
|
||||||
if (_commandManager.TryProcessCommand(_executionContext, line, _container))
|
if (_commandManager.TryProcessCommand(_executionContext, line))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,8 +175,8 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
|||||||
Assert.True(s.PoolId.Equals(_expectedPoolId));
|
Assert.True(s.PoolId.Equals(_expectedPoolId));
|
||||||
Assert.True(s.WorkFolder.Equals(_expectedWorkFolder));
|
Assert.True(s.WorkFolder.Equals(_expectedWorkFolder));
|
||||||
|
|
||||||
// validate GetAgentPoolsAsync gets called twice with automation pool type
|
// validate GetAgentPoolsAsync gets called once with automation pool type
|
||||||
_runnerServer.Verify(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.Is<TaskAgentPoolType>(p => p == TaskAgentPoolType.Automation)), Times.Exactly(2));
|
_runnerServer.Verify(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.Is<TaskAgentPoolType>(p => p == TaskAgentPoolType.Automation)), Times.Once);
|
||||||
|
|
||||||
_runnerServer.Verify(x => x.AddAgentAsync(It.IsAny<int>(), It.Is<TaskAgent>(a => a.Labels.Contains("self-hosted") && a.Labels.Contains(VarUtil.OS) && a.Labels.Contains(VarUtil.OSArchitecture))), Times.Once);
|
_runnerServer.Verify(x => x.AddAgentAsync(It.IsAny<int>(), It.Is<TaskAgent>(a => a.Labels.Contains("self-hosted") && a.Labels.Contains(VarUtil.OS) && a.Labels.Contains(VarUtil.OSArchitecture))), Times.Once);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using GitHub.Runner.Worker;
|
using GitHub.Runner.Worker;
|
||||||
using GitHub.Runner.Worker.Container;
|
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||||
@@ -13,35 +11,47 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
{
|
{
|
||||||
public sealed class ActionCommandManagerL0
|
public sealed class ActionCommandManagerL0
|
||||||
{
|
{
|
||||||
private ActionCommandManager _commandManager;
|
|
||||||
private Mock<IExecutionContext> _ec;
|
|
||||||
private Mock<IExtensionManager> _extensionManager;
|
|
||||||
private Mock<IPipelineDirectoryManager> _pipelineDirectoryManager;
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void EnablePluginInternalCommand()
|
public void EnablePluginInternalCommand()
|
||||||
{
|
{
|
||||||
using (TestHostContext hc = CreateTestContext())
|
using (TestHostContext _hc = new TestHostContext(this))
|
||||||
{
|
{
|
||||||
|
var extensionManger = new Mock<IExtensionManager>();
|
||||||
|
var directoryManager = new Mock<IPipelineDirectoryManager>();
|
||||||
|
|
||||||
|
var pluginCommand = new InternalPluginSetRepoPathCommandExtension();
|
||||||
|
pluginCommand.Initialize(_hc);
|
||||||
|
|
||||||
|
var envCommand = new SetEnvCommandExtension();
|
||||||
|
envCommand.Initialize(_hc);
|
||||||
|
|
||||||
|
extensionManger.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
||||||
|
.Returns(new List<IActionCommandExtension>() { pluginCommand, envCommand });
|
||||||
|
_hc.SetSingleton<IExtensionManager>(extensionManger.Object);
|
||||||
|
_hc.SetSingleton<IPipelineDirectoryManager>(directoryManager.Object);
|
||||||
|
|
||||||
|
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns((string tag, string line) =>
|
.Returns((string tag, string line) =>
|
||||||
{
|
{
|
||||||
hc.GetTrace().Info($"{tag} {line}");
|
_hc.GetTrace().Info($"{tag} {line}");
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
||||||
.Callback((Issue issue, string message) =>
|
.Callback((Issue issue, string message) =>
|
||||||
{
|
{
|
||||||
hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
_hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
||||||
});
|
});
|
||||||
|
ActionCommandManager commandManager = new ActionCommandManager();
|
||||||
|
commandManager.Initialize(_hc);
|
||||||
|
|
||||||
_commandManager.EnablePluginInternalCommand();
|
commandManager.EnablePluginInternalCommand();
|
||||||
|
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath", null));
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath"));
|
||||||
|
|
||||||
_pipelineDirectoryManager.Verify(x => x.UpdateRepositoryDirectory(_ec.Object, "actions/runner", "somepath", true), Times.Once);
|
directoryManager.Verify(x => x.UpdateRepositoryDirectory(_ec.Object, "actions/runner", "somepath", true), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,29 +60,47 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void DisablePluginInternalCommand()
|
public void DisablePluginInternalCommand()
|
||||||
{
|
{
|
||||||
using (TestHostContext hc = CreateTestContext())
|
using (TestHostContext _hc = new TestHostContext(this))
|
||||||
{
|
{
|
||||||
|
var extensionManger = new Mock<IExtensionManager>();
|
||||||
|
var directoryManager = new Mock<IPipelineDirectoryManager>();
|
||||||
|
|
||||||
|
var pluginCommand = new InternalPluginSetRepoPathCommandExtension();
|
||||||
|
pluginCommand.Initialize(_hc);
|
||||||
|
|
||||||
|
var envCommand = new SetEnvCommandExtension();
|
||||||
|
envCommand.Initialize(_hc);
|
||||||
|
|
||||||
|
extensionManger.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
||||||
|
.Returns(new List<IActionCommandExtension>() { pluginCommand, envCommand });
|
||||||
|
|
||||||
|
_hc.SetSingleton<IExtensionManager>(extensionManger.Object);
|
||||||
|
_hc.SetSingleton<IPipelineDirectoryManager>(directoryManager.Object);
|
||||||
|
|
||||||
|
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns((string tag, string line) =>
|
.Returns((string tag, string line) =>
|
||||||
{
|
{
|
||||||
hc.GetTrace().Info($"{tag} {line}");
|
_hc.GetTrace().Info($"{tag} {line}");
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
||||||
.Callback((Issue issue, string message) =>
|
.Callback((Issue issue, string message) =>
|
||||||
{
|
{
|
||||||
hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
_hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
||||||
});
|
});
|
||||||
|
ActionCommandManager commandManager = new ActionCommandManager();
|
||||||
|
commandManager.Initialize(_hc);
|
||||||
|
|
||||||
_commandManager.EnablePluginInternalCommand();
|
commandManager.EnablePluginInternalCommand();
|
||||||
|
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath", null));
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath"));
|
||||||
|
|
||||||
_commandManager.DisablePluginInternalCommand();
|
commandManager.DisablePluginInternalCommand();
|
||||||
|
|
||||||
Assert.False(_commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath", null));
|
Assert.False(commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath"));
|
||||||
|
|
||||||
_pipelineDirectoryManager.Verify(x => x.UpdateRepositoryDirectory(_ec.Object, "actions/runner", "somepath", true), Times.Once);
|
directoryManager.Verify(x => x.UpdateRepositoryDirectory(_ec.Object, "actions/runner", "somepath", true), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,27 +109,42 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void StopProcessCommand()
|
public void StopProcessCommand()
|
||||||
{
|
{
|
||||||
using (TestHostContext hc = CreateTestContext())
|
using (TestHostContext _hc = new TestHostContext(this))
|
||||||
{
|
{
|
||||||
|
var extensionManger = new Mock<IExtensionManager>();
|
||||||
|
var pluginCommand = new InternalPluginSetRepoPathCommandExtension();
|
||||||
|
pluginCommand.Initialize(_hc);
|
||||||
|
|
||||||
|
var envCommand = new SetEnvCommandExtension();
|
||||||
|
envCommand.Initialize(_hc);
|
||||||
|
|
||||||
|
extensionManger.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
||||||
|
.Returns(new List<IActionCommandExtension>() { pluginCommand, envCommand });
|
||||||
|
_hc.SetSingleton<IExtensionManager>(extensionManger.Object);
|
||||||
|
|
||||||
|
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns((string tag, string line) =>
|
.Returns((string tag, string line) =>
|
||||||
{
|
{
|
||||||
hc.GetTrace().Info($"{tag} {line}");
|
_hc.GetTrace().Info($"{tag} {line}");
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
||||||
.Callback((Issue issue, string message) =>
|
.Callback((Issue issue, string message) =>
|
||||||
{
|
{
|
||||||
hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
_hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
||||||
});
|
});
|
||||||
|
|
||||||
_ec.Setup(x => x.EnvironmentVariables).Returns(new Dictionary<string, string>());
|
_ec.Setup(x => x.EnvironmentVariables).Returns(new Dictionary<string, string>());
|
||||||
|
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[stop-commands]stopToken", null));
|
ActionCommandManager commandManager = new ActionCommandManager();
|
||||||
Assert.False(_commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar", null));
|
commandManager.Initialize(_hc);
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[stopToken]", null));
|
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar", null));
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[stop-commands]stopToken"));
|
||||||
|
Assert.False(commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar"));
|
||||||
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[stopToken]"));
|
||||||
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,29 +153,41 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void EchoProcessCommand()
|
public void EchoProcessCommand()
|
||||||
{
|
{
|
||||||
using (TestHostContext hc = CreateTestContext())
|
using (TestHostContext _hc = new TestHostContext(this))
|
||||||
{
|
{
|
||||||
|
var extensionManager = new Mock<IExtensionManager>();
|
||||||
|
var echoCommand = new EchoCommandExtension();
|
||||||
|
echoCommand.Initialize(_hc);
|
||||||
|
|
||||||
|
extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
||||||
|
.Returns(new List<IActionCommandExtension>() { echoCommand });
|
||||||
|
_hc.SetSingleton<IExtensionManager>(extensionManager.Object);
|
||||||
|
|
||||||
|
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns((string tag, string line) =>
|
.Returns((string tag, string line) =>
|
||||||
{
|
{
|
||||||
hc.GetTrace().Info($"{tag} {line}");
|
_hc.GetTrace().Info($"{tag} {line}");
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
_ec.SetupAllProperties();
|
_ec.SetupAllProperties();
|
||||||
|
|
||||||
|
ActionCommandManager commandManager = new ActionCommandManager();
|
||||||
|
commandManager.Initialize(_hc);
|
||||||
|
|
||||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::on", null));
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::on"));
|
||||||
Assert.True(_ec.Object.EchoOnActionCommand);
|
Assert.True(_ec.Object.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::off", null));
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::off"));
|
||||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::ON", null));
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::ON"));
|
||||||
Assert.True(_ec.Object.EchoOnActionCommand);
|
Assert.True(_ec.Object.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::Off ", null));
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::Off "));
|
||||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,7 +197,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void EchoProcessCommandDebugOn()
|
public void EchoProcessCommandDebugOn()
|
||||||
{
|
{
|
||||||
using (TestHostContext hc = CreateTestContext())
|
using (TestHostContext _hc = new TestHostContext(this))
|
||||||
{
|
{
|
||||||
// Set up a few things
|
// Set up a few things
|
||||||
// 1. Job request message (with ACTIONS_STEP_DEBUG = true)
|
// 1. Job request message (with ACTIONS_STEP_DEBUG = true)
|
||||||
@@ -164,135 +219,84 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
var jobServerQueue = new Mock<IJobServerQueue>();
|
var jobServerQueue = new Mock<IJobServerQueue>();
|
||||||
jobServerQueue.Setup(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.IsAny<TimelineRecord>()));
|
jobServerQueue.Setup(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.IsAny<TimelineRecord>()));
|
||||||
|
|
||||||
hc.SetSingleton(jobServerQueue.Object);
|
_hc.SetSingleton(jobServerQueue.Object);
|
||||||
|
|
||||||
|
var extensionManager = new Mock<IExtensionManager>();
|
||||||
|
var echoCommand = new EchoCommandExtension();
|
||||||
|
echoCommand.Initialize(_hc);
|
||||||
|
|
||||||
|
extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
||||||
|
.Returns(new List<IActionCommandExtension>() { echoCommand });
|
||||||
|
_hc.SetSingleton<IExtensionManager>(extensionManager.Object);
|
||||||
|
|
||||||
var configurationStore = new Mock<IConfigurationStore>();
|
var configurationStore = new Mock<IConfigurationStore>();
|
||||||
configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings());
|
configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings());
|
||||||
hc.SetSingleton(configurationStore.Object);
|
_hc.SetSingleton(configurationStore.Object);
|
||||||
|
|
||||||
var pagingLogger = new Mock<IPagingLogger>();
|
var pagingLogger = new Mock<IPagingLogger>();
|
||||||
hc.EnqueueInstance(pagingLogger.Object);
|
_hc.EnqueueInstance(pagingLogger.Object);
|
||||||
|
|
||||||
|
ActionCommandManager commandManager = new ActionCommandManager();
|
||||||
|
commandManager.Initialize(_hc);
|
||||||
|
|
||||||
|
var _ec = new Runner.Worker.ExecutionContext();
|
||||||
|
_ec.Initialize(_hc);
|
||||||
|
|
||||||
// Initialize the job (to exercise logic that sets EchoOnActionCommand)
|
// Initialize the job (to exercise logic that sets EchoOnActionCommand)
|
||||||
var ec = new Runner.Worker.ExecutionContext();
|
_ec.InitializeJob(jobRequest, System.Threading.CancellationToken.None);
|
||||||
ec.Initialize(hc);
|
|
||||||
ec.InitializeJob(jobRequest, System.Threading.CancellationToken.None);
|
|
||||||
|
|
||||||
ec.Complete();
|
_ec.Complete();
|
||||||
|
|
||||||
Assert.True(ec.EchoOnActionCommand);
|
Assert.True(_ec.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(_commandManager.TryProcessCommand(ec, "::echo::off", null));
|
Assert.True(commandManager.TryProcessCommand(_ec, "::echo::off"));
|
||||||
Assert.False(ec.EchoOnActionCommand);
|
Assert.False(_ec.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(_commandManager.TryProcessCommand(ec, "::echo::on", null));
|
Assert.True(commandManager.TryProcessCommand(_ec, "::echo::on"));
|
||||||
Assert.True(ec.EchoOnActionCommand);
|
Assert.True(_ec.EchoOnActionCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void EchoProcessCommandInvalid()
|
public void EchoProcessCommandInvalid()
|
||||||
{
|
{
|
||||||
using (TestHostContext hc = CreateTestContext())
|
using (TestHostContext _hc = new TestHostContext(this))
|
||||||
{
|
{
|
||||||
|
var extensionManager = new Mock<IExtensionManager>();
|
||||||
|
var echoCommand = new EchoCommandExtension();
|
||||||
|
echoCommand.Initialize(_hc);
|
||||||
|
|
||||||
|
extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
||||||
|
.Returns(new List<IActionCommandExtension>() { echoCommand });
|
||||||
|
_hc.SetSingleton<IExtensionManager>(extensionManager.Object);
|
||||||
|
|
||||||
|
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns((string tag, string line) =>
|
.Returns((string tag, string line) =>
|
||||||
{
|
{
|
||||||
hc.GetTrace().Info($"{tag} {line}");
|
_hc.GetTrace().Info($"{tag} {line}");
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
_ec.SetupAllProperties();
|
_ec.SetupAllProperties();
|
||||||
|
|
||||||
|
ActionCommandManager commandManager = new ActionCommandManager();
|
||||||
|
commandManager.Initialize(_hc);
|
||||||
|
|
||||||
// Echo commands below are considered "processed", but are invalid
|
// Echo commands below are considered "processed", but are invalid
|
||||||
// 1. Invalid echo value
|
// 1. Invalid echo value
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::invalid", null));
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::invalid"));
|
||||||
Assert.Equal(TaskResult.Failed, _ec.Object.CommandResult);
|
Assert.Equal(TaskResult.Failed, _ec.Object.CommandResult);
|
||||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||||
|
|
||||||
// 2. No value
|
// 2. No value
|
||||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::", null));
|
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::"));
|
||||||
Assert.Equal(TaskResult.Failed, _ec.Object.CommandResult);
|
Assert.Equal(TaskResult.Failed, _ec.Object.CommandResult);
|
||||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
[Trait("Level", "L0")]
|
|
||||||
[Trait("Category", "Worker")]
|
|
||||||
public void AddMatcherTranslatesFilePath()
|
|
||||||
{
|
|
||||||
using (TestHostContext hc = CreateTestContext())
|
|
||||||
{
|
|
||||||
// Create a problem matcher config file
|
|
||||||
var hostDirectory = hc.GetDirectory(WellKnownDirectory.Temp);
|
|
||||||
var hostFile = Path.Combine(hostDirectory, "my-matcher.json");
|
|
||||||
Directory.CreateDirectory(hostDirectory);
|
|
||||||
var content = @"
|
|
||||||
{
|
|
||||||
""problemMatcher"": [
|
|
||||||
{
|
|
||||||
""owner"": ""my-matcher"",
|
|
||||||
""pattern"": [
|
|
||||||
{
|
|
||||||
""regexp"": ""^ERROR: (.+)$"",
|
|
||||||
""message"": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}";
|
|
||||||
File.WriteAllText(hostFile, content);
|
|
||||||
|
|
||||||
// Setup translation info
|
|
||||||
var container = new ContainerInfo();
|
|
||||||
var containerDirectory = "/some-container-directory";
|
|
||||||
var containerFile = Path.Combine(containerDirectory, "my-matcher.json");
|
|
||||||
container.AddPathTranslateMapping(hostDirectory, containerDirectory);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
_commandManager.TryProcessCommand(_ec.Object, $"::add-matcher::{containerFile}", container);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
_ec.Verify(x => x.AddMatchers(It.IsAny<IssueMatchersConfig>()), Times.Once);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TestHostContext CreateTestContext([CallerMemberName] string testName = "")
|
|
||||||
{
|
|
||||||
var hostContext = new TestHostContext(this, testName);
|
|
||||||
|
|
||||||
// Mock extension manager
|
|
||||||
_extensionManager = new Mock<IExtensionManager>();
|
|
||||||
var commands = new IActionCommandExtension[]
|
|
||||||
{
|
|
||||||
new AddMatcherCommandExtension(),
|
|
||||||
new EchoCommandExtension(),
|
|
||||||
new InternalPluginSetRepoPathCommandExtension(),
|
|
||||||
new SetEnvCommandExtension(),
|
|
||||||
};
|
|
||||||
foreach (var command in commands)
|
|
||||||
{
|
|
||||||
command.Initialize(hostContext);
|
|
||||||
}
|
|
||||||
_extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
|
||||||
.Returns(new List<IActionCommandExtension>(commands));
|
|
||||||
hostContext.SetSingleton<IExtensionManager>(_extensionManager.Object);
|
|
||||||
|
|
||||||
// Mock pipeline directory manager
|
|
||||||
_pipelineDirectoryManager = new Mock<IPipelineDirectoryManager>();
|
|
||||||
hostContext.SetSingleton<IPipelineDirectoryManager>(_pipelineDirectoryManager.Object);
|
|
||||||
|
|
||||||
// Execution context
|
|
||||||
_ec = new Mock<IExecutionContext>();
|
|
||||||
|
|
||||||
// Command manager
|
|
||||||
_commandManager = new ActionCommandManager();
|
|
||||||
_commandManager.Initialize(hostContext);
|
|
||||||
|
|
||||||
return hostContext;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -973,8 +973,8 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
});
|
});
|
||||||
|
|
||||||
_commandManager = new Mock<IActionCommandManager>();
|
_commandManager = new Mock<IActionCommandManager>();
|
||||||
_commandManager.Setup(x => x.TryProcessCommand(It.IsAny<IExecutionContext>(), It.IsAny<string>(), It.IsAny<ContainerInfo>()))
|
_commandManager.Setup(x => x.TryProcessCommand(It.IsAny<IExecutionContext>(), It.IsAny<string>()))
|
||||||
.Returns((IExecutionContext executionContext, string line, ContainerInfo container) =>
|
.Returns((IExecutionContext executionContext, string line) =>
|
||||||
{
|
{
|
||||||
if (line.IndexOf("##[some-command]") >= 0)
|
if (line.IndexOf("##[some-command]") >= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
11
src/dev.cmd
11
src/dev.cmd
@@ -1,16 +1,5 @@
|
|||||||
@setlocal
|
@setlocal
|
||||||
@echo off
|
@echo off
|
||||||
rem add expected utils to path
|
|
||||||
IF EXIST C:\Program Files\Git\usr\bin (
|
|
||||||
SET PATH=C:\Program Files\Git\usr\bin;%PATH%
|
|
||||||
)
|
|
||||||
IF EXIST C:\Program Files\Git\mingw64\bin (
|
|
||||||
SET PATH=C:\Program Files\Git\mingw64\bin;%PATH%
|
|
||||||
)
|
|
||||||
IF EXIST C:\Program Files\Git\bin (
|
|
||||||
SET PATH=C:\Program Files\Git\bin;%PATH%
|
|
||||||
)
|
|
||||||
|
|
||||||
rem Check if SH_PATH is defined.
|
rem Check if SH_PATH is defined.
|
||||||
if defined SH_PATH (
|
if defined SH_PATH (
|
||||||
goto run
|
goto run
|
||||||
|
|||||||
Reference in New Issue
Block a user