Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/checks/nodejs.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ The runner carries its own copies of node.js executables under `<runner_root>/ex

All javascript base Actions will get executed by the built-in `node` at either `<runner_root>/externals/node20/` or `<runner_root>/externals/node24/` depending on the version specified in the action's metadata.

The runner's own internal operations (for example `hashFiles()` and this check) use `<runner_root>/externals/node24/`. Set `ACTIONS_RUNNER_FORCED_INTERNAL_NODE_VERSION=node20` to use `node20` instead.

> Not the `node` from `$PATH`

## What is checked?
Expand Down
4 changes: 2 additions & 2 deletions images/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ ARG TARGETOS
ARG TARGETARCH
ARG RUNNER_VERSION
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.7.0
ARG DOCKER_VERSION=29.8.1
ARG BUILDX_VERSION=0.37.1
ARG DOCKER_VERSION=29.8.2
ARG BUILDX_VERSION=0.37.2

RUN apt update -y && apt install curl unzip -y

Expand Down
2 changes: 1 addition & 1 deletion patches/last_processed_commit.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
a634d7339463392169ca6eea270e36b66c68e9a3
539695a10a5b0fe3af98990525044236bfa67a75
6 changes: 3 additions & 3 deletions patches/runner-main-sdk8-arm.patch
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ index 4ed18b2b..e0c88fbc 100644
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64;win-arm64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
diff --git a/src/Runner.Common/Util/NodeUtil.cs b/src/Runner.Common/Util/NodeUtil.cs
index d87224f9..07d822fb 100644
index 7b8055b9..b4683559 100644
--- a/src/Runner.Common/Util/NodeUtil.cs
+++ b/src/Runner.Common/Util/NodeUtil.cs
@@ -144,7 +144,7 @@ namespace GitHub.Runner.Common.Util
Expand Down Expand Up @@ -157,7 +157,7 @@ index 03290778..efd2b8cd 100644
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64;win-arm64</RuntimeIdentifiers>
<SelfContained>true</SelfContained>
diff --git a/src/Sdk/Sdk.csproj b/src/Sdk/Sdk.csproj
index 5db8c10e..49bc0143 100644
index e6ba57af..0b5b1d62 100644
--- a/src/Sdk/Sdk.csproj
+++ b/src/Sdk/Sdk.csproj
@@ -1,7 +1,7 @@
Expand Down Expand Up @@ -279,4 +279,4 @@ index 5821cb36..70cfe5c2 100644
+ "version": "9.0.318"
}
}
# From upstream commit: a634d7339463392169ca6eea270e36b66c68e9a3
# From upstream commit: 539695a10a5b0fe3af98990525044236bfa67a75
4 changes: 2 additions & 2 deletions patches/runner-main-sdk8-ppc64le.patch
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ index 97273a1a..78f78701 100644
throw new NotSupportedException(); // Should never reach here.
}
diff --git a/src/Sdk/Sdk.csproj b/src/Sdk/Sdk.csproj
index 5db8c10e..7c4ba7ac 100644
index e6ba57af..fc8b3d34 100644
--- a/src/Sdk/Sdk.csproj
+++ b/src/Sdk/Sdk.csproj
@@ -4,7 +4,7 @@
Expand Down Expand Up @@ -284,4 +284,4 @@ index 056a312e..3f9a3679 100644
<Exec Command="%22$(DesktopMSBuild)%22 Runner.Service/Windows/RunnerService.csproj /p:Configuration=$(BUILDCONFIG) /p:PackageRuntime=$(PackageRuntime) /p:OutputPath=%22$(MSBuildProjectDirectory)/../_layout/bin%22" ConsoleToMSBuild="true" Condition="'$(PackageRuntime)' == 'win-x64' Or '$(PackageRuntime)' == 'win-x86' Or '$(PackageRuntime)' == 'win-arm64'" />
</Target>

# From upstream commit: a634d7339463392169ca6eea270e36b66c68e9a3
# From upstream commit: 539695a10a5b0fe3af98990525044236bfa67a75
4 changes: 2 additions & 2 deletions patches/runner-main-sdk8-s390x.patch
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ index 97273a1a..78f78701 100644
throw new NotSupportedException(); // Should never reach here.
}
diff --git a/src/Sdk/Sdk.csproj b/src/Sdk/Sdk.csproj
index 5db8c10e..7c4ba7ac 100644
index e6ba57af..fc8b3d34 100644
--- a/src/Sdk/Sdk.csproj
+++ b/src/Sdk/Sdk.csproj
@@ -4,7 +4,7 @@
Expand Down Expand Up @@ -284,4 +284,4 @@ index 056a312e..3f9a3679 100644
<Exec Command="%22$(DesktopMSBuild)%22 Runner.Service/Windows/RunnerService.csproj /p:Configuration=$(BUILDCONFIG) /p:PackageRuntime=$(PackageRuntime) /p:OutputPath=%22$(MSBuildProjectDirectory)/../_layout/bin%22" ConsoleToMSBuild="true" Condition="'$(PackageRuntime)' == 'win-x64' Or '$(PackageRuntime)' == 'win-x86' Or '$(PackageRuntime)' == 'win-arm64'" />
</Target>

# From upstream commit: a634d7339463392169ca6eea270e36b66c68e9a3
# From upstream commit: 539695a10a5b0fe3af98990525044236bfa67a75
39 changes: 21 additions & 18 deletions src/Misc/expressionFunc/hashFiles/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/Misc/layoutbin/runsvc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ if [ -f ".path" ]; then
echo ".path=${PATH}"
fi

nodever="node20"
nodever="node24"

# insert anything to setup env when running as a service
# run the host process which keep the listener alive
Expand Down
114 changes: 114 additions & 0 deletions src/Runner.Common/BrokerServer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using GitHub.Actions.RunService.WebApi;
Expand Down Expand Up @@ -28,6 +31,9 @@ public interface IBrokerServer : IRunnerService
Task UpdateConnectionIfNeeded(Uri serverUri, VssCredentials credentials);

Task ForceRefreshConnection(VssCredentials credentials);

// Temporary probe: holds/reconnects a websocket to the broker listener until cancelled.
Task<BrokerWebSocketProbeResult> RunLongPollWebSocketProbeAsync(CancellationToken cancellationToken);
}

public sealed class BrokerServer : RunnerService, IBrokerServer
Expand All @@ -37,6 +43,9 @@ public sealed class BrokerServer : RunnerService, IBrokerServer
private RawConnection _connection;
private BrokerHttpClient _brokerHttpClient;

private static readonly TimeSpan MinDelayForWebSocketReconnect = TimeSpan.FromSeconds(10);
private static readonly TimeSpan MaxDelayForWebSocketReconnect = TimeSpan.FromSeconds(300);

public async Task ConnectAsync(Uri serverUri, VssCredentials credentials)
{
Trace.Entering();
Expand Down Expand Up @@ -80,6 +89,111 @@ public async Task AcknowledgeRunnerRequestAsync(string runnerRequestId, Guid? se
await _brokerHttpClient.AcknowledgeRunnerRequestAsync(runnerRequestId, sessionId, version, status, os, architecture, cancellationToken);
}

public async Task<BrokerWebSocketProbeResult> RunLongPollWebSocketProbeAsync(CancellationToken cancellationToken)
{
CheckConnection();

var result = new BrokerWebSocketProbeResult();
var stopwatch = Stopwatch.StartNew();

while (!cancellationToken.IsCancellationRequested)
{
var socket = await ConnectWebSocketAsync(cancellationToken);
if (socket == null)
{
result.ConnectFailures++;
result.LastCloseReason = "connect_failed";

var delay = BackoffTimerHelper.GetRandomBackoff(MinDelayForWebSocketReconnect, MaxDelayForWebSocketReconnect);
try
{
await Task.Delay(delay, cancellationToken);
}
catch (OperationCanceledException)
{
break;
}

continue;
}

result.Connected = true;
result.ConnectCount++;

using (socket)
{
var buffer = new byte[4096];
try
{
while (socket.State == WebSocketState.Open)
{
var receiveResult = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);
if (receiveResult.MessageType == WebSocketMessageType.Close)
{
result.LastCloseReason = $"server_closed:{receiveResult.CloseStatus}:{receiveResult.CloseStatusDescription}";
Trace.Info($"Runner websocket closed by server. CloseStatus: {receiveResult.CloseStatus}, Description: {receiveResult.CloseStatusDescription}");
await socket.CloseOutputAsync(receiveResult.CloseStatus.Value, "Closing websocket", cancellationToken);
break;
}

result.PingsReceived++;
Trace.Info($"Runner websocket received a ping: " + $"{Encoding.UTF8.GetString(buffer, 0, receiveResult.Count)}");

if (receiveResult.MessageType == WebSocketMessageType.Text)
{
await socket.SendAsync(
new ArraySegment<byte>(buffer, 0, receiveResult.Count),
receiveResult.MessageType,
receiveResult.EndOfMessage,
cancellationToken);
Trace.Info($"Runner replied via websocket with: " + $"{Encoding.UTF8.GetString(buffer, 0, receiveResult.Count)}");
}
}
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
result.LastCloseReason = "job_completed";
}
catch (Exception ex)
{
Trace.Info("Exception caught while holding runner websocket, will reconnect.");
Trace.Error(ex);
if (!result.Errors.Contains(ex.Message))
{
result.Errors.Add(ex.Message);
}
result.LastCloseReason = "error";
}

if (socket.State == WebSocketState.Open)
{
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing websocket", CancellationToken.None);
}
}
}

stopwatch.Stop();
result.TotalDurationMs = stopwatch.ElapsedMilliseconds;
return result;
}

private async Task<ClientWebSocket> ConnectWebSocketAsync(CancellationToken cancellationToken)
{
try
{
Trace.Info("Attempting to start runner websocket client.");
var socket = await _brokerHttpClient.ConnectRunnerLongPollWebSocketAsync(cancellationToken);
Trace.Info("Successfully started runner websocket client.");
return socket;
}
catch (Exception ex)
{
Trace.Info("Exception caught during runner websocket connect, will retry.");
Trace.Error(ex);
return null;
}
}

public async Task DeleteSessionAsync(Guid sessionId, CancellationToken cancellationToken)
{
CheckConnection();
Expand Down
4 changes: 2 additions & 2 deletions src/Runner.Common/Util/NodeUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ private class EnvironmentVariableInfo
public bool FromSystem { get; set; }
}

private const string _defaultNodeVersion = "node20";
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node20" });
private const string _defaultNodeVersion = "node24";
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node20", "node24" });
public static string GetInternalNodeVersion()
{
var forcedInternalNodeVersion = Environment.GetEnvironmentVariable(Constants.Variables.Agent.ForcedInternalNodeVersion);
Expand Down
6 changes: 3 additions & 3 deletions src/Runner.Sdk/RunnerWebProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ public Uri GetProxy(Uri destination)
return null;
}

if (destination.Scheme == Uri.UriSchemeHttps)
if (destination.Scheme == Uri.UriSchemeHttps || destination.Scheme == Uri.UriSchemeWss)
{
return new Uri(_httpsProxyAddress);
}
Expand All @@ -197,12 +197,12 @@ public Uri GetProxy(Uri destination)

public bool IsBypassed(Uri uri)
{
if (uri.Scheme == Uri.UriSchemeHttps && string.IsNullOrEmpty(_httpsProxyAddress))
if ((uri.Scheme == Uri.UriSchemeHttps || uri.Scheme == Uri.UriSchemeWss) && string.IsNullOrEmpty(_httpsProxyAddress))
{
return true;
}

if (uri.Scheme == Uri.UriSchemeHttp && string.IsNullOrEmpty(_httpProxyAddress))
if ((uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeWs) && string.IsNullOrEmpty(_httpProxyAddress))
{
return true;
}
Expand Down
9 changes: 5 additions & 4 deletions src/Runner.Sdk/Util/VssUtil.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.InteropServices;
using GitHub.DistributedTask.WebApi;
using GitHub.Services.Common;
using GitHub.Services.WebApi;
using GitHub.Services.OAuth;
using System.Net.Http.Headers;
using System.Runtime.InteropServices;
using System.Net;
using GitHub.Services.WebApi;
using Sdk.WebApi.WebApi.RawClient;

namespace GitHub.Runner.Sdk
Expand All @@ -34,6 +34,7 @@ public static void InitializeVssClientSettings(List<ProductInfoHeaderValue> addi

VssClientHttpRequestSettings.Default.UserAgent = headerValues;
VssHttpMessageHandler.DefaultWebProxy = proxy;
RawHttpMessageHandler.DefaultWebProxy = proxy;

if (StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_TLS_NO_VERIFY")))
{
Expand Down
Loading
Loading