Compare commits

..

17 Commits

Author SHA1 Message Date
Tingluo Huang
c8caf59bb7 Update releaseVersion 2021-09-01 16:29:49 -04:00
Tingluo Huang
77c5a664ed Cherry-pick changes for 2.281.1 (#1306)
* Temporary fix for macOS runner upgrade crash loop. (#1304)

* Typo fixed (#1289)

* Update error to say 'uninstall' not 'unconfigure' (#1179)

* Update error to say 'uninstall' not 'unconfigure'

* Say uninstall service in *nix config error msgs

Co-authored-by: Ferenc Hammerl <31069338+fhammerl@users.noreply.github.com>

* Allow setting default severity to "notice" (#1213)

* Show More Step Information in composite Actions (#1279)

* Prepare 2.281.1 runner release. (#1305)

Co-authored-by: Daniel Asztalos <asztalosdani@users.noreply.github.com>
Co-authored-by: Nick Fields <50085412+nick-invision@users.noreply.github.com>
Co-authored-by: Ferenc Hammerl <31069338+fhammerl@users.noreply.github.com>
Co-authored-by: Vladimir Panteleev <CyberShadow@users.noreply.github.com>
Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com>
2021-09-01 16:29:31 -04:00
Ferenc Hammerl
b6aa01fabc Update releaseVersion 2021-08-30 19:27:28 +02:00
Ferenc Hammerl
3615fb6923 Runner 2.281.0 (#1298)
* Add generateIdTokenUrl as an env var

* Add generateIdTokenUrl to env vars

* Update runnerversion

* Remove old relese notes

* Update releaseNote.md
2021-08-30 18:57:24 +02:00
Ferenc Hammerl
f61dcad5bb Don't try to login to ghcr.io with GHES tokens (#1291)
* Don't try GHXX tokens for ghcr.io login

* Explain hosted / onpremise in comment

* Nitfix variable name
2021-08-30 11:52:12 +02:00
Tingluo Huang
62d568674c Add ACTIONS_ID_TOKEN_REQUEST_URL/Token to script as well. (#1287) 2021-08-26 13:29:02 -04:00
Ferenc Hammerl
07c00f6a8a PowerShell secret masking (#1258)
* Trim pwsh special chars when masking secrets

* Add pwsh valueEncoder

* Explain regex

* Update ValueEncoders.cs

* Add tests for pwsh color codes in secrets

* Formatting

* Group tests into theories

* Split secret on PS chars and mask for them

* Clean up comments

* Remove unused unittest

* Rename escape methods
2021-08-25 23:07:19 +02:00
Tingluo Huang
05b84297b7 Add extra env for the Token log-in action is going to use to request ID_TOKEN. (#1270) 2021-08-23 14:50:35 -04:00
Thomas Boop
04679b56a9 Runner 2.280.3 Release (#1276) 2021-08-19 08:40:11 -04:00
Thomas Boop
d2ca24fa43 For Main Steps, just run the step, don't check condition (#1273)
* For Main Steps, just run the step, don't check condition

* fix whitespace

* pr feedback
2021-08-18 16:40:25 -04:00
Thomas Boop
abdaacfa6e Runner release 2.280.2 (#1259)
* Runner release 2.280.2

* update

* update
2021-08-12 12:55:45 -04:00
Thomas Boop
53fd7161e2 send path when resolving actions (#1250) 2021-08-11 09:48:32 -04:00
Ferenc Hammerl
ce68f3b167 Allow the use of flags in scripts/create-latest-svc.sh in a backwards compatible way (#1220)
* Use flags in svc creation script

* Refactor regex and add comments

* Fix indentation and typo in user matching

* Consistency use flags in automation scripts

* Update documentation to reflect new usage

* Make example more readable

* Remove test echos from script

* Remove test echo

* Format scripts and remove test script

* Remove tar

* Use getopts and single letter flags

* Update docs to show flag usage

* Update usage of create svc

* Revert svc to not use flags

* Revert delete script

* Update docs

* Readd deleted comments
2021-08-09 10:22:19 +02:00
Thomas Boop
e2c7329292 Release notes for 2.280.1 runner (#1244) 2021-08-04 13:28:32 -04:00
Thomas Boop
22a9d89772 Correctly set post step step context (#1243) 2021-08-04 11:39:22 -04:00
Thomas Boop
3851acd0cf fix continue on error (#1238) 2021-08-03 17:44:58 -04:00
Tingluo Huang
aab4aca8f7 Finish job when worker crashed with IOException. (#1239) 2021-08-03 16:21:39 -04:00
18 changed files with 305 additions and 133 deletions

View File

@@ -1,12 +1,17 @@
## Features
- Allow setting default severity to "notice" (#1213)
- Show More Step Information in composite Actions (#1279)
## Bugs
- Send Path when resolving actions so we can correctly validate Policy for Composite Actions (#1250)
- Temporary fix for macOS runner upgrade crash loop. (#1304)
- Fixed an issue where GHES runners fail to download public docker images (#1199)
## Misc
- Allows flags instead of parameters when configuring the runner (#1220)
- Update error to say 'uninstall' not 'unconfigure' (#1179)
- Typo fixed (#1289)
## 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.

View File

@@ -1 +1 @@
2.280.2
2.281.1

View File

@@ -118,6 +118,43 @@ then
exit 1
fi
# fix upgrade issue with macOS
currentplatform=$(uname | awk '{print tolower($0)}')
if [[ "$currentplatform" == 'darwin' ]]; then
# need a short-term fix for https://github.com/actions/runner/issues/743
# we will recreate all the ./externals/node12/bin/node of the past 5 versions
# v2.280.3 v2.280.2 v2.280.1 v2.279.0 v2.278.0
if [[ ! -e "$rootfolder/externals.2.280.3/node12/bin/node" ]]
then
mkdir -p "$rootfolder/externals.2.280.3/node12/bin"
cp "$rootfolder/externals/node12/bin/node" "$rootfolder/externals.2.280.3/node12/bin/node"
fi
if [[ ! -e "$rootfolder/externals.2.280.2/node12/bin/node" ]]
then
mkdir -p "$rootfolder/externals.2.280.2/node12/bin"
cp "$rootfolder/externals/node12/bin/node" "$rootfolder/externals.2.280.2/node12/bin/node"
fi
if [[ ! -e "$rootfolder/externals.2.280.1/node12/bin/node" ]]
then
mkdir -p "$rootfolder/externals.2.280.1/node12/bin"
cp "$rootfolder/externals/node12/bin/node" "$rootfolder/externals.2.280.1/node12/bin/node"
fi
if [[ ! -e "$rootfolder/externals.2.279.0/node12/bin/node" ]]
then
mkdir -p "$rootfolder/externals.2.279.0/node12/bin"
cp "$rootfolder/externals/node12/bin/node" "$rootfolder/externals.2.279.0/node12/bin/node"
fi
if [[ ! -e "$rootfolder/externals.2.278.0/node12/bin/node" ]]
then
mkdir -p "$rootfolder/externals.2.278.0/node12/bin"
cp "$rootfolder/externals/node12/bin/node" "$rootfolder/externals.2.278.0/node12/bin/node"
fi
fi
date "+[%F %T-%4N] Update succeed" >> "$logfile"
# rename the update log file with %logfile%.succeed/.failed/succeedneedrestart

View File

@@ -90,6 +90,8 @@ namespace GitHub.Runner.Common
this.SecretMasker.AddValueEncoder(ValueEncoders.UriDataEscape);
this.SecretMasker.AddValueEncoder(ValueEncoders.XmlDataEscape);
this.SecretMasker.AddValueEncoder(ValueEncoders.TrimDoubleQuotes);
this.SecretMasker.AddValueEncoder(ValueEncoders.PowerShellPreAmpersandEscape);
this.SecretMasker.AddValueEncoder(ValueEncoders.PowerShellPostAmpersandEscape);
// Create the trace manager.
if (string.IsNullOrEmpty(logFile))

View File

@@ -117,6 +117,7 @@ namespace GitHub.Runner.Listener.Configuration
try
{
// Determine the service deployment type based on connection data. (Hosted/OnPremises)
// Hosted usually means github.com or localhost, while OnPremises means GHES or GHAE
runnerSettings.IsHostedServer = runnerSettings.GitHubUrl == null || UrlUtil.IsHostedServer(new UriBuilder(runnerSettings.GitHubUrl));
// Warn if the Actions server url and GHES server url has different Host
@@ -346,12 +347,9 @@ namespace GitHub.Runner.Listener.Configuration
_term.WriteLine();
_term.WriteSuccessMessage("Runner service removed");
#elif OS_LINUX
// unconfig system D service first
throw new Exception("Unconfigure service first");
#elif OS_OSX
// unconfig osx service first
throw new Exception("Unconfigure service first");
#else
// unconfig systemd or osx service first
throw new Exception("Uninstall service first");
#endif
}

View File

@@ -74,10 +74,12 @@ namespace GitHub.Runner.Listener
await jobDispatcher.WaitAsync(token);
Trace.Info($"All running job has exited.");
// We need to keep runner backup around for macOS until we fixed https://github.com/actions/runner/issues/743
#if !OS_OSX
// delete runner backup
DeletePreviousVersionRunnerBackup(token);
Trace.Info($"Delete old version runner backup.");
#endif
// generate update script from template
await UpdateRunnerUpdateStateAsync("Generate and execute update script.");
@@ -96,7 +98,7 @@ namespace GitHub.Runner.Listener
invokeScript.Start();
Trace.Info($"Update script start running");
await UpdateRunnerUpdateStateAsync("Runner will exit shortly for update, should back online within 10 seconds.");
await UpdateRunnerUpdateStateAsync("Runner will exit shortly for update, should be back online within 10 seconds.");
return true;
}

View File

@@ -494,7 +494,8 @@ namespace GitHub.Runner.Worker
private void UpdateRegistryAuthForGitHubToken(IExecutionContext executionContext, ContainerInfo container)
{
var registryIsTokenCompatible = container.RegistryServer.Equals("ghcr.io", StringComparison.OrdinalIgnoreCase) || container.RegistryServer.Equals("containers.pkg.github.com", StringComparison.OrdinalIgnoreCase);
if (!registryIsTokenCompatible)
var isFallbackTokenFromHostedGithub = HostContext.GetService<IConfigurationStore>().GetSettings().IsHostedServer;
if (!registryIsTokenCompatible || !isFallbackTokenFromHostedGithub)
{
return;
}

View File

@@ -980,18 +980,6 @@ namespace GitHub.Runner.Worker
context.Write(null, message);
}
public static void WriteDetails(this IExecutionContext context, string message)
{
if (context.IsEmbedded)
{
context.Debug(message);
}
else
{
context.Output(message);
}
}
// Do not add a format string overload. See comment on ExecutionContext.Write().
public static void Command(this IExecutionContext context, string message)
{

View File

@@ -295,99 +295,108 @@ namespace GitHub.Runner.Worker.Handlers
CancellationTokenRegistration? jobCancelRegister = null;
try
{
// Register job cancellation call back only if job cancellation token not been fire before each step run
if (!ExecutionContext.Root.CancellationToken.IsCancellationRequested)
{
// Test the condition again. The job was canceled after the condition was originally evaluated.
jobCancelRegister = ExecutionContext.Root.CancellationToken.Register(() =>
{
// Mark job as cancelled
ExecutionContext.Root.Result = TaskResult.Canceled;
ExecutionContext.Root.JobContext.Status = ExecutionContext.Root.Result?.ToActionResult();
step.ExecutionContext.Debug($"Re-evaluate condition on job cancellation for step: '{step.DisplayName}'.");
var conditionReTestTraceWriter = new ConditionTraceWriter(Trace, null); // host tracing only
var conditionReTestResult = false;
if (HostContext.RunnerShutdownToken.IsCancellationRequested)
{
step.ExecutionContext.Debug($"Skip Re-evaluate condition on runner shutdown.");
}
else
{
try
{
var templateEvaluator = step.ExecutionContext.ToPipelineTemplateEvaluator(conditionReTestTraceWriter);
var condition = new BasicExpressionToken(null, null, null, step.Condition);
conditionReTestResult = templateEvaluator.EvaluateStepIf(condition, step.ExecutionContext.ExpressionValues, step.ExecutionContext.ExpressionFunctions, step.ExecutionContext.ToExpressionState());
}
catch (Exception ex)
{
// Cancel the step since we get exception while re-evaluate step condition
Trace.Info("Caught exception from expression when re-test condition on job cancellation.");
step.ExecutionContext.Error(ex);
}
}
if (!conditionReTestResult)
{
// Cancel the step
Trace.Info("Cancel current running step.");
step.ExecutionContext.CancelToken();
}
});
}
else
{
if (ExecutionContext.Root.Result != TaskResult.Canceled)
{
// Mark job as cancelled
ExecutionContext.Root.Result = TaskResult.Canceled;
ExecutionContext.Root.JobContext.Status = ExecutionContext.Root.Result?.ToActionResult();
}
}
// Evaluate condition
step.ExecutionContext.Debug($"Evaluating condition for step: '{step.DisplayName}'");
var conditionTraceWriter = new ConditionTraceWriter(Trace, step.ExecutionContext);
var conditionResult = false;
var conditionEvaluateError = default(Exception);
if (HostContext.RunnerShutdownToken.IsCancellationRequested)
{
step.ExecutionContext.Debug($"Skip evaluate condition on runner shutdown.");
}
else
{
try
{
var templateEvaluator = step.ExecutionContext.ToPipelineTemplateEvaluator(conditionTraceWriter);
var condition = new BasicExpressionToken(null, null, null, step.Condition);
conditionResult = templateEvaluator.EvaluateStepIf(condition, step.ExecutionContext.ExpressionValues, step.ExecutionContext.ExpressionFunctions, step.ExecutionContext.ToExpressionState());
}
catch (Exception ex)
{
Trace.Info("Caught exception from expression.");
Trace.Error(ex);
conditionEvaluateError = ex;
}
}
if (!conditionResult && conditionEvaluateError == null)
{
// Condition is false
Trace.Info("Skipping step due to condition evaluation.");
step.ExecutionContext.Result = TaskResult.Skipped;
continue;
}
else if (conditionEvaluateError != null)
{
// Condition error
step.ExecutionContext.Error(conditionEvaluateError);
step.ExecutionContext.Result = TaskResult.Failed;
ExecutionContext.Result = TaskResult.Failed;
break;
}
else
// For main steps just run the action
if (stage == ActionRunStage.Main)
{
await RunStepAsync(step);
}
// We need to evaluate conditions for pre/post steps
else
{
// Register job cancellation call back only if job cancellation token not been fire before each step run
if (!ExecutionContext.Root.CancellationToken.IsCancellationRequested)
{
// Test the condition again. The job was canceled after the condition was originally evaluated.
jobCancelRegister = ExecutionContext.Root.CancellationToken.Register(() =>
{
// Mark job as cancelled
ExecutionContext.Root.Result = TaskResult.Canceled;
ExecutionContext.Root.JobContext.Status = ExecutionContext.Root.Result?.ToActionResult();
step.ExecutionContext.Debug($"Re-evaluate condition on job cancellation for step: '{step.DisplayName}'.");
var conditionReTestTraceWriter = new ConditionTraceWriter(Trace, null); // host tracing only
var conditionReTestResult = false;
if (HostContext.RunnerShutdownToken.IsCancellationRequested)
{
step.ExecutionContext.Debug($"Skip Re-evaluate condition on runner shutdown.");
}
else
{
try
{
var templateEvaluator = step.ExecutionContext.ToPipelineTemplateEvaluator(conditionReTestTraceWriter);
var condition = new BasicExpressionToken(null, null, null, step.Condition);
conditionReTestResult = templateEvaluator.EvaluateStepIf(condition, step.ExecutionContext.ExpressionValues, step.ExecutionContext.ExpressionFunctions, step.ExecutionContext.ToExpressionState());
}
catch (Exception ex)
{
// Cancel the step since we get exception while re-evaluate step condition
Trace.Info("Caught exception from expression when re-test condition on job cancellation.");
step.ExecutionContext.Error(ex);
}
}
if (!conditionReTestResult)
{
// Cancel the step
Trace.Info("Cancel current running step.");
step.ExecutionContext.CancelToken();
}
});
}
else
{
if (ExecutionContext.Root.Result != TaskResult.Canceled)
{
// Mark job as cancelled
ExecutionContext.Root.Result = TaskResult.Canceled;
ExecutionContext.Root.JobContext.Status = ExecutionContext.Root.Result?.ToActionResult();
}
}
// Evaluate condition
step.ExecutionContext.Debug($"Evaluating condition for step: '{step.DisplayName}'");
var conditionTraceWriter = new ConditionTraceWriter(Trace, step.ExecutionContext);
var conditionResult = false;
var conditionEvaluateError = default(Exception);
if (HostContext.RunnerShutdownToken.IsCancellationRequested)
{
step.ExecutionContext.Debug($"Skip evaluate condition on runner shutdown.");
}
else
{
try
{
var templateEvaluator = step.ExecutionContext.ToPipelineTemplateEvaluator(conditionTraceWriter);
var condition = new BasicExpressionToken(null, null, null, step.Condition);
conditionResult = templateEvaluator.EvaluateStepIf(condition, step.ExecutionContext.ExpressionValues, step.ExecutionContext.ExpressionFunctions, step.ExecutionContext.ToExpressionState());
}
catch (Exception ex)
{
Trace.Info("Caught exception from expression.");
Trace.Error(ex);
conditionEvaluateError = ex;
}
}
if (!conditionResult && conditionEvaluateError == null)
{
// Condition is false
Trace.Info("Skipping step due to condition evaluation.");
step.ExecutionContext.Result = TaskResult.Skipped;
continue;
}
else if (conditionEvaluateError != null)
{
// Condition error
step.ExecutionContext.Error(conditionEvaluateError);
step.ExecutionContext.Result = TaskResult.Failed;
ExecutionContext.Result = TaskResult.Failed;
break;
}
else
{
await RunStepAsync(step);
}
}
}
finally
{

View File

@@ -50,8 +50,8 @@ namespace GitHub.Runner.Worker.Handlers
var dockerFile = Path.Combine(ActionDirectory, Data.Image);
ArgUtil.File(dockerFile, nameof(Data.Image));
ExecutionContext.WriteDetails(ExecutionContext.IsEmbedded ? "Building docker image" : $"##[group]Building docker image");
ExecutionContext.WriteDetails($"Dockerfile for action: '{dockerFile}'.");
ExecutionContext.Output($"##[group]Building docker image");
ExecutionContext.Output($"Dockerfile for action: '{dockerFile}'.");
var imageName = $"{dockerManager.DockerInstanceLabel}:{ExecutionContext.Id.ToString("N")}";
var buildExitCode = await dockerManager.DockerBuild(
ExecutionContext,
@@ -59,7 +59,7 @@ namespace GitHub.Runner.Worker.Handlers
dockerFile,
Directory.GetParent(dockerFile).FullName,
imageName);
ExecutionContext.WriteDetails(ExecutionContext.IsEmbedded ? "" : "##[endgroup]");
ExecutionContext.Output("##[endgroup]");
if (buildExitCode != 0)
{
@@ -217,6 +217,7 @@ namespace GitHub.Runner.Worker.Handlers
if (systemConnection.Data.TryGetValue("GenerateIdTokenUrl", out var generateIdTokenUrl) && !string.IsNullOrEmpty(generateIdTokenUrl))
{
Environment["ACTIONS_ID_TOKEN_REQUEST_URL"] = generateIdTokenUrl;
Environment["ACTIONS_ID_TOKEN_REQUEST_TOKEN"] = systemConnection.Authorization.Parameters[EndpointAuthorizationParameters.AccessToken];
}
foreach (var variable in this.Environment)

View File

@@ -82,7 +82,7 @@ namespace GitHub.Runner.Worker.Handlers
if (stage == ActionRunStage.Post)
{
ExecutionContext.WriteDetails($"Post job cleanup.");
ExecutionContext.Output($"Post job cleanup.");
return;
}
@@ -118,30 +118,30 @@ namespace GitHub.Runner.Worker.Handlers
groupName = "Action details";
}
ExecutionContext.WriteDetails(ExecutionContext.IsEmbedded ? groupName : $"##[group]{groupName}");
ExecutionContext.Output($"##[group]{groupName}");
if (this.Inputs?.Count > 0)
{
ExecutionContext.WriteDetails("with:");
ExecutionContext.Output("with:");
foreach (var input in this.Inputs)
{
if (!string.IsNullOrEmpty(input.Value))
{
ExecutionContext.WriteDetails($" {input.Key}: {input.Value}");
ExecutionContext.Output($" {input.Key}: {input.Value}");
}
}
}
if (this.Environment?.Count > 0)
{
ExecutionContext.WriteDetails("env:");
ExecutionContext.Output("env:");
foreach (var env in this.Environment)
{
ExecutionContext.WriteDetails($" {env.Key}: {env.Value}");
ExecutionContext.Output($" {env.Key}: {env.Value}");
}
}
ExecutionContext.WriteDetails(ExecutionContext.IsEmbedded ? "" : "##[endgroup]");
ExecutionContext.Output("##[endgroup]");
}
public override void Initialize(IHostContext hostContext)

View File

@@ -56,6 +56,7 @@ namespace GitHub.Runner.Worker.Handlers
if (systemConnection.Data.TryGetValue("GenerateIdTokenUrl", out var generateIdTokenUrl) && !string.IsNullOrEmpty(generateIdTokenUrl))
{
Environment["ACTIONS_ID_TOKEN_REQUEST_URL"] = generateIdTokenUrl;
Environment["ACTIONS_ID_TOKEN_REQUEST_TOKEN"] = systemConnection.Authorization.Parameters[EndpointAuthorizationParameters.AccessToken];
}
// Resolve the target script.

View File

@@ -40,7 +40,7 @@ namespace GitHub.Runner.Worker.Handlers
firstLine = firstLine.Substring(0, firstNewLine);
}
ExecutionContext.WriteDetails(ExecutionContext.IsEmbedded ? $"Run {firstLine}" : $"##[group]Run {firstLine}");
ExecutionContext.Output($"##[group]Run {firstLine}");
}
else
{
@@ -51,7 +51,7 @@ namespace GitHub.Runner.Worker.Handlers
foreach (var line in multiLines)
{
// Bright Cyan color
ExecutionContext.WriteDetails($"\x1b[36;1m{line}\x1b[0m");
ExecutionContext.Output($"\x1b[36;1m{line}\x1b[0m");
}
string argFormat;
@@ -110,23 +110,23 @@ namespace GitHub.Runner.Worker.Handlers
if (!string.IsNullOrEmpty(shellCommandPath))
{
ExecutionContext.WriteDetails($"shell: {shellCommandPath} {argFormat}");
ExecutionContext.Output($"shell: {shellCommandPath} {argFormat}");
}
else
{
ExecutionContext.WriteDetails($"shell: {shellCommand} {argFormat}");
ExecutionContext.Output($"shell: {shellCommand} {argFormat}");
}
if (this.Environment?.Count > 0)
{
ExecutionContext.WriteDetails("env:");
ExecutionContext.Output("env:");
foreach (var env in this.Environment)
{
ExecutionContext.WriteDetails($" {env.Key}: {env.Value}");
ExecutionContext.Output($" {env.Key}: {env.Value}");
}
}
ExecutionContext.WriteDetails(ExecutionContext.IsEmbedded ? "" : "##[endgroup]");
ExecutionContext.Output("##[endgroup]");
}
public async Task RunAsync(ActionRunStage stage)
@@ -147,7 +147,8 @@ namespace GitHub.Runner.Worker.Handlers
// Add Telemetry to JobContext to send with JobCompleteMessage
if (stage == ActionRunStage.Main)
{
var telemetry = new ActionsStepTelemetry {
var telemetry = new ActionsStepTelemetry
{
IsEmbedded = ExecutionContext.IsEmbedded,
Type = "run",
};
@@ -276,6 +277,13 @@ namespace GitHub.Runner.Worker.Handlers
fileName = node12;
}
#endif
var systemConnection = ExecutionContext.Global.Endpoints.Single(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase));
if (systemConnection.Data.TryGetValue("GenerateIdTokenUrl", out var generateIdTokenUrl) && !string.IsNullOrEmpty(generateIdTokenUrl))
{
Environment["ACTIONS_ID_TOKEN_REQUEST_URL"] = generateIdTokenUrl;
Environment["ACTIONS_ID_TOKEN_REQUEST_TOKEN"] = systemConnection.Authorization.Parameters[EndpointAuthorizationParameters.AccessToken];
}
ExecutionContext.Debug($"{fileName} {arguments}");
using (var stdoutManager = new OutputManager(ExecutionContext, ActionCommandManager))

View File

@@ -350,6 +350,7 @@ namespace GitHub.Runner.Worker
case "":
case "ERROR":
case "WARNING":
case "NOTICE":
break;
default:
throw new ArgumentException($"Matcher '{_owner}' contains unexpected default severity '{_severity}'");

View File

@@ -2,6 +2,7 @@
using System.ComponentModel;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
namespace GitHub.DistributedTask.Logging
@@ -80,6 +81,65 @@ namespace GitHub.DistributedTask.Logging
return trimmed;
}
public static String PowerShellPreAmpersandEscape(String value)
{
// if the secret is passed to PS as a command and it causes an error, sections of it can be surrounded by color codes
// or printed individually.
// The secret secretpart1&secretpart2&secretpart3 would be split into 2 sections:
// 'secretpart1&secretpart2&' and 'secretpart3'. This method masks for the first section.
// The secret secretpart1&+secretpart2&secretpart3 would be split into 2 sections:
// 'secretpart1&+' and (no 's') 'ecretpart2&secretpart3'. This method masks for the first section.
var trimmed = string.Empty;
if (!string.IsNullOrEmpty(value) && value.Contains("&"))
{
var secretSection = string.Empty;
if (value.Contains("&+"))
{
secretSection = value.Substring(0, value.IndexOf("&+") + "&+".Length);
}
else
{
secretSection = value.Substring(0, value.LastIndexOf("&") + "&".Length);
}
// Don't mask short secrets
if (secretSection.Length >= 6)
{
trimmed = secretSection;
}
}
return trimmed;
}
public static String PowerShellPostAmpersandEscape(String value)
{
var trimmed = string.Empty;
if (!string.IsNullOrEmpty(value) && value.Contains("&"))
{
var secretSection = string.Empty;
if (value.Contains("&+"))
{
// +1 to skip the letter that got colored
secretSection = value.Substring(value.IndexOf("&+") + "&+".Length + 1);
}
else
{
secretSection = value.Substring(value.LastIndexOf("&") + "&".Length);
}
if (secretSection.Length >= 6)
{
trimmed = secretSection;
}
}
return trimmed;
}
private static string Base64StringEscapeShift(String value, int shift)
{
var bytes = Encoding.UTF8.GetBytes(value);

View File

@@ -112,6 +112,36 @@ namespace GitHub.Runner.Common.Tests
}
}
[Theory]
[InlineData("secret&secret&secret", "secret&secret&\x0033[96msecret\x0033[0m", "***\x0033[96m***\x0033[0m")]
[InlineData("secret&secret+secret", "secret&\x0033[96msecret+secret\x0033[0m", "***\x0033[96m***\x0033[0m")]
[InlineData("secret+secret&secret", "secret+secret&\x0033[96msecret\x0033[0m", "***\x0033[96m***\x0033[0m")]
[InlineData("secret&secret&+secretsecret", "secret&secret&+\x0033[96ms\x0033[0mecretsecret", "***\x0033[96ms\x0033[0m***")]
[InlineData("secret&+secret&secret", "secret&+\x0033[96ms\x0033[0mecret&secret", "***\x0033[96ms\x0033[0m***")]
[InlineData("secret&+secret&+secret", "secret&+\x0033[96ms\x0033[0mecret&+secret", "***\x0033[96ms\x0033[0m***")]
[InlineData("secret&+secret&secret&+secret", "secret&+\x0033[96ms\x0033[0mecret&secret&+secret", "***\x0033[96ms\x0033[0m***")]
[Trait("Level", "L0")]
[Trait("Category", "Common")]
public void SecretSectionMasking(string secret, string rawOutput, string maskedOutput)
{
try
{
// Arrange.
Setup();
// Act.
_hc.SecretMasker.AddValue(secret);
// Assert.
Assert.Equal(maskedOutput, _hc.SecretMasker.MaskSecrets(rawOutput));
}
finally
{
// Cleanup.
Teardown();
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Common")]

View File

@@ -392,6 +392,35 @@ namespace GitHub.Runner.Common.Tests.Worker
Assert.Equal("not-working", match.Message);
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void Matcher_MultiplePatterns_DefaultSeverityNotice()
{
var config = JsonUtility.FromString<IssueMatchersConfig>(@"
{
""problemMatcher"": [
{
""owner"": ""myMatcher"",
""severity"": ""notice"",
""pattern"": [
{
""regexp"": ""^(.+)$"",
""message"": 1
}
]
}
]
}
");
config.Validate();
var matcher = new IssueMatcher(config.Matchers[0], TimeSpan.FromSeconds(1));
var match = matcher.Match("just-a-notice");
Assert.Equal("notice", match.Severity);
Assert.Equal("just-a-notice", match.Message);
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]

View File

@@ -1 +1 @@
2.280.2
2.281.1