Compare commits

..

1 Commits

Author SHA1 Message Date
Pavel Iakovenko
f8cd472d17 Upgrade to .net6 2021-11-11 21:44:58 -05:00
47 changed files with 218 additions and 498 deletions

View File

@@ -3,8 +3,7 @@ PACKAGERUNTIME=$1
PRECACHE=$2
NODE_URL=https://nodejs.org/dist
NODE12_VERSION="12.22.7"
NODE16_VERSION="16.13.0"
NODE12_VERSION="12.13.1"
get_abs_path() {
# exploits the fact that pwd will print abs path when no args
@@ -127,8 +126,6 @@ function acquireExternalTool() {
if [[ "$PACKAGERUNTIME" == "win-x64" || "$PACKAGERUNTIME" == "win-x86" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/$PACKAGERUNTIME/node.exe" node12/bin
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/$PACKAGERUNTIME/node.lib" node12/bin
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/$PACKAGERUNTIME/node.exe" node16/bin
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/$PACKAGERUNTIME/node.lib" node16/bin
if [[ "$PRECACHE" != "" ]]; then
acquireExternalTool "https://github.com/microsoft/vswhere/releases/download/2.6.7/vswhere.exe" vswhere
fi
@@ -137,23 +134,18 @@ fi
# Download the external tools only for OSX.
if [[ "$PACKAGERUNTIME" == "osx-x64" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-darwin-x64.tar.gz" node12 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-darwin-x64.tar.gz" node16 fix_nested_dir
fi
# Download the external tools for Linux PACKAGERUNTIMEs.
if [[ "$PACKAGERUNTIME" == "linux-x64" ]]; then
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-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 "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/${NODE12_VERSION}/alpine/x64/node-${NODE12_VERSION}-alpine-x64.tar.gz" node12_alpine
fi
if [[ "$PACKAGERUNTIME" == "linux-arm64" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-arm64.tar.gz" node12 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-linux-arm64.tar.gz" node16 fix_nested_dir
fi
if [[ "$PACKAGERUNTIME" == "linux-arm" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-armv7l.tar.gz" node12 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-linux-armv7l.tar.gz" node16 fix_nested_dir
fi

View File

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

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
<OutputType>Library</OutputType>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>

View File

@@ -51,7 +51,7 @@ namespace GitHub.Runner.Common
Task<PackageMetadata> GetPackageAsync(string packageType, string platform, string version, bool includeToken, CancellationToken cancellationToken);
// agent update
Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, int agentId, string currentState, string trace);
Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, int agentId, string currentState);
}
public sealed class RunnerServer : RunnerService, IRunnerServer
@@ -341,10 +341,25 @@ namespace GitHub.Runner.Common
return _genericTaskAgentClient.GetPackageAsync(packageType, platform, version, includeToken, cancellationToken: cancellationToken);
}
public Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, int agentId, string currentState, string trace)
public Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, int agentId, string currentState)
{
CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.UpdateAgentUpdateStateAsync(agentPoolId, agentId, currentState, trace);
return _genericTaskAgentClient.UpdateAgentUpdateStateAsync(agentPoolId, agentId, currentState);
}
//-----------------------------------------------------------------
// Runner Auth Url
//-----------------------------------------------------------------
public Task<string> GetRunnerAuthUrlAsync(int runnerPoolId, int runnerId)
{
CheckConnection(RunnerConnectionType.MessageQueue);
return _messageTaskAgentClient.GetAgentAuthUrlAsync(runnerPoolId, runnerId);
}
public Task ReportRunnerAuthUrlErrorAsync(int runnerPoolId, int runnerId, string error)
{
CheckConnection(RunnerConnectionType.MessageQueue);
return _messageTaskAgentClient.ReportAgentAuthUrlMigrationErrorAsync(runnerPoolId, runnerId, error);
}
}
}

View File

@@ -243,6 +243,7 @@ namespace GitHub.Runner.Listener
validator: Validators.ServerUrlValidator);
}
#if OS_WINDOWS
public string GetWindowsLogonAccount(string defaultValue, string descriptionMsg)
{
return GetArgOrPrompt(
@@ -251,6 +252,7 @@ namespace GitHub.Runner.Listener
defaultValue: defaultValue,
validator: Validators.NTAccountValidator);
}
#endif
public string GetWindowsLogonPassword(string accountName)
{

View File

@@ -67,6 +67,7 @@ namespace GitHub.Runner.Listener.Configuration
return !string.IsNullOrEmpty(value);
}
#if OS_WINDOWS
public static bool NTAccountValidator(string arg)
{
if (string.IsNullOrEmpty(arg) || String.IsNullOrEmpty(arg.TrimStart('.', '\\')))
@@ -87,5 +88,6 @@ namespace GitHub.Runner.Listener.Configuration
return true;
}
#endif
}
}

View File

@@ -129,7 +129,7 @@ namespace GitHub.Runner.Listener
private static void LoadAndSetEnv()
{
var binDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var binDir = Path.GetDirectoryName(AppContext.BaseDirectory);
var rootDir = new DirectoryInfo(binDir).Parent.FullName;
string envFile = Path.Combine(rootDir, ".env");
if (File.Exists(envFile))

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
<OutputType>Exe</OutputType>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>

View File

@@ -13,7 +13,6 @@ using GitHub.Services.WebApi;
using GitHub.Services.Common;
using GitHub.Runner.Common;
using GitHub.Runner.Sdk;
using System.Text;
namespace GitHub.Runner.Listener
{
@@ -64,25 +63,23 @@ namespace GitHub.Runner.Listener
// Print console line that warn user not shutdown runner.
await UpdateRunnerUpdateStateAsync("Runner update in progress, do not shutdown runner.");
await UpdateRunnerUpdateStateAsync($"Downloading {_targetPackage.Version} runner", $"RunnerPlatform: {_targetPackage.Platform}");
await UpdateRunnerUpdateStateAsync($"Downloading {_targetPackage.Version} runner");
var downloadTrace = await DownloadLatestRunner(token);
await DownloadLatestRunner(token);
Trace.Info($"Download latest runner and unzip into runner root.");
// wait till all running job finish
await UpdateRunnerUpdateStateAsync("Waiting for current job finish running.", downloadTrace);
await UpdateRunnerUpdateStateAsync("Waiting for current job finish running.");
await jobDispatcher.WaitAsync(token);
Trace.Info($"All running job has exited.");
// We need to keep runner backup around for macOS until we fixed https://github.com/actions/runner/issues/743
// delete runner backup
var stopWatch = Stopwatch.StartNew();
DeletePreviousVersionRunnerBackup(token);
Trace.Info($"Delete old version runner backup.");
stopWatch.Stop();
// generate update script from template
await UpdateRunnerUpdateStateAsync("Generate and execute update script.", $"DeleteRunnerBackupTime: {stopWatch.ElapsedMilliseconds}ms");
await UpdateRunnerUpdateStateAsync("Generate and execute update script.");
string updateScript = GenerateUpdateScript(restartInteractiveRunner);
Trace.Info($"Generate update script into: {updateScript}");
@@ -99,7 +96,7 @@ namespace GitHub.Runner.Listener
invokeScript.Start();
Trace.Info($"Update script start running");
await UpdateRunnerUpdateStateAsync("Runner will exit shortly for update, should be back online within 10 seconds.", $"RestartInteractiveRunner: {restartInteractiveRunner}");
await UpdateRunnerUpdateStateAsync("Runner will exit shortly for update, should be back online within 10 seconds.");
return true;
}
@@ -153,10 +150,8 @@ namespace GitHub.Runner.Listener
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
private async Task<string> DownloadLatestRunner(CancellationToken token)
private async Task DownloadLatestRunner(CancellationToken token)
{
var traceStringBuilder = new StringBuilder();
traceStringBuilder.AppendLine($"DownloadUrl: {_targetPackage.DownloadUrl}");
string latestRunnerDirectory = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), Constants.Path.UpdateDirectory);
IOUtil.DeleteDirectory(latestRunnerDirectory, token);
Directory.CreateDirectory(latestRunnerDirectory);
@@ -165,7 +160,6 @@ namespace GitHub.Runner.Listener
string archiveFile = null;
bool downloadSucceeded = false;
var stopWatch = Stopwatch.StartNew();
try
{
// Download the runner, using multiple attempts in order to be resilient against any networking/CDN issues
@@ -216,7 +210,6 @@ namespace GitHub.Runner.Listener
try
{
Trace.Info($"Download runner: begin download");
long downloadSize = 0;
//open zip stream in async mode
using (HttpClient httpClient = new HttpClient(HostContext.CreateHttpClientHandler()))
@@ -235,16 +228,11 @@ namespace GitHub.Runner.Listener
//81920 is the default used by System.IO.Stream.CopyTo and is under the large object heap threshold (85k).
await result.CopyToAsync(fs, 81920, downloadCts.Token);
await fs.FlushAsync(downloadCts.Token);
downloadSize = fs.Length;
}
}
Trace.Info($"Download runner: finished download");
downloadSucceeded = true;
stopWatch.Stop();
traceStringBuilder.AppendLine($"PackageDownloadTime: {stopWatch.ElapsedMilliseconds}ms");
traceStringBuilder.AppendLine($"Attempts: {attempt}");
traceStringBuilder.AppendLine($"PackageSize: {downloadSize / 1024 / 1024}MB");
break;
}
catch (OperationCanceledException) when (token.IsCancellationRequested)
@@ -269,7 +257,6 @@ namespace GitHub.Runner.Listener
throw new TaskCanceledException($"Runner package '{archiveFile}' failed after {Constants.RunnerDownloadRetryMaxAttempts} download attempts");
}
stopWatch.Restart();
// If we got this far, we know that we've successfully downloaded the runner package
// Validate Hash Matches if it is provided
using (FileStream stream = File.OpenRead(archiveFile))
@@ -333,9 +320,7 @@ namespace GitHub.Runner.Listener
throw new NotSupportedException($"{archiveFile}");
}
stopWatch.Stop();
Trace.Info($"Finished getting latest runner package at: {latestRunnerDirectory}.");
traceStringBuilder.AppendLine($"PackageExtractTime: {stopWatch.ElapsedMilliseconds}ms");
}
finally
{
@@ -355,7 +340,6 @@ namespace GitHub.Runner.Listener
}
}
stopWatch.Restart();
// copy latest runner into runner root folder
// copy bin from _work/_update -> bin.version under root
string binVersionDir = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Root), $"{Constants.Path.BinDirectory}.{_targetPackage.Version}");
@@ -381,11 +365,6 @@ namespace GitHub.Runner.Listener
IOUtil.DeleteFile(destination);
file.CopyTo(destination, true);
}
stopWatch.Stop();
traceStringBuilder.AppendLine($"CopyRunnerToRootTime: {stopWatch.ElapsedMilliseconds}ms");
return traceStringBuilder.ToString();
}
private void DeletePreviousVersionRunnerBackup(CancellationToken token)
@@ -505,18 +484,13 @@ namespace GitHub.Runner.Listener
return updateScript;
}
private async Task UpdateRunnerUpdateStateAsync(string currentState, string trace = "")
private async Task UpdateRunnerUpdateStateAsync(string currentState)
{
_terminal.WriteLine(currentState);
if (!string.IsNullOrEmpty(trace))
{
Trace.Info(trace);
}
try
{
await _runnerServer.UpdateAgentUpdateStateAsync(_poolId, _agentId, currentState, trace);
await _runnerServer.UpdateAgentUpdateStateAsync(_poolId, _agentId, currentState);
}
catch (VssResourceNotFoundException)
{

View File

@@ -95,7 +95,7 @@ namespace GitHub.Runner.PluginHost
string assemblyFilename = assembly.Name + ".dll";
if (string.IsNullOrEmpty(executingAssemblyLocation))
{
executingAssemblyLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
executingAssemblyLocation = Path.GetDirectoryName(AppContext.BaseDirectory);
}
return context.LoadFromAssemblyPath(Path.Combine(executingAssemblyLocation, assemblyFilename));
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
<OutputType>Exe</OutputType>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>

View File

@@ -444,7 +444,7 @@ namespace GitHub.Runner.Plugins.Artifact
{
// We should never
context.Error($"Error '{ex.Message}' when downloading file '{fileToDownload}'. (Downloader {downloaderId})");
throw ex;
throw;
}
}
@@ -528,7 +528,7 @@ namespace GitHub.Runner.Plugins.Artifact
catch (Exception ex)
{
context.Output($"File error '{ex.Message}' when uploading file '{fileToUpload}'.");
throw ex;
throw;
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
<OutputType>Library</OutputType>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
<OutputType>Library</OutputType>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>

View File

@@ -278,7 +278,7 @@ namespace GitHub.Runner.Worker
}
// Clone action so we can modify the condition without affecting the original
var clonedAction = action.Clone() as Pipelines.ActionStep;
_cachedEmbeddedPostSteps[parentStepId].Push(clonedAction);
_cachedEmbeddedPostSteps[parentStepId].Push(clonedAction);
}
}
}
@@ -443,7 +443,7 @@ namespace GitHub.Runner.Worker
{
for (var i = 0; i < compositeAction.Steps.Count; i++)
{
// Load stored Ids for later load actions
// Store Id's for later load actions
compositeAction.Steps[i].Id = _cachedEmbeddedStepIds[action.Id][i];
if (string.IsNullOrEmpty(executionContext.Global.Variables.Get("DistributedTask.EnableCompositeActions")) && compositeAction.Steps[i].Reference.Type != Pipelines.ActionSourceType.Script)
{
@@ -451,16 +451,6 @@ namespace GitHub.Runner.Worker
}
}
}
else
{
_cachedEmbeddedStepIds[action.Id] = new List<Guid>();
foreach (var compositeStep in compositeAction.Steps)
{
var guid = Guid.NewGuid();
compositeStep.Id = guid;
_cachedEmbeddedStepIds[action.Id].Add(guid);
}
}
}
else
{
@@ -1199,8 +1189,6 @@ namespace GitHub.Runner.Worker
public string Pre { get; set; }
public string Post { get; set; }
public string NodeVersion { get; set; }
}
public sealed class PluginActionExecutionData : ActionExecutionData

View File

@@ -451,8 +451,7 @@ namespace GitHub.Runner.Worker
};
}
}
else if (string.Equals(usingToken.Value, "node12", StringComparison.OrdinalIgnoreCase)||
string.Equals(usingToken.Value, "node16", StringComparison.OrdinalIgnoreCase))
else if (string.Equals(usingToken.Value, "node12", StringComparison.OrdinalIgnoreCase))
{
if (string.IsNullOrEmpty(mainToken?.Value))
{
@@ -462,7 +461,6 @@ namespace GitHub.Runner.Worker
{
return new NodeJSActionExecutionData()
{
NodeVersion = usingToken.Value,
Script = mainToken.Value,
Pre = preToken?.Value,
InitCondition = preIfToken?.Value ?? "always()",
@@ -492,7 +490,7 @@ namespace GitHub.Runner.Worker
}
else
{
throw new ArgumentOutOfRangeException($"'using: {usingToken.Value}' is not supported, use 'docker', 'node12' or 'node16' instead.");
throw new ArgumentOutOfRangeException($"'using: {usingToken.Value}' is not supported, use 'docker' or 'node12' instead.");
}
}
else if (pluginToken != null)

View File

@@ -59,7 +59,7 @@ namespace GitHub.Runner.Worker.Expressions
context.Trace.Info($"Search root directory: '{githubWorkspace}'");
context.Trace.Info($"Search pattern: '{string.Join(", ", patterns)}'");
string binDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
string binDir = Path.GetDirectoryName(AppContext.BaseDirectory);
string runnerRoot = new DirectoryInfo(binDir).Parent.FullName;
string node = Path.Combine(runnerRoot, "externals", "node12", "bin", $"node{IOUtil.ExeExtension}");

View File

@@ -83,7 +83,7 @@ namespace GitHub.Runner.Worker.Handlers
HasPreStep = Data.HasPre,
HasPostStep = Data.HasPost,
IsEmbedded = ExecutionContext.IsEmbedded,
Type = Data.NodeVersion
Type = "node12"
};
ExecutionContext.Root.ActionsStepsTelemetry.Add(telemetry);
}
@@ -99,7 +99,7 @@ namespace GitHub.Runner.Worker.Handlers
workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work);
}
var nodeRuntimeVersion = await StepHost.DetermineNodeRuntimeVersion(ExecutionContext, Data.NodeVersion);
var nodeRuntimeVersion = await StepHost.DetermineNodeRuntimeVersion(ExecutionContext);
string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), nodeRuntimeVersion, "bin", $"node{IOUtil.ExeExtension}");
// Format the arguments passed to node.

View File

@@ -23,7 +23,7 @@ namespace GitHub.Runner.Worker.Handlers
string ResolvePathForStepHost(string path);
Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion);
Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext);
Task<int> ExecuteAsync(string workingDirectory,
string fileName,
@@ -58,9 +58,9 @@ namespace GitHub.Runner.Worker.Handlers
return path;
}
public Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
public Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext)
{
return Task.FromResult<string>(preferredVersion);
return Task.FromResult<string>("node12");
}
public async Task<int> ExecuteAsync(string workingDirectory,
@@ -123,7 +123,7 @@ namespace GitHub.Runner.Worker.Handlers
}
}
public async Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
public async Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext)
{
// Best effort to determine a compatible node runtime
// There may be more variation in which libraries are linked than just musl/glibc,
@@ -148,14 +148,14 @@ namespace GitHub.Runner.Worker.Handlers
var msg = $"JavaScript Actions in Alpine containers are only supported on x64 Linux runners. Detected {os} {arch}";
throw new NotSupportedException(msg);
}
nodeExternal = $"{preferredVersion}_alpine";
nodeExternal = "node12_alpine";
executionContext.Debug($"Container distribution is alpine. Running JavaScript Action with external tool: {nodeExternal}");
return nodeExternal;
}
}
}
// Optimistically use the default
nodeExternal = preferredVersion;
nodeExternal = "node12";
executionContext.Debug($"Running JavaScript Action with default external tool: {nodeExternal}");
return nodeExternal;
}

View File

@@ -142,12 +142,6 @@ namespace GitHub.Runner.Worker
Trace.Error(ex);
}
var secretSource = context.GetGitHubContext("secret_source");
if (!string.IsNullOrEmpty(secretSource))
{
context.Output($"Secret source: {secretSource}");
}
var repoFullName = context.GetGitHubContext("repository");
ArgUtil.NotNull(repoFullName, nameof(repoFullName));
context.Debug($"Primary repository: {repoFullName}");

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
<OutputType>Exe</OutputType>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>

View File

@@ -46,7 +46,7 @@
"runs": {
"one-of": [
"container-runs",
"node-runs",
"node12-runs",
"plugin-runs",
"composite-runs"
]
@@ -80,7 +80,7 @@
"loose-value-type": "string"
}
},
"node-runs": {
"node12-runs": {
"mapping": {
"properties": {
"using": "non-empty-string",
@@ -112,10 +112,10 @@
"item-type": "composite-step"
}
},
"composite-step": {
"composite-step":{
"one-of": [
"run-step",
"uses-step"
"uses-step"
]
},
"run-step": {
@@ -254,4 +254,4 @@
}
}
}
}
}

View File

@@ -28,14 +28,6 @@ namespace GitHub.Services.Common
}
}
public IDictionary<string, object> Properties
{
get
{
return m_request.Properties;
}
}
IEnumerable<String> IHttpHeaders.GetValues(String name)
{
IEnumerable<String> values;

View File

@@ -14,10 +14,5 @@ namespace GitHub.Services.Common
{
get;
}
IDictionary<string, object> Properties
{
get;
}
}
}

View File

@@ -20,12 +20,11 @@ namespace GitHub.Services.Common.Diagnostics
public static VssTraceActivity GetActivity(this HttpRequestMessage message)
{
Object traceActivity;
if (!message.Properties.TryGetValue(VssTraceActivity.PropertyName, out traceActivity))
if (!message.Options.TryGetValue(VssTraceActivity.PropertyName, out VssTraceActivity traceActivity))
{
return VssTraceActivity.Empty;
}
return (VssTraceActivity)traceActivity;
return traceActivity;
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Net.Http;
namespace GitHub.Services.Common.Diagnostics
{
@@ -98,7 +99,7 @@ namespace GitHub.Services.Common.Diagnostics
/// <summary>
/// Gets the property name used to cache this object on extensible objects.
/// </summary>
public const String PropertyName = "MS.VSS.Diagnostics.TraceActivity";
public static readonly HttpRequestOptionsKey<VssTraceActivity> PropertyName = new HttpRequestOptionsKey<VssTraceActivity>("MS.VSS.Diagnostics.TraceActivity");
private static Lazy<VssTraceActivity> s_empty = new Lazy<VssTraceActivity>(() => new VssTraceActivity(Guid.Empty));
private sealed class CorrelationScope : IDisposable

View File

@@ -110,7 +110,7 @@ namespace GitHub.Services.Common
}
}
internal static readonly String PropertyName = "MS.VS.MessageHandler";
internal static readonly HttpRequestOptionsKey<VssHttpMessageHandler> PropertyName = new HttpRequestOptionsKey<VssHttpMessageHandler>("MS.VS.MessageHandler");
/// <summary>
/// Handles the authentication hand-shake for a Visual Studio service.
@@ -169,7 +169,7 @@ namespace GitHub.Services.Common
}
// Add ourselves to the message so the underlying token issuers may use it if necessary
request.Properties[VssHttpMessageHandler.PropertyName] = this;
request.Options.Set(VssHttpMessageHandler.PropertyName, this);
Boolean succeeded = false;
Boolean lastResponseDemandedProxyAuth = false;
@@ -409,7 +409,7 @@ namespace GitHub.Services.Common
// Read the completion option provided by the caller. If we don't find the property then we
// assume it is OK to buffer by default.
HttpCompletionOption completionOption;
if (!request.Properties.TryGetValue(VssHttpRequestSettings.HttpCompletionOptionPropertyName, out completionOption))
if (!request.Options.TryGetValue(VssHttpRequestSettings.HttpCompletionOptionPropertyName, out completionOption))
{
completionOption = HttpCompletionOption.ResponseContentRead;
}

View File

@@ -11,7 +11,7 @@ namespace GitHub.Services.Common
{
DateTime _lastTime;
static readonly String TfsTraceInfoKey = "TFS_TraceInfo";
private static readonly HttpRequestOptionsKey<VssHttpMessageHandlerTraceInfo> TfsTraceInfoKey = new HttpRequestOptionsKey<VssHttpMessageHandlerTraceInfo>("TFS_TraceInfo");
public int TokenRetries { get; internal set; }
@@ -76,10 +76,9 @@ namespace GitHub.Services.Common
/// <param name="traceInfo"></param>
public static void SetTraceInfo(HttpRequestMessage message, VssHttpMessageHandlerTraceInfo traceInfo)
{
object existingTraceInfo;
if (!message.Properties.TryGetValue(TfsTraceInfoKey, out existingTraceInfo))
if (!message.Options.TryGetValue(TfsTraceInfoKey, out var _))
{
message.Properties.Add(TfsTraceInfoKey, traceInfo);
message.Options.Set(TfsTraceInfoKey, traceInfo);
}
}
@@ -90,13 +89,8 @@ namespace GitHub.Services.Common
/// <returns></returns>
public static VssHttpMessageHandlerTraceInfo GetTraceInfo(HttpRequestMessage message)
{
VssHttpMessageHandlerTraceInfo traceInfo = null;
if (message.Properties.TryGetValue(TfsTraceInfoKey, out object traceInfoObject))
{
traceInfo = traceInfoObject as VssHttpMessageHandlerTraceInfo;
}
VssHttpMessageHandlerTraceInfo traceInfo;
message.Options.TryGetValue(TfsTraceInfoKey, out traceInfo);
return traceInfo;
}

View File

@@ -291,12 +291,12 @@ namespace GitHub.Services.Common
protected internal virtual Boolean ApplyTo(HttpRequestMessage request)
{
// Make sure we only apply the settings to the request once
if (request.Properties.ContainsKey(PropertyName))
if (request.Options.TryGetValue(PropertyName, out var _))
{
return false;
}
request.Properties.Add(PropertyName, this);
request.Options.Set(PropertyName, this);
if (this.AcceptLanguages != null && this.AcceptLanguages.Count > 0)
{
@@ -366,12 +366,12 @@ namespace GitHub.Services.Common
/// <summary>
/// Gets the property name used to reference this object.
/// </summary>
public const String PropertyName = "MS.VS.RequestSettings";
public static readonly HttpRequestOptionsKey<VssHttpRequestSettings> PropertyName = new HttpRequestOptionsKey<VssHttpRequestSettings>("MS.VS.RequestSettings");
/// <summary>
/// Gets the property name used to reference the completion option for a specific request.
/// </summary>
public const String HttpCompletionOptionPropertyName = "MS.VS.HttpCompletionOption";
public static readonly HttpRequestOptionsKey<HttpCompletionOption> HttpCompletionOptionPropertyName = new HttpRequestOptionsKey<HttpCompletionOption>("MS.VS.HttpCompletionOption");
/// <summary>
/// Header to include the light weight response client option.

View File

@@ -53,23 +53,14 @@ namespace GitHub.Services.Common
VssTraceActivity traceActivity = VssTraceActivity.Current;
// Allow overriding default retry options per request
VssHttpRetryOptions retryOptions = m_retryOptions;
object retryOptionsObject;
if (request.Properties.TryGetValue(HttpRetryOptionsKey, out retryOptionsObject)) // NETSTANDARD compliant, TryGetValue<T> is not
{
// Fallback to default options if object of unexpected type was passed
retryOptions = retryOptionsObject as VssHttpRetryOptions ?? m_retryOptions;
}
TimeSpan minBackoff = retryOptions.MinBackoff;
Int32 maxAttempts = retryOptions.MaxRetries + 1;
VssHttpRetryOptions retryOptions;
request.Options.TryGetValue(HttpRetryOptionsKey, out retryOptions);
TimeSpan minBackoff = (retryOptions ?? m_retryOptions).MinBackoff;
Int32 maxAttempts = (retryOptions ?? m_retryOptions).MaxRetries + 1;
IVssHttpRetryInfo retryInfo = null;
object retryInfoObject;
if (request.Properties.TryGetValue(HttpRetryInfoKey, out retryInfoObject)) // NETSTANDARD compliant, TryGetValue<T> is not
{
retryInfo = retryInfoObject as IVssHttpRetryInfo;
}
request.Options.TryGetValue(HttpRetryInfoKey, out retryInfo);
if (IsLowPriority(request))
{
@@ -225,8 +216,8 @@ namespace GitHub.Services.Common
}
private VssHttpRetryOptions m_retryOptions;
public const string HttpRetryInfoKey = "HttpRetryInfo";
public const string HttpRetryOptionsKey = "VssHttpRetryOptions";
public static readonly HttpRequestOptionsKey<IVssHttpRetryInfo> HttpRetryInfoKey = new HttpRequestOptionsKey<IVssHttpRetryInfo>("HttpRetryInfo");
public static readonly HttpRequestOptionsKey<VssHttpRetryOptions> HttpRetryOptionsKey = new HttpRequestOptionsKey<VssHttpRetryOptions>("VssHttpRetryOptions");
private string m_clientName = "";
}
}

View File

@@ -768,7 +768,6 @@ namespace GitHub.DistributedTask.WebApi
/// <param name="poolId"></param>
/// <param name="agentId"></param>
/// <param name="currentState"></param>
/// <param name="updateTrace"></param>
/// <param name="userState"></param>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
@@ -776,7 +775,6 @@ namespace GitHub.DistributedTask.WebApi
int poolId,
int agentId,
string currentState,
string updateTrace,
object userState = null,
CancellationToken cancellationToken = default)
{
@@ -786,7 +784,6 @@ namespace GitHub.DistributedTask.WebApi
List<KeyValuePair<string, string>> queryParams = new List<KeyValuePair<string, string>>();
queryParams.Add("currentState", currentState);
queryParams.Add("updateTrace", updateTrace);
return SendAsync<TaskAgent>(
httpMethod,
@@ -797,5 +794,65 @@ namespace GitHub.DistributedTask.WebApi
userState: userState,
cancellationToken: cancellationToken);
}
/// <summary>
/// [Preview API]
/// </summary>
/// <param name="poolId"></param>
/// <param name="agentId"></param>
/// <param name="userState"></param>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
public Task<String> GetAgentAuthUrlAsync(
int poolId,
int agentId,
object userState = null,
CancellationToken cancellationToken = default)
{
HttpMethod httpMethod = new HttpMethod("GET");
Guid locationId = new Guid("a82a119c-1e46-44b6-8d75-c82a79cf975b");
object routeValues = new { poolId = poolId, agentId = agentId };
return SendAsync<String>(
httpMethod,
locationId,
routeValues: routeValues,
version: new ApiResourceVersion(6.0, 1),
userState: userState,
cancellationToken: cancellationToken);
}
/// <summary>
/// [Preview API]
/// </summary>
/// <param name="poolId"></param>
/// <param name="agentId"></param>
/// <param name="error"></param>
/// <param name="userState"></param>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual async Task ReportAgentAuthUrlMigrationErrorAsync(
int poolId,
int agentId,
string error,
object userState = null,
CancellationToken cancellationToken = default)
{
HttpMethod httpMethod = new HttpMethod("POST");
Guid locationId = new Guid("a82a119c-1e46-44b6-8d75-c82a79cf975b");
object routeValues = new { poolId = poolId, agentId = agentId };
HttpContent content = new ObjectContent<string>(error, new VssJsonMediaTypeFormatter(true));
using (HttpResponseMessage response = await SendAsync(
httpMethod,
locationId,
routeValues: routeValues,
version: new ApiResourceVersion(6.0, 1),
userState: userState,
cancellationToken: cancellationToken,
content: content).ConfigureAwait(false))
{
return;
}
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
<OutputType>Library</OutputType>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>

View File

@@ -833,7 +833,7 @@ namespace GitHub.Services.WebApi
{
if (userState != null)
{
message.Properties[UserStatePropertyName] = userState;
message.Options.Set(UserStatePropertyName, userState);
}
if (!message.Headers.Contains(Common.Internal.HttpHeaders.VssE2EID))
@@ -842,11 +842,11 @@ namespace GitHub.Services.WebApi
}
VssHttpEventSource.Log.HttpRequestStart(traceActivity, message);
message.Trace();
message.Properties[VssTraceActivity.PropertyName] = traceActivity;
message.Options.Set(VssTraceActivity.PropertyName, traceActivity);
// Send the completion option to the inner handler stack so we know when it's safe to buffer
// and when we should avoid buffering.
message.Properties[VssHttpRequestSettings.HttpCompletionOptionPropertyName] = completionOption;
message.Options.Set(VssHttpRequestSettings.HttpCompletionOptionPropertyName, completionOption);
//ConfigureAwait(false) enables the continuation to be run outside
//any captured SyncronizationContext (such as ASP.NET's) which keeps things
@@ -1154,7 +1154,9 @@ namespace GitHub.Services.WebApi
{
if (BaseAddress != null)
{
#pragma warning disable SYSLIB0014
ServicePoint servicePoint = ServicePointManager.FindServicePoint(BaseAddress);
#pragma warning restore SYSLIB0014
servicePoint.UseNagleAlgorithm = false;
servicePoint.SetTcpKeepAlive(
enabled: true,
@@ -1272,7 +1274,7 @@ namespace GitHub.Services.WebApi
private const String c_jsonMediaType = "application/json";
public readonly static String UserStatePropertyName = "VssClientBaseUserState";
public static readonly HttpRequestOptionsKey<object> UserStatePropertyName = new HttpRequestOptionsKey<object>("VssClientBaseUserState");
protected sealed class OperationScope : IDisposable
{

View File

@@ -138,7 +138,7 @@ namespace GitHub.Services.WebApi
if (routeReplacementOptions.HasFlag(RouteReplacementOptions.EscapeUri))
{
sbResult = new StringBuilder(Uri.EscapeUriString(sbResult.ToString()));
sbResult = new StringBuilder(Uri.EscapeDataString(sbResult.ToString()));
}
if (routeReplacementOptions.HasFlag(RouteReplacementOptions.AppendUnusedAsQueryParams) && unusedValues.Count > 0)

View File

@@ -6,27 +6,24 @@ using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.InteropServices;
namespace GitHub.Services.WebApi
{
internal static class HttpMessageExtensions
{
private const string tracerKey = "VSS_HTTP_TIMER_TRACE";
private static readonly HttpRequestOptionsKey<VssRequestTimerTrace> tracerKey = new HttpRequestOptionsKey<VssRequestTimerTrace>("VSS_HTTP_TIMER_TRACE");
internal static void Trace(this HttpRequestMessage request)
{
Object tracerObj = null;
VssRequestTimerTrace tracer = null;
if (request.Properties.TryGetValue(tracerKey, out tracerObj))
VssRequestTimerTrace tracer;
if (request.Options.TryGetValue(tracerKey, out tracer))
{
tracer = tracerObj as VssRequestTimerTrace;
Debug.Assert(tracer != null, "Tracer object is the wrong type!");
}
else
{
tracer = new VssRequestTimerTrace();
request.Properties[tracerKey] = tracer;
request.Options.Set(tracerKey, tracer);
}
if (tracer != null)
@@ -37,11 +34,9 @@ namespace GitHub.Services.WebApi
internal static void Trace(this HttpResponseMessage response)
{
Object tracerObj = null;
VssRequestTimerTrace tracer = null;
if (response.RequestMessage.Properties.TryGetValue(tracerKey, out tracerObj))
VssRequestTimerTrace tracer;
if (response.RequestMessage.Options.TryGetValue(tracerKey, out tracer))
{
tracer = tracerObj as VssRequestTimerTrace;
Debug.Assert(tracer != null, "Tracer object is the wrong type!");
}

View File

@@ -547,6 +547,7 @@ namespace GitHub.Runner.Common.Tests
}
}
#if OS_WINDOWS
[Fact]
[Trait("Level", "L0")]
[Trait("Category", nameof(CommandSettings))]
@@ -574,6 +575,7 @@ namespace GitHub.Runner.Common.Tests
Assert.Equal("some windows logon account", actual);
}
}
#endif
[Fact]
[Trait("Level", "L0")]

View File

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

View File

@@ -965,7 +965,7 @@ namespace GitHub.Runner.Common.Tests.Worker
};
//Act
var result = await _actionManager.PrepareActionsAsync(_ec.Object, actions);
var result = await _actionManager.PrepareActionsAsync(_ec.Object, actions);
//Assert
Assert.Equal(1, result.PreStepTracker.Count);
@@ -1288,7 +1288,7 @@ runs:
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void LoadsNode12ActionDefinition()
public void LoadsNodeActionDefinition()
{
try
{
@@ -1344,78 +1344,8 @@ runs:
Assert.True(string.IsNullOrEmpty(inputDefaults["entryPoint"]));
Assert.NotNull(definition.Data.Execution); // execution
Assert.NotNull(definition.Data.Execution as NodeJSActionExecutionData);
Assert.NotNull((definition.Data.Execution as NodeJSActionExecutionData));
Assert.Equal("task.js", (definition.Data.Execution as NodeJSActionExecutionData).Script);
Assert.Equal("node12", (definition.Data.Execution as NodeJSActionExecutionData).NodeVersion);
}
finally
{
Teardown();
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void LoadsNode16ActionDefinition()
{
try
{
// Arrange.
Setup();
const string Content = @"
# Container action
name: 'Hello World'
description: 'Greet the world and record the time'
author: 'GitHub'
inputs:
greeting: # id of input
description: 'The greeting we choose - will print ""{greeting}, World!"" on stdout'
required: true
default: 'Hello'
entryPoint: # id of input
description: 'optional docker entrypoint overwrite.'
required: false
outputs:
time: # id of output
description: 'The time we did the greeting'
icon: 'hello.svg' # vector art to display in the GitHub Marketplace
color: 'green' # optional, decorates the entry in the GitHub Marketplace
runs:
using: 'node16'
main: 'task.js'
";
Pipelines.ActionStep instance;
string directory;
CreateAction(yamlContent: Content, instance: out instance, directory: out directory);
// Act.
Definition definition = _actionManager.LoadAction(_ec.Object, instance);
// Assert.
Assert.NotNull(definition);
Assert.Equal(directory, definition.Directory);
Assert.NotNull(definition.Data);
Assert.NotNull(definition.Data.Inputs); // inputs
Dictionary<string, string> inputDefaults = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (var input in definition.Data.Inputs)
{
var name = input.Key.AssertString("key").Value;
var value = input.Value.AssertScalar("value").ToString();
_hc.GetTrace().Info($"Default: {name} = {value}");
inputDefaults[name] = value;
}
Assert.Equal(2, inputDefaults.Count);
Assert.True(inputDefaults.ContainsKey("greeting"));
Assert.Equal("Hello", inputDefaults["greeting"]);
Assert.True(string.IsNullOrEmpty(inputDefaults["entryPoint"]));
Assert.NotNull(definition.Data.Execution); // execution
Assert.NotNull(definition.Data.Execution as NodeJSActionExecutionData);
Assert.Equal("task.js", (definition.Data.Execution as NodeJSActionExecutionData).Script);
Assert.Equal("node16", (definition.Data.Execution as NodeJSActionExecutionData).NodeVersion);
}
finally
{

View File

@@ -408,50 +408,6 @@ namespace GitHub.Runner.Common.Tests.Worker
var nodeAction = result.Execution as NodeJSActionExecutionData;
Assert.Equal("main.js", nodeAction.Script);
Assert.Equal("node12", nodeAction.NodeVersion);
}
finally
{
Teardown();
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void Load_Node16Action()
{
try
{
//Arrange
Setup();
var actionManifest = new ActionManifestManager();
actionManifest.Initialize(_hc);
//Act
var result = actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "node16action.yml"));
//Assert
Assert.Equal("Hello World", result.Name);
Assert.Equal("Greet the world and record the time", result.Description);
Assert.Equal(2, result.Inputs.Count);
Assert.Equal("greeting", result.Inputs[0].Key.AssertString("key").Value);
Assert.Equal("Hello", result.Inputs[0].Value.AssertString("value").Value);
Assert.Equal("entryPoint", result.Inputs[1].Key.AssertString("key").Value);
Assert.Equal("", result.Inputs[1].Value.AssertString("value").Value);
Assert.Equal(1, result.Deprecated.Count);
Assert.True(result.Deprecated.ContainsKey("greeting"));
result.Deprecated.TryGetValue("greeting", out string value);
Assert.Equal("This property has been deprecated", value);
Assert.Equal(ActionExecutionType.NodeJS, result.Execution.ExecutionType);
var nodeAction = result.Execution as NodeJSActionExecutionData;
Assert.Equal("main.js", nodeAction.Script);
Assert.Equal("node16", nodeAction.NodeVersion);
}
finally
{

View File

@@ -118,7 +118,7 @@ namespace GitHub.Runner.Common.Tests.Worker
await _actionRunner.RunAsync();
//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]

View File

@@ -102,7 +102,6 @@ namespace GitHub.Runner.Common.Tests.Worker
_message = new Pipelines.AgentJobRequestMessage(plan, timeline, jobId, "test", "test", null, null, null, new Dictionary<string, VariableValue>(), new List<MaskHint>(), new Pipelines.JobResources(), new Pipelines.ContextData.DictionaryContextData(), new Pipelines.WorkspaceOptions(), steps, null, null, null, null);
GitHubContext github = new GitHubContext();
github["repository"] = new Pipelines.ContextData.StringContextData("actions/runner");
github["secret_source"] = new Pipelines.ContextData.StringContextData("Actions");
_message.ContextData.Add("github", github);
hc.SetSingleton(_actionManager.Object);

View File

@@ -153,7 +153,7 @@ namespace GitHub.Runner.Common.Tests.Worker
// Assert.
_trackingManager.Verify(x => x.LoadIfExists(_ec.Object, _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);
// 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,109 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Moq;
using Xunit;
using GitHub.Runner.Worker;
using GitHub.Runner.Worker.Handlers;
using GitHub.Runner.Worker.Container;
namespace GitHub.Runner.Common.Tests.Worker
{
public sealed class StepHostL0
{
private Mock<IExecutionContext> _ec;
private Mock<IDockerCommandManager> _dc;
private TestHostContext CreateTestContext([CallerMemberName] String testName = "")
{
var hc = new TestHostContext(this, testName);
_ec = new Mock<IExecutionContext>();
_ec.SetupAllProperties();
_ec.Setup(x => x.Global).Returns(new GlobalContext { WriteDebug = true });
var trace = hc.GetTrace();
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>())).Callback((string tag, string message) => { trace.Info($"[{tag}]{message}"); });
_dc = new Mock<IDockerCommandManager>();
hc.SetSingleton(_dc.Object);
return hc;
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public async Task DetermineNodeRuntimeVersionInContainerAsync()
{
using (TestHostContext hc = CreateTestContext())
{
// Arrange.
var sh = new ContainerStepHost();
sh.Initialize(hc);
sh.Container = new ContainerInfo() { ContainerId = "1234abcd" };
_dc.Setup(d => d.DockerExec(_ec.Object, It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<List<string>>()))
.ReturnsAsync(0);
// Act.
var nodeVersion = await sh.DetermineNodeRuntimeVersion(_ec.Object, "node12");
// Assert.
Assert.Equal("node12", nodeVersion);
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public async Task DetermineNodeRuntimeVersionInAlpineContainerAsync()
{
using (TestHostContext hc = CreateTestContext())
{
// Arrange.
var sh = new ContainerStepHost();
sh.Initialize(hc);
sh.Container = new ContainerInfo() { ContainerId = "1234abcd" };
_dc.Setup(d => d.DockerExec(_ec.Object, It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<List<string>>()))
.Callback((IExecutionContext ec, string id, string options, string command, List<string> output) =>
{
output.Add("alpine");
})
.ReturnsAsync(0);
// Act.
var nodeVersion = await sh.DetermineNodeRuntimeVersion(_ec.Object, "node16");
// Assert.
Assert.Equal("node16_alpine", nodeVersion);
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public async Task DetermineNodeRuntimeVersionInUnknowContainerAsync()
{
using (TestHostContext hc = CreateTestContext())
{
// Arrange.
var sh = new ContainerStepHost();
sh.Initialize(hc);
sh.Container = new ContainerInfo() { ContainerId = "1234abcd" };
_dc.Setup(d => d.DockerExec(_ec.Object, It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<List<string>>()))
.Callback((IExecutionContext ec, string id, string options, string command, List<string> output) =>
{
output.Add("github");
})
.ReturnsAsync(0);
// Act.
var nodeVersion = await sh.DetermineNodeRuntimeVersion(_ec.Object, "node16");
// Assert.
Assert.Equal("node16", nodeVersion);
}
}
}
}

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<NoWarn>NU1701;NU1603;NU1603;xUnit2013;</NoWarn>

View File

@@ -1,20 +0,0 @@
name: 'Hello World'
description: 'Greet the world and record the time'
author: 'Test Corporation'
inputs:
greeting: # id of input
description: 'The greeting we choose - will print ""{greeting}, World!"" on stdout'
required: true
default: 'Hello'
deprecationMessage: 'This property has been deprecated'
entryPoint: # id of input
description: 'optional docker entrypoint overwrite.'
required: false
outputs:
time: # id of output
description: 'The time we did the greeting'
icon: 'hello.svg' # vector art to display in the GitHub Marketplace
color: 'green' # optional, decorates the entry in the GitHub Marketplace
runs:
using: 'node16'
main: 'main.js'

View File

@@ -14,10 +14,10 @@ DEV_TARGET_RUNTIME=$3
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LAYOUT_DIR="$SCRIPT_DIR/../_layout"
DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/net6"
PACKAGE_DIR="$SCRIPT_DIR/../_package"
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
DOTNETSDK_VERSION="3.1.302"
DOTNETSDK_VERSION="6.0.100"
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
RUNNER_VERSION=$(cat runnerversion)

View File

@@ -1,5 +1,5 @@
{
"sdk": {
"version": "3.1.302"
"version": "net6"
}
}