Compare commits

..

1 Commits

Author SHA1 Message Date
TingluoHuang
5057893a13 . 2021-11-24 14:58:29 -05:00
16 changed files with 91 additions and 239 deletions

View File

@@ -37,7 +37,7 @@ jobs:
devScript: ./dev.sh devScript: ./dev.sh
- runtime: win-x64 - runtime: win-x64
os: windows-2019 os: windows-latest
devScript: ./dev devScript: ./dev
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}

View File

@@ -72,7 +72,7 @@ jobs:
devScript: ./dev.sh devScript: ./dev.sh
- runtime: win-x64 - runtime: win-x64
os: windows-2019 os: windows-latest
devScript: ./dev devScript: ./dev
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
@@ -164,7 +164,6 @@ jobs:
release_name: "v${{ steps.releaseNote.outputs.version }}" release_name: "v${{ steps.releaseNote.outputs.version }}"
body: | body: |
${{ steps.releaseNote.outputs.note }} ${{ steps.releaseNote.outputs.note }}
prerelease: true
# Upload release assets # Upload release assets
- name: Upload Release Asset (win-x64) - name: Upload Release Asset (win-x64)

View File

@@ -1,17 +1,19 @@
## Features ## Features
- n/a - Expose GITHUB_REF_* as environment variable (#1314)
- Add arch to runner context (#1372)
- Support Conditional Steps in Composite Actions (#1438)
- Log current runner version in terminal (#1441)
## Bugs ## Bugs
- Fixed an issue where container environment variables names or values could escape the docker command (#2108) - Makes the user keychains available to the service (#847)
- Sanitize Windows ENVs (#2280) - Use Actions Service health and api.github.com endpoints after connection failure on Actions Server and Hosted (#1385)
- Fix an issue where nested local composite actions did not correctly register post steps (#1433)
## Misc ## Misc
- n/a - Cleanup Older versions on MacOS now that we recreate node versions as needed (#1410)
## 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 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.

View File

@@ -1 +1 @@
2.285.3 <Update to ./src/runnerversion when creating release>

View File

@@ -3,7 +3,7 @@ PACKAGERUNTIME=$1
PRECACHE=$2 PRECACHE=$2
NODE_URL=https://nodejs.org/dist NODE_URL=https://nodejs.org/dist
NODE12_VERSION="12.13.1" NODE12_VERSION="12.22.7"
NODE16_VERSION="16.13.0" NODE16_VERSION="16.13.0"
get_abs_path() { get_abs_path() {
@@ -143,7 +143,7 @@ fi
# Download the external tools for Linux PACKAGERUNTIMEs. # Download the external tools for Linux PACKAGERUNTIMEs.
if [[ "$PACKAGERUNTIME" == "linux-x64" ]]; then if [[ "$PACKAGERUNTIME" == "linux-x64" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-x64.tar.gz" node12 fix_nested_dir acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-x64.tar.gz" node12 fix_nested_dir
acquireExternalTool "https://vstsagenttools.blob.core.windows.net/tools/nodejs/${NODE12_VERSION}/alpine/x64/node-${NODE12_VERSION}-alpine-x64.tar.gz" node12_alpine acquireExternalTool "https://vstsagenttools.blob.core.windows.net/tools/nodejs/${NODE12_VERSION}/alpine/x64/node-v${NODE12_VERSION}-alpine-x64.tar.gz" node12_alpine
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-linux-x64.tar.gz" node16 fix_nested_dir acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-linux-x64.tar.gz" node16 fix_nested_dir
acquireExternalTool "https://vstsagenttools.blob.core.windows.net/tools/nodejs/${NODE16_VERSION}/alpine/x64/node-v${NODE16_VERSION}-alpine-x64.tar.gz" node16_alpine acquireExternalTool "https://vstsagenttools.blob.core.windows.net/tools/nodejs/${NODE16_VERSION}/alpine/x64/node-v${NODE16_VERSION}-alpine-x64.tar.gz" node16_alpine
fi fi

View File

@@ -9,6 +9,7 @@ using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Loader; using System.Runtime.Loader;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -25,8 +26,8 @@ namespace GitHub.Runner.Common
ISecretMasker SecretMasker { get; } ISecretMasker SecretMasker { get; }
List<ProductInfoHeaderValue> UserAgents { get; } List<ProductInfoHeaderValue> UserAgents { get; }
RunnerWebProxy WebProxy { get; } RunnerWebProxy WebProxy { get; }
string GetDirectory(WellKnownDirectory directory); string GetDirectory(WellKnownDirectory directory, string rootCaller = "", [CallerMemberName] string caller = "");
string GetConfigFile(WellKnownConfigFile configFile); string GetConfigFile(WellKnownConfigFile configFile, string rootCaller = "", [CallerMemberName] string caller = "");
Tracing GetTrace(string name); Tracing GetTrace(string name);
Task Delay(TimeSpan delay, CancellationToken cancellationToken); Task Delay(TimeSpan delay, CancellationToken cancellationToken);
T CreateService<T>() where T : class, IRunnerService; T CreateService<T>() where T : class, IRunnerService;
@@ -213,8 +214,13 @@ namespace GitHub.Runner.Common
} }
} }
public string GetDirectory(WellKnownDirectory directory) public string GetDirectory(WellKnownDirectory directory, string rootCaller = "", [CallerMemberName] string caller = "")
{ {
if (string.IsNullOrEmpty(rootCaller))
{
rootCaller = caller;
}
string path; string path;
switch (directory) switch (directory)
{ {
@@ -224,29 +230,29 @@ namespace GitHub.Runner.Common
case WellKnownDirectory.Diag: case WellKnownDirectory.Diag:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
Constants.Path.DiagDirectory); Constants.Path.DiagDirectory);
break; break;
case WellKnownDirectory.Externals: case WellKnownDirectory.Externals:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
Constants.Path.ExternalsDirectory); Constants.Path.ExternalsDirectory);
break; break;
case WellKnownDirectory.Root: case WellKnownDirectory.Root:
path = new DirectoryInfo(GetDirectory(WellKnownDirectory.Bin)).Parent.FullName; path = new DirectoryInfo(GetDirectory(WellKnownDirectory.Bin, rootCaller)).Parent.FullName;
break; break;
case WellKnownDirectory.Temp: case WellKnownDirectory.Temp:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Work), GetDirectory(WellKnownDirectory.Work, rootCaller),
Constants.Path.TempDirectory); Constants.Path.TempDirectory);
break; break;
case WellKnownDirectory.Actions: case WellKnownDirectory.Actions:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Work), GetDirectory(WellKnownDirectory.Work, rootCaller),
Constants.Path.ActionsDirectory); Constants.Path.ActionsDirectory);
break; break;
@@ -257,14 +263,14 @@ namespace GitHub.Runner.Common
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))
{ {
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Work), GetDirectory(WellKnownDirectory.Work, rootCaller),
Constants.Path.ToolDirectory); Constants.Path.ToolDirectory);
} }
break; break;
case WellKnownDirectory.Update: case WellKnownDirectory.Update:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Work), GetDirectory(WellKnownDirectory.Work, rootCaller),
Constants.Path.UpdateDirectory); Constants.Path.UpdateDirectory);
break; break;
@@ -274,94 +280,99 @@ namespace GitHub.Runner.Common
ArgUtil.NotNull(settings, nameof(settings)); ArgUtil.NotNull(settings, nameof(settings));
ArgUtil.NotNullOrEmpty(settings.WorkFolder, nameof(settings.WorkFolder)); ArgUtil.NotNullOrEmpty(settings.WorkFolder, nameof(settings.WorkFolder));
path = Path.GetFullPath(Path.Combine( path = Path.GetFullPath(Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
settings.WorkFolder)); settings.WorkFolder));
break; break;
default: default:
throw new NotSupportedException($"Unexpected well known directory: '{directory}'"); throw new NotSupportedException($"Unexpected well known directory: '{directory}' ({rootCaller})");
} }
_trace.Info($"Well known directory '{directory}': '{path}'"); _trace.Info($"Well known directory '{directory}': '{path}' ({rootCaller})");
return path; return path;
} }
public string GetConfigFile(WellKnownConfigFile configFile) public string GetConfigFile(WellKnownConfigFile configFile, string rootCaller = "", [CallerMemberName] string caller = "")
{ {
if (string.IsNullOrEmpty(rootCaller))
{
rootCaller = caller;
}
string path; string path;
switch (configFile) switch (configFile)
{ {
case WellKnownConfigFile.Runner: case WellKnownConfigFile.Runner:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".runner"); ".runner");
break; break;
case WellKnownConfigFile.Credentials: case WellKnownConfigFile.Credentials:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".credentials"); ".credentials");
break; break;
case WellKnownConfigFile.MigratedCredentials: case WellKnownConfigFile.MigratedCredentials:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".credentials_migrated"); ".credentials_migrated");
break; break;
case WellKnownConfigFile.RSACredentials: case WellKnownConfigFile.RSACredentials:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".credentials_rsaparams"); ".credentials_rsaparams");
break; break;
case WellKnownConfigFile.Service: case WellKnownConfigFile.Service:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".service"); ".service");
break; break;
case WellKnownConfigFile.CredentialStore: case WellKnownConfigFile.CredentialStore:
#if OS_OSX #if OS_OSX
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".credential_store.keychain"); ".credential_store.keychain");
#else #else
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".credential_store"); ".credential_store");
#endif #endif
break; break;
case WellKnownConfigFile.Certificates: case WellKnownConfigFile.Certificates:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".certificates"); ".certificates");
break; break;
case WellKnownConfigFile.Options: case WellKnownConfigFile.Options:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".options"); ".options");
break; break;
case WellKnownConfigFile.SetupInfo: case WellKnownConfigFile.SetupInfo:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".setup_info"); ".setup_info");
break; break;
case WellKnownConfigFile.Telemetry: case WellKnownConfigFile.Telemetry:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Diag), GetDirectory(WellKnownDirectory.Diag, rootCaller),
".telemetry"); ".telemetry");
break; break;
default: default:
throw new NotSupportedException($"Unexpected well known config file: '{configFile}'"); throw new NotSupportedException($"Unexpected well known config file: '{configFile}' ({rootCaller})");
} }
_trace.Info($"Well known config file '{configFile}': '{path}'"); _trace.Info($"Well known config file '{configFile}': '{path}' ({rootCaller})");
return path; return path;
} }

View File

@@ -264,17 +264,7 @@ namespace GitHub.Runner.Sdk
{ {
foreach (KeyValuePair<string, string> kvp in environment) foreach (KeyValuePair<string, string> kvp in environment)
{ {
#if OS_WINDOWS
string tempKey = String.IsNullOrWhiteSpace(kvp.Key) ? kvp.Key : kvp.Key.Split('\0')[0];
string tempValue = String.IsNullOrWhiteSpace(kvp.Value) ? kvp.Value : kvp.Value.Split('\0')[0];
if(!String.IsNullOrWhiteSpace(tempKey))
{
_proc.StartInfo.Environment[tempKey] = tempValue;
}
#else
_proc.StartInfo.Environment[kvp.Key] = kvp.Value; _proc.StartInfo.Environment[kvp.Key] = kvp.Value;
#endif
} }
} }

View File

@@ -131,11 +131,11 @@ namespace GitHub.Runner.Worker.Container
{ {
if (String.IsNullOrEmpty(env.Value)) if (String.IsNullOrEmpty(env.Value))
{ {
dockerOptions.Add(DockerUtil.CreateEscapedOption("-e", env.Key)); dockerOptions.Add($"-e \"{env.Key}\"");
} }
else else
{ {
dockerOptions.Add(DockerUtil.CreateEscapedOption("-e", env.Key, env.Value)); dockerOptions.Add($"-e \"{env.Key}={env.Value.Replace("\"", "\\\"")}\"");
} }
} }
@@ -202,7 +202,7 @@ namespace GitHub.Runner.Worker.Container
{ {
// e.g. -e MY_SECRET maps the value into the exec'ed process without exposing // e.g. -e MY_SECRET maps the value into the exec'ed process without exposing
// the value directly in the command // the value directly in the command
dockerOptions.Add(DockerUtil.CreateEscapedOption("-e", env.Key)); dockerOptions.Add($"-e {env.Key}");
} }
// Watermark for GitHub Action environment // Watermark for GitHub Action environment

View File

@@ -6,9 +6,6 @@ namespace GitHub.Runner.Worker.Container
{ {
public class DockerUtil public class DockerUtil
{ {
private static readonly Regex QuoteEscape = new Regex(@"(\\*)" + "\"", RegexOptions.Compiled);
private static readonly Regex EndOfStringEscape = new Regex(@"(\\+)$", RegexOptions.Compiled);
public static List<PortMapping> ParseDockerPort(IList<string> portMappingLines) public static List<PortMapping> ParseDockerPort(IList<string> portMappingLines)
{ {
const string targetPort = "targetPort"; const string targetPort = "targetPort";
@@ -20,7 +17,7 @@ namespace GitHub.Runner.Worker.Container
string pattern = $"^(?<{targetPort}>\\d+)/(?<{proto}>\\w+) -> (?<{host}>.+):(?<{hostPort}>\\d+)$"; string pattern = $"^(?<{targetPort}>\\d+)/(?<{proto}>\\w+) -> (?<{host}>.+):(?<{hostPort}>\\d+)$";
List<PortMapping> portMappings = new List<PortMapping>(); List<PortMapping> portMappings = new List<PortMapping>();
foreach (var line in portMappingLines) foreach(var line in portMappingLines)
{ {
Match m = Regex.Match(line, pattern, RegexOptions.None, TimeSpan.FromSeconds(1)); Match m = Regex.Match(line, pattern, RegexOptions.None, TimeSpan.FromSeconds(1));
if (m.Success) if (m.Success)
@@ -64,44 +61,5 @@ namespace GitHub.Runner.Worker.Container
} }
return ""; return "";
} }
public static string CreateEscapedOption(string flag, string key)
{
if (String.IsNullOrEmpty(key))
{
return "";
}
return $"{flag} {EscapeString(key)}";
}
public static string CreateEscapedOption(string flag, string key, string value)
{
if (String.IsNullOrEmpty(key))
{
return "";
}
var escapedString = EscapeString($"{key}={value}");
return $"{flag} {escapedString}";
}
private static string EscapeString(string value)
{
if (String.IsNullOrEmpty(value))
{
return "";
}
// Dotnet escaping rules are weird here, we can only escape \ if it precedes a "
// If a double quotation mark follows two or an even number of backslashes, each proceeding backslash pair is replaced with one backslash and the double quotation mark is removed.
// If a double quotation mark follows an odd number of backslashes, including just one, each preceding pair is replaced with one backslash and the remaining backslash is removed; however, in this case the double quotation mark is not removed.
// https://docs.microsoft.com/en-us/dotnet/api/system.environment.getcommandlineargs?redirectedfrom=MSDN&view=net-6.0#remarks
// First, find any \ followed by a " and double the number of \ + 1.
value = QuoteEscape.Replace(value, @"$1$1\" + "\"");
// Next, what if it ends in `\`, it would escape the end quote. So, we need to detect that at the end of the string and perform the same escape
// Luckily, we can just use the $ character with detects the end of string in regex
value = EndOfStringEscape.Replace(value, @"$1$1");
// Finally, wrap it in quotes
return $"\"{value}\"";
}
} }
} }

View File

@@ -188,7 +188,7 @@ namespace GitHub.Runner.Worker.Handlers
{ {
// e.g. -e MY_SECRET maps the value into the exec'ed process without exposing // e.g. -e MY_SECRET maps the value into the exec'ed process without exposing
// the value directly in the command // the value directly in the command
dockerCommandArgs.Add(DockerUtil.CreateEscapedOption("-e", env.Key)); dockerCommandArgs.Add($"-e {env.Key}");
} }
if (!string.IsNullOrEmpty(PrependPath)) if (!string.IsNullOrEmpty(PrependPath))
{ {

View File

@@ -144,54 +144,5 @@ namespace GitHub.Runner.Common.Tests.Worker.Container
var actual = DockerUtil.ParseRegistryHostnameFromImageName(input); var actual = DockerUtil.ParseRegistryHostnameFromImageName(input);
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
[Theory]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
[InlineData("", "")]
[InlineData("foo", "foo")]
[InlineData("foo \\ bar", "foo \\ bar")]
[InlineData("foo \\", "foo \\\\")]
[InlineData("foo \\\\", "foo \\\\\\\\")]
[InlineData("foo \\\" bar", "foo \\\\\\\" bar")]
[InlineData("foo \\\\\" bar", "foo \\\\\\\\\\\" bar")]
public void CreateEscapedOption_keyOnly(string input, string escaped)
{
var flag = "--example";
var actual = DockerUtil.CreateEscapedOption(flag, input);
string expected;
if (String.IsNullOrEmpty(input))
{
expected = "";
}
else
{
expected = $"{flag} \"{escaped}\"";
}
Assert.Equal(expected, actual);
}
[Theory]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
[InlineData("foo", "bar", "foo=bar")]
[InlineData("foo\\", "bar", "foo\\=bar")]
[InlineData("foo\\", "bar\\", "foo\\=bar\\\\")]
[InlineData("foo \\","bar \\", "foo \\=bar \\\\")]
public void CreateEscapedOption_keyValue(string keyInput, string valueInput, string escapedString)
{
var flag = "--example";
var actual = DockerUtil.CreateEscapedOption(flag, keyInput, valueInput);
string expected;
if (String.IsNullOrEmpty(keyInput))
{
expected = "";
}
else
{
expected = $"{flag} \"{escapedString}\"";
}
Assert.Equal(expected, actual);
}
} }
} }

View File

@@ -129,76 +129,7 @@ namespace GitHub.Runner.Common.Tests
} }
} }
} }
#if OS_WINDOWS
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Common")]
public async Task SetTestEnvWithNullInKey()
{
using (TestHostContext hc = new TestHostContext(this))
{
Tracing trace = hc.GetTrace();
Int32 exitCode = -1;
var processInvoker = new ProcessInvokerWrapper();
processInvoker.Initialize(hc);
var stdout = new List<string>();
var stderr = new List<string>();
processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) =>
{
trace.Info(e.Data);
stdout.Add(e.Data);
};
processInvoker.ErrorDataReceived += (object sender, ProcessDataReceivedEventArgs e) =>
{
trace.Info(e.Data);
stderr.Add(e.Data);
};
exitCode = await processInvoker.ExecuteAsync("", "cmd.exe", "/c \"echo %TEST%\"", new Dictionary<string, string>() { { "TEST\0second", "first" } }, CancellationToken.None);
trace.Info("Exit Code: {0}", exitCode);
Assert.Equal(0, exitCode);
Assert.Equal("first", stdout.First(x => !string.IsNullOrWhiteSpace(x)));
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Common")]
public async Task SetTestEnvWithNullInValue()
{
using (TestHostContext hc = new TestHostContext(this))
{
Tracing trace = hc.GetTrace();
Int32 exitCode = -1;
var processInvoker = new ProcessInvokerWrapper();
processInvoker.Initialize(hc);
var stdout = new List<string>();
var stderr = new List<string>();
processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) =>
{
trace.Info(e.Data);
stdout.Add(e.Data);
};
processInvoker.ErrorDataReceived += (object sender, ProcessDataReceivedEventArgs e) =>
{
trace.Info(e.Data);
stderr.Add(e.Data);
};
exitCode = await processInvoker.ExecuteAsync("", "cmd.exe", "/c \"echo %TEST%\"", new Dictionary<string, string>() { { "TEST", "first\0second" } }, CancellationToken.None);
trace.Info("Exit Code: {0}", exitCode);
Assert.Equal(0, exitCode);
Assert.Equal("first", stdout.First(x => !string.IsNullOrWhiteSpace(x)));
}
}
#endif
[Fact] [Fact]
[Trait("Level", "L0")] [Trait("Level", "L0")]
[Trait("Category", "Common")] [Trait("Category", "Common")]
@@ -266,7 +197,7 @@ namespace GitHub.Runner.Common.Tests
#if OS_WINDOWS #if OS_WINDOWS
execTask = processInvoker.ExecuteAsync("", "cmd.exe", $"/c \"choice /T {SecondsToRun} /D y\"", null, tokenSource.Token); execTask = processInvoker.ExecuteAsync("", "cmd.exe", $"/c \"choice /T {SecondsToRun} /D y\"", null, tokenSource.Token);
#else #else
execTask = processInvoker.ExecuteAsync("", "bash", $"-c \"sleep {SecondsToRun}\"", null, tokenSource.Token); execTask = processInvoker.ExecuteAsync("", "bash", $"-c \"sleep {SecondsToRun}s\"", null, tokenSource.Token);
#endif #endif
await Task.Delay(500); await Task.Delay(500);
tokenSource.Cancel(); tokenSource.Cancel();

View File

@@ -159,8 +159,13 @@ namespace GitHub.Runner.Common.Tests
_serviceSingletons[typeof(T)] = singleton; _serviceSingletons[typeof(T)] = singleton;
} }
public string GetDirectory(WellKnownDirectory directory) public string GetDirectory(WellKnownDirectory directory, string rootCaller = "", [CallerMemberName] string caller = "")
{ {
if (string.IsNullOrEmpty(rootCaller))
{
rootCaller = caller;
}
string path; string path;
switch (directory) switch (directory)
{ {
@@ -170,13 +175,13 @@ namespace GitHub.Runner.Common.Tests
case WellKnownDirectory.Diag: case WellKnownDirectory.Diag:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
Constants.Path.DiagDirectory); Constants.Path.DiagDirectory);
break; break;
case WellKnownDirectory.Externals: case WellKnownDirectory.Externals:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
Constants.Path.ExternalsDirectory); Constants.Path.ExternalsDirectory);
break; break;
@@ -186,13 +191,13 @@ namespace GitHub.Runner.Common.Tests
case WellKnownDirectory.Temp: case WellKnownDirectory.Temp:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Work), GetDirectory(WellKnownDirectory.Work, rootCaller),
Constants.Path.TempDirectory); Constants.Path.TempDirectory);
break; break;
case WellKnownDirectory.Actions: case WellKnownDirectory.Actions:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Work), GetDirectory(WellKnownDirectory.Work, rootCaller),
Constants.Path.ActionsDirectory); Constants.Path.ActionsDirectory);
break; break;
@@ -202,14 +207,14 @@ namespace GitHub.Runner.Common.Tests
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))
{ {
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Work), GetDirectory(WellKnownDirectory.Work, rootCaller),
Constants.Path.ToolDirectory); Constants.Path.ToolDirectory);
} }
break; break;
case WellKnownDirectory.Update: case WellKnownDirectory.Update:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Work), GetDirectory(WellKnownDirectory.Work, rootCaller),
Constants.Path.UpdateDirectory); Constants.Path.UpdateDirectory);
break; break;
@@ -223,66 +228,71 @@ namespace GitHub.Runner.Common.Tests
throw new NotSupportedException($"Unexpected well known directory: '{directory}'"); throw new NotSupportedException($"Unexpected well known directory: '{directory}'");
} }
_trace.Info($"Well known directory '{directory}': '{path}'"); _trace.Info($"Well known directory '{directory}': '{path}' ({rootCaller})");
return path; return path;
} }
public string GetConfigFile(WellKnownConfigFile configFile) public string GetConfigFile(WellKnownConfigFile configFile, string rootCaller = "", [CallerMemberName] string caller = "")
{ {
if (string.IsNullOrEmpty(rootCaller))
{
rootCaller = caller;
}
string path; string path;
switch (configFile) switch (configFile)
{ {
case WellKnownConfigFile.Runner: case WellKnownConfigFile.Runner:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".agent"); ".agent");
break; break;
case WellKnownConfigFile.Credentials: case WellKnownConfigFile.Credentials:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".credentials"); ".credentials");
break; break;
case WellKnownConfigFile.RSACredentials: case WellKnownConfigFile.RSACredentials:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".credentials_rsaparams"); ".credentials_rsaparams");
break; break;
case WellKnownConfigFile.Service: case WellKnownConfigFile.Service:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".service"); ".service");
break; break;
case WellKnownConfigFile.CredentialStore: case WellKnownConfigFile.CredentialStore:
#if OS_OSX #if OS_OSX
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".credential_store.keychain"); ".credential_store.keychain");
#else #else
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".credential_store"); ".credential_store");
#endif #endif
break; break;
case WellKnownConfigFile.Certificates: case WellKnownConfigFile.Certificates:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".certificates"); ".certificates");
break; break;
case WellKnownConfigFile.Options: case WellKnownConfigFile.Options:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".options"); ".options");
break; break;
case WellKnownConfigFile.SetupInfo: case WellKnownConfigFile.SetupInfo:
path = Path.Combine( path = Path.Combine(
GetDirectory(WellKnownDirectory.Root), GetDirectory(WellKnownDirectory.Root, rootCaller),
".setup_info"); ".setup_info");
break; break;
@@ -290,7 +300,7 @@ namespace GitHub.Runner.Common.Tests
throw new NotSupportedException($"Unexpected well known config file: '{configFile}'"); throw new NotSupportedException($"Unexpected well known config file: '{configFile}'");
} }
_trace.Info($"Well known config file '{configFile}': '{path}'"); _trace.Info($"Well known config file '{configFile}': '{path}' ({rootCaller})");
return path; return path;
} }

View File

@@ -118,7 +118,7 @@ namespace GitHub.Runner.Common.Tests.Worker
await _actionRunner.RunAsync(); await _actionRunner.RunAsync();
//Assert //Assert
_ec.Verify(x => x.SetGitHubContext("event_path", Path.Combine(_hc.GetDirectory(WellKnownDirectory.Temp), "_github_workflow", "event.json")), Times.Once); _ec.Verify(x => x.SetGitHubContext("event_path", Path.Combine(_hc.GetDirectory(WellKnownDirectory.Temp, "", ""), "_github_workflow", "event.json")), Times.Once);
} }
[Fact] [Fact]

View File

@@ -153,7 +153,7 @@ namespace GitHub.Runner.Common.Tests.Worker
// Assert. // Assert.
_trackingManager.Verify(x => x.LoadIfExists(_ec.Object, _trackingFile)); _trackingManager.Verify(x => x.LoadIfExists(_ec.Object, _trackingFile));
_trackingManager.Verify(x => x.Update(_ec.Object, _existingConfig, _trackingFile)); _trackingManager.Verify(x => x.Update(_ec.Object, _existingConfig, _trackingFile));
_ec.Verify(x => x.SetGitHubContext("workspace", Path.Combine(hc.GetDirectory(WellKnownDirectory.Work), _existingConfig.PipelineDirectory, "my_new_path"))); _ec.Verify(x => x.SetGitHubContext("workspace", Path.Combine(hc.GetDirectory(WellKnownDirectory.Work, "", ""), _existingConfig.PipelineDirectory, "my_new_path")));
} }
} }
@@ -190,7 +190,7 @@ namespace GitHub.Runner.Common.Tests.Worker
_trackingManager.Setup(x => x.LoadIfExists(_ec.Object, _trackingFile)).Returns(_existingConfig); _trackingManager.Setup(x => x.LoadIfExists(_ec.Object, _trackingFile)).Returns(_existingConfig);
// Act. // Act.
Assert.ThrowsAny<ArgumentException>(()=> _pipelineDirectoryManager.UpdateRepositoryDirectory(_ec.Object, "actions/notrunner", Path.Combine(hc.GetDirectory(WellKnownDirectory.Work), "not_under_pipeline_directory"), false)); Assert.ThrowsAny<ArgumentException>(() => _pipelineDirectoryManager.UpdateRepositoryDirectory(_ec.Object, "actions/notrunner", Path.Combine(hc.GetDirectory(WellKnownDirectory.Work), "not_under_pipeline_directory"), false));
} }
} }

View File

@@ -1 +1 @@
2.285.3 2.284.0