Prepare runner release 2.327.1

This commit is contained in:
Salman Chishti
2025-07-25 15:48:59 +00:00
parent 6ca97eeb88
commit 769c511e03
4 changed files with 132 additions and 11 deletions

View File

@@ -1,13 +1,9 @@
## What's Changed
* Try add orchestrationid into user-agent using token claim. by @TingluoHuang in https://github.com/actions/runner/pull/3945
* Fix null reference exception in user agent handling by @salmanmkc in https://github.com/actions/runner/pull/3946
* Runner Support for executing Node24 Actions by @salmanmkc in https://github.com/actions/runner/pull/3940
* Update dotnet sdk to latest version @8.0.412 by @github-actions[bot] in https://github.com/actions/runner/pull/3941
* Update Docker to v28.3.2 and Buildx to v0.26.1 by @github-actions[bot] in https://github.com/actions/runner/pull/3953
* Fix if statement structure in update script and variable reference by @salmanmkc in https://github.com/actions/runner/pull/3956
## New Contributors
* @salmanmkc made their first contribution in https://github.com/actions/runner/pull/3946
**Full Changelog**: https://github.com/actions/runner/compare/v2.326.0...v2.327.0
**Full Changelog**: https://github.com/actions/runner/compare/v2.327.0...v2.327.1
_Note: Actions Runner follows a progressive release policy, so the latest release might not be available to your enterprise, organization, or repository yet.
To confirm which version of the Actions Runner you should expect, please view the download instructions for your enterprise, organization, or repository.

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace GitHub.Runner.Common.Util
@@ -18,6 +19,87 @@ namespace GitHub.Runner.Common.Util
}
return _defaultNodeVersion;
}
/// <summary>
/// Determines the appropriate Node version for Actions to use
/// </summary>
/// <param name="workflowEnvironment">Optional dictionary containing workflow-level environment variables</param>
/// <param name="useNode24ByDefault">Feature flag indicating if Node 24 should be the default</param>
/// <param name="requireNode24">Feature flag indicating if Node 24 is required</param>
/// <param name="warningCallback">Optional callback for emitting warnings</param>
/// <returns>The Node version to use (node20 or node24) and warning message if both env vars are set</returns>
public static (string nodeVersion, string warningMessage) DetermineActionsNodeVersion(
IDictionary<string, string> workflowEnvironment = null,
bool useNode24ByDefault = false,
bool requireNode24 = false)
{
// Get effective values for the flags, with workflow taking precedence over system
bool forceNode24 = IsEnvironmentVariableTrue(Constants.Runner.NodeMigration.ForceNode24Variable, workflowEnvironment);
bool allowUnsecureNode = IsEnvironmentVariableTrue(Constants.Runner.NodeMigration.AllowUnsecureNodeVersionVariable, workflowEnvironment);
string warningMessage = null;
// Phase 3: Always use Node 24 regardless of environment variables
if (requireNode24)
{
return (Constants.Runner.NodeMigration.Node24, null);
}
// Check if both flags are set from the same source
bool bothFromWorkflow = false;
bool bothFromSystem = false;
if (workflowEnvironment != null)
{
bool workflowHasForce = workflowEnvironment.TryGetValue(Constants.Runner.NodeMigration.ForceNode24Variable, out string forceValue) &&
!string.IsNullOrEmpty(forceValue);
bool workflowHasAllow = workflowEnvironment.TryGetValue(Constants.Runner.NodeMigration.AllowUnsecureNodeVersionVariable, out string allowValue) &&
!string.IsNullOrEmpty(allowValue);
bothFromWorkflow = workflowHasForce && workflowHasAllow &&
string.Equals(forceValue, "true", StringComparison.OrdinalIgnoreCase) &&
string.Equals(allowValue, "true", StringComparison.OrdinalIgnoreCase);
}
// Check if both are set in system and neither is overridden by workflow
string sysForce = Environment.GetEnvironmentVariable(Constants.Runner.NodeMigration.ForceNode24Variable);
string sysAllow = Environment.GetEnvironmentVariable(Constants.Runner.NodeMigration.AllowUnsecureNodeVersionVariable);
bool systemHasForce = !string.IsNullOrEmpty(sysForce) && string.Equals(sysForce, "true", StringComparison.OrdinalIgnoreCase);
bool systemHasAllow = !string.IsNullOrEmpty(sysAllow) && string.Equals(sysAllow, "true", StringComparison.OrdinalIgnoreCase);
// Both are set in system and not overridden by workflow
bothFromSystem = systemHasForce && systemHasAllow &&
(workflowEnvironment == null ||
(!workflowEnvironment.ContainsKey(Constants.Runner.NodeMigration.ForceNode24Variable) &&
!workflowEnvironment.ContainsKey(Constants.Runner.NodeMigration.AllowUnsecureNodeVersionVariable)));
// Handle the case when both are set in the same source
if ((bothFromWorkflow || bothFromSystem) && !requireNode24)
{
string defaultVersion = useNode24ByDefault ? Constants.Runner.NodeMigration.Node24 : Constants.Runner.NodeMigration.Node20;
warningMessage = $"Both {Constants.Runner.NodeMigration.ForceNode24Variable} and {Constants.Runner.NodeMigration.AllowUnsecureNodeVersionVariable} environment variables are set to true. This is likely a configuration error. Using the default Node version: {defaultVersion}.";
return (defaultVersion, warningMessage);
}
// Phase 2: Node 24 is the default
if (useNode24ByDefault)
{
if (allowUnsecureNode)
{
return (Constants.Runner.NodeMigration.Node20, null);
}
return (Constants.Runner.NodeMigration.Node24, null);
}
// Phase 1: Node 20 is the default
if (forceNode24)
{
return (Constants.Runner.NodeMigration.Node24, null);
}
return (Constants.Runner.NodeMigration.Node20, null);
}
/// <summary>
/// Checks if Node24 is requested but running on ARM32 Linux, and determines if fallback is needed.
@@ -26,14 +108,34 @@ namespace GitHub.Runner.Common.Util
/// <returns>A tuple containing the adjusted node version and an optional warning message</returns>
public static (string nodeVersion, string warningMessage) CheckNodeVersionForLinuxArm32(string preferredVersion)
{
if (string.Equals(preferredVersion, "node24", StringComparison.OrdinalIgnoreCase) &&
if (string.Equals(preferredVersion, Constants.Runner.NodeMigration.Node24, StringComparison.OrdinalIgnoreCase) &&
Constants.Runner.PlatformArchitecture.Equals(Constants.Architecture.Arm) &&
Constants.Runner.Platform.Equals(Constants.OSPlatform.Linux))
{
return ("node20", "Node 24 is not supported on Linux ARM32 platforms. Falling back to Node 20.");
return (Constants.Runner.NodeMigration.Node20, "Node 24 is not supported on Linux ARM32 platforms. Falling back to Node 20.");
}
return (preferredVersion, null);
}
/// <summary>
/// Checks if an environment variable is set to "true" in either the workflow environment or system environment
/// </summary>
/// <param name="variableName">The name of the environment variable</param>
/// <param name="workflowEnvironment">Optional dictionary containing workflow-level environment variables</param>
/// <returns>True if the variable is set to "true" in either environment</returns>
private static bool IsEnvironmentVariableTrue(string variableName, IDictionary<string, string> workflowEnvironment)
{
// Workflow environment variables take precedence over system environment variables
// If the workflow explicitly sets the value (even to false), we respect that over the system value
if (workflowEnvironment != null && workflowEnvironment.TryGetValue(variableName, out string workflowValue))
{
return string.Equals(workflowValue, "true", StringComparison.OrdinalIgnoreCase);
}
// Fall back to system environment variable only if workflow doesn't specify this variable
string systemValue = Environment.GetEnvironmentVariable(variableName);
return string.Equals(systemValue, "true", StringComparison.OrdinalIgnoreCase);
}
}
}

View File

@@ -58,10 +58,33 @@ namespace GitHub.Runner.Worker.Handlers
var nodeData = data as NodeJSActionExecutionData;
// With node12 EoL in 04/2022 and node16 EoL in 09/23, we want to execute all JS actions using node20
// With node20 EoL approaching, we're preparing to migrate to node24
if (string.Equals(nodeData.NodeVersion, "node12", StringComparison.InvariantCultureIgnoreCase) ||
string.Equals(nodeData.NodeVersion, "node16", StringComparison.InvariantCultureIgnoreCase))
{
nodeData.NodeVersion = "node20";
nodeData.NodeVersion = Common.Constants.Runner.NodeMigration.Node20;
}
// Check if node20 was explicitly specified in the action
// We don't modify if node24 was explicitly specified
if (string.Equals(nodeData.NodeVersion, Constants.Runner.NodeMigration.Node20, StringComparison.InvariantCultureIgnoreCase))
{
bool useNode24ByDefault = true;
bool requireNode24 = FeatureManager.IsFeatureEnabled(executionContext.Global.Variables, Constants.Runner.NodeMigration.RequireNode24Flag);
var (nodeVersion, configWarningMessage) = NodeUtil.DetermineActionsNodeVersion(environment, useNode24ByDefault, requireNode24);
var (finalNodeVersion, platformWarningMessage) = NodeUtil.CheckNodeVersionForLinuxArm32(nodeVersion);
nodeData.NodeVersion = finalNodeVersion;
if (!string.IsNullOrEmpty(configWarningMessage))
{
executionContext.Warning(configWarningMessage);
}
if (!string.IsNullOrEmpty(platformWarningMessage))
{
executionContext.Warning(platformWarningMessage);
}
}
(handler as INodeScriptActionHandler).Data = nodeData;

View File

@@ -1 +1 @@
2.327.0
2.327.1