diff --git a/docs/start/envosx.md b/docs/start/envosx.md
index 13969600a..d93f7a3eb 100644
--- a/docs/start/envosx.md
+++ b/docs/start/envosx.md
@@ -4,7 +4,7 @@
## Supported Versions
- - macOS Sierra (10.12) and later versions
+ - macOS High Sierra (10.13) and later versions
-## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/macos-prerequisites?tabs=netcore2x)
+## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/macos-prerequisites?tabs=netcore30)
diff --git a/docs/start/envwin.md b/docs/start/envwin.md
index 4dd316990..fc3500a64 100644
--- a/docs/start/envwin.md
+++ b/docs/start/envwin.md
@@ -5,8 +5,8 @@
- Windows 7 64-bit
- Windows 8.1 64-bit
- Windows 10 64-bit
- - Windows Server 2008 R2 SP1 64-bit
- Windows Server 2012 R2 64-bit
- Windows Server 2016 64-bit
+ - Windows Server 2019 64-bit
-## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)
+## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore30)
diff --git a/src/Runner.Service/Windows/FinalPublicKey.snk b/src/Runner.Service/Windows/FinalPublicKey.snk
deleted file mode 100644
index 110b59c7b..000000000
Binary files a/src/Runner.Service/Windows/FinalPublicKey.snk and /dev/null differ
diff --git a/src/Runner.Service/Windows/RunnerService.csproj b/src/Runner.Service/Windows/RunnerService.csproj
index 8871f9a80..73fe4ecc6 100644
--- a/src/Runner.Service/Windows/RunnerService.csproj
+++ b/src/Runner.Service/Windows/RunnerService.csproj
@@ -9,9 +9,8 @@
Properties
RunnerService
RunnerService
- true
- FinalPublicKey.snk
- true
+ false
+ false
v4.5
512
true
@@ -64,7 +63,6 @@
-
diff --git a/src/Runner.Worker/ActionCommandManager.cs b/src/Runner.Worker/ActionCommandManager.cs
index 2e2e6af1e..023e2f304 100644
--- a/src/Runner.Worker/ActionCommandManager.cs
+++ b/src/Runner.Worker/ActionCommandManager.cs
@@ -73,7 +73,7 @@ namespace GitHub.Runner.Worker
return false;
}
- // process action command in serialize oreder.
+ // process action command in serialize order.
lock (_commandSerializeLock)
{
if (_stopProcessCommand)
@@ -107,32 +107,19 @@ namespace GitHub.Runner.Worker
}
else if (_commandExtensions.TryGetValue(actionCommand.Command, out IActionCommandExtension extension))
{
- bool commandHasBeenOutput = false;
+ if (context.EchoOnActionCommand && !extension.OmitEcho)
+ {
+ context.Output(input);
+ }
try
{
- if (context.EchoOnActionCommand)
- {
- context.Output(input);
- context.Debug($"Processing command '{actionCommand.Command}'");
- commandHasBeenOutput = true;
- }
-
extension.ProcessCommand(context, input, actionCommand);
-
- if (context.EchoOnActionCommand)
- {
- context.Debug($"Processed command '{actionCommand.Command}' successfully");
- }
}
catch (Exception ex)
{
- if (!commandHasBeenOutput)
- {
- context.Output(input);
- }
-
- context.Error($"Unable to process command '{input}' successfully.");
+ var commandInformation = extension.OmitEcho ? extension.Command : input;
+ context.Error($"Unable to process command '{commandInformation}' successfully.");
context.Error(ex);
context.CommandResult = TaskResult.Failed;
}
@@ -151,6 +138,7 @@ namespace GitHub.Runner.Worker
public interface IActionCommandExtension : IExtension
{
string Command { get; }
+ bool OmitEcho { get; }
void ProcessCommand(IExecutionContext context, string line, ActionCommand command);
}
@@ -158,6 +146,7 @@ namespace GitHub.Runner.Worker
public sealed class InternalPluginSetRepoPathCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "internal-set-repo-path";
+ public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -187,6 +176,7 @@ namespace GitHub.Runner.Worker
public sealed class SetEnvCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "set-env";
+ public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -211,6 +201,7 @@ namespace GitHub.Runner.Worker
public sealed class SetOutputCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "set-output";
+ public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -234,6 +225,7 @@ namespace GitHub.Runner.Worker
public sealed class SaveStateCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "save-state";
+ public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -257,6 +249,7 @@ namespace GitHub.Runner.Worker
public sealed class AddMaskCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "add-mask";
+ public bool OmitEcho => true;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -268,6 +261,11 @@ namespace GitHub.Runner.Worker
}
else
{
+ if (context.EchoOnActionCommand)
+ {
+ context.Output($"::{Command}::***");
+ }
+
HostContext.SecretMasker.AddValue(command.Data);
Trace.Info($"Add new secret mask with length of {command.Data.Length}");
}
@@ -277,6 +275,7 @@ namespace GitHub.Runner.Worker
public sealed class AddPathCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "add-path";
+ public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -291,6 +290,7 @@ namespace GitHub.Runner.Worker
public sealed class AddMatcherCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "add-matcher";
+ public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -337,6 +337,7 @@ namespace GitHub.Runner.Worker
public sealed class RemoveMatcherCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "remove-matcher";
+ public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -404,6 +405,7 @@ namespace GitHub.Runner.Worker
public sealed class DebugCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "debug";
+ public bool OmitEcho => true;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -431,6 +433,7 @@ namespace GitHub.Runner.Worker
{
public abstract IssueType Type { get; }
public abstract string Command { get; }
+ public bool OmitEcho => true;
public Type ExtensionType => typeof(IActionCommandExtension);
@@ -510,6 +513,8 @@ namespace GitHub.Runner.Worker
public abstract class GroupingCommandExtension : RunnerService, IActionCommandExtension
{
public abstract string Command { get; }
+ public bool OmitEcho => false;
+
public Type ExtensionType => typeof(IActionCommandExtension);
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
@@ -522,6 +527,7 @@ namespace GitHub.Runner.Worker
public sealed class EchoCommandExtension : RunnerService, IActionCommandExtension
{
public string Command => "echo";
+ public bool OmitEcho => false;
public Type ExtensionType => typeof(IActionCommandExtension);
diff --git a/src/Runner.Worker/Handlers/OutputManager.cs b/src/Runner.Worker/Handlers/OutputManager.cs
index 0a06bf956..a53a0436f 100644
--- a/src/Runner.Worker/Handlers/OutputManager.cs
+++ b/src/Runner.Worker/Handlers/OutputManager.cs
@@ -263,15 +263,17 @@ namespace GitHub.Runner.Worker.Handlers
// Root using fromPath
if (!string.IsNullOrWhiteSpace(match.FromPath) && !Path.IsPathRooted(file))
{
- file = Path.Combine(match.FromPath, file);
+ var fromDirectory = Path.GetDirectoryName(match.FromPath);
+ if (!string.IsNullOrWhiteSpace(fromDirectory))
+ {
+ file = Path.Combine(fromDirectory, file);
+ }
}
- // Root using system.defaultWorkingDirectory
+ // Root using workspace
if (!Path.IsPathRooted(file))
{
- var githubContext = _executionContext.ExpressionValues["github"] as GitHubContext;
- ArgUtil.NotNull(githubContext, nameof(githubContext));
- var workspace = githubContext["workspace"].ToString();
+ var workspace = _executionContext.GetGitHubContext("workspace");
ArgUtil.NotNullOrEmpty(workspace, "workspace");
file = Path.Combine(workspace, file);
@@ -297,7 +299,7 @@ namespace GitHub.Runner.Worker.Handlers
}
else
{
- // prefer `/` on all platforms
+ // Prefer `/` on all platforms
issue.Data["file"] = file.Substring(repositoryPath.Length).TrimStart(Path.DirectorySeparatorChar).Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
}
}
diff --git a/src/Test/L0/Worker/OutputManagerL0.cs b/src/Test/L0/Worker/OutputManagerL0.cs
index 8e0680dda..cb0eefebd 100644
--- a/src/Test/L0/Worker/OutputManagerL0.cs
+++ b/src/Test/L0/Worker/OutputManagerL0.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using GitHub.Runner.Sdk;
@@ -158,7 +159,7 @@ namespace GitHub.Runner.Common.Tests.Worker
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
- public void Code()
+ public void MatcherCode()
{
var matchers = new IssueMatchersConfig
{
@@ -300,7 +301,7 @@ namespace GitHub.Runner.Common.Tests.Worker
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
- public void LineColumn()
+ public void MatcherLineColumn()
{
var matchers = new IssueMatchersConfig
{
@@ -348,7 +349,7 @@ namespace GitHub.Runner.Common.Tests.Worker
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
- public void ProcessCommand()
+ public void MatcherDoesNotReceiveCommand()
{
using (Setup())
using (_outputManager)
@@ -382,7 +383,7 @@ namespace GitHub.Runner.Common.Tests.Worker
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
- public void RemoveColorCodes()
+ public void MatcherRemoveColorCodes()
{
using (Setup())
using (_outputManager)
@@ -528,7 +529,7 @@ namespace GitHub.Runner.Common.Tests.Worker
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
- public void Severity()
+ public void MatcherSeverity()
{
var matchers = new IssueMatchersConfig
{
@@ -589,7 +590,7 @@ namespace GitHub.Runner.Common.Tests.Worker
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
- public void Timeout()
+ public void MatcherTimeout()
{
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_ISSUE_MATCHER_TIMEOUT", "0:0:0.01");
var matchers = new IssueMatchersConfig
@@ -640,10 +641,216 @@ namespace GitHub.Runner.Common.Tests.Worker
}
}
- // todo: roots file against fromPath
- // todo: roots file against system.defaultWorkingDirectory
- // todo: matches repository
- // todo: checks file exists
+ [Fact]
+ [Trait("Level", "L0")]
+ [Trait("Category", "Worker")]
+ public void MatcherFile()
+ {
+ var matchers = new IssueMatchersConfig
+ {
+ Matchers =
+ {
+ new IssueMatcherConfig
+ {
+ Owner = "my-matcher-1",
+ Patterns = new[]
+ {
+ new IssuePatternConfig
+ {
+ Pattern = @"(.+): (.+)",
+ File = 1,
+ Message = 2,
+ },
+ },
+ },
+ },
+ };
+ using (var hostContext = Setup(matchers: matchers))
+ using (_outputManager)
+ {
+ // Setup github.workspace
+ var workDirectory = hostContext.GetDirectory(WellKnownDirectory.Work);
+ ArgUtil.NotNullOrEmpty(workDirectory, nameof(workDirectory));
+ Directory.CreateDirectory(workDirectory);
+ var workspaceDirectory = Path.Combine(workDirectory, "workspace");
+ Directory.CreateDirectory(workspaceDirectory);
+ _executionContext.Setup(x => x.GetGitHubContext("workspace")).Returns(workspaceDirectory);
+
+ // Create a test file
+ Directory.CreateDirectory(Path.Combine(workspaceDirectory, "some-directory"));
+ var filePath = Path.Combine(workspaceDirectory, "some-directory", "some-file.txt");
+ File.WriteAllText(filePath, "");
+
+ // Process
+ Process("some-directory/some-file.txt: some error");
+ Assert.Equal(1, _issues.Count);
+ Assert.Equal("some error", _issues[0].Item1.Message);
+ Assert.Equal("some-directory/some-file.txt", _issues[0].Item1.Data["file"]);
+ Assert.Equal(0, _commands.Count);
+ Assert.Equal(0, _messages.Count);
+ }
+ }
+
+ [Fact]
+ [Trait("Level", "L0")]
+ [Trait("Category", "Worker")]
+ public void MatcherFileExists()
+ {
+ var matchers = new IssueMatchersConfig
+ {
+ Matchers =
+ {
+ new IssueMatcherConfig
+ {
+ Owner = "my-matcher-1",
+ Patterns = new[]
+ {
+ new IssuePatternConfig
+ {
+ Pattern = @"(.+): (.+)",
+ File = 1,
+ Message = 2,
+ },
+ },
+ },
+ },
+ };
+ using (var hostContext = Setup(matchers: matchers))
+ using (_outputManager)
+ {
+ // Setup github.workspace
+ var workDirectory = hostContext.GetDirectory(WellKnownDirectory.Work);
+ ArgUtil.NotNullOrEmpty(workDirectory, nameof(workDirectory));
+ Directory.CreateDirectory(workDirectory);
+ var workspaceDirectory = Path.Combine(workDirectory, "workspace");
+ Directory.CreateDirectory(workspaceDirectory);
+ _executionContext.Setup(x => x.GetGitHubContext("workspace")).Returns(workspaceDirectory);
+
+ // Create a test file
+ File.WriteAllText(Path.Combine(workspaceDirectory, "some-file-1.txt"), "");
+
+ // Process
+ Process("some-file-1.txt: some error 1"); // file exists
+ Process("some-file-2.txt: some error 2"); // file does not exist
+
+ Assert.Equal(2, _issues.Count);
+ Assert.Equal("some error 1", _issues[0].Item1.Message);
+ Assert.Equal("some-file-1.txt", _issues[0].Item1.Data["file"]);
+ Assert.Equal("some error 2", _issues[1].Item1.Message);
+ Assert.False(_issues[1].Item1.Data.ContainsKey("file")); // does not contain file key
+ Assert.Equal(0, _commands.Count);
+ Assert.Equal(0, _messages.Where(x => !x.StartsWith("##[debug]")).Count());
+ }
+ }
+
+ [Fact]
+ [Trait("Level", "L0")]
+ [Trait("Category", "Worker")]
+ public void MatcherFileOutsideRepository()
+ {
+ var matchers = new IssueMatchersConfig
+ {
+ Matchers =
+ {
+ new IssueMatcherConfig
+ {
+ Owner = "my-matcher-1",
+ Patterns = new[]
+ {
+ new IssuePatternConfig
+ {
+ Pattern = @"(.+): (.+)",
+ File = 1,
+ Message = 2,
+ },
+ },
+ },
+ },
+ };
+ using (var hostContext = Setup(matchers: matchers))
+ using (_outputManager)
+ {
+ // Setup github.workspace
+ var workDirectory = hostContext.GetDirectory(WellKnownDirectory.Work);
+ ArgUtil.NotNullOrEmpty(workDirectory, nameof(workDirectory));
+ Directory.CreateDirectory(workDirectory);
+ var workspaceDirectory = Path.Combine(workDirectory, "workspace");
+ Directory.CreateDirectory(workspaceDirectory);
+ _executionContext.Setup(x => x.GetGitHubContext("workspace")).Returns(workspaceDirectory);
+
+ // Create test files
+ var filePath1 = Path.Combine(workspaceDirectory, "some-file-1.txt");
+ File.WriteAllText(filePath1, "");
+ var workspaceSiblingDirectory = Path.Combine(Path.GetDirectoryName(workspaceDirectory), "workspace-sibling");
+ Directory.CreateDirectory(workspaceSiblingDirectory);
+ var filePath2 = Path.Combine(workspaceSiblingDirectory, "some-file-2.txt");
+ File.WriteAllText(filePath2, "");
+
+ // Process
+ Process($"{filePath1}: some error 1"); // file exists inside workspace
+ Process($"{filePath2}: some error 2"); // file exists outside workspace
+
+ Assert.Equal(2, _issues.Count);
+ Assert.Equal("some error 1", _issues[0].Item1.Message);
+ Assert.Equal("some-file-1.txt", _issues[0].Item1.Data["file"]);
+ Assert.Equal("some error 2", _issues[1].Item1.Message);
+ Assert.False(_issues[1].Item1.Data.ContainsKey("file")); // does not contain file key
+ Assert.Equal(0, _commands.Count);
+ Assert.Equal(0, _messages.Where(x => !x.StartsWith("##[debug]")).Count());
+ }
+ }
+
+ [Fact]
+ [Trait("Level", "L0")]
+ [Trait("Category", "Worker")]
+ public void MatcherFromPath()
+ {
+ var matchers = new IssueMatchersConfig
+ {
+ Matchers =
+ {
+ new IssueMatcherConfig
+ {
+ Owner = "my-matcher-1",
+ Patterns = new[]
+ {
+ new IssuePatternConfig
+ {
+ Pattern = @"(.+): (.+) \[(.+)\]",
+ File = 1,
+ Message = 2,
+ FromPath = 3,
+ },
+ },
+ },
+ },
+ };
+ using (var hostContext = Setup(matchers: matchers))
+ using (_outputManager)
+ {
+ // Setup github.workspace
+ var workDirectory = hostContext.GetDirectory(WellKnownDirectory.Work);
+ ArgUtil.NotNullOrEmpty(workDirectory, nameof(workDirectory));
+ Directory.CreateDirectory(workDirectory);
+ var workspaceDirectory = Path.Combine(workDirectory, "workspace");
+ Directory.CreateDirectory(workspaceDirectory);
+ _executionContext.Setup(x => x.GetGitHubContext("workspace")).Returns(workspaceDirectory);
+
+ // Create a test file
+ Directory.CreateDirectory(Path.Combine(workspaceDirectory, "some-directory"));
+ Directory.CreateDirectory(Path.Combine(workspaceDirectory, "some-project", "some-directory"));
+ var filePath = Path.Combine(workspaceDirectory, "some-project", "some-directory", "some-file.txt");
+ File.WriteAllText(filePath, "");
+
+ // Process
+ Process("some-directory/some-file.txt: some error [some-project/some-project.proj]");
+ Assert.Equal(1, _issues.Count);
+ Assert.Equal("some error", _issues[0].Item1.Message);
+ Assert.Equal("some-project/some-directory/some-file.txt", _issues[0].Item1.Data["file"]);
+ Assert.Equal(0, _commands.Count);
+ Assert.Equal(0, _messages.Count);
+ }
+ }
private TestHostContext Setup(
[CallerMemberName] string name = "",
diff --git a/src/runnerversion b/src/runnerversion
index da0e9ef0d..68c57659e 100644
--- a/src/runnerversion
+++ b/src/runnerversion
@@ -1 +1 @@
-2.161.0
\ No newline at end of file
+2.161.0