Skip to content

Commit 3bd3bff

Browse files
committed
Add support for tracking actions on Node.js 20 due to ARM32 limitations
1 parent 4c5eac9 commit 3bd3bff

6 files changed

Lines changed: 54 additions & 11 deletions

File tree

src/Runner.Common/Util/NodeUtil.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public static (string nodeVersion, string warningMessage) DetermineActionsNodeVe
5858
{
5959
return (Constants.Runner.NodeMigration.Node24, null);
6060
}
61-
61+
6262
// Get environment variable details with source information
6363
var forceNode24Details = GetEnvironmentVariableDetails(
6464
Constants.Runner.NodeMigration.ForceNode24Variable, workflowEnvironment);

src/Runner.Worker/ExecutionContext.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,9 @@ public void InitializeJob(Pipelines.AgentJobRequestMessage message, Cancellation
857857
// Track actions upgraded from Node.js 20 to Node.js 24
858858
Global.UpgradedToNode24Actions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
859859

860+
// Track actions stuck on Node.js 20 due to ARM32 (separate from general deprecation)
861+
Global.Arm32Node20Actions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
862+
860863
// Job Outputs
861864
JobOutputs = new Dictionary<string, VariableValue>(StringComparer.OrdinalIgnoreCase);
862865

src/Runner.Worker/GlobalContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ public sealed class GlobalContext
3535
public bool HasDeprecatedSaveState { get; set; }
3636
public HashSet<string> DeprecatedNode20Actions { get; set; }
3737
public HashSet<string> UpgradedToNode24Actions { get; set; }
38+
public HashSet<string> Arm32Node20Actions { get; set; }
3839
}
3940
}

src/Runner.Worker/Handlers/HandlerFactory.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ public IHandler Create(
6565
nodeData.NodeVersion = Common.Constants.Runner.NodeMigration.Node20;
6666
}
6767

68-
// Track Node.js 20 actions for deprecation annotation
69-
// Note: tracking happens before potential upgrade to node24
70-
// Actions that get upgraded will be moved to UpgradedToNode24Actions below
68+
// Read flags early; actionName is also resolved up front for tracking after version is determined
7169
bool warnOnNode20 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.WarnOnNode20Flag) ?? false;
7270
string actionName = GetActionName(action);
7371

@@ -110,9 +108,14 @@ public IHandler Create(
110108
// Action was upgraded from node20 to node24
111109
executionContext.Global.UpgradedToNode24Actions?.Add(actionName);
112110
}
111+
else if (deprecateArm32 && string.Equals(finalNodeVersion, Constants.Runner.NodeMigration.Node20, StringComparison.OrdinalIgnoreCase))
112+
{
113+
// Action is on node20 because ARM32 can't run node24
114+
executionContext.Global.Arm32Node20Actions?.Add(actionName);
115+
}
113116
else if (warnOnNode20)
114117
{
115-
// Action is still running on node20 (e.g., ARM32 fallback)
118+
// Action is still running on node20 (general case)
116119
executionContext.Global.DeprecatedNode20Actions?.Add(actionName);
117120
}
118121
}

src/Runner.Worker/Handlers/StepHost.cs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,17 @@ public string ResolvePathForStepHost(IExecutionContext executionContext, string
5858

5959
public Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
6060
{
61-
// Use NodeUtil to check if Node24 is requested but we're on ARM32 Linux
62-
var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion);
61+
bool deprecateArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.DeprecateLinuxArm32Flag) ?? false;
62+
bool killArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.KillLinuxArm32Flag) ?? false;
63+
64+
var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, deprecateArm32, killArm32);
65+
66+
if (nodeVersion == null)
67+
{
68+
executionContext.Error(warningMessage);
69+
throw new InvalidOperationException(warningMessage);
70+
}
71+
6372
if (!string.IsNullOrEmpty(warningMessage))
6473
{
6574
executionContext.Warning(warningMessage);
@@ -142,8 +151,17 @@ public string ResolvePathForStepHost(IExecutionContext executionContext, string
142151

143152
public async Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
144153
{
145-
// Use NodeUtil to check if Node24 is requested but we're on ARM32 Linux
146-
var (nodeExternal, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion);
154+
bool deprecateArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.DeprecateLinuxArm32Flag) ?? false;
155+
bool killArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.KillLinuxArm32Flag) ?? false;
156+
157+
var (nodeExternal, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, deprecateArm32, killArm32);
158+
159+
if (nodeExternal == null)
160+
{
161+
executionContext.Error(warningMessage);
162+
throw new InvalidOperationException(warningMessage);
163+
}
164+
147165
if (!string.IsNullOrEmpty(warningMessage))
148166
{
149167
executionContext.Warning(warningMessage);
@@ -273,8 +291,17 @@ await containerHookManager.RunScriptStepAsync(context,
273291

274292
private string CheckPlatformForAlpineContainer(IExecutionContext executionContext, string preferredVersion)
275293
{
276-
// Use NodeUtil to check if Node24 is requested but we're on ARM32 Linux
277-
var (nodeExternal, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion);
294+
bool deprecateArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.DeprecateLinuxArm32Flag) ?? false;
295+
bool killArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.KillLinuxArm32Flag) ?? false;
296+
297+
var (nodeExternal, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, deprecateArm32, killArm32);
298+
299+
if (nodeExternal == null)
300+
{
301+
executionContext.Error(warningMessage);
302+
throw new InvalidOperationException(warningMessage);
303+
}
304+
278305
if (!string.IsNullOrEmpty(warningMessage))
279306
{
280307
executionContext.Warning(warningMessage);

src/Runner.Worker/JobExtension.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,15 @@ public async Task FinalizeJob(IExecutionContext jobContext, Pipelines.AgentJobRe
753753
var upgradeMessage = $"Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: {actionsList}. For more information see: {Constants.Runner.NodeMigration.Node20DeprecationUrl}";
754754
context.Warning(upgradeMessage);
755755
}
756+
757+
// Add annotation for ARM32 actions stuck on Node.js 20 (ARM32 can't run node24)
758+
if (context.Global.Arm32Node20Actions?.Count > 0)
759+
{
760+
var sortedActions = context.Global.Arm32Node20Actions.OrderBy(a => a, StringComparer.OrdinalIgnoreCase);
761+
var actionsList = string.Join(", ", sortedActions);
762+
var arm32Message = $"The following actions are running on Node.js 20 because Node.js 24 is not available on Linux ARM32: {actionsList}. Linux ARM32 runners are deprecated and will no longer be supported after {Constants.Runner.NodeMigration.LinuxArm32DeprecationDate}. Please migrate to a supported platform. For more information see: {Constants.Runner.NodeMigration.Node20DeprecationUrl}";
763+
context.Warning(arm32Message);
764+
}
756765
}
757766
catch (Exception ex)
758767
{

0 commit comments

Comments
 (0)