mirror of
https://github.com/actions/runner.git
synced 2025-12-11 12:57:05 +00:00
Compare commits
10 Commits
features/n
...
v2.285.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50afba61b4 | ||
|
|
66ee648c13 | ||
|
|
16e83b0e84 | ||
|
|
c75a77df66 | ||
|
|
6332f9a42f | ||
|
|
5b8ff174c6 | ||
|
|
e3e977fd84 | ||
|
|
4dc8a09db3 | ||
|
|
dcc5d34ad1 | ||
|
|
3e34fb10c1 |
@@ -1,19 +1,16 @@
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Expose GITHUB_REF_* as environment variable (#1314)
|
- n/a
|
||||||
- Add arch to runner context (#1372)
|
|
||||||
- Support Conditional Steps in Composite Actions (#1438)
|
|
||||||
- Log current runner version in terminal (#1441)
|
|
||||||
|
|
||||||
## Bugs
|
## Bugs
|
||||||
|
|
||||||
- Makes the user keychains available to the service (#847)
|
- Revert node12 version due to fs.copyFileSync hang #1537
|
||||||
- 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
|
||||||
|
|
||||||
- Cleanup Older versions on MacOS now that we recreate node versions as needed (#1410)
|
- n/a
|
||||||
|
|
||||||
|
|
||||||
## 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.
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
<Update to ./src/runnerversion when creating release>
|
2.285.1
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ PRECACHE=$2
|
|||||||
|
|
||||||
NODE_URL=https://nodejs.org/dist
|
NODE_URL=https://nodejs.org/dist
|
||||||
NODE12_VERSION="12.13.1"
|
NODE12_VERSION="12.13.1"
|
||||||
|
NODE16_VERSION="16.13.0"
|
||||||
|
|
||||||
get_abs_path() {
|
get_abs_path() {
|
||||||
# exploits the fact that pwd will print abs path when no args
|
# exploits the fact that pwd will print abs path when no args
|
||||||
@@ -126,6 +127,8 @@ function acquireExternalTool() {
|
|||||||
if [[ "$PACKAGERUNTIME" == "win-x64" || "$PACKAGERUNTIME" == "win-x86" ]]; then
|
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.exe" node12/bin
|
||||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/$PACKAGERUNTIME/node.lib" 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
|
if [[ "$PRECACHE" != "" ]]; then
|
||||||
acquireExternalTool "https://github.com/microsoft/vswhere/releases/download/2.6.7/vswhere.exe" vswhere
|
acquireExternalTool "https://github.com/microsoft/vswhere/releases/download/2.6.7/vswhere.exe" vswhere
|
||||||
fi
|
fi
|
||||||
@@ -134,18 +137,23 @@ fi
|
|||||||
# Download the external tools only for OSX.
|
# Download the external tools only for OSX.
|
||||||
if [[ "$PACKAGERUNTIME" == "osx-x64" ]]; then
|
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${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
|
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-${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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$PACKAGERUNTIME" == "linux-arm64" ]]; then
|
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${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
|
fi
|
||||||
|
|
||||||
if [[ "$PACKAGERUNTIME" == "linux-arm" ]]; then
|
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${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
|
fi
|
||||||
|
|||||||
@@ -200,9 +200,17 @@ namespace GitHub.Runner.Common
|
|||||||
if (credData != null &&
|
if (credData != null &&
|
||||||
credData.Data.TryGetValue("clientId", out var clientId))
|
credData.Data.TryGetValue("clientId", out var clientId))
|
||||||
{
|
{
|
||||||
_userAgents.Add(new ProductInfoHeaderValue($"RunnerId", clientId));
|
_userAgents.Add(new ProductInfoHeaderValue("ClientId", 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)
|
public string GetDirectory(WellKnownDirectory directory)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace GitHub.Runner.Common
|
|||||||
Task<PackageMetadata> GetPackageAsync(string packageType, string platform, string version, bool includeToken, CancellationToken cancellationToken);
|
Task<PackageMetadata> GetPackageAsync(string packageType, string platform, string version, bool includeToken, CancellationToken cancellationToken);
|
||||||
|
|
||||||
// agent update
|
// agent update
|
||||||
Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, int agentId, string currentState);
|
Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, int agentId, string currentState, string trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class RunnerServer : RunnerService, IRunnerServer
|
public sealed class RunnerServer : RunnerService, IRunnerServer
|
||||||
@@ -341,25 +341,10 @@ namespace GitHub.Runner.Common
|
|||||||
return _genericTaskAgentClient.GetPackageAsync(packageType, platform, version, includeToken, cancellationToken: cancellationToken);
|
return _genericTaskAgentClient.GetPackageAsync(packageType, platform, version, includeToken, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, int agentId, string currentState)
|
public Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, int agentId, string currentState, string trace)
|
||||||
{
|
{
|
||||||
CheckConnection(RunnerConnectionType.Generic);
|
CheckConnection(RunnerConnectionType.Generic);
|
||||||
return _genericTaskAgentClient.UpdateAgentUpdateStateAsync(agentPoolId, agentId, currentState);
|
return _genericTaskAgentClient.UpdateAgentUpdateStateAsync(agentPoolId, agentId, currentState, trace);
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,7 +243,6 @@ namespace GitHub.Runner.Listener
|
|||||||
validator: Validators.ServerUrlValidator);
|
validator: Validators.ServerUrlValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OS_WINDOWS
|
|
||||||
public string GetWindowsLogonAccount(string defaultValue, string descriptionMsg)
|
public string GetWindowsLogonAccount(string defaultValue, string descriptionMsg)
|
||||||
{
|
{
|
||||||
return GetArgOrPrompt(
|
return GetArgOrPrompt(
|
||||||
@@ -252,7 +251,6 @@ namespace GitHub.Runner.Listener
|
|||||||
defaultValue: defaultValue,
|
defaultValue: defaultValue,
|
||||||
validator: Validators.NTAccountValidator);
|
validator: Validators.NTAccountValidator);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
public string GetWindowsLogonPassword(string accountName)
|
public string GetWindowsLogonPassword(string accountName)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
return !string.IsNullOrEmpty(value);
|
return !string.IsNullOrEmpty(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OS_WINDOWS
|
|
||||||
public static bool NTAccountValidator(string arg)
|
public static bool NTAccountValidator(string arg)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(arg) || String.IsNullOrEmpty(arg.TrimStart('.', '\\')))
|
if (string.IsNullOrEmpty(arg) || String.IsNullOrEmpty(arg.TrimStart('.', '\\')))
|
||||||
@@ -88,6 +87,5 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ namespace GitHub.Runner.Listener
|
|||||||
|
|
||||||
private static void LoadAndSetEnv()
|
private static void LoadAndSetEnv()
|
||||||
{
|
{
|
||||||
var binDir = Path.GetDirectoryName(AppContext.BaseDirectory);
|
var binDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||||
var rootDir = new DirectoryInfo(binDir).Parent.FullName;
|
var rootDir = new DirectoryInfo(binDir).Parent.FullName;
|
||||||
string envFile = Path.Combine(rootDir, ".env");
|
string envFile = Path.Combine(rootDir, ".env");
|
||||||
if (File.Exists(envFile))
|
if (File.Exists(envFile))
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using GitHub.Services.WebApi;
|
|||||||
using GitHub.Services.Common;
|
using GitHub.Services.Common;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace GitHub.Runner.Listener
|
namespace GitHub.Runner.Listener
|
||||||
{
|
{
|
||||||
@@ -63,23 +64,25 @@ namespace GitHub.Runner.Listener
|
|||||||
|
|
||||||
// Print console line that warn user not shutdown runner.
|
// Print console line that warn user not shutdown runner.
|
||||||
await UpdateRunnerUpdateStateAsync("Runner update in progress, do not shutdown runner.");
|
await UpdateRunnerUpdateStateAsync("Runner update in progress, do not shutdown runner.");
|
||||||
await UpdateRunnerUpdateStateAsync($"Downloading {_targetPackage.Version} runner");
|
await UpdateRunnerUpdateStateAsync($"Downloading {_targetPackage.Version} runner", $"RunnerPlatform: {_targetPackage.Platform}");
|
||||||
|
|
||||||
await DownloadLatestRunner(token);
|
var downloadTrace = await DownloadLatestRunner(token);
|
||||||
Trace.Info($"Download latest runner and unzip into runner root.");
|
Trace.Info($"Download latest runner and unzip into runner root.");
|
||||||
|
|
||||||
// wait till all running job finish
|
// wait till all running job finish
|
||||||
await UpdateRunnerUpdateStateAsync("Waiting for current job finish running.");
|
await UpdateRunnerUpdateStateAsync("Waiting for current job finish running.", downloadTrace);
|
||||||
|
|
||||||
await jobDispatcher.WaitAsync(token);
|
await jobDispatcher.WaitAsync(token);
|
||||||
Trace.Info($"All running job has exited.");
|
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
|
// We need to keep runner backup around for macOS until we fixed https://github.com/actions/runner/issues/743
|
||||||
// delete runner backup
|
// delete runner backup
|
||||||
|
var stopWatch = Stopwatch.StartNew();
|
||||||
DeletePreviousVersionRunnerBackup(token);
|
DeletePreviousVersionRunnerBackup(token);
|
||||||
Trace.Info($"Delete old version runner backup.");
|
Trace.Info($"Delete old version runner backup.");
|
||||||
|
stopWatch.Stop();
|
||||||
// generate update script from template
|
// generate update script from template
|
||||||
await UpdateRunnerUpdateStateAsync("Generate and execute update script.");
|
await UpdateRunnerUpdateStateAsync("Generate and execute update script.", $"DeleteRunnerBackupTime: {stopWatch.ElapsedMilliseconds}ms");
|
||||||
|
|
||||||
string updateScript = GenerateUpdateScript(restartInteractiveRunner);
|
string updateScript = GenerateUpdateScript(restartInteractiveRunner);
|
||||||
Trace.Info($"Generate update script into: {updateScript}");
|
Trace.Info($"Generate update script into: {updateScript}");
|
||||||
@@ -96,7 +99,7 @@ namespace GitHub.Runner.Listener
|
|||||||
invokeScript.Start();
|
invokeScript.Start();
|
||||||
Trace.Info($"Update script start running");
|
Trace.Info($"Update script start running");
|
||||||
|
|
||||||
await UpdateRunnerUpdateStateAsync("Runner will exit shortly for update, should be back online within 10 seconds.");
|
await UpdateRunnerUpdateStateAsync("Runner will exit shortly for update, should be back online within 10 seconds.", $"RestartInteractiveRunner: {restartInteractiveRunner}");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -150,8 +153,10 @@ namespace GitHub.Runner.Listener
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task DownloadLatestRunner(CancellationToken token)
|
private async Task<string> DownloadLatestRunner(CancellationToken token)
|
||||||
{
|
{
|
||||||
|
var traceStringBuilder = new StringBuilder();
|
||||||
|
traceStringBuilder.AppendLine($"DownloadUrl: {_targetPackage.DownloadUrl}");
|
||||||
string latestRunnerDirectory = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), Constants.Path.UpdateDirectory);
|
string latestRunnerDirectory = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), Constants.Path.UpdateDirectory);
|
||||||
IOUtil.DeleteDirectory(latestRunnerDirectory, token);
|
IOUtil.DeleteDirectory(latestRunnerDirectory, token);
|
||||||
Directory.CreateDirectory(latestRunnerDirectory);
|
Directory.CreateDirectory(latestRunnerDirectory);
|
||||||
@@ -160,6 +165,7 @@ namespace GitHub.Runner.Listener
|
|||||||
string archiveFile = null;
|
string archiveFile = null;
|
||||||
bool downloadSucceeded = false;
|
bool downloadSucceeded = false;
|
||||||
|
|
||||||
|
var stopWatch = Stopwatch.StartNew();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Download the runner, using multiple attempts in order to be resilient against any networking/CDN issues
|
// Download the runner, using multiple attempts in order to be resilient against any networking/CDN issues
|
||||||
@@ -210,6 +216,7 @@ namespace GitHub.Runner.Listener
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Trace.Info($"Download runner: begin download");
|
Trace.Info($"Download runner: begin download");
|
||||||
|
long downloadSize = 0;
|
||||||
|
|
||||||
//open zip stream in async mode
|
//open zip stream in async mode
|
||||||
using (HttpClient httpClient = new HttpClient(HostContext.CreateHttpClientHandler()))
|
using (HttpClient httpClient = new HttpClient(HostContext.CreateHttpClientHandler()))
|
||||||
@@ -228,11 +235,16 @@ namespace GitHub.Runner.Listener
|
|||||||
//81920 is the default used by System.IO.Stream.CopyTo and is under the large object heap threshold (85k).
|
//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 result.CopyToAsync(fs, 81920, downloadCts.Token);
|
||||||
await fs.FlushAsync(downloadCts.Token);
|
await fs.FlushAsync(downloadCts.Token);
|
||||||
|
downloadSize = fs.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Trace.Info($"Download runner: finished download");
|
Trace.Info($"Download runner: finished download");
|
||||||
downloadSucceeded = true;
|
downloadSucceeded = true;
|
||||||
|
stopWatch.Stop();
|
||||||
|
traceStringBuilder.AppendLine($"PackageDownloadTime: {stopWatch.ElapsedMilliseconds}ms");
|
||||||
|
traceStringBuilder.AppendLine($"Attempts: {attempt}");
|
||||||
|
traceStringBuilder.AppendLine($"PackageSize: {downloadSize / 1024 / 1024}MB");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException) when (token.IsCancellationRequested)
|
catch (OperationCanceledException) when (token.IsCancellationRequested)
|
||||||
@@ -257,6 +269,7 @@ namespace GitHub.Runner.Listener
|
|||||||
throw new TaskCanceledException($"Runner package '{archiveFile}' failed after {Constants.RunnerDownloadRetryMaxAttempts} download attempts");
|
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
|
// If we got this far, we know that we've successfully downloaded the runner package
|
||||||
// Validate Hash Matches if it is provided
|
// Validate Hash Matches if it is provided
|
||||||
using (FileStream stream = File.OpenRead(archiveFile))
|
using (FileStream stream = File.OpenRead(archiveFile))
|
||||||
@@ -320,7 +333,9 @@ namespace GitHub.Runner.Listener
|
|||||||
throw new NotSupportedException($"{archiveFile}");
|
throw new NotSupportedException($"{archiveFile}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stopWatch.Stop();
|
||||||
Trace.Info($"Finished getting latest runner package at: {latestRunnerDirectory}.");
|
Trace.Info($"Finished getting latest runner package at: {latestRunnerDirectory}.");
|
||||||
|
traceStringBuilder.AppendLine($"PackageExtractTime: {stopWatch.ElapsedMilliseconds}ms");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -340,6 +355,7 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stopWatch.Restart();
|
||||||
// copy latest runner into runner root folder
|
// copy latest runner into runner root folder
|
||||||
// copy bin from _work/_update -> bin.version under root
|
// copy bin from _work/_update -> bin.version under root
|
||||||
string binVersionDir = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Root), $"{Constants.Path.BinDirectory}.{_targetPackage.Version}");
|
string binVersionDir = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Root), $"{Constants.Path.BinDirectory}.{_targetPackage.Version}");
|
||||||
@@ -365,6 +381,11 @@ namespace GitHub.Runner.Listener
|
|||||||
IOUtil.DeleteFile(destination);
|
IOUtil.DeleteFile(destination);
|
||||||
file.CopyTo(destination, true);
|
file.CopyTo(destination, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stopWatch.Stop();
|
||||||
|
traceStringBuilder.AppendLine($"CopyRunnerToRootTime: {stopWatch.ElapsedMilliseconds}ms");
|
||||||
|
|
||||||
|
return traceStringBuilder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeletePreviousVersionRunnerBackup(CancellationToken token)
|
private void DeletePreviousVersionRunnerBackup(CancellationToken token)
|
||||||
@@ -484,13 +505,18 @@ namespace GitHub.Runner.Listener
|
|||||||
return updateScript;
|
return updateScript;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateRunnerUpdateStateAsync(string currentState)
|
private async Task UpdateRunnerUpdateStateAsync(string currentState, string trace = "")
|
||||||
{
|
{
|
||||||
_terminal.WriteLine(currentState);
|
_terminal.WriteLine(currentState);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(trace))
|
||||||
|
{
|
||||||
|
Trace.Info(trace);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _runnerServer.UpdateAgentUpdateStateAsync(_poolId, _agentId, currentState);
|
await _runnerServer.UpdateAgentUpdateStateAsync(_poolId, _agentId, currentState, trace);
|
||||||
}
|
}
|
||||||
catch (VssResourceNotFoundException)
|
catch (VssResourceNotFoundException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ namespace GitHub.Runner.PluginHost
|
|||||||
string assemblyFilename = assembly.Name + ".dll";
|
string assemblyFilename = assembly.Name + ".dll";
|
||||||
if (string.IsNullOrEmpty(executingAssemblyLocation))
|
if (string.IsNullOrEmpty(executingAssemblyLocation))
|
||||||
{
|
{
|
||||||
executingAssemblyLocation = Path.GetDirectoryName(AppContext.BaseDirectory);
|
executingAssemblyLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
}
|
}
|
||||||
return context.LoadFromAssemblyPath(Path.Combine(executingAssemblyLocation, assemblyFilename));
|
return context.LoadFromAssemblyPath(Path.Combine(executingAssemblyLocation, assemblyFilename));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
|
|||||||
@@ -444,7 +444,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
{
|
{
|
||||||
// We should never
|
// We should never
|
||||||
context.Error($"Error '{ex.Message}' when downloading file '{fileToDownload}'. (Downloader {downloaderId})");
|
context.Error($"Error '{ex.Message}' when downloading file '{fileToDownload}'. (Downloader {downloaderId})");
|
||||||
throw;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,7 +528,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
context.Output($"File error '{ex.Message}' when uploading file '{fileToUpload}'.");
|
context.Output($"File error '{ex.Message}' when uploading file '{fileToUpload}'.");
|
||||||
throw;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
// Clone action so we can modify the condition without affecting the original
|
// Clone action so we can modify the condition without affecting the original
|
||||||
var clonedAction = action.Clone() as Pipelines.ActionStep;
|
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++)
|
for (var i = 0; i < compositeAction.Steps.Count; i++)
|
||||||
{
|
{
|
||||||
// Store Id's for later load actions
|
// Load stored Ids for later load actions
|
||||||
compositeAction.Steps[i].Id = _cachedEmbeddedStepIds[action.Id][i];
|
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)
|
if (string.IsNullOrEmpty(executionContext.Global.Variables.Get("DistributedTask.EnableCompositeActions")) && compositeAction.Steps[i].Reference.Type != Pipelines.ActionSourceType.Script)
|
||||||
{
|
{
|
||||||
@@ -451,6 +451,16 @@ 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
|
else
|
||||||
{
|
{
|
||||||
@@ -1189,6 +1199,8 @@ namespace GitHub.Runner.Worker
|
|||||||
public string Pre { get; set; }
|
public string Pre { get; set; }
|
||||||
|
|
||||||
public string Post { get; set; }
|
public string Post { get; set; }
|
||||||
|
|
||||||
|
public string NodeVersion { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class PluginActionExecutionData : ActionExecutionData
|
public sealed class PluginActionExecutionData : ActionExecutionData
|
||||||
|
|||||||
@@ -451,7 +451,8 @@ namespace GitHub.Runner.Worker
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (string.Equals(usingToken.Value, "node12", StringComparison.OrdinalIgnoreCase))
|
else if (string.Equals(usingToken.Value, "node12", StringComparison.OrdinalIgnoreCase)||
|
||||||
|
string.Equals(usingToken.Value, "node16", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(mainToken?.Value))
|
if (string.IsNullOrEmpty(mainToken?.Value))
|
||||||
{
|
{
|
||||||
@@ -461,6 +462,7 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
return new NodeJSActionExecutionData()
|
return new NodeJSActionExecutionData()
|
||||||
{
|
{
|
||||||
|
NodeVersion = usingToken.Value,
|
||||||
Script = mainToken.Value,
|
Script = mainToken.Value,
|
||||||
Pre = preToken?.Value,
|
Pre = preToken?.Value,
|
||||||
InitCondition = preIfToken?.Value ?? "always()",
|
InitCondition = preIfToken?.Value ?? "always()",
|
||||||
@@ -490,7 +492,7 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException($"'using: {usingToken.Value}' is not supported, use 'docker' or 'node12' instead.");
|
throw new ArgumentOutOfRangeException($"'using: {usingToken.Value}' is not supported, use 'docker', 'node12' or 'node16' instead.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (pluginToken != null)
|
else if (pluginToken != null)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace GitHub.Runner.Worker.Expressions
|
|||||||
context.Trace.Info($"Search root directory: '{githubWorkspace}'");
|
context.Trace.Info($"Search root directory: '{githubWorkspace}'");
|
||||||
context.Trace.Info($"Search pattern: '{string.Join(", ", patterns)}'");
|
context.Trace.Info($"Search pattern: '{string.Join(", ", patterns)}'");
|
||||||
|
|
||||||
string binDir = Path.GetDirectoryName(AppContext.BaseDirectory);
|
string binDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||||
string runnerRoot = new DirectoryInfo(binDir).Parent.FullName;
|
string runnerRoot = new DirectoryInfo(binDir).Parent.FullName;
|
||||||
|
|
||||||
string node = Path.Combine(runnerRoot, "externals", "node12", "bin", $"node{IOUtil.ExeExtension}");
|
string node = Path.Combine(runnerRoot, "externals", "node12", "bin", $"node{IOUtil.ExeExtension}");
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
HasPreStep = Data.HasPre,
|
HasPreStep = Data.HasPre,
|
||||||
HasPostStep = Data.HasPost,
|
HasPostStep = Data.HasPost,
|
||||||
IsEmbedded = ExecutionContext.IsEmbedded,
|
IsEmbedded = ExecutionContext.IsEmbedded,
|
||||||
Type = "node12"
|
Type = Data.NodeVersion
|
||||||
};
|
};
|
||||||
ExecutionContext.Root.ActionsStepsTelemetry.Add(telemetry);
|
ExecutionContext.Root.ActionsStepsTelemetry.Add(telemetry);
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work);
|
workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work);
|
||||||
}
|
}
|
||||||
|
|
||||||
var nodeRuntimeVersion = await StepHost.DetermineNodeRuntimeVersion(ExecutionContext);
|
var nodeRuntimeVersion = await StepHost.DetermineNodeRuntimeVersion(ExecutionContext, Data.NodeVersion);
|
||||||
string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), nodeRuntimeVersion, "bin", $"node{IOUtil.ExeExtension}");
|
string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), nodeRuntimeVersion, "bin", $"node{IOUtil.ExeExtension}");
|
||||||
|
|
||||||
// Format the arguments passed to node.
|
// Format the arguments passed to node.
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
|
|
||||||
string ResolvePathForStepHost(string path);
|
string ResolvePathForStepHost(string path);
|
||||||
|
|
||||||
Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext);
|
Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion);
|
||||||
|
|
||||||
Task<int> ExecuteAsync(string workingDirectory,
|
Task<int> ExecuteAsync(string workingDirectory,
|
||||||
string fileName,
|
string fileName,
|
||||||
@@ -58,9 +58,9 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext)
|
public Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
|
||||||
{
|
{
|
||||||
return Task.FromResult<string>("node12");
|
return Task.FromResult<string>(preferredVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> ExecuteAsync(string workingDirectory,
|
public async Task<int> ExecuteAsync(string workingDirectory,
|
||||||
@@ -123,7 +123,7 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext)
|
public async Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
|
||||||
{
|
{
|
||||||
// Best effort to determine a compatible node runtime
|
// Best effort to determine a compatible node runtime
|
||||||
// There may be more variation in which libraries are linked than just musl/glibc,
|
// 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}";
|
var msg = $"JavaScript Actions in Alpine containers are only supported on x64 Linux runners. Detected {os} {arch}";
|
||||||
throw new NotSupportedException(msg);
|
throw new NotSupportedException(msg);
|
||||||
}
|
}
|
||||||
nodeExternal = "node12_alpine";
|
nodeExternal = $"{preferredVersion}_alpine";
|
||||||
executionContext.Debug($"Container distribution is alpine. Running JavaScript Action with external tool: {nodeExternal}");
|
executionContext.Debug($"Container distribution is alpine. Running JavaScript Action with external tool: {nodeExternal}");
|
||||||
return nodeExternal;
|
return nodeExternal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Optimistically use the default
|
// Optimistically use the default
|
||||||
nodeExternal = "node12";
|
nodeExternal = preferredVersion;
|
||||||
executionContext.Debug($"Running JavaScript Action with default external tool: {nodeExternal}");
|
executionContext.Debug($"Running JavaScript Action with default external tool: {nodeExternal}");
|
||||||
return nodeExternal;
|
return nodeExternal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,6 +142,12 @@ namespace GitHub.Runner.Worker
|
|||||||
Trace.Error(ex);
|
Trace.Error(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var secretSource = context.GetGitHubContext("secret_source");
|
||||||
|
if (!string.IsNullOrEmpty(secretSource))
|
||||||
|
{
|
||||||
|
context.Output($"Secret source: {secretSource}");
|
||||||
|
}
|
||||||
|
|
||||||
var repoFullName = context.GetGitHubContext("repository");
|
var repoFullName = context.GetGitHubContext("repository");
|
||||||
ArgUtil.NotNull(repoFullName, nameof(repoFullName));
|
ArgUtil.NotNull(repoFullName, nameof(repoFullName));
|
||||||
context.Debug($"Primary repository: {repoFullName}");
|
context.Debug($"Primary repository: {repoFullName}");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
"runs": {
|
"runs": {
|
||||||
"one-of": [
|
"one-of": [
|
||||||
"container-runs",
|
"container-runs",
|
||||||
"node12-runs",
|
"node-runs",
|
||||||
"plugin-runs",
|
"plugin-runs",
|
||||||
"composite-runs"
|
"composite-runs"
|
||||||
]
|
]
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
"loose-value-type": "string"
|
"loose-value-type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node12-runs": {
|
"node-runs": {
|
||||||
"mapping": {
|
"mapping": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"using": "non-empty-string",
|
"using": "non-empty-string",
|
||||||
@@ -112,10 +112,10 @@
|
|||||||
"item-type": "composite-step"
|
"item-type": "composite-step"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"composite-step":{
|
"composite-step": {
|
||||||
"one-of": [
|
"one-of": [
|
||||||
"run-step",
|
"run-step",
|
||||||
"uses-step"
|
"uses-step"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"run-step": {
|
"run-step": {
|
||||||
@@ -254,4 +254,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,6 +28,14 @@ namespace GitHub.Services.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IDictionary<string, object> Properties
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_request.Properties;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IEnumerable<String> IHttpHeaders.GetValues(String name)
|
IEnumerable<String> IHttpHeaders.GetValues(String name)
|
||||||
{
|
{
|
||||||
IEnumerable<String> values;
|
IEnumerable<String> values;
|
||||||
|
|||||||
@@ -14,5 +14,10 @@ namespace GitHub.Services.Common
|
|||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDictionary<string, object> Properties
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,12 @@ namespace GitHub.Services.Common.Diagnostics
|
|||||||
|
|
||||||
public static VssTraceActivity GetActivity(this HttpRequestMessage message)
|
public static VssTraceActivity GetActivity(this HttpRequestMessage message)
|
||||||
{
|
{
|
||||||
if (!message.Options.TryGetValue(VssTraceActivity.PropertyName, out VssTraceActivity traceActivity))
|
Object traceActivity;
|
||||||
|
if (!message.Properties.TryGetValue(VssTraceActivity.PropertyName, out traceActivity))
|
||||||
{
|
{
|
||||||
return VssTraceActivity.Empty;
|
return VssTraceActivity.Empty;
|
||||||
}
|
}
|
||||||
return traceActivity;
|
return (VssTraceActivity)traceActivity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Net.Http;
|
|
||||||
|
|
||||||
namespace GitHub.Services.Common.Diagnostics
|
namespace GitHub.Services.Common.Diagnostics
|
||||||
{
|
{
|
||||||
@@ -99,7 +98,7 @@ namespace GitHub.Services.Common.Diagnostics
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the property name used to cache this object on extensible objects.
|
/// Gets the property name used to cache this object on extensible objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly HttpRequestOptionsKey<VssTraceActivity> PropertyName = new HttpRequestOptionsKey<VssTraceActivity>("MS.VSS.Diagnostics.TraceActivity");
|
public const String PropertyName = "MS.VSS.Diagnostics.TraceActivity";
|
||||||
private static Lazy<VssTraceActivity> s_empty = new Lazy<VssTraceActivity>(() => new VssTraceActivity(Guid.Empty));
|
private static Lazy<VssTraceActivity> s_empty = new Lazy<VssTraceActivity>(() => new VssTraceActivity(Guid.Empty));
|
||||||
|
|
||||||
private sealed class CorrelationScope : IDisposable
|
private sealed class CorrelationScope : IDisposable
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ namespace GitHub.Services.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static readonly HttpRequestOptionsKey<VssHttpMessageHandler> PropertyName = new HttpRequestOptionsKey<VssHttpMessageHandler>("MS.VS.MessageHandler");
|
internal static readonly String PropertyName = "MS.VS.MessageHandler";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles the authentication hand-shake for a Visual Studio service.
|
/// 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
|
// Add ourselves to the message so the underlying token issuers may use it if necessary
|
||||||
request.Options.Set(VssHttpMessageHandler.PropertyName, this);
|
request.Properties[VssHttpMessageHandler.PropertyName] = this;
|
||||||
|
|
||||||
Boolean succeeded = false;
|
Boolean succeeded = false;
|
||||||
Boolean lastResponseDemandedProxyAuth = 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
|
// 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.
|
// assume it is OK to buffer by default.
|
||||||
HttpCompletionOption completionOption;
|
HttpCompletionOption completionOption;
|
||||||
if (!request.Options.TryGetValue(VssHttpRequestSettings.HttpCompletionOptionPropertyName, out completionOption))
|
if (!request.Properties.TryGetValue(VssHttpRequestSettings.HttpCompletionOptionPropertyName, out completionOption))
|
||||||
{
|
{
|
||||||
completionOption = HttpCompletionOption.ResponseContentRead;
|
completionOption = HttpCompletionOption.ResponseContentRead;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace GitHub.Services.Common
|
|||||||
{
|
{
|
||||||
DateTime _lastTime;
|
DateTime _lastTime;
|
||||||
|
|
||||||
private static readonly HttpRequestOptionsKey<VssHttpMessageHandlerTraceInfo> TfsTraceInfoKey = new HttpRequestOptionsKey<VssHttpMessageHandlerTraceInfo>("TFS_TraceInfo");
|
static readonly String TfsTraceInfoKey = "TFS_TraceInfo";
|
||||||
|
|
||||||
public int TokenRetries { get; internal set; }
|
public int TokenRetries { get; internal set; }
|
||||||
|
|
||||||
@@ -76,9 +76,10 @@ namespace GitHub.Services.Common
|
|||||||
/// <param name="traceInfo"></param>
|
/// <param name="traceInfo"></param>
|
||||||
public static void SetTraceInfo(HttpRequestMessage message, VssHttpMessageHandlerTraceInfo traceInfo)
|
public static void SetTraceInfo(HttpRequestMessage message, VssHttpMessageHandlerTraceInfo traceInfo)
|
||||||
{
|
{
|
||||||
if (!message.Options.TryGetValue(TfsTraceInfoKey, out var _))
|
object existingTraceInfo;
|
||||||
|
if (!message.Properties.TryGetValue(TfsTraceInfoKey, out existingTraceInfo))
|
||||||
{
|
{
|
||||||
message.Options.Set(TfsTraceInfoKey, traceInfo);
|
message.Properties.Add(TfsTraceInfoKey, traceInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,8 +90,13 @@ namespace GitHub.Services.Common
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static VssHttpMessageHandlerTraceInfo GetTraceInfo(HttpRequestMessage message)
|
public static VssHttpMessageHandlerTraceInfo GetTraceInfo(HttpRequestMessage message)
|
||||||
{
|
{
|
||||||
VssHttpMessageHandlerTraceInfo traceInfo;
|
VssHttpMessageHandlerTraceInfo traceInfo = null;
|
||||||
message.Options.TryGetValue(TfsTraceInfoKey, out traceInfo);
|
|
||||||
|
if (message.Properties.TryGetValue(TfsTraceInfoKey, out object traceInfoObject))
|
||||||
|
{
|
||||||
|
traceInfo = traceInfoObject as VssHttpMessageHandlerTraceInfo;
|
||||||
|
}
|
||||||
|
|
||||||
return traceInfo;
|
return traceInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -291,12 +291,12 @@ namespace GitHub.Services.Common
|
|||||||
protected internal virtual Boolean ApplyTo(HttpRequestMessage request)
|
protected internal virtual Boolean ApplyTo(HttpRequestMessage request)
|
||||||
{
|
{
|
||||||
// Make sure we only apply the settings to the request once
|
// Make sure we only apply the settings to the request once
|
||||||
if (request.Options.TryGetValue(PropertyName, out var _))
|
if (request.Properties.ContainsKey(PropertyName))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Options.Set(PropertyName, this);
|
request.Properties.Add(PropertyName, this);
|
||||||
|
|
||||||
if (this.AcceptLanguages != null && this.AcceptLanguages.Count > 0)
|
if (this.AcceptLanguages != null && this.AcceptLanguages.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -366,12 +366,12 @@ namespace GitHub.Services.Common
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the property name used to reference this object.
|
/// Gets the property name used to reference this object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly HttpRequestOptionsKey<VssHttpRequestSettings> PropertyName = new HttpRequestOptionsKey<VssHttpRequestSettings>("MS.VS.RequestSettings");
|
public const String PropertyName = "MS.VS.RequestSettings";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the property name used to reference the completion option for a specific request.
|
/// Gets the property name used to reference the completion option for a specific request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly HttpRequestOptionsKey<HttpCompletionOption> HttpCompletionOptionPropertyName = new HttpRequestOptionsKey<HttpCompletionOption>("MS.VS.HttpCompletionOption");
|
public const String HttpCompletionOptionPropertyName = "MS.VS.HttpCompletionOption";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Header to include the light weight response client option.
|
/// Header to include the light weight response client option.
|
||||||
|
|||||||
@@ -53,14 +53,23 @@ namespace GitHub.Services.Common
|
|||||||
VssTraceActivity traceActivity = VssTraceActivity.Current;
|
VssTraceActivity traceActivity = VssTraceActivity.Current;
|
||||||
|
|
||||||
// Allow overriding default retry options per request
|
// Allow overriding default retry options per request
|
||||||
VssHttpRetryOptions retryOptions;
|
VssHttpRetryOptions retryOptions = m_retryOptions;
|
||||||
request.Options.TryGetValue(HttpRetryOptionsKey, out retryOptions);
|
object retryOptionsObject;
|
||||||
|
if (request.Properties.TryGetValue(HttpRetryOptionsKey, out retryOptionsObject)) // NETSTANDARD compliant, TryGetValue<T> is not
|
||||||
TimeSpan minBackoff = (retryOptions ?? m_retryOptions).MinBackoff;
|
{
|
||||||
Int32 maxAttempts = (retryOptions ?? m_retryOptions).MaxRetries + 1;
|
// 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;
|
||||||
|
|
||||||
IVssHttpRetryInfo retryInfo = null;
|
IVssHttpRetryInfo retryInfo = null;
|
||||||
request.Options.TryGetValue(HttpRetryInfoKey, out retryInfo);
|
object retryInfoObject;
|
||||||
|
if (request.Properties.TryGetValue(HttpRetryInfoKey, out retryInfoObject)) // NETSTANDARD compliant, TryGetValue<T> is not
|
||||||
|
{
|
||||||
|
retryInfo = retryInfoObject as IVssHttpRetryInfo;
|
||||||
|
}
|
||||||
|
|
||||||
if (IsLowPriority(request))
|
if (IsLowPriority(request))
|
||||||
{
|
{
|
||||||
@@ -216,8 +225,8 @@ namespace GitHub.Services.Common
|
|||||||
}
|
}
|
||||||
|
|
||||||
private VssHttpRetryOptions m_retryOptions;
|
private VssHttpRetryOptions m_retryOptions;
|
||||||
public static readonly HttpRequestOptionsKey<IVssHttpRetryInfo> HttpRetryInfoKey = new HttpRequestOptionsKey<IVssHttpRetryInfo>("HttpRetryInfo");
|
public const string HttpRetryInfoKey = "HttpRetryInfo";
|
||||||
public static readonly HttpRequestOptionsKey<VssHttpRetryOptions> HttpRetryOptionsKey = new HttpRequestOptionsKey<VssHttpRetryOptions>("VssHttpRetryOptions");
|
public const string HttpRetryOptionsKey = "VssHttpRetryOptions";
|
||||||
private string m_clientName = "";
|
private string m_clientName = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -768,6 +768,7 @@ namespace GitHub.DistributedTask.WebApi
|
|||||||
/// <param name="poolId"></param>
|
/// <param name="poolId"></param>
|
||||||
/// <param name="agentId"></param>
|
/// <param name="agentId"></param>
|
||||||
/// <param name="currentState"></param>
|
/// <param name="currentState"></param>
|
||||||
|
/// <param name="updateTrace"></param>
|
||||||
/// <param name="userState"></param>
|
/// <param name="userState"></param>
|
||||||
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
|
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
@@ -775,6 +776,7 @@ namespace GitHub.DistributedTask.WebApi
|
|||||||
int poolId,
|
int poolId,
|
||||||
int agentId,
|
int agentId,
|
||||||
string currentState,
|
string currentState,
|
||||||
|
string updateTrace,
|
||||||
object userState = null,
|
object userState = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
@@ -784,6 +786,7 @@ namespace GitHub.DistributedTask.WebApi
|
|||||||
|
|
||||||
List<KeyValuePair<string, string>> queryParams = new List<KeyValuePair<string, string>>();
|
List<KeyValuePair<string, string>> queryParams = new List<KeyValuePair<string, string>>();
|
||||||
queryParams.Add("currentState", currentState);
|
queryParams.Add("currentState", currentState);
|
||||||
|
queryParams.Add("updateTrace", updateTrace);
|
||||||
|
|
||||||
return SendAsync<TaskAgent>(
|
return SendAsync<TaskAgent>(
|
||||||
httpMethod,
|
httpMethod,
|
||||||
@@ -794,65 +797,5 @@ namespace GitHub.DistributedTask.WebApi
|
|||||||
userState: userState,
|
userState: userState,
|
||||||
cancellationToken: cancellationToken);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
|
|||||||
@@ -833,7 +833,7 @@ namespace GitHub.Services.WebApi
|
|||||||
{
|
{
|
||||||
if (userState != null)
|
if (userState != null)
|
||||||
{
|
{
|
||||||
message.Options.Set(UserStatePropertyName, userState);
|
message.Properties[UserStatePropertyName] = userState;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!message.Headers.Contains(Common.Internal.HttpHeaders.VssE2EID))
|
if (!message.Headers.Contains(Common.Internal.HttpHeaders.VssE2EID))
|
||||||
@@ -842,11 +842,11 @@ namespace GitHub.Services.WebApi
|
|||||||
}
|
}
|
||||||
VssHttpEventSource.Log.HttpRequestStart(traceActivity, message);
|
VssHttpEventSource.Log.HttpRequestStart(traceActivity, message);
|
||||||
message.Trace();
|
message.Trace();
|
||||||
message.Options.Set(VssTraceActivity.PropertyName, traceActivity);
|
message.Properties[VssTraceActivity.PropertyName] = traceActivity;
|
||||||
|
|
||||||
// Send the completion option to the inner handler stack so we know when it's safe to buffer
|
// Send the completion option to the inner handler stack so we know when it's safe to buffer
|
||||||
// and when we should avoid buffering.
|
// and when we should avoid buffering.
|
||||||
message.Options.Set(VssHttpRequestSettings.HttpCompletionOptionPropertyName, completionOption);
|
message.Properties[VssHttpRequestSettings.HttpCompletionOptionPropertyName] = completionOption;
|
||||||
|
|
||||||
//ConfigureAwait(false) enables the continuation to be run outside
|
//ConfigureAwait(false) enables the continuation to be run outside
|
||||||
//any captured SyncronizationContext (such as ASP.NET's) which keeps things
|
//any captured SyncronizationContext (such as ASP.NET's) which keeps things
|
||||||
@@ -1154,9 +1154,7 @@ namespace GitHub.Services.WebApi
|
|||||||
{
|
{
|
||||||
if (BaseAddress != null)
|
if (BaseAddress != null)
|
||||||
{
|
{
|
||||||
#pragma warning disable SYSLIB0014
|
|
||||||
ServicePoint servicePoint = ServicePointManager.FindServicePoint(BaseAddress);
|
ServicePoint servicePoint = ServicePointManager.FindServicePoint(BaseAddress);
|
||||||
#pragma warning restore SYSLIB0014
|
|
||||||
servicePoint.UseNagleAlgorithm = false;
|
servicePoint.UseNagleAlgorithm = false;
|
||||||
servicePoint.SetTcpKeepAlive(
|
servicePoint.SetTcpKeepAlive(
|
||||||
enabled: true,
|
enabled: true,
|
||||||
@@ -1274,7 +1272,7 @@ namespace GitHub.Services.WebApi
|
|||||||
|
|
||||||
private const String c_jsonMediaType = "application/json";
|
private const String c_jsonMediaType = "application/json";
|
||||||
|
|
||||||
public static readonly HttpRequestOptionsKey<object> UserStatePropertyName = new HttpRequestOptionsKey<object>("VssClientBaseUserState");
|
public readonly static String UserStatePropertyName = "VssClientBaseUserState";
|
||||||
|
|
||||||
protected sealed class OperationScope : IDisposable
|
protected sealed class OperationScope : IDisposable
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ namespace GitHub.Services.WebApi
|
|||||||
|
|
||||||
if (routeReplacementOptions.HasFlag(RouteReplacementOptions.EscapeUri))
|
if (routeReplacementOptions.HasFlag(RouteReplacementOptions.EscapeUri))
|
||||||
{
|
{
|
||||||
sbResult = new StringBuilder(Uri.EscapeDataString(sbResult.ToString()));
|
sbResult = new StringBuilder(Uri.EscapeUriString(sbResult.ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (routeReplacementOptions.HasFlag(RouteReplacementOptions.AppendUnusedAsQueryParams) && unusedValues.Count > 0)
|
if (routeReplacementOptions.HasFlag(RouteReplacementOptions.AppendUnusedAsQueryParams) && unusedValues.Count > 0)
|
||||||
|
|||||||
@@ -6,24 +6,27 @@ using System.Globalization;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace GitHub.Services.WebApi
|
namespace GitHub.Services.WebApi
|
||||||
{
|
{
|
||||||
internal static class HttpMessageExtensions
|
internal static class HttpMessageExtensions
|
||||||
{
|
{
|
||||||
private static readonly HttpRequestOptionsKey<VssRequestTimerTrace> tracerKey = new HttpRequestOptionsKey<VssRequestTimerTrace>("VSS_HTTP_TIMER_TRACE");
|
private const string tracerKey = "VSS_HTTP_TIMER_TRACE";
|
||||||
|
|
||||||
internal static void Trace(this HttpRequestMessage request)
|
internal static void Trace(this HttpRequestMessage request)
|
||||||
{
|
{
|
||||||
VssRequestTimerTrace tracer;
|
Object tracerObj = null;
|
||||||
if (request.Options.TryGetValue(tracerKey, out tracer))
|
VssRequestTimerTrace tracer = null;
|
||||||
|
if (request.Properties.TryGetValue(tracerKey, out tracerObj))
|
||||||
{
|
{
|
||||||
|
tracer = tracerObj as VssRequestTimerTrace;
|
||||||
Debug.Assert(tracer != null, "Tracer object is the wrong type!");
|
Debug.Assert(tracer != null, "Tracer object is the wrong type!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tracer = new VssRequestTimerTrace();
|
tracer = new VssRequestTimerTrace();
|
||||||
request.Options.Set(tracerKey, tracer);
|
request.Properties[tracerKey] = tracer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tracer != null)
|
if (tracer != null)
|
||||||
@@ -34,9 +37,11 @@ namespace GitHub.Services.WebApi
|
|||||||
|
|
||||||
internal static void Trace(this HttpResponseMessage response)
|
internal static void Trace(this HttpResponseMessage response)
|
||||||
{
|
{
|
||||||
VssRequestTimerTrace tracer;
|
Object tracerObj = null;
|
||||||
if (response.RequestMessage.Options.TryGetValue(tracerKey, out tracer))
|
VssRequestTimerTrace tracer = null;
|
||||||
|
if (response.RequestMessage.Properties.TryGetValue(tracerKey, out tracerObj))
|
||||||
{
|
{
|
||||||
|
tracer = tracerObj as VssRequestTimerTrace;
|
||||||
Debug.Assert(tracer != null, "Tracer object is the wrong type!");
|
Debug.Assert(tracer != null, "Tracer object is the wrong type!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -547,7 +547,6 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OS_WINDOWS
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", nameof(CommandSettings))]
|
[Trait("Category", nameof(CommandSettings))]
|
||||||
@@ -575,7 +574,6 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
Assert.Equal("some windows logon account", actual);
|
Assert.Equal("some windows logon account", actual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
|
|||||||
@@ -965,7 +965,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
var result = await _actionManager.PrepareActionsAsync(_ec.Object, actions);
|
var result = await _actionManager.PrepareActionsAsync(_ec.Object, actions);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
Assert.Equal(1, result.PreStepTracker.Count);
|
Assert.Equal(1, result.PreStepTracker.Count);
|
||||||
@@ -1288,7 +1288,7 @@ runs:
|
|||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void LoadsNodeActionDefinition()
|
public void LoadsNode12ActionDefinition()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1344,8 +1344,78 @@ runs:
|
|||||||
Assert.True(string.IsNullOrEmpty(inputDefaults["entryPoint"]));
|
Assert.True(string.IsNullOrEmpty(inputDefaults["entryPoint"]));
|
||||||
Assert.NotNull(definition.Data.Execution); // execution
|
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("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
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -408,6 +408,50 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
var nodeAction = result.Execution as NodeJSActionExecutionData;
|
var nodeAction = result.Execution as NodeJSActionExecutionData;
|
||||||
|
|
||||||
Assert.Equal("main.js", nodeAction.Script);
|
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
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ 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);
|
_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();
|
GitHubContext github = new GitHubContext();
|
||||||
github["repository"] = new Pipelines.ContextData.StringContextData("actions/runner");
|
github["repository"] = new Pipelines.ContextData.StringContextData("actions/runner");
|
||||||
|
github["secret_source"] = new Pipelines.ContextData.StringContextData("Actions");
|
||||||
_message.ContextData.Add("github", github);
|
_message.ContextData.Add("github", github);
|
||||||
|
|
||||||
hc.SetSingleton(_actionManager.Object);
|
hc.SetSingleton(_actionManager.Object);
|
||||||
|
|||||||
109
src/Test/L0/Worker/StepHostL0.cs
Normal file
109
src/Test/L0/Worker/StepHostL0.cs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
<NoWarn>NU1701;NU1603;NU1603;xUnit2013;</NoWarn>
|
<NoWarn>NU1701;NU1603;NU1603;xUnit2013;</NoWarn>
|
||||||
|
|||||||
20
src/Test/TestData/node16action.yml
Normal file
20
src/Test/TestData/node16action.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
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'
|
||||||
@@ -14,10 +14,10 @@ DEV_TARGET_RUNTIME=$3
|
|||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
LAYOUT_DIR="$SCRIPT_DIR/../_layout"
|
LAYOUT_DIR="$SCRIPT_DIR/../_layout"
|
||||||
DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/net6"
|
DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
|
||||||
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
||||||
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
||||||
DOTNETSDK_VERSION="6.0.100"
|
DOTNETSDK_VERSION="3.1.302"
|
||||||
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
|
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
|
||||||
RUNNER_VERSION=$(cat runnerversion)
|
RUNNER_VERSION=$(cat runnerversion)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "net6"
|
"version": "3.1.302"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.284.0
|
2.285.1
|
||||||
|
|||||||
Reference in New Issue
Block a user