mirror of
https://github.com/actions/runner.git
synced 2025-12-10 20:36:49 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f764f5dfa7 | ||
|
|
e4716930a9 |
@@ -5,7 +5,7 @@
|
|||||||
"features": {
|
"features": {
|
||||||
"ghcr.io/devcontainers/features/docker-in-docker:1": {},
|
"ghcr.io/devcontainers/features/docker-in-docker:1": {},
|
||||||
"ghcr.io/devcontainers/features/dotnet": {
|
"ghcr.io/devcontainers/features/dotnet": {
|
||||||
"version": "6.0.405"
|
"version": "6.0.300"
|
||||||
},
|
},
|
||||||
"ghcr.io/devcontainers/features/node:1": {
|
"ghcr.io/devcontainers/features/node:1": {
|
||||||
"version": "16"
|
"version": "16"
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ FROM mcr.microsoft.com/dotnet/runtime-deps:6.0 as build
|
|||||||
ARG RUNNER_VERSION
|
ARG RUNNER_VERSION
|
||||||
ARG RUNNER_ARCH="x64"
|
ARG RUNNER_ARCH="x64"
|
||||||
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.2.0
|
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.2.0
|
||||||
ARG DOCKER_VERSION=20.10.23
|
|
||||||
|
|
||||||
RUN apt update -y && apt install curl unzip -y
|
RUN apt update -y && apt install curl unzip -y
|
||||||
|
|
||||||
@@ -16,12 +15,6 @@ RUN curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-c
|
|||||||
&& unzip ./runner-container-hooks.zip -d ./k8s \
|
&& unzip ./runner-container-hooks.zip -d ./k8s \
|
||||||
&& rm runner-container-hooks.zip
|
&& rm runner-container-hooks.zip
|
||||||
|
|
||||||
RUN export DOCKER_ARCH=x86_64 \
|
|
||||||
&& if [ "$RUNNER_ARCH" = "arm64" ]; then export DOCKER_ARCH=aarch64 ; fi \
|
|
||||||
&& curl -fLo docker.tgz https://download.docker.com/linux/static/stable/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz \
|
|
||||||
&& tar zxvf docker.tgz \
|
|
||||||
&& rm -rf docker.tgz
|
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/runtime-deps:6.0
|
FROM mcr.microsoft.com/dotnet/runtime-deps:6.0
|
||||||
|
|
||||||
ENV RUNNER_ALLOW_RUNASROOT=1
|
ENV RUNNER_ALLOW_RUNASROOT=1
|
||||||
@@ -30,5 +23,3 @@ ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1
|
|||||||
|
|
||||||
WORKDIR /actions-runner
|
WORKDIR /actions-runner
|
||||||
COPY --from=build /actions-runner .
|
COPY --from=build /actions-runner .
|
||||||
|
|
||||||
RUN install -o root -g root -m 755 docker/* /usr/bin/ && rm -rf docker
|
|
||||||
@@ -1,15 +1,19 @@
|
|||||||
## Features
|
## Features
|
||||||
- Add support for ghe.com domain (#2420)
|
- Log GitHub RequestId for better traceability (#2332)
|
||||||
- Add docker cli to the runner image. (#2425)
|
- Dual upload summary to Actions and Result service (#2334)
|
||||||
|
- Allow providing extra User-Agent for better correlation (#2370)
|
||||||
|
- Show more information in the runner log (#2377)
|
||||||
|
- New option to remove local config files (#2367)
|
||||||
|
|
||||||
## Bugs
|
## Bugs
|
||||||
- Fix URL construction bug for RunService (#2396)
|
- Treat jitconfig as secret (#2335)
|
||||||
- Defer evaluation of a step's DisplayName until its condition is evaluated. (#2313)
|
- Add Header/Footer to multi-line message in StdoutTraceListener (#2336)
|
||||||
- Replace '(' and ')' with '[' and '] from OS.Description for fixing User-Agent header validation (#2288)
|
- Update Node dependencies (#2381)
|
||||||
|
|
||||||
## Misc
|
## Misc
|
||||||
- Bump dotnet sdk to latest version. (#2392)
|
- Make runner image print diag log to STDOUT (#2331)
|
||||||
- Start calling run service for job completion (#2412, #2423)
|
- Update Node.js to 16.16.0 (#2371)
|
||||||
|
- Add a disclaimer for which runner version is available to a given tenant (#2362)
|
||||||
|
|
||||||
_Note: Actions Runner follows a progressive release policy, so the latest release might not be available to your enterprise, organization, or repository yet.
|
_Note: Actions Runner follows a progressive release policy, so the latest release might not be available to your enterprise, organization, or repository yet.
|
||||||
To confirm which version of the Actions Runner you should expect, please view the download instructions for your enterprise, organization, or repository.
|
To confirm which version of the Actions Runner you should expect, please view the download instructions for your enterprise, organization, or repository.
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.302.1
|
2.301.1
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
39f2a931565d6a10e695ac8ed14bb9dcbb568151410349b32dbf9c27bae29602
|
1d709d93e5d3c6c6c656a61aa6c1781050224788a05b0e6ecc4c3c0408bdf89c
|
||||||
@@ -1 +1 @@
|
|||||||
29ffb303537d8ba674fbebc7729292c21c4ebd17b3198f91ed593ef4cbbb67b5
|
b92a47cfeaad02255b1f7a377060651b73ae5e5db22a188dbbcb4183ab03a03d
|
||||||
@@ -1 +1 @@
|
|||||||
de6868a836fa3cb9e5ddddbc079da1c25e819aa2d2fc193cc9931c353687c57c
|
68a9a8ef0843a8bb74241894f6f63fd76241a82295c5337d3cc7a940a314c78e
|
||||||
@@ -1 +1 @@
|
|||||||
339d3e1a5fd28450c0fe6cb820cc7aae291f0f9e2d153ac34e1f7b080e35d30e
|
02c7126ff4d63ee2a0ae390c81434c125630522aadf35903bbeebb1a99d8af99
|
||||||
@@ -1 +1 @@
|
|||||||
dcb7f606c1d7d290381e5020ee73e7f16dcbd2f20ac9b431362ccbb5120d449c
|
c9d5a542f8d765168855a89e83ae0a8970d00869041c4f9a766651c04c72b212
|
||||||
@@ -1 +1 @@
|
|||||||
1bbcb0e9a2cf4be4b1fce77458de139b70ac58efcbb415a6db028b9373ae1673
|
39d0683f0f115a211cb10c473e9574c16549a19d4e9a6c637ded3d7022bf809f
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
44cd25f3c104d0abb44d262397a80e0b2c4f206465c5d899a22eec043dac0fb3
|
d94f2fbaf210297162bc9f3add819d73682c3aa6899e321c3872412b924d5504
|
||||||
@@ -18,20 +18,6 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
|
|||||||
done
|
done
|
||||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
|
||||||
# Wait for docker to start
|
|
||||||
if [ ! -z "$RUNNER_WAIT_FOR_DOCKER_IN_SECONDS" ]; then
|
|
||||||
if [ "$RUNNER_WAIT_FOR_DOCKER_IN_SECONDS" -gt 0 ]; then
|
|
||||||
echo "Waiting for docker to be ready."
|
|
||||||
for i in $(seq "$RUNNER_WAIT_FOR_DOCKER_IN_SECONDS"); do
|
|
||||||
if docker ps > /dev/null 2>&1; then
|
|
||||||
echo "Docker is ready."
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
"$DIR"/safe_sleep.sh 1
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
updateFile="update.finished"
|
updateFile="update.finished"
|
||||||
"$DIR"/bin/Runner.Listener run $*
|
"$DIR"/bin/Runner.Listener run $*
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ Microsoft.Win32.Registry.dll
|
|||||||
mscordaccore.dll
|
mscordaccore.dll
|
||||||
mscordaccore_amd64_amd64_6.0.522.21309.dll
|
mscordaccore_amd64_amd64_6.0.522.21309.dll
|
||||||
mscordaccore_arm64_arm64_6.0.522.21309.dll
|
mscordaccore_arm64_arm64_6.0.522.21309.dll
|
||||||
mscordaccore_amd64_amd64_6.0.1322.58009.dll
|
|
||||||
mscordbi.dll
|
mscordbi.dll
|
||||||
mscorlib.dll
|
mscorlib.dll
|
||||||
mscorrc.debug.dll
|
mscorrc.debug.dll
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.Actions.RunService.WebApi;
|
|
||||||
using GitHub.DistributedTask.Pipelines;
|
using GitHub.DistributedTask.Pipelines;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using GitHub.Services.Common;
|
using GitHub.Services.Common;
|
||||||
|
using GitHub.Services.WebApi;
|
||||||
using Sdk.WebApi.WebApi.RawClient;
|
using Sdk.WebApi.WebApi.RawClient;
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
@@ -17,8 +16,6 @@ namespace GitHub.Runner.Common
|
|||||||
Task ConnectAsync(Uri serverUrl, VssCredentials credentials);
|
Task ConnectAsync(Uri serverUrl, VssCredentials credentials);
|
||||||
|
|
||||||
Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken token);
|
Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken token);
|
||||||
|
|
||||||
Task CompleteJobAsync(Guid planId, Guid jobId, TaskResult result, Dictionary<String, VariableValue> outputs, IList<StepResult> stepResults, CancellationToken token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class RunServer : RunnerService, IRunServer
|
public sealed class RunServer : RunnerService, IRunServer
|
||||||
@@ -32,7 +29,7 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
requestUri = serverUri;
|
requestUri = serverUri;
|
||||||
|
|
||||||
_connection = VssUtil.CreateRawConnection(serverUri, credentials);
|
_connection = VssUtil.CreateRawConnection(new Uri(serverUri.Authority), credentials);
|
||||||
_runServiceHttpClient = await _connection.GetClientAsync<RunServiceHttpClient>();
|
_runServiceHttpClient = await _connection.GetClientAsync<RunServiceHttpClient>();
|
||||||
_hasConnection = true;
|
_hasConnection = true;
|
||||||
}
|
}
|
||||||
@@ -58,11 +55,5 @@ namespace GitHub.Runner.Common
|
|||||||
return jobMessage;
|
return jobMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task CompleteJobAsync(Guid planId, Guid jobId, TaskResult result, Dictionary<String, VariableValue> outputs, IList<StepResult> stepResults, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
CheckConnection();
|
|
||||||
return RetryRequest(
|
|
||||||
async () => await _runServiceHttpClient.CompleteJobAsync(requestUri, planId, jobId, result, outputs, stepResults, cancellationToken), cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,19 +68,6 @@ namespace GitHub.Runner.Common
|
|||||||
throw new InvalidOperationException(nameof(EstablishVssConnection));
|
throw new InvalidOperationException(nameof(EstablishVssConnection));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task RetryRequest(Func<Task> func,
|
|
||||||
CancellationToken cancellationToken,
|
|
||||||
int maxRetryAttemptsCount = 5
|
|
||||||
)
|
|
||||||
{
|
|
||||||
async Task<Unit> wrappedFunc()
|
|
||||||
{
|
|
||||||
await func();
|
|
||||||
return Unit.Value;
|
|
||||||
}
|
|
||||||
await RetryRequest<Unit>(wrappedFunc, cancellationToken, maxRetryAttemptsCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async Task<T> RetryRequest<T>(Func<Task<T>> func,
|
protected async Task<T> RetryRequest<T>(Func<Task<T>> func,
|
||||||
CancellationToken cancellationToken,
|
CancellationToken cancellationToken,
|
||||||
int maxRetryAttemptsCount = 5
|
int maxRetryAttemptsCount = 5
|
||||||
@@ -98,7 +85,7 @@ namespace GitHub.Runner.Common
|
|||||||
// TODO: Add handling of non-retriable exceptions: https://github.com/github/actions-broker/issues/122
|
// TODO: Add handling of non-retriable exceptions: https://github.com/github/actions-broker/issues/122
|
||||||
catch (Exception ex) when (retryCount < maxRetryAttemptsCount)
|
catch (Exception ex) when (retryCount < maxRetryAttemptsCount)
|
||||||
{
|
{
|
||||||
Trace.Error("Catch exception during request");
|
Trace.Error("Catch exception during get full job message");
|
||||||
Trace.Error(ex);
|
Trace.Error(ex);
|
||||||
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
|
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
|
||||||
Trace.Warning($"Back off {backOff.TotalSeconds} seconds before next retry. {maxRetryAttemptsCount - retryCount} attempt left.");
|
Trace.Warning($"Back off {backOff.TotalSeconds} seconds before next retry. {maxRetryAttemptsCount - retryCount} attempt left.");
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
// Represents absence of value.
|
|
||||||
namespace GitHub.Runner.Common
|
|
||||||
{
|
|
||||||
public readonly struct Unit
|
|
||||||
{
|
|
||||||
public static readonly Unit Value = default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -73,7 +73,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
{
|
{
|
||||||
var headerValues = new List<ProductInfoHeaderValue>();
|
var headerValues = new List<ProductInfoHeaderValue>();
|
||||||
headerValues.Add(new ProductInfoHeaderValue($"GitHubActionsRunner-Plugin", BuildConstants.RunnerPackage.Version));
|
headerValues.Add(new ProductInfoHeaderValue($"GitHubActionsRunner-Plugin", BuildConstants.RunnerPackage.Version));
|
||||||
headerValues.Add(new ProductInfoHeaderValue($"({StringUtil.SanitizeUserAgentHeader(RuntimeInformation.OSDescription)})"));
|
headerValues.Add(new ProductInfoHeaderValue($"({RuntimeInformation.OSDescription.Trim()})"));
|
||||||
|
|
||||||
if (VssClientHttpRequestSettings.Default.UserAgent != null && VssClientHttpRequestSettings.Default.UserAgent.Count > 0)
|
if (VssClientHttpRequestSettings.Default.UserAgent != null && VssClientHttpRequestSettings.Default.UserAgent.Count > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -123,12 +123,5 @@ namespace GitHub.Runner.Sdk
|
|||||||
{
|
{
|
||||||
return value?.Substring(0, Math.Min(value.Length, count));
|
return value?.Substring(0, Math.Min(value.Length, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixes format violations e.g. https://github.com/actions/runner/issues/2165
|
|
||||||
public static string SanitizeUserAgentHeader(string header)
|
|
||||||
{
|
|
||||||
return header.Replace("(", "[").Replace(")", "]").Trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,9 @@ namespace GitHub.Runner.Sdk
|
|||||||
{
|
{
|
||||||
public static bool IsHostedServer(UriBuilder gitHubUrl)
|
public static bool IsHostedServer(UriBuilder gitHubUrl)
|
||||||
{
|
{
|
||||||
if (StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_FORCE_GHES")))
|
return string.Equals(gitHubUrl.Host, "github.com", StringComparison.OrdinalIgnoreCase) ||
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
string.Equals(gitHubUrl.Host, "github.com", StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
string.Equals(gitHubUrl.Host, "www.github.com", StringComparison.OrdinalIgnoreCase) ||
|
string.Equals(gitHubUrl.Host, "www.github.com", StringComparison.OrdinalIgnoreCase) ||
|
||||||
string.Equals(gitHubUrl.Host, "github.localhost", StringComparison.OrdinalIgnoreCase) ||
|
string.Equals(gitHubUrl.Host, "github.localhost", StringComparison.OrdinalIgnoreCase);
|
||||||
gitHubUrl.Host.EndsWith(".ghe.com", StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uri GetCredentialEmbeddedUrl(Uri baseUrl, string username, string password)
|
public static Uri GetCredentialEmbeddedUrl(Uri baseUrl, string username, string password)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
{
|
{
|
||||||
var headerValues = new List<ProductInfoHeaderValue>();
|
var headerValues = new List<ProductInfoHeaderValue>();
|
||||||
headerValues.AddRange(additionalUserAgents);
|
headerValues.AddRange(additionalUserAgents);
|
||||||
headerValues.Add(new ProductInfoHeaderValue($"({StringUtil.SanitizeUserAgentHeader(RuntimeInformation.OSDescription)})"));
|
headerValues.Add(new ProductInfoHeaderValue($"({RuntimeInformation.OSDescription.Trim()})"));
|
||||||
|
|
||||||
if (VssClientHttpRequestSettings.Default.UserAgent != null && VssClientHttpRequestSettings.Default.UserAgent.Count > 0)
|
if (VssClientHttpRequestSettings.Default.UserAgent != null && VssClientHttpRequestSettings.Default.UserAgent.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -116,7 +116,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
// settings are applied to an HttpRequestMessage.
|
// settings are applied to an HttpRequestMessage.
|
||||||
settings.AcceptLanguages.Remove(CultureInfo.InvariantCulture);
|
settings.AcceptLanguages.Remove(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
RawConnection connection = new(serverUri, new RawHttpMessageHandler(credentials.Federated, settings), additionalDelegatingHandler);
|
RawConnection connection = new(serverUri, new RawHttpMessageHandler(credentials.ToOAuthCredentials(), settings), additionalDelegatingHandler);
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace GitHub.Runner.Worker
|
|||||||
public interface IActionRunner : IStep, IRunnerService
|
public interface IActionRunner : IStep, IRunnerService
|
||||||
{
|
{
|
||||||
ActionRunStage Stage { get; set; }
|
ActionRunStage Stage { get; set; }
|
||||||
|
bool TryEvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context);
|
||||||
Pipelines.ActionStep Action { get; set; }
|
Pipelines.ActionStep Action { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,67 +285,25 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public bool TryEvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context)
|
||||||
/// Attempts to update the DisplayName.
|
|
||||||
/// As the "Try..." name implies, this method should never throw an exception.
|
|
||||||
/// Returns true if the DisplayName is already present or it was successfully updated.
|
|
||||||
/// </summary>
|
|
||||||
public bool TryUpdateDisplayName(out bool updated)
|
|
||||||
{
|
|
||||||
updated = false;
|
|
||||||
|
|
||||||
// REVIEW: This try/catch can be removed if some future implementation of EvaluateDisplayName and UpdateTimelineRecordDisplayName
|
|
||||||
// can make reasonable guarantees that they won't throw an exception.
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// This attempt is only worthwhile at the "Main" stage.
|
|
||||||
// When the job starts, there's an initial attempt to evaluate the DisplayName. (see JobExtension::InitializeJob)
|
|
||||||
// During the "Pre" stage, we expect that no contexts will have changed since the initial evaluation.
|
|
||||||
// "Main" stage is handled here.
|
|
||||||
// During the "Post" stage, it no longer matters.
|
|
||||||
if (this.Stage == ActionRunStage.Main && EvaluateDisplayName(this.ExecutionContext.ExpressionValues, this.ExecutionContext, out updated))
|
|
||||||
{
|
|
||||||
if (updated)
|
|
||||||
{
|
|
||||||
this.ExecutionContext.UpdateTimelineRecordDisplayName(this.DisplayName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Trace.Warning("Caught exception while attempting to evaulate/update the step's DisplayName. Exception Details: {0}", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For consistency with other implementations of TryUpdateDisplayName we use !string.IsNullOrEmpty below,
|
|
||||||
// but note that (at the time of this writing) ActionRunner::DisplayName::get always returns a non-empty string due to its fallback logic.
|
|
||||||
// In other words, the net effect is that this particular implementation of TryUpdateDisplayName will always return true.
|
|
||||||
return !string.IsNullOrEmpty(this.DisplayName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to evaluate the DisplayName of this IActionRunner.
|
|
||||||
/// Returns true if the DisplayName is already present or it was successfully evaluated.
|
|
||||||
/// </summary>
|
|
||||||
public bool EvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context, out bool updated)
|
|
||||||
{
|
{
|
||||||
ArgUtil.NotNull(context, nameof(context));
|
ArgUtil.NotNull(context, nameof(context));
|
||||||
ArgUtil.NotNull(Action, nameof(Action));
|
ArgUtil.NotNull(Action, nameof(Action));
|
||||||
|
|
||||||
updated = false;
|
// If we have already expanded the display name, there is no need to expand it again
|
||||||
// If we have already expanded the display name, don't bother attempting [re-]expansion.
|
// TODO: Remove the ShouldEvaluateDisplayName check and field post m158 deploy, we should do it by default once the server is updated
|
||||||
if (_didFullyEvaluateDisplayName || !string.IsNullOrEmpty(Action.DisplayName))
|
if (_didFullyEvaluateDisplayName || !string.IsNullOrEmpty(Action.DisplayName))
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_displayName = GenerateDisplayName(Action, contextData, context, out bool didFullyEvaluate);
|
bool didFullyEvaluate;
|
||||||
|
_displayName = GenerateDisplayName(Action, contextData, context, out didFullyEvaluate);
|
||||||
|
|
||||||
// If we evaluated, fully mask any secrets
|
// If we evaluated fully mask any secrets
|
||||||
if (didFullyEvaluate)
|
if (didFullyEvaluate)
|
||||||
{
|
{
|
||||||
_displayName = HostContext.SecretMasker.MaskSecrets(_displayName);
|
_displayName = HostContext.SecretMasker.MaskSecrets(_displayName);
|
||||||
updated = true;
|
|
||||||
}
|
}
|
||||||
context.Debug($"Set step '{Action.Name}' display name to: '{_displayName}'");
|
context.Debug($"Set step '{Action.Name}' display name to: '{_displayName}'");
|
||||||
_didFullyEvaluateDisplayName = didFullyEvaluate;
|
_didFullyEvaluateDisplayName = didFullyEvaluate;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.Actions.RunService.WebApi;
|
|
||||||
using GitHub.DistributedTask.Expressions2;
|
using GitHub.DistributedTask.Expressions2;
|
||||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||||
@@ -438,17 +437,6 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
PublishStepTelemetry();
|
PublishStepTelemetry();
|
||||||
|
|
||||||
var stepResult = new StepResult();
|
|
||||||
stepResult.ExternalID = _record.Id;
|
|
||||||
stepResult.Conclusion = _record.Result ?? TaskResult.Succeeded;
|
|
||||||
stepResult.Status = _record.State;
|
|
||||||
stepResult.Number = _record.Order;
|
|
||||||
stepResult.Name = _record.Name;
|
|
||||||
stepResult.StartedAt = _record.StartTime;
|
|
||||||
stepResult.CompletedAt = _record.FinishTime;
|
|
||||||
|
|
||||||
Global.StepsResult.Add(stepResult);
|
|
||||||
|
|
||||||
if (Root != this)
|
if (Root != this)
|
||||||
{
|
{
|
||||||
// only dispose TokenSource for step level ExecutionContext
|
// only dispose TokenSource for step level ExecutionContext
|
||||||
@@ -722,9 +710,6 @@ namespace GitHub.Runner.Worker
|
|||||||
// ActionsStepTelemetry for entire job
|
// ActionsStepTelemetry for entire job
|
||||||
Global.StepsTelemetry = new List<ActionsStepTelemetry>();
|
Global.StepsTelemetry = new List<ActionsStepTelemetry>();
|
||||||
|
|
||||||
// Steps results for entire job
|
|
||||||
Global.StepsResult = new List<StepResult>();
|
|
||||||
|
|
||||||
// Job Outputs
|
// Job Outputs
|
||||||
JobOutputs = new Dictionary<string, VariableValue>(StringComparer.OrdinalIgnoreCase);
|
JobOutputs = new Dictionary<string, VariableValue>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using GitHub.Actions.RunService.WebApi;
|
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using GitHub.Runner.Common.Util;
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Worker.Container;
|
using GitHub.Runner.Worker.Container;
|
||||||
@@ -17,7 +16,6 @@ namespace GitHub.Runner.Worker
|
|||||||
public IList<String> FileTable { get; set; }
|
public IList<String> FileTable { get; set; }
|
||||||
public IDictionary<String, IDictionary<String, String>> JobDefaults { get; set; }
|
public IDictionary<String, IDictionary<String, String>> JobDefaults { get; set; }
|
||||||
public List<ActionsStepTelemetry> StepsTelemetry { get; set; }
|
public List<ActionsStepTelemetry> StepsTelemetry { get; set; }
|
||||||
public List<StepResult> StepsResult { get; set; }
|
|
||||||
public List<JobTelemetry> JobTelemetry { get; set; }
|
public List<JobTelemetry> JobTelemetry { get; set; }
|
||||||
public TaskOrchestrationPlanReference Plan { get; set; }
|
public TaskOrchestrationPlanReference Plan { get; set; }
|
||||||
public List<string> PrependPath { get; set; }
|
public List<string> PrependPath { get; set; }
|
||||||
|
|||||||
@@ -306,13 +306,13 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actionRunner.EvaluateDisplayName(contextData, context, out _);
|
actionRunner.TryEvaluateDisplayName(contextData, context);
|
||||||
jobSteps.Add(actionRunner);
|
jobSteps.Add(actionRunner);
|
||||||
|
|
||||||
if (prepareResult.PreStepTracker.TryGetValue(step.Id, out var preStep))
|
if (prepareResult.PreStepTracker.TryGetValue(step.Id, out var preStep))
|
||||||
{
|
{
|
||||||
Trace.Info($"Adding pre-{action.DisplayName}.");
|
Trace.Info($"Adding pre-{action.DisplayName}.");
|
||||||
preStep.EvaluateDisplayName(contextData, context, out _);
|
preStep.TryEvaluateDisplayName(contextData, context);
|
||||||
preStep.DisplayName = $"Pre {preStep.DisplayName}";
|
preStep.DisplayName = $"Pre {preStep.DisplayName}";
|
||||||
preJobSteps.Add(preStep);
|
preJobSteps.Add(preStep);
|
||||||
}
|
}
|
||||||
@@ -328,10 +328,10 @@ namespace GitHub.Runner.Worker
|
|||||||
if (message.ContextData.TryGetValue("inputs", out var pipelineContextData))
|
if (message.ContextData.TryGetValue("inputs", out var pipelineContextData))
|
||||||
{
|
{
|
||||||
var inputs = pipelineContextData.AssertDictionary("inputs");
|
var inputs = pipelineContextData.AssertDictionary("inputs");
|
||||||
if (inputs.Any())
|
if (inputs.Any())
|
||||||
{
|
{
|
||||||
context.Output($"##[group] Inputs");
|
context.Output($"##[group] Inputs");
|
||||||
foreach (var input in inputs)
|
foreach (var input in inputs)
|
||||||
{
|
{
|
||||||
context.Output($" {input.Key}: {input.Value}");
|
context.Output($" {input.Key}: {input.Value}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Worker
|
namespace GitHub.Runner.Worker
|
||||||
{
|
{
|
||||||
@@ -33,18 +32,5 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
await _runAsync(ExecutionContext, _data);
|
await _runAsync(ExecutionContext, _data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryUpdateDisplayName(out bool updated)
|
|
||||||
{
|
|
||||||
updated = false;
|
|
||||||
return !string.IsNullOrEmpty(this.DisplayName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool EvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context, out bool updated)
|
|
||||||
{
|
|
||||||
updated = false;
|
|
||||||
return !string.IsNullOrEmpty(this.DisplayName);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Net.Http;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
using GitHub.Runner.Common.Util;
|
using GitHub.Runner.Common.Util;
|
||||||
@@ -39,34 +40,21 @@ namespace GitHub.Runner.Worker
|
|||||||
Trace.Info("Job ID {0}", message.JobId);
|
Trace.Info("Job ID {0}", message.JobId);
|
||||||
|
|
||||||
DateTime jobStartTimeUtc = DateTime.UtcNow;
|
DateTime jobStartTimeUtc = DateTime.UtcNow;
|
||||||
IRunnerService server = null;
|
|
||||||
|
|
||||||
ServiceEndpoint systemConnection = message.Resources.Endpoints.Single(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase));
|
ServiceEndpoint systemConnection = message.Resources.Endpoints.Single(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase));
|
||||||
if (string.Equals(message.MessageType, JobRequestMessageTypes.RunnerJobRequest, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
var runServer = HostContext.GetService<IRunServer>();
|
|
||||||
VssCredentials jobServerCredential = VssUtil.GetVssCredential(systemConnection);
|
|
||||||
await runServer.ConnectAsync(systemConnection.Url, jobServerCredential);
|
|
||||||
server = runServer;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Setup the job server and job server queue.
|
|
||||||
var jobServer = HostContext.GetService<IJobServer>();
|
|
||||||
VssCredentials jobServerCredential = VssUtil.GetVssCredential(systemConnection);
|
|
||||||
Uri jobServerUrl = systemConnection.Url;
|
|
||||||
|
|
||||||
Trace.Info($"Creating job server with URL: {jobServerUrl}");
|
// Setup the job server and job server queue.
|
||||||
// jobServerQueue is the throttling reporter.
|
var jobServer = HostContext.GetService<IJobServer>();
|
||||||
_jobServerQueue = HostContext.GetService<IJobServerQueue>();
|
VssCredentials jobServerCredential = VssUtil.GetVssCredential(systemConnection);
|
||||||
VssConnection jobConnection = VssUtil.CreateConnection(jobServerUrl, jobServerCredential, new DelegatingHandler[] { new ThrottlingReportHandler(_jobServerQueue) });
|
Uri jobServerUrl = systemConnection.Url;
|
||||||
await jobServer.ConnectAsync(jobConnection);
|
|
||||||
|
|
||||||
_jobServerQueue.Start(message);
|
Trace.Info($"Creating job server with URL: {jobServerUrl}");
|
||||||
server = jobServer;
|
// jobServerQueue is the throttling reporter.
|
||||||
}
|
_jobServerQueue = HostContext.GetService<IJobServerQueue>();
|
||||||
|
VssConnection jobConnection = VssUtil.CreateConnection(jobServerUrl, jobServerCredential, new DelegatingHandler[] { new ThrottlingReportHandler(_jobServerQueue) });
|
||||||
|
await jobServer.ConnectAsync(jobConnection);
|
||||||
|
|
||||||
|
_jobServerQueue.Start(message);
|
||||||
HostContext.WritePerfCounter($"WorkerJobServerQueueStarted_{message.RequestId.ToString()}");
|
HostContext.WritePerfCounter($"WorkerJobServerQueueStarted_{message.RequestId.ToString()}");
|
||||||
|
|
||||||
IExecutionContext jobContext = null;
|
IExecutionContext jobContext = null;
|
||||||
@@ -111,7 +99,7 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
Trace.Error(ex);
|
Trace.Error(ex);
|
||||||
jobContext.Error(ex);
|
jobContext.Error(ex);
|
||||||
return await CompleteJobAsync(server, jobContext, message, TaskResult.Failed);
|
return await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jobContext.Global.WriteDebug)
|
if (jobContext.Global.WriteDebug)
|
||||||
@@ -148,7 +136,7 @@ namespace GitHub.Runner.Worker
|
|||||||
// don't log error issue to job ExecutionContext, since server owns the job level issue
|
// don't log error issue to job ExecutionContext, since server owns the job level issue
|
||||||
Trace.Error($"Job is cancelled during initialize.");
|
Trace.Error($"Job is cancelled during initialize.");
|
||||||
Trace.Error($"Caught exception: {ex}");
|
Trace.Error($"Caught exception: {ex}");
|
||||||
return await CompleteJobAsync(server, jobContext, message, TaskResult.Canceled);
|
return await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Canceled);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -156,7 +144,7 @@ namespace GitHub.Runner.Worker
|
|||||||
// don't log error issue to job ExecutionContext, since server owns the job level issue
|
// don't log error issue to job ExecutionContext, since server owns the job level issue
|
||||||
Trace.Error($"Job initialize failed.");
|
Trace.Error($"Job initialize failed.");
|
||||||
Trace.Error($"Caught exception from {nameof(jobExtension.InitializeJob)}: {ex}");
|
Trace.Error($"Caught exception from {nameof(jobExtension.InitializeJob)}: {ex}");
|
||||||
return await CompleteJobAsync(server, jobContext, message, TaskResult.Failed);
|
return await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// trace out all steps
|
// trace out all steps
|
||||||
@@ -193,7 +181,7 @@ namespace GitHub.Runner.Worker
|
|||||||
// Log the error and fail the job.
|
// Log the error and fail the job.
|
||||||
Trace.Error($"Caught exception from job steps {nameof(StepsRunner)}: {ex}");
|
Trace.Error($"Caught exception from job steps {nameof(StepsRunner)}: {ex}");
|
||||||
jobContext.Error(ex);
|
jobContext.Error(ex);
|
||||||
return await CompleteJobAsync(server, jobContext, message, TaskResult.Failed);
|
return await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -204,7 +192,7 @@ namespace GitHub.Runner.Worker
|
|||||||
Trace.Info($"Job result after all job steps finish: {jobContext.Result ?? TaskResult.Succeeded}");
|
Trace.Info($"Job result after all job steps finish: {jobContext.Result ?? TaskResult.Succeeded}");
|
||||||
|
|
||||||
Trace.Info("Completing the job execution context.");
|
Trace.Info("Completing the job execution context.");
|
||||||
return await CompleteJobAsync(server, jobContext, message);
|
return await CompleteJobAsync(jobServer, jobContext, message);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -218,66 +206,6 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<TaskResult> CompleteJobAsync(IRunnerService server, IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, TaskResult? taskResult = null)
|
|
||||||
{
|
|
||||||
if (server is IRunServer runServer)
|
|
||||||
{
|
|
||||||
return await CompleteJobAsync(runServer, jobContext, message, taskResult);
|
|
||||||
}
|
|
||||||
else if (server is IJobServer jobServer)
|
|
||||||
{
|
|
||||||
return await CompleteJobAsync(jobServer, jobContext, message, taskResult);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<TaskResult> CompleteJobAsync(IRunServer runServer, IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, TaskResult? taskResult = null)
|
|
||||||
{
|
|
||||||
jobContext.Debug($"Finishing: {message.JobDisplayName}");
|
|
||||||
TaskResult result = jobContext.Complete(taskResult);
|
|
||||||
if (jobContext.Global.Variables.TryGetValue("Node12ActionsWarnings", out var node12Warnings))
|
|
||||||
{
|
|
||||||
var actions = string.Join(", ", StringUtil.ConvertFromJson<HashSet<string>>(node12Warnings));
|
|
||||||
jobContext.Warning(string.Format(Constants.Runner.Node12DetectedAfterEndOfLife, actions));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure to clean temp after file upload since they may be pending fileupload still use the TEMP dir.
|
|
||||||
_tempDirectoryManager?.CleanupTempDirectory();
|
|
||||||
|
|
||||||
// Load any upgrade telemetry
|
|
||||||
LoadFromTelemetryFile(jobContext.Global.JobTelemetry);
|
|
||||||
|
|
||||||
// Make sure we don't submit secrets as telemetry
|
|
||||||
MaskTelemetrySecrets(jobContext.Global.JobTelemetry);
|
|
||||||
|
|
||||||
Trace.Info($"Raising job completed against run service");
|
|
||||||
var completeJobRetryLimit = 5;
|
|
||||||
var exceptions = new List<Exception>();
|
|
||||||
while (completeJobRetryLimit-- > 0)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await runServer.CompleteJobAsync(message.Plan.PlanId, message.JobId, result, jobContext.JobOutputs, jobContext.Global.StepsResult, default);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Trace.Error($"Catch exception while attempting to complete job {message.JobId}, job request {message.RequestId}.");
|
|
||||||
Trace.Error(ex);
|
|
||||||
exceptions.Add(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// delay 5 seconds before next retry.
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
// rethrow exceptions from all attempts.
|
|
||||||
throw new AggregateException(exceptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<TaskResult> CompleteJobAsync(IJobServer jobServer, IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, TaskResult? taskResult = null)
|
private async Task<TaskResult> CompleteJobAsync(IJobServer jobServer, IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, TaskResult? taskResult = null)
|
||||||
{
|
{
|
||||||
jobContext.Debug($"Finishing: {message.JobDisplayName}");
|
jobContext.Debug($"Finishing: {message.JobDisplayName}");
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.DistributedTask.Expressions2;
|
using GitHub.DistributedTask.Expressions2;
|
||||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||||
|
using GitHub.DistributedTask.Pipelines;
|
||||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||||
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
|
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
@@ -11,6 +14,8 @@ using GitHub.Runner.Common;
|
|||||||
using GitHub.Runner.Common.Util;
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using GitHub.Runner.Worker.Expressions;
|
using GitHub.Runner.Worker.Expressions;
|
||||||
|
using ObjectTemplating = GitHub.DistributedTask.ObjectTemplating;
|
||||||
|
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||||
|
|
||||||
namespace GitHub.Runner.Worker
|
namespace GitHub.Runner.Worker
|
||||||
{
|
{
|
||||||
@@ -21,8 +26,6 @@ namespace GitHub.Runner.Worker
|
|||||||
string DisplayName { get; set; }
|
string DisplayName { get; set; }
|
||||||
IExecutionContext ExecutionContext { get; set; }
|
IExecutionContext ExecutionContext { get; set; }
|
||||||
TemplateToken Timeout { get; }
|
TemplateToken Timeout { get; }
|
||||||
bool TryUpdateDisplayName(out bool updated);
|
|
||||||
bool EvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context, out bool updated);
|
|
||||||
Task RunAsync();
|
Task RunAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,12 +195,6 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This is our last, best chance to expand the display name. (At this point, all the requirements for successful expansion should be met.)
|
|
||||||
// That being said, evaluating the display name should still be considered as a "best effort" exercise. (It's not critical or paramount.)
|
|
||||||
// For that reason, we call a safe "Try..." wrapper method to ensure that any potential problems we encounter in evaluating the display name
|
|
||||||
// don't interfere with our ultimate goal within this code block: evaluation of the condition.
|
|
||||||
step.TryUpdateDisplayName(out _);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var templateEvaluator = step.ExecutionContext.ToPipelineTemplateEvaluator(conditionTraceWriter);
|
var templateEvaluator = step.ExecutionContext.ToPipelineTemplateEvaluator(conditionTraceWriter);
|
||||||
@@ -259,6 +256,14 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
private async Task RunStepAsync(IStep step, CancellationToken jobCancellationToken)
|
private async Task RunStepAsync(IStep step, CancellationToken jobCancellationToken)
|
||||||
{
|
{
|
||||||
|
// Check to see if we can expand the display name
|
||||||
|
if (step is IActionRunner actionRunner &&
|
||||||
|
actionRunner.Stage == ActionRunStage.Main &&
|
||||||
|
actionRunner.TryEvaluateDisplayName(step.ExecutionContext.ExpressionValues, step.ExecutionContext))
|
||||||
|
{
|
||||||
|
step.ExecutionContext.UpdateTimelineRecordDisplayName(actionRunner.DisplayName);
|
||||||
|
}
|
||||||
|
|
||||||
// Start the step
|
// Start the step
|
||||||
Trace.Info("Starting the step.");
|
Trace.Info("Starting the step.");
|
||||||
step.ExecutionContext.Debug($"Starting: {step.DisplayName}");
|
step.ExecutionContext.Debug($"Starting: {step.DisplayName}");
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using GitHub.Services.OAuth;
|
||||||
|
|
||||||
|
namespace GitHub.Services.Common
|
||||||
|
{
|
||||||
|
public static class VssCredentialsExtension
|
||||||
|
{
|
||||||
|
public static VssOAuthCredential ToOAuthCredentials(
|
||||||
|
this VssCredentials credentials)
|
||||||
|
{
|
||||||
|
if (credentials.Federated.CredentialType == VssCredentialsType.OAuth)
|
||||||
|
{
|
||||||
|
return credentials.Federated as VssOAuthCredential;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,20 +12,20 @@ namespace GitHub.Services.Common
|
|||||||
public class RawHttpMessageHandler: HttpMessageHandler
|
public class RawHttpMessageHandler: HttpMessageHandler
|
||||||
{
|
{
|
||||||
public RawHttpMessageHandler(
|
public RawHttpMessageHandler(
|
||||||
FederatedCredential credentials)
|
VssOAuthCredential credentials)
|
||||||
: this(credentials, new RawClientHttpRequestSettings())
|
: this(credentials, new RawClientHttpRequestSettings())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public RawHttpMessageHandler(
|
public RawHttpMessageHandler(
|
||||||
FederatedCredential credentials,
|
VssOAuthCredential credentials,
|
||||||
RawClientHttpRequestSettings settings)
|
RawClientHttpRequestSettings settings)
|
||||||
: this(credentials, settings, new HttpClientHandler())
|
: this(credentials, settings, new HttpClientHandler())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public RawHttpMessageHandler(
|
public RawHttpMessageHandler(
|
||||||
FederatedCredential credentials,
|
VssOAuthCredential credentials,
|
||||||
RawClientHttpRequestSettings settings,
|
RawClientHttpRequestSettings settings,
|
||||||
HttpMessageHandler innerHandler)
|
HttpMessageHandler innerHandler)
|
||||||
{
|
{
|
||||||
@@ -56,7 +56,7 @@ namespace GitHub.Services.Common
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the credentials associated with this handler.
|
/// Gets the credentials associated with this handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public FederatedCredential Credentials
|
public VssOAuthCredential Credentials
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
private set;
|
private set;
|
||||||
@@ -111,7 +111,7 @@ namespace GitHub.Services.Common
|
|||||||
// Ensure that we attempt to use the most appropriate authentication mechanism by default.
|
// Ensure that we attempt to use the most appropriate authentication mechanism by default.
|
||||||
if (m_tokenProvider == null)
|
if (m_tokenProvider == null)
|
||||||
{
|
{
|
||||||
m_tokenProvider = this.Credentials.CreateTokenProvider(request.RequestUri, null, null);
|
m_tokenProvider = this.Credentials.GetTokenProvider(request.RequestUri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ namespace GitHub.Services.Common
|
|||||||
private CredentialWrapper m_credentialWrapper;
|
private CredentialWrapper m_credentialWrapper;
|
||||||
private object m_thisLock;
|
private object m_thisLock;
|
||||||
private const Int32 m_maxAuthRetries = 3;
|
private const Int32 m_maxAuthRetries = 3;
|
||||||
private IssuedTokenProvider m_tokenProvider;
|
private VssOAuthTokenProvider m_tokenProvider;
|
||||||
|
|
||||||
//.Net Core does not attempt NTLM schema on Linux, unless ICredentials is a CredentialCache instance
|
//.Net Core does not attempt NTLM schema on Linux, unless ICredentials is a CredentialCache instance
|
||||||
//This workaround may not be needed after this corefx fix is consumed: https://github.com/dotnet/corefx/pull/7923
|
//This workaround may not be needed after this corefx fix is consumed: https://github.com/dotnet/corefx/pull/7923
|
||||||
|
|||||||
@@ -42,10 +42,9 @@ namespace GitHub.DistributedTask.Pipelines
|
|||||||
IList<String> fileTable,
|
IList<String> fileTable,
|
||||||
TemplateToken jobOutputs,
|
TemplateToken jobOutputs,
|
||||||
IList<TemplateToken> defaults,
|
IList<TemplateToken> defaults,
|
||||||
ActionsEnvironmentReference actionsEnvironment,
|
ActionsEnvironmentReference actionsEnvironment)
|
||||||
String messageType = JobRequestMessageTypes.PipelineAgentJobRequest)
|
|
||||||
{
|
{
|
||||||
this.MessageType = messageType;
|
this.MessageType = JobRequestMessageTypes.PipelineAgentJobRequest;
|
||||||
this.Plan = plan;
|
this.Plan = plan;
|
||||||
this.JobId = jobId;
|
this.JobId = jobId;
|
||||||
this.JobDisplayName = jobDisplayName;
|
this.JobDisplayName = jobDisplayName;
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.DistributedTask.Pipelines;
|
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
using GitHub.Services.Common;
|
using GitHub.Services.Common;
|
||||||
using GitHub.Services.OAuth;
|
using GitHub.Services.OAuth;
|
||||||
using GitHub.Services.WebApi;
|
using GitHub.Services.WebApi;
|
||||||
using Sdk.WebApi.WebApi;
|
using Sdk.WebApi.WebApi;
|
||||||
|
|
||||||
namespace GitHub.Actions.RunService.WebApi
|
namespace GitHub.DistributedTask.WebApi
|
||||||
{
|
{
|
||||||
|
[ResourceArea(TaskResourceIds.AreaId)]
|
||||||
public class RunServiceHttpClient : RawHttpClientBase
|
public class RunServiceHttpClient : RawHttpClientBase
|
||||||
{
|
{
|
||||||
public RunServiceHttpClient(
|
public RunServiceHttpClient(
|
||||||
@@ -54,54 +52,24 @@ namespace GitHub.Actions.RunService.WebApi
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<AgentJobRequestMessage> GetJobMessageAsync(
|
public Task<Pipelines.AgentJobRequestMessage> GetJobMessageAsync(
|
||||||
Uri requestUri,
|
Uri requestUri,
|
||||||
string messageId,
|
string messageId,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
HttpMethod httpMethod = new HttpMethod("POST");
|
HttpMethod httpMethod = new HttpMethod("POST");
|
||||||
var payload = new AcquireJobRequest
|
var payload = new {
|
||||||
{
|
|
||||||
StreamID = messageId
|
StreamID = messageId
|
||||||
};
|
};
|
||||||
|
|
||||||
requestUri = new Uri(requestUri, "acquirejob");
|
var payloadJson = JsonUtility.ToString(payload);
|
||||||
|
var requestContent = new StringContent(payloadJson, System.Text.Encoding.UTF8, "application/json");
|
||||||
var requestContent = new ObjectContent<AcquireJobRequest>(payload, new VssJsonMediaTypeFormatter(true));
|
return SendAsync<Pipelines.AgentJobRequestMessage>(
|
||||||
return SendAsync<AgentJobRequestMessage>(
|
|
||||||
httpMethod,
|
httpMethod,
|
||||||
|
additionalHeaders: null,
|
||||||
requestUri: requestUri,
|
requestUri: requestUri,
|
||||||
content: requestContent,
|
content: requestContent,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task CompleteJobAsync(
|
|
||||||
Uri requestUri,
|
|
||||||
Guid planId,
|
|
||||||
Guid jobId,
|
|
||||||
TaskResult result,
|
|
||||||
Dictionary<String, VariableValue> outputs,
|
|
||||||
IList<StepResult> stepResults,
|
|
||||||
CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
HttpMethod httpMethod = new HttpMethod("POST");
|
|
||||||
var payload = new CompleteJobRequest()
|
|
||||||
{
|
|
||||||
PlanID = planId,
|
|
||||||
JobID = jobId,
|
|
||||||
Conclusion = result,
|
|
||||||
Outputs = outputs,
|
|
||||||
StepResults = stepResults
|
|
||||||
};
|
|
||||||
|
|
||||||
requestUri = new Uri(requestUri, "completejob");
|
|
||||||
|
|
||||||
var requestContent = new ObjectContent<CompleteJobRequest>(payload, new VssJsonMediaTypeFormatter(true));
|
|
||||||
return SendAsync(
|
|
||||||
httpMethod,
|
|
||||||
requestUri,
|
|
||||||
content: requestContent,
|
|
||||||
cancellationToken: cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
|
|
||||||
namespace GitHub.Actions.RunService.WebApi
|
|
||||||
{
|
|
||||||
[DataContract]
|
|
||||||
public class AcquireJobRequest
|
|
||||||
{
|
|
||||||
[DataMember(Name = "streamId", EmitDefaultValue = false)]
|
|
||||||
public string StreamID { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
|
|
||||||
namespace GitHub.Actions.RunService.WebApi
|
|
||||||
{
|
|
||||||
[DataContract]
|
|
||||||
public class CompleteJobRequest
|
|
||||||
{
|
|
||||||
[DataMember(Name = "planId", EmitDefaultValue = false)]
|
|
||||||
public Guid PlanID { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "jobId", EmitDefaultValue = false)]
|
|
||||||
public Guid JobID { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "conclusion")]
|
|
||||||
public TaskResult Conclusion { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "outputs", EmitDefaultValue = false)]
|
|
||||||
public Dictionary<string, VariableValue> Outputs { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "stepResults", EmitDefaultValue = false)]
|
|
||||||
public IList<StepResult> StepResults { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
|
|
||||||
namespace GitHub.Actions.RunService.WebApi
|
|
||||||
{
|
|
||||||
[DataContract]
|
|
||||||
public class StepResult
|
|
||||||
{
|
|
||||||
[DataMember(Name = "external_id", EmitDefaultValue = false)]
|
|
||||||
public Guid ExternalID { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "number", EmitDefaultValue = false)]
|
|
||||||
public int? Number { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "name", EmitDefaultValue = false)]
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "status")]
|
|
||||||
public TimelineRecordState? Status { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "conclusion")]
|
|
||||||
public TaskResult? Conclusion { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "started_at", EmitDefaultValue = false)]
|
|
||||||
public DateTime? StartedAt { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "completed_at", EmitDefaultValue = false)]
|
|
||||||
public DateTime? CompletedAt { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "completed_log_url", EmitDefaultValue = false)]
|
|
||||||
public string CompletedLogURL { get; set; }
|
|
||||||
|
|
||||||
[DataMember(Name = "completed_log_lines", EmitDefaultValue = false)]
|
|
||||||
public long? CompletedLogLines { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -101,17 +101,6 @@ namespace Sdk.WebApi.WebApi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Task<T> SendAsync<T>(
|
|
||||||
HttpMethod method,
|
|
||||||
Uri requestUri,
|
|
||||||
HttpContent content = null,
|
|
||||||
IEnumerable<KeyValuePair<String, String>> queryParameters = null,
|
|
||||||
Object userState = null,
|
|
||||||
CancellationToken cancellationToken = default(CancellationToken))
|
|
||||||
{
|
|
||||||
return SendAsync<T>(method, null, requestUri, content, queryParameters, userState, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async Task<T> SendAsync<T>(
|
protected async Task<T> SendAsync<T>(
|
||||||
HttpMethod method,
|
HttpMethod method,
|
||||||
IEnumerable<KeyValuePair<String, String>> additionalHeaders,
|
IEnumerable<KeyValuePair<String, String>> additionalHeaders,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Common.Util;
|
||||||
|
using GitHub.Runner.Sdk;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@@ -185,19 +186,5 @@ namespace GitHub.Runner.Common.Tests.Util
|
|||||||
Assert.False(result9, $"'{undefineString3}' should convert to false.");
|
Assert.False(result9, $"'{undefineString3}' should convert to false.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("", "")]
|
|
||||||
[InlineData("(())", "[[]]")]
|
|
||||||
[InlineData("()()", "[][]")]
|
|
||||||
[InlineData(" Liquorix kernel OS Description is poorly formatted (linux version ", "Liquorix kernel OS Description is poorly formatted [linux version")]
|
|
||||||
[InlineData("Liquorix kernel OS Description is poorly formatted (linux version", "Liquorix kernel OS Description is poorly formatted [linux version")]
|
|
||||||
[InlineData("()((.", "[][[.")]
|
|
||||||
[Trait("Level", "L0")]
|
|
||||||
[Trait("Category", "Common")]
|
|
||||||
public void SanitizeUserAgentHeader(string input, string expected)
|
|
||||||
{
|
|
||||||
Assert.Equal(expected, StringUtil.SanitizeUserAgentHeader(input));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,20 @@ using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
|||||||
using GitHub.DistributedTask.Pipelines;
|
using GitHub.DistributedTask.Pipelines;
|
||||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Worker;
|
using GitHub.Runner.Worker;
|
||||||
|
using GitHub.Runner.Worker.Container;
|
||||||
using GitHub.Runner.Worker.Handlers;
|
using GitHub.Runner.Worker.Handlers;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||||
|
|
||||||
@@ -143,12 +149,11 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
_context.Add("matrix", matrixData);
|
_context.Add("matrix", matrixData);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
// Should report success with no updated required if there's already a valid display name.
|
// Should not do anything if we don't have a displayNameToken to expand
|
||||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
var didUpdateDisplayName = _actionRunner.TryEvaluateDisplayName(_context, _actionRunner.ExecutionContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(validDisplayName);
|
Assert.False(didUpdateDisplayName);
|
||||||
Assert.False(updated);
|
|
||||||
Assert.Equal(actionDisplayName, _actionRunner.DisplayName);
|
Assert.Equal(actionDisplayName, _actionRunner.DisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,51 +183,13 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
|
|
||||||
// Act
|
// Act
|
||||||
// Should expand the displaynameToken and set the display name to that
|
// Should expand the displaynameToken and set the display name to that
|
||||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
var didUpdateDisplayName = _actionRunner.TryEvaluateDisplayName(_context, _actionRunner.ExecutionContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(validDisplayName);
|
Assert.True(didUpdateDisplayName);
|
||||||
Assert.True(updated);
|
|
||||||
Assert.Equal(expectedString, _actionRunner.DisplayName);
|
Assert.Equal(expectedString, _actionRunner.DisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
[Trait("Level", "L0")]
|
|
||||||
[Trait("Category", "Worker")]
|
|
||||||
public void IgnoreDisplayNameTokenWhenDisplayNameIsExplicitlySet()
|
|
||||||
{
|
|
||||||
var explicitDisplayName = "Explcitly Set Name";
|
|
||||||
|
|
||||||
// Arrange
|
|
||||||
Setup();
|
|
||||||
var actionId = Guid.NewGuid();
|
|
||||||
var action = new Pipelines.ActionStep()
|
|
||||||
{
|
|
||||||
Name = "action",
|
|
||||||
Id = actionId,
|
|
||||||
DisplayName = explicitDisplayName,
|
|
||||||
DisplayNameToken = new BasicExpressionToken(null, null, null, "matrix.node"),
|
|
||||||
};
|
|
||||||
|
|
||||||
_actionRunner.Action = action;
|
|
||||||
|
|
||||||
var matrixData = new DictionaryContextData
|
|
||||||
{
|
|
||||||
["node"] = new StringContextData("8")
|
|
||||||
};
|
|
||||||
_context.Add("matrix", matrixData);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
// Should ignore the displayNameToken since there's already an explicit value for DisplayName
|
|
||||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.True(validDisplayName);
|
|
||||||
Assert.False(updated);
|
|
||||||
Assert.Equal(explicitDisplayName, _actionRunner.DisplayName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
@@ -251,11 +218,10 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
|
|
||||||
// Act
|
// Act
|
||||||
// Should expand the displaynameToken and set the display name to that
|
// Should expand the displaynameToken and set the display name to that
|
||||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
var didUpdateDisplayName = _actionRunner.TryEvaluateDisplayName(_context, _actionRunner.ExecutionContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(validDisplayName);
|
Assert.True(didUpdateDisplayName);
|
||||||
Assert.True(updated);
|
|
||||||
Assert.Equal("Run 8", _actionRunner.DisplayName);
|
Assert.Equal("Run 8", _actionRunner.DisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,11 +246,10 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
|
|
||||||
// Act
|
// Act
|
||||||
// Should expand the displaynameToken and set the display name to that
|
// Should expand the displaynameToken and set the display name to that
|
||||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
var didUpdateDisplayName = _actionRunner.TryEvaluateDisplayName(_context, _actionRunner.ExecutionContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(validDisplayName);
|
Assert.True(didUpdateDisplayName);
|
||||||
Assert.True(updated);
|
|
||||||
Assert.Equal("Run TestImageName:latest", _actionRunner.DisplayName);
|
Assert.Equal("Run TestImageName:latest", _actionRunner.DisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,11 +272,10 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
|
|
||||||
// Act
|
// Act
|
||||||
// Should not do anything if we don't have context on the display name
|
// Should not do anything if we don't have context on the display name
|
||||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
var didUpdateDisplayName = _actionRunner.TryEvaluateDisplayName(_context, _actionRunner.ExecutionContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(validDisplayName);
|
Assert.False(didUpdateDisplayName);
|
||||||
Assert.False(updated);
|
|
||||||
// Should use the pretty display name until we can eval
|
// Should use the pretty display name until we can eval
|
||||||
Assert.Equal("${{ matrix.node }}", _actionRunner.DisplayName);
|
Assert.Equal("${{ matrix.node }}", _actionRunner.DisplayName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -711,63 +711,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
[Trait("Level", "L0")]
|
|
||||||
[Trait("Category", "Worker")]
|
|
||||||
public void PublishStepResult_EmbeddedStep()
|
|
||||||
{
|
|
||||||
using (TestHostContext hc = CreateTestContext())
|
|
||||||
{
|
|
||||||
// Arrange: Create a job request message.
|
|
||||||
TaskOrchestrationPlanReference plan = new();
|
|
||||||
TimelineReference timeline = new();
|
|
||||||
Guid jobId = Guid.NewGuid();
|
|
||||||
string jobName = "some job name";
|
|
||||||
var jobRequest = new Pipelines.AgentJobRequestMessage(plan, timeline, jobId, jobName, jobName, null, null, null, new Dictionary<string, VariableValue>(), new List<MaskHint>(), new Pipelines.JobResources(), new Pipelines.ContextData.DictionaryContextData(), new Pipelines.WorkspaceOptions(), new List<Pipelines.ActionStep>(), null, null, null, null);
|
|
||||||
jobRequest.Resources.Repositories.Add(new Pipelines.RepositoryResource()
|
|
||||||
{
|
|
||||||
Alias = Pipelines.PipelineConstants.SelfAlias,
|
|
||||||
Id = "github",
|
|
||||||
Version = "sha1"
|
|
||||||
});
|
|
||||||
jobRequest.ContextData["github"] = new Pipelines.ContextData.DictionaryContextData();
|
|
||||||
|
|
||||||
// Arrange: Setup the paging logger.
|
|
||||||
var pagingLogger = new Mock<IPagingLogger>();
|
|
||||||
var pagingLogger2 = new Mock<IPagingLogger>();
|
|
||||||
var jobServerQueue = new Mock<IJobServerQueue>();
|
|
||||||
jobServerQueue.Setup(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.IsAny<TimelineRecord>()));
|
|
||||||
|
|
||||||
hc.EnqueueInstance(pagingLogger.Object);
|
|
||||||
hc.EnqueueInstance(pagingLogger2.Object);
|
|
||||||
hc.SetSingleton(jobServerQueue.Object);
|
|
||||||
|
|
||||||
var ec = new Runner.Worker.ExecutionContext();
|
|
||||||
ec.Initialize(hc);
|
|
||||||
|
|
||||||
// Act.
|
|
||||||
ec.InitializeJob(jobRequest, CancellationToken.None);
|
|
||||||
ec.Start();
|
|
||||||
|
|
||||||
var embeddedStep = ec.CreateChild(Guid.NewGuid(), "action_1_pre", "action_1_pre", null, null, ActionRunStage.Main, isEmbedded: true);
|
|
||||||
embeddedStep.Start();
|
|
||||||
|
|
||||||
embeddedStep.StepTelemetry.Type = "node16";
|
|
||||||
embeddedStep.StepTelemetry.Action = "actions/checkout";
|
|
||||||
embeddedStep.StepTelemetry.Ref = "v2";
|
|
||||||
|
|
||||||
embeddedStep.AddIssue(new Issue() { Type = IssueType.Error, Message = "error" });
|
|
||||||
embeddedStep.AddIssue(new Issue() { Type = IssueType.Warning, Message = "warning" });
|
|
||||||
embeddedStep.AddIssue(new Issue() { Type = IssueType.Notice, Message = "notice" });
|
|
||||||
|
|
||||||
ec.Complete();
|
|
||||||
|
|
||||||
// Assert.
|
|
||||||
Assert.Equal(1, ec.Global.StepsResult.Count);
|
|
||||||
Assert.Equal(TaskResult.Succeeded, ec.Global.StepsResult.Single().Conclusion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TestHostContext CreateTestContext([CallerMemberName] String testName = "")
|
private TestHostContext CreateTestContext([CallerMemberName] String testName = "")
|
||||||
{
|
{
|
||||||
var hc = new TestHostContext(this, testName);
|
var hc = new TestHostContext(this, testName);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using GitHub.Actions.RunService.WebApi;
|
|
||||||
using GitHub.DistributedTask.Pipelines;
|
using GitHub.DistributedTask.Pipelines;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
|
|||||||
@@ -16,10 +16,9 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
private IExecutionContext _jobEc;
|
private IExecutionContext _jobEc;
|
||||||
private JobRunner _jobRunner;
|
private JobRunner _jobRunner;
|
||||||
private List<IStep> _initResult = new();
|
private List<IStep> _initResult = new();
|
||||||
|
private Pipelines.AgentJobRequestMessage _message;
|
||||||
private CancellationTokenSource _tokenSource;
|
private CancellationTokenSource _tokenSource;
|
||||||
private Mock<IJobServer> _jobServer;
|
private Mock<IJobServer> _jobServer;
|
||||||
|
|
||||||
private Mock<IRunServer> _runServer;
|
|
||||||
private Mock<IJobServerQueue> _jobServerQueue;
|
private Mock<IJobServerQueue> _jobServerQueue;
|
||||||
private Mock<IConfigurationStore> _config;
|
private Mock<IConfigurationStore> _config;
|
||||||
private Mock<IExtensionManager> _extensions;
|
private Mock<IExtensionManager> _extensions;
|
||||||
@@ -39,7 +38,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
_extensions = new Mock<IExtensionManager>();
|
_extensions = new Mock<IExtensionManager>();
|
||||||
_jobExtension = new Mock<IJobExtension>();
|
_jobExtension = new Mock<IJobExtension>();
|
||||||
_jobServer = new Mock<IJobServer>();
|
_jobServer = new Mock<IJobServer>();
|
||||||
_runServer = new Mock<IRunServer>();
|
|
||||||
_jobServerQueue = new Mock<IJobServerQueue>();
|
_jobServerQueue = new Mock<IJobServerQueue>();
|
||||||
_stepRunner = new Mock<IStepsRunner>();
|
_stepRunner = new Mock<IStepsRunner>();
|
||||||
_logger = new Mock<IPagingLogger>();
|
_logger = new Mock<IPagingLogger>();
|
||||||
@@ -57,6 +55,33 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
_jobRunner = new JobRunner();
|
_jobRunner = new JobRunner();
|
||||||
_jobRunner.Initialize(hc);
|
_jobRunner.Initialize(hc);
|
||||||
|
|
||||||
|
TaskOrchestrationPlanReference plan = new();
|
||||||
|
TimelineReference timeline = new Timeline(Guid.NewGuid());
|
||||||
|
Guid jobId = Guid.NewGuid();
|
||||||
|
_message = new Pipelines.AgentJobRequestMessage(plan, timeline, jobId, testName, testName, null, null, null, new Dictionary<string, VariableValue>(), new List<MaskHint>(), new Pipelines.JobResources(), new Pipelines.ContextData.DictionaryContextData(), new Pipelines.WorkspaceOptions(), new List<Pipelines.ActionStep>(), null, null, null, null);
|
||||||
|
_message.Variables[Constants.Variables.System.Culture] = "en-US";
|
||||||
|
_message.Resources.Endpoints.Add(new ServiceEndpoint()
|
||||||
|
{
|
||||||
|
Name = WellKnownServiceEndpointNames.SystemVssConnection,
|
||||||
|
Url = new Uri("https://pipelines.actions.githubusercontent.com"),
|
||||||
|
Authorization = new EndpointAuthorization()
|
||||||
|
{
|
||||||
|
Scheme = "Test",
|
||||||
|
Parameters = {
|
||||||
|
{"AccessToken", "token"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
_message.Resources.Repositories.Add(new Pipelines.RepositoryResource()
|
||||||
|
{
|
||||||
|
Alias = Pipelines.PipelineConstants.SelfAlias,
|
||||||
|
Id = "github",
|
||||||
|
Version = "sha1"
|
||||||
|
});
|
||||||
|
_message.ContextData.Add("github", new Pipelines.ContextData.DictionaryContextData());
|
||||||
|
|
||||||
_initResult.Clear();
|
_initResult.Clear();
|
||||||
|
|
||||||
_jobExtension.Setup(x => x.InitializeJob(It.IsAny<IExecutionContext>(), It.IsAny<Pipelines.AgentJobRequestMessage>())).
|
_jobExtension.Setup(x => x.InitializeJob(It.IsAny<IExecutionContext>(), It.IsAny<Pipelines.AgentJobRequestMessage>())).
|
||||||
@@ -77,7 +102,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
|
|
||||||
hc.SetSingleton(_config.Object);
|
hc.SetSingleton(_config.Object);
|
||||||
hc.SetSingleton(_jobServer.Object);
|
hc.SetSingleton(_jobServer.Object);
|
||||||
hc.SetSingleton(_runServer.Object);
|
|
||||||
hc.SetSingleton(_jobServerQueue.Object);
|
hc.SetSingleton(_jobServerQueue.Object);
|
||||||
hc.SetSingleton(_stepRunner.Object);
|
hc.SetSingleton(_stepRunner.Object);
|
||||||
hc.SetSingleton(_extensions.Object);
|
hc.SetSingleton(_extensions.Object);
|
||||||
@@ -89,43 +113,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
return hc;
|
return hc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pipelines.AgentJobRequestMessage GetMessage(String messageType = JobRequestMessageTypes.PipelineAgentJobRequest, [CallerMemberName] String testName = "")
|
|
||||||
{
|
|
||||||
TaskOrchestrationPlanReference plan = new();
|
|
||||||
TimelineReference timeline = new Timeline(Guid.NewGuid());
|
|
||||||
Guid jobId = Guid.NewGuid();
|
|
||||||
var message = new Pipelines.AgentJobRequestMessage(
|
|
||||||
plan,
|
|
||||||
timeline,
|
|
||||||
jobId,
|
|
||||||
testName,
|
|
||||||
testName, null, null, null, new Dictionary<string, VariableValue>(), new List<MaskHint>(), new Pipelines.JobResources(), new Pipelines.ContextData.DictionaryContextData(), new Pipelines.WorkspaceOptions(), new List<Pipelines.ActionStep>(), null, null, null, null,
|
|
||||||
messageType: messageType);
|
|
||||||
message.Variables[Constants.Variables.System.Culture] = "en-US";
|
|
||||||
message.Resources.Endpoints.Add(new ServiceEndpoint()
|
|
||||||
{
|
|
||||||
Name = WellKnownServiceEndpointNames.SystemVssConnection,
|
|
||||||
Url = new Uri("https://pipelines.actions.githubusercontent.com"),
|
|
||||||
Authorization = new EndpointAuthorization()
|
|
||||||
{
|
|
||||||
Scheme = "Test",
|
|
||||||
Parameters = {
|
|
||||||
{"AccessToken", "token"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
message.Resources.Repositories.Add(new Pipelines.RepositoryResource()
|
|
||||||
{
|
|
||||||
Alias = Pipelines.PipelineConstants.SelfAlias,
|
|
||||||
Id = "github",
|
|
||||||
Version = "sha1"
|
|
||||||
});
|
|
||||||
message.ContextData.Add("github", new Pipelines.ContextData.DictionaryContextData());
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
@@ -136,7 +123,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
_jobExtension.Setup(x => x.InitializeJob(It.IsAny<IExecutionContext>(), It.IsAny<Pipelines.AgentJobRequestMessage>()))
|
_jobExtension.Setup(x => x.InitializeJob(It.IsAny<IExecutionContext>(), It.IsAny<Pipelines.AgentJobRequestMessage>()))
|
||||||
.Throws(new Exception());
|
.Throws(new Exception());
|
||||||
|
|
||||||
await _jobRunner.RunAsync(GetMessage(), _tokenSource.Token);
|
await _jobRunner.RunAsync(_message, _tokenSource.Token);
|
||||||
|
|
||||||
Assert.Equal(TaskResult.Failed, _jobEc.Result);
|
Assert.Equal(TaskResult.Failed, _jobEc.Result);
|
||||||
_stepRunner.Verify(x => x.RunAsync(It.IsAny<IExecutionContext>()), Times.Never);
|
_stepRunner.Verify(x => x.RunAsync(It.IsAny<IExecutionContext>()), Times.Never);
|
||||||
@@ -154,24 +141,11 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
.Throws(new OperationCanceledException());
|
.Throws(new OperationCanceledException());
|
||||||
_tokenSource.Cancel();
|
_tokenSource.Cancel();
|
||||||
|
|
||||||
await _jobRunner.RunAsync(GetMessage(), _tokenSource.Token);
|
await _jobRunner.RunAsync(_message, _tokenSource.Token);
|
||||||
|
|
||||||
Assert.Equal(TaskResult.Canceled, _jobEc.Result);
|
Assert.Equal(TaskResult.Canceled, _jobEc.Result);
|
||||||
_stepRunner.Verify(x => x.RunAsync(It.IsAny<IExecutionContext>()), Times.Never);
|
_stepRunner.Verify(x => x.RunAsync(It.IsAny<IExecutionContext>()), Times.Never);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
[Trait("Level", "L0")]
|
|
||||||
[Trait("Category", "Worker")]
|
|
||||||
public async Task WorksWithRunnerJobRequestMessageType()
|
|
||||||
{
|
|
||||||
using (TestHostContext hc = CreateTestContext())
|
|
||||||
{
|
|
||||||
var message = GetMessage(JobRequestMessageTypes.RunnerJobRequest);
|
|
||||||
await _jobRunner.RunAsync(message, _tokenSource.Token);
|
|
||||||
Assert.Equal(TaskResult.Succeeded, _jobEc.Result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using System.Linq;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.Actions.RunService.WebApi;
|
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using GitHub.Runner.Worker;
|
using GitHub.Runner.Worker;
|
||||||
using GitHub.Runner.Worker.Container;
|
using GitHub.Runner.Worker.Container;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
|
|||||||
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
||||||
PACKAGE_TRIMS_DIR="$SCRIPT_DIR/../_package_trims"
|
PACKAGE_TRIMS_DIR="$SCRIPT_DIR/../_package_trims"
|
||||||
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
||||||
DOTNETSDK_VERSION="6.0.405"
|
DOTNETSDK_VERSION="6.0.300"
|
||||||
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": "6.0.405"
|
"version": "6.0.300"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.302.1
|
2.301.1
|
||||||
|
|||||||
Reference in New Issue
Block a user