mirror of
https://github.com/actions/runner.git
synced 2026-07-04 11:42:21 +08:00
Compare commits
3 Commits
fix/normal
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcab143723 | ||
|
|
b549247bee | ||
|
|
d36839b001 |
@@ -4,7 +4,7 @@
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
|
||||
"ghcr.io/devcontainers/features/dotnet": {
|
||||
"version": "8.0.420"
|
||||
"version": "8.0.421"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "20"
|
||||
|
||||
@@ -25,11 +25,11 @@ The `installdependencies.sh` script should install all required dependencies on
|
||||
|
||||
Debian based OS (Debian, Ubuntu, Linux Mint)
|
||||
|
||||
- liblttng-ust1 or liblttng-ust0
|
||||
- liblttng-ust1t64, liblttng-ust1 or liblttng-ust0
|
||||
- libkrb5-3
|
||||
- zlib1g
|
||||
- libssl3t64, libssl3, libssl1.1, libssl1.0.2 or libssl1.0.0
|
||||
- libicu76, libicu75, ..., libicu66, libicu65, libicu63, libicu60, libicu57, libicu55, or libicu52
|
||||
- libicu80, libicu79, ..., libicu66, libicu65, libicu63, libicu60, libicu57, libicu55, or libicu52
|
||||
|
||||
Fedora based OS (Fedora, Red Hat Enterprise Linux, CentOS, Oracle Linux 7)
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ then
|
||||
fi
|
||||
}
|
||||
|
||||
apt_get_with_fallbacks liblttng-ust1 liblttng-ust0
|
||||
apt_get_with_fallbacks liblttng-ust1t64 liblttng-ust1 liblttng-ust0
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'$apt_get' failed with exit code '$?'"
|
||||
@@ -110,7 +110,7 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
apt_get_with_fallbacks libicu76 libicu75 libicu74 libicu73 libicu72 libicu71 libicu70 libicu69 libicu68 libicu67 libicu66 libicu65 libicu63 libicu60 libicu57 libicu55 libicu52
|
||||
apt_get_with_fallbacks libicu80 libicu79 libicu78 libicu77 libicu76 libicu75 libicu74 libicu73 libicu72 libicu71 libicu70 libicu69 libicu68 libicu67 libicu66 libicu65 libicu63 libicu60 libicu57 libicu55 libicu52
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'$apt_get' failed with exit code '$?'"
|
||||
|
||||
@@ -64,7 +64,6 @@ namespace GitHub.Runner.Common
|
||||
private readonly List<ProductInfoHeaderValue> _userAgents = new() { new ProductInfoHeaderValue($"GitHubActionsRunner-{BuildConstants.RunnerPackage.PackageName}", BuildConstants.RunnerPackage.Version) };
|
||||
private CancellationTokenSource _runnerShutdownTokenSource = new();
|
||||
private object _perfLock = new();
|
||||
private string _canonicalRootDirectory;
|
||||
private Tracing _trace;
|
||||
private Tracing _actionsHttpTrace;
|
||||
private Tracing _netcoreHttpTrace;
|
||||
@@ -392,12 +391,7 @@ namespace GitHub.Runner.Common
|
||||
break;
|
||||
|
||||
case WellKnownDirectory.Root:
|
||||
if (_canonicalRootDirectory == null)
|
||||
{
|
||||
_canonicalRootDirectory = PathUtil.GetCanonicalPath(
|
||||
new DirectoryInfo(GetDirectory(WellKnownDirectory.Bin)).Parent.FullName);
|
||||
}
|
||||
path = _canonicalRootDirectory;
|
||||
path = new DirectoryInfo(GetDirectory(WellKnownDirectory.Bin)).Parent.FullName;
|
||||
break;
|
||||
|
||||
case WellKnownDirectory.Temp:
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace GitHub.Runner.Sdk
|
||||
{
|
||||
@@ -9,98 +6,8 @@ namespace GitHub.Runner.Sdk
|
||||
{
|
||||
#if OS_WINDOWS
|
||||
public static readonly string PathVariable = "Path";
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern SafeFileHandle CreateFile(
|
||||
string lpFileName,
|
||||
uint dwDesiredAccess,
|
||||
uint dwShareMode,
|
||||
System.IntPtr lpSecurityAttributes,
|
||||
uint dwCreationDisposition,
|
||||
uint dwFlagsAndAttributes,
|
||||
System.IntPtr hTemplateFile);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
private static extern uint GetFinalPathNameByHandle(
|
||||
SafeFileHandle hFile,
|
||||
[Out] StringBuilder lpszFilePath,
|
||||
uint cchFilePath,
|
||||
uint dwFlags);
|
||||
|
||||
private const uint FILE_READ_ATTRIBUTES = 0x80;
|
||||
private const uint FILE_SHARE_READ = 0x1;
|
||||
private const uint FILE_SHARE_WRITE = 0x2;
|
||||
private const uint FILE_SHARE_DELETE = 0x4;
|
||||
private const uint OPEN_EXISTING = 3;
|
||||
private const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
|
||||
private const uint VOLUME_NAME_DOS = 0x0;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the NTFS canonical path for a directory, resolving drive letter
|
||||
/// and folder name casing to match what is stored on disk.
|
||||
/// On non-Windows platforms, returns the path unchanged.
|
||||
/// </summary>
|
||||
public static string GetCanonicalPath(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path) || !Directory.Exists(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
using var handle = CreateFile(
|
||||
path,
|
||||
FILE_READ_ATTRIBUTES,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
System.IntPtr.Zero,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
System.IntPtr.Zero);
|
||||
|
||||
if (handle.IsInvalid)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
var buffer = new StringBuilder(1024);
|
||||
var result = GetFinalPathNameByHandle(handle, buffer, (uint)buffer.Capacity, VOLUME_NAME_DOS);
|
||||
if (result == 0)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
// Retry with a larger buffer if the path was longer than expected
|
||||
if (result >= buffer.Capacity)
|
||||
{
|
||||
buffer = new StringBuilder((int)result + 1);
|
||||
result = GetFinalPathNameByHandle(handle, buffer, (uint)buffer.Capacity, VOLUME_NAME_DOS);
|
||||
if (result == 0 || result >= buffer.Capacity)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
var canonicalPath = buffer.ToString();
|
||||
|
||||
// Strip the \\?\UNC\ prefix and convert to standard UNC path
|
||||
if (canonicalPath.StartsWith(@"\\?\UNC\", System.StringComparison.Ordinal))
|
||||
{
|
||||
canonicalPath = @"\\" + canonicalPath.Substring(8);
|
||||
}
|
||||
// Strip the \\?\ prefix for local paths
|
||||
else if (canonicalPath.StartsWith(@"\\?\", System.StringComparison.Ordinal))
|
||||
{
|
||||
canonicalPath = canonicalPath.Substring(4);
|
||||
}
|
||||
|
||||
return canonicalPath;
|
||||
}
|
||||
#else
|
||||
public static readonly string PathVariable = "PATH";
|
||||
|
||||
public static string GetCanonicalPath(string path)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
public static string PrependPath(string path, string currentPath)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="10.0.3" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="10.0.3" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="10.0.8" />
|
||||
<PackageReference Include="System.Threading.Channels" Version="10.0.3" />
|
||||
<PackageReference Include="YamlDotNet.Signed" Version="5.3.0" />
|
||||
<PackageReference Include="Microsoft.DevTunnels.Connections" Version="1.3.39" />
|
||||
|
||||
@@ -299,52 +299,6 @@ namespace GitHub.Runner.Common.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void GetDirectoryRootReturnsCachedValue()
|
||||
{
|
||||
try
|
||||
{
|
||||
Setup();
|
||||
|
||||
// Call GetDirectory(Root) twice — should return the same reference
|
||||
var root1 = _hc.GetDirectory(WellKnownDirectory.Root);
|
||||
var root2 = _hc.GetDirectory(WellKnownDirectory.Root);
|
||||
|
||||
Assert.NotNull(root1);
|
||||
Assert.Equal(root1, root2);
|
||||
Assert.True(Directory.Exists(root1));
|
||||
}
|
||||
finally
|
||||
{
|
||||
Teardown();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void GetDirectoryDerivedPathsUseRootCasing()
|
||||
{
|
||||
try
|
||||
{
|
||||
Setup();
|
||||
|
||||
var root = _hc.GetDirectory(WellKnownDirectory.Root);
|
||||
var diag = _hc.GetDirectory(WellKnownDirectory.Diag);
|
||||
var externals = _hc.GetDirectory(WellKnownDirectory.Externals);
|
||||
|
||||
// Diag and Externals should start with the same Root prefix
|
||||
Assert.StartsWith(root, diag);
|
||||
Assert.StartsWith(root, externals);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Teardown();
|
||||
}
|
||||
}
|
||||
|
||||
private void Setup([CallerMemberName] string testName = "")
|
||||
{
|
||||
_tokenSource = new CancellationTokenSource();
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
using GitHub.Runner.Sdk;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xunit;
|
||||
|
||||
namespace GitHub.Runner.Common.Tests.Util
|
||||
{
|
||||
public sealed class PathUtilL0
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void GetCanonicalPath_ReturnsPath_WhenDirectoryDoesNotExist()
|
||||
{
|
||||
var fakePath = Path.Combine(Path.GetTempPath(), "nonexistent_" + Path.GetRandomFileName());
|
||||
var result = PathUtil.GetCanonicalPath(fakePath);
|
||||
Assert.Equal(fakePath, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void GetCanonicalPath_ReturnsPath_WhenNull()
|
||||
{
|
||||
Assert.Null(PathUtil.GetCanonicalPath(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void GetCanonicalPath_ReturnsEmpty_WhenEmpty()
|
||||
{
|
||||
Assert.Equal(string.Empty, PathUtil.GetCanonicalPath(string.Empty));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void GetCanonicalPath_ReturnsValidPath_ForExistingDirectory()
|
||||
{
|
||||
var tempDir = Path.Combine(Path.GetTempPath(), "pathutil_test_" + Path.GetRandomFileName());
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(tempDir);
|
||||
var result = PathUtil.GetCanonicalPath(tempDir);
|
||||
Assert.NotNull(result);
|
||||
Assert.True(Directory.Exists(result));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (Directory.Exists(tempDir))
|
||||
{
|
||||
Directory.Delete(tempDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if OS_WINDOWS
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void GetCanonicalPath_NormalizesDriveLetter_OnWindows()
|
||||
{
|
||||
var tempDir = Path.GetTempPath().TrimEnd(Path.DirectorySeparatorChar);
|
||||
|
||||
// Skip if temp is a UNC path (no drive letter to normalize)
|
||||
if (tempDir.StartsWith(@"\\"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Force lowercase drive letter
|
||||
var lowerCased = char.ToLower(tempDir[0]) + tempDir.Substring(1);
|
||||
|
||||
var result = PathUtil.GetCanonicalPath(lowerCased);
|
||||
|
||||
// The canonical path should have an uppercase drive letter
|
||||
Assert.True(char.IsUpper(result[0]),
|
||||
$"Expected uppercase drive letter but got: {result}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void GetCanonicalPath_NormalizesFolderCasing_OnWindows()
|
||||
{
|
||||
// Create a directory with known casing, then query with wrong casing
|
||||
var basePath = Path.GetTempPath();
|
||||
if (basePath.StartsWith(@"\\"))
|
||||
{
|
||||
return; // Skip UNC
|
||||
}
|
||||
|
||||
var realName = "PathUtilTest_MiXeDcAsE_" + Path.GetRandomFileName();
|
||||
var realDir = Path.Combine(basePath, realName);
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(realDir);
|
||||
|
||||
// Query with all-lowercase version
|
||||
var wrongCased = Path.Combine(basePath, realName.ToLowerInvariant());
|
||||
|
||||
var result = PathUtil.GetCanonicalPath(wrongCased);
|
||||
|
||||
// The canonical result should contain the original mixed-case name
|
||||
Assert.Contains(realName, result);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (Directory.Exists(realDir))
|
||||
{
|
||||
Directory.Delete(realDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void GetCanonicalPath_IsIdempotent_OnWindows()
|
||||
{
|
||||
// Calling GetCanonicalPath twice should return the same result
|
||||
var tempDir = Path.GetTempPath().TrimEnd(Path.DirectorySeparatorChar);
|
||||
var first = PathUtil.GetCanonicalPath(tempDir);
|
||||
var second = PathUtil.GetCanonicalPath(first);
|
||||
Assert.Equal(first, second);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void GetCanonicalPath_ReturnsSameResult_RegardlessOfInputCasing_OnWindows()
|
||||
{
|
||||
var tempDir = Path.GetTempPath().TrimEnd(Path.DirectorySeparatorChar);
|
||||
if (tempDir.StartsWith(@"\\"))
|
||||
{
|
||||
return; // Skip UNC
|
||||
}
|
||||
|
||||
var upper = tempDir.ToUpperInvariant();
|
||||
var lower = tempDir.ToLowerInvariant();
|
||||
|
||||
var resultUpper = PathUtil.GetCanonicalPath(upper);
|
||||
var resultLower = PathUtil.GetCanonicalPath(lower);
|
||||
|
||||
// Both should resolve to the same canonical path
|
||||
Assert.Equal(resultUpper, resultLower);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ LAYOUT_DIR="$SCRIPT_DIR/../_layout"
|
||||
DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
|
||||
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
||||
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
||||
DOTNETSDK_VERSION="8.0.420"
|
||||
DOTNETSDK_VERSION="8.0.421"
|
||||
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
|
||||
RUNNER_VERSION=$(cat runnerversion)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.420"
|
||||
"version": "8.0.421"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user