mirror of
https://github.com/actions/runner.git
synced 2025-12-13 10:05:23 +00:00
Compare commits
1 Commits
v2.291.0
...
users/tihu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d316c0a75 |
@@ -1,12 +1,18 @@
|
|||||||
## Features
|
## Features
|
||||||
- Relaxed naming requirements for dockerfiles (e.g. `Dockerfile.test` can now be built) (#1738)
|
- Continue-on-error is now possible for the composite action steps (#1763)
|
||||||
|
- Now it's possible to use context evaluation in the `shell` of composite action run steps (#1767)
|
||||||
|
|
||||||
## Bugs
|
## Bugs
|
||||||
- Fixed a bug where windows path separators were used in generated folders (#1617)
|
- Fix a bug where job would be marked as 'cancelled' after self-hosted runner going offline (#1792)
|
||||||
- Fixed an issue where runner's invoked via `run.sh` or `run.cmd` did not properly restart after update (#1812). This fix applies to all future updates after installing this version
|
- Translate paths in `github` and `runner` contexts when running on a container (#1762)
|
||||||
|
- Warn about invalid flags when configuring or running the runner (#1781)
|
||||||
|
- Fix a bug where job hooks would use job level working directory (#1809)
|
||||||
|
|
||||||
## Misc
|
## Misc
|
||||||
- Relaxed Actions Summary size limit to 1MiB (#1839)
|
- Allow warnings about actions using Node v12 (#1735)
|
||||||
|
- Better exception handling when runner is configured with invalid Url or token (#1741)
|
||||||
|
- Set user agent for websocket requests (#1791)
|
||||||
|
- Gracefully handle websocket failures (#1789)
|
||||||
|
|
||||||
## Windows x64
|
## Windows x64
|
||||||
We recommend configuring the runner in a root folder of the Windows drive (e.g. "C:\actions-runner"). This will help avoid issues related to service identity folder permissions and long file path restrictions on Windows.
|
We recommend configuring the runner in a root folder of the Windows drive (e.g. "C:\actions-runner"). This will help avoid issues related to service identity folder permissions and long file path restrictions on Windows.
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.291.0
|
<Update to ./src/runnerversion when creating release>
|
||||||
|
|||||||
@@ -1004,7 +1004,7 @@ namespace GitHub.Runner.Worker
|
|||||||
if (actionDefinitionData.Execution.ExecutionType == ActionExecutionType.Container)
|
if (actionDefinitionData.Execution.ExecutionType == ActionExecutionType.Container)
|
||||||
{
|
{
|
||||||
var containerAction = actionDefinitionData.Execution as ContainerActionExecutionData;
|
var containerAction = actionDefinitionData.Execution as ContainerActionExecutionData;
|
||||||
if (DockerUtil.IsDockerfile(containerAction.Image))
|
if (containerAction.Image.EndsWith("Dockerfile") || containerAction.Image.EndsWith("dockerfile"))
|
||||||
{
|
{
|
||||||
var dockerFileFullPath = Path.Combine(actionEntryDirectory, containerAction.Image);
|
var dockerFileFullPath = Path.Combine(actionEntryDirectory, containerAction.Image);
|
||||||
executionContext.Debug($"Dockerfile for action: '{dockerFileFullPath}'.");
|
executionContext.Debug($"Dockerfile for action: '{dockerFileFullPath}'.");
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace GitHub.Runner.Worker.Container
|
namespace GitHub.Runner.Worker.Container
|
||||||
@@ -18,7 +17,7 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
string pattern = $"^(?<{targetPort}>\\d+)/(?<{proto}>\\w+) -> (?<{host}>.+):(?<{hostPort}>\\d+)$";
|
string pattern = $"^(?<{targetPort}>\\d+)/(?<{proto}>\\w+) -> (?<{host}>.+):(?<{hostPort}>\\d+)$";
|
||||||
|
|
||||||
List<PortMapping> portMappings = new List<PortMapping>();
|
List<PortMapping> portMappings = new List<PortMapping>();
|
||||||
foreach (var line in portMappingLines)
|
foreach(var line in portMappingLines)
|
||||||
{
|
{
|
||||||
Match m = Regex.Match(line, pattern, RegexOptions.None, TimeSpan.FromSeconds(1));
|
Match m = Regex.Match(line, pattern, RegexOptions.None, TimeSpan.FromSeconds(1));
|
||||||
if (m.Success)
|
if (m.Success)
|
||||||
@@ -62,15 +61,5 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsDockerfile(string image)
|
|
||||||
{
|
|
||||||
if (image.StartsWith("docker://", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var imageWithoutPath = image.Split('/').Last();
|
|
||||||
return imageWithoutPath.StartsWith("Dockerfile.") || imageWithoutPath.StartsWith("dockerfile.") || imageWithoutPath.EndsWith("Dockerfile") || imageWithoutPath.EndsWith("dockerfile");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
void InitializeFiles(IExecutionContext context, ContainerInfo container);
|
void InitializeFiles(IExecutionContext context, ContainerInfo container);
|
||||||
void ProcessFiles(IExecutionContext context, ContainerInfo container);
|
void ProcessFiles(IExecutionContext context, ContainerInfo container);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class FileCommandManager : RunnerService, IFileCommandManager
|
public sealed class FileCommandManager : RunnerService, IFileCommandManager
|
||||||
@@ -57,7 +57,7 @@ namespace GitHub.Runner.Worker
|
|||||||
TryDeleteFile(newPath);
|
TryDeleteFile(newPath);
|
||||||
File.Create(newPath).Dispose();
|
File.Create(newPath).Dispose();
|
||||||
|
|
||||||
var pathToSet = container != null ? container.TranslateToContainerPath(newPath) : newPath;
|
var pathToSet = container != null ? container.TranslateToContainerPath(newPath) : newPath;
|
||||||
context.SetGitHubContext(fileCommand.ContextName, pathToSet);
|
context.SetGitHubContext(fileCommand.ContextName, pathToSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
foreach (var fileCommand in _commandExtensions)
|
foreach (var fileCommand in _commandExtensions)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fileCommand.ProcessCommand(context, Path.Combine(_fileCommandDirectory, fileCommand.FilePrefix + _fileSuffix),container);
|
fileCommand.ProcessCommand(context, Path.Combine(_fileCommandDirectory, fileCommand.FilePrefix + _fileSuffix),container);
|
||||||
}
|
}
|
||||||
@@ -266,7 +266,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public sealed class CreateStepSummaryCommand : RunnerService, IFileCommandExtension
|
public sealed class CreateStepSummaryCommand : RunnerService, IFileCommandExtension
|
||||||
{
|
{
|
||||||
public const int AttachmentSizeLimit = 1024 * 1024;
|
private const int _attachmentSizeLimit = 128 * 1024;
|
||||||
|
|
||||||
public string ContextName => "step_summary";
|
public string ContextName => "step_summary";
|
||||||
public string FilePrefix => "step_summary_";
|
public string FilePrefix => "step_summary_";
|
||||||
@@ -296,9 +296,9 @@ namespace GitHub.Runner.Worker
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileSize > AttachmentSizeLimit)
|
if (fileSize > _attachmentSizeLimit)
|
||||||
{
|
{
|
||||||
context.Error(String.Format(Constants.Runner.UnsupportedSummarySize, AttachmentSizeLimit / 1024, fileSize / 1024));
|
context.Error(String.Format(Constants.Runner.UnsupportedSummarySize, _attachmentSizeLimit / 1024, fileSize / 1024));
|
||||||
Trace.Info($"Step Summary file ({filePath}) is too large ({fileSize} bytes); skipping attachment upload");
|
Trace.Info($"Step Summary file ({filePath}) is too large ({fileSize} bytes); skipping attachment upload");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -44,8 +44,9 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
{
|
{
|
||||||
Data.Image = Data.Image.Substring("docker://".Length);
|
Data.Image = Data.Image.Substring("docker://".Length);
|
||||||
}
|
}
|
||||||
else if (DockerUtil.IsDockerfile(Data.Image))
|
else if (Data.Image.EndsWith("Dockerfile") || Data.Image.EndsWith("dockerfile"))
|
||||||
{
|
{
|
||||||
|
// ensure docker file exist
|
||||||
var dockerFile = Path.Combine(ActionDirectory, Data.Image);
|
var dockerFile = Path.Combine(ActionDirectory, Data.Image);
|
||||||
ArgUtil.File(dockerFile, nameof(Data.Image));
|
ArgUtil.File(dockerFile, nameof(Data.Image));
|
||||||
|
|
||||||
@@ -67,10 +68,6 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
|
|
||||||
Data.Image = imageName;
|
Data.Image = imageName;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"'{Data.Image}' should be either '[path]/Dockerfile' or 'docker://image[:tag]'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
string type = Action.Type == Pipelines.ActionSourceType.Repository ? "Dockerfile" : "DockerHub";
|
string type = Action.Type == Pipelines.ActionSourceType.Repository ? "Dockerfile" : "DockerHub";
|
||||||
// Set extra telemetry base on the current context.
|
// Set extra telemetry base on the current context.
|
||||||
|
|||||||
@@ -154,6 +154,12 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
if (line.Contains("fatal: unsafe repository", StringComparison.OrdinalIgnoreCase))
|
if (line.Contains("fatal: unsafe repository", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
_executionContext.StepTelemetry.ErrorMessages.Add(line);
|
_executionContext.StepTelemetry.ErrorMessages.Add(line);
|
||||||
|
var gitUnsafeDirNotice = new DTWebApi.Issue
|
||||||
|
{
|
||||||
|
Message = $"You may experience error caused by a recently git safe directory enforcement. For more information see: https://github.blog/changelog/xxx",
|
||||||
|
Type = DTWebApi.IssueType.Notice,
|
||||||
|
};
|
||||||
|
_executionContext.AddIssue(gitUnsafeDirNotice);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regular output
|
// Regular output
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace GitHub.Services.Common.ClientStorage
|
|||||||
private readonly string m_filePath;
|
private readonly string m_filePath;
|
||||||
private readonly VssFileStorageReader m_reader;
|
private readonly VssFileStorageReader m_reader;
|
||||||
private readonly IVssClientStorageWriter m_writer;
|
private readonly IVssClientStorageWriter m_writer;
|
||||||
|
|
||||||
private const char c_defaultPathSeparator = '\\';
|
private const char c_defaultPathSeparator = '\\';
|
||||||
private const bool c_defaultIgnoreCaseInPaths = false;
|
private const bool c_defaultIgnoreCaseInPaths = false;
|
||||||
|
|
||||||
@@ -191,7 +192,7 @@ namespace GitHub.Services.Common.ClientStorage
|
|||||||
// Windows Impersonation is being used.
|
// Windows Impersonation is being used.
|
||||||
|
|
||||||
// Check to see if we can find the user's local application data directory.
|
// Check to see if we can find the user's local application data directory.
|
||||||
string subDir = Path.Combine("GitHub", "ActionsService");
|
string subDir = "GitHub\\ActionsService";
|
||||||
string path = Environment.GetEnvironmentVariable("localappdata");
|
string path = Environment.GetEnvironmentVariable("localappdata");
|
||||||
SafeGetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
SafeGetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||||
if (string.IsNullOrEmpty(path))
|
if (string.IsNullOrEmpty(path))
|
||||||
|
|||||||
@@ -144,48 +144,5 @@ namespace GitHub.Runner.Common.Tests.Worker.Container
|
|||||||
var actual = DockerUtil.ParseRegistryHostnameFromImageName(input);
|
var actual = DockerUtil.ParseRegistryHostnameFromImageName(input);
|
||||||
Assert.Equal(expected, actual);
|
Assert.Equal(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[Trait("Level", "L0")]
|
|
||||||
[Trait("Category", "Worker")]
|
|
||||||
[InlineData("dockerhub/repo", false)]
|
|
||||||
[InlineData("debian:latest", false)]
|
|
||||||
[InlineData("something/dockerfileimage", false)]
|
|
||||||
[InlineData("ghcr.io/docker/dockerfile", true)] // should be false but might break the current workflows
|
|
||||||
[InlineData("Dockerfile", true)]
|
|
||||||
[InlineData("Dockerfile.", true)]
|
|
||||||
[InlineData(".Dockerfile", true)]
|
|
||||||
[InlineData(".Dockerfile.", false)]
|
|
||||||
[InlineData("dockerfile", true)]
|
|
||||||
[InlineData("dockerfile.", true)]
|
|
||||||
[InlineData(".dockerfile", true)]
|
|
||||||
[InlineData(".dockerfile.", false)]
|
|
||||||
[InlineData("Dockerfile.test", true)]
|
|
||||||
[InlineData("test.Dockerfile", true)]
|
|
||||||
[InlineData("docker/dockerfile:latest", false)]
|
|
||||||
[InlineData("/some/path/dockerfile:latest", false)]
|
|
||||||
[InlineData("dockerfile:latest", false)]
|
|
||||||
[InlineData("Dockerfile:latest", false)]
|
|
||||||
[InlineData("dockerfile-latest", false)]
|
|
||||||
[InlineData("Dockerfile-latest", false)]
|
|
||||||
[InlineData("dockerfile.latest", true)]
|
|
||||||
[InlineData("Dockerfile.latest", true)]
|
|
||||||
[InlineData("../dockerfile/dockerfileone", false)]
|
|
||||||
[InlineData("../Dockerfile/dockerfileone", false)]
|
|
||||||
[InlineData("../dockerfile.test", true)]
|
|
||||||
[InlineData("../Dockerfile.test", true)]
|
|
||||||
[InlineData("./dockerfile/image", false)]
|
|
||||||
[InlineData("./Dockerfile/image", false)]
|
|
||||||
[InlineData("example/Dockerfile.test", true)]
|
|
||||||
[InlineData("./example/Dockerfile.test", true)]
|
|
||||||
[InlineData("example/test.dockerfile", true)]
|
|
||||||
[InlineData("./example/test.dockerfile", true)]
|
|
||||||
[InlineData("docker://Dockerfile", false)]
|
|
||||||
[InlineData("docker://ubuntu:latest", false)]
|
|
||||||
public void IsDockerfile(string input, bool expected)
|
|
||||||
{
|
|
||||||
var actual = DockerUtil.IsDockerfile(input);
|
|
||||||
Assert.Equal(expected, actual);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
using (var hostContext = Setup(featureFlagState: "false"))
|
using (var hostContext = Setup(featureFlagState: "false"))
|
||||||
{
|
{
|
||||||
var stepSummaryFile = Path.Combine(_rootDirectory, "feature-off");
|
var stepSummaryFile = Path.Combine(_rootDirectory, "feature-off");
|
||||||
|
|
||||||
_createStepCommand.ProcessCommand(_executionContext.Object, stepSummaryFile, null);
|
_createStepCommand.ProcessCommand(_executionContext.Object, stepSummaryFile, null);
|
||||||
_jobExecutionContext.Complete();
|
_jobExecutionContext.Complete();
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
using (var hostContext = Setup())
|
using (var hostContext = Setup())
|
||||||
{
|
{
|
||||||
var stepSummaryFile = Path.Combine(_rootDirectory, "empty-file");
|
var stepSummaryFile = Path.Combine(_rootDirectory, "empty-file");
|
||||||
File.WriteAllBytes(stepSummaryFile, new byte[CreateStepSummaryCommand.AttachmentSizeLimit + 1]);
|
File.WriteAllBytes(stepSummaryFile, new byte[128 * 1024 + 1]);
|
||||||
|
|
||||||
_createStepCommand.ProcessCommand(_executionContext.Object, stepSummaryFile, null);
|
_createStepCommand.ProcessCommand(_executionContext.Object, stepSummaryFile, null);
|
||||||
_jobExecutionContext.Complete();
|
_jobExecutionContext.Complete();
|
||||||
|
|||||||
@@ -947,6 +947,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
{
|
{
|
||||||
Process("fatal: unsafe repository ('/github/workspace' is owned by someone else)");
|
Process("fatal: unsafe repository ('/github/workspace' is owned by someone else)");
|
||||||
Assert.Contains("fatal: unsafe repository ('/github/workspace' is owned by someone else)", _executionContext.Object.StepTelemetry.ErrorMessages);
|
Assert.Contains("fatal: unsafe repository ('/github/workspace' is owned by someone else)", _executionContext.Object.StepTelemetry.ErrorMessages);
|
||||||
|
Assert.Contains(_issues, x => x.Item1.Type == DTWebApi.IssueType.Notice && x.Item1.Message.Contains("You may experience error caused by a recently git safe directory enforcement"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.291.0
|
2.290.0
|
||||||
|
|||||||
Reference in New Issue
Block a user