Node 24 enforcement + Linux ARM32 deprecation support#4303
Open
Node 24 enforcement + Linux ARM32 deprecation support#4303
Conversation
ff34d03 to
4c5eac9
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds Node.js 24 enforcement/tracking for Node.js actions, with special handling for Linux ARM32 where Node 24 binaries are unavailable (deprecation/kill switch behavior and messaging).
Changes:
- Track Node20-targeting actions separately as either still-on-node20 vs. forced-to-node24, and emit separate job-level annotations.
- Add Linux ARM32 deprecation + kill-switch feature flags and plumb them into Node version selection.
- Add/extend L0 tests covering upgraded vs. deprecated tracking and ARM32-related NodeUtil behavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Test/L0/Worker/StepHostNodeVersionL0.cs | Adds L0 tests for ARM32 deprecate/kill behaviors in NodeUtil. |
| src/Test/L0/Worker/HandlerFactoryL0.cs | Adds L0 tests for upgraded-to-node24 vs deprecated tracking behavior. |
| src/Runner.Worker/JobExtension.cs | Splits job-finalization warnings for still-on-node20 vs upgraded-to-node24 actions. |
| src/Runner.Worker/Handlers/HandlerFactory.cs | Implements per-action Node version enforcement, ARM32 deprecate/kill logic, and tracking into two sets. |
| src/Runner.Worker/GlobalContext.cs | Adds a new global set for actions upgraded to node24. |
| src/Runner.Worker/ExecutionContext.cs | Initializes the new upgraded-actions tracking set at job start. |
| src/Runner.Common/Util/NodeUtil.cs | Extends ARM32 node version check to support deprecation and kill-switch phases. |
| src/Runner.Common/Constants.cs | Adds ARM32 feature flag constants and ARM32 deprecation message/date constants. |
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
+66
to
+86
| public void CheckNodeVersionForArm32_DeprecationFlagShowsWarning() | ||
| { | ||
| string preferredVersion = "node24"; | ||
| var (nodeVersion, warningMessage) = Common.Util.NodeUtil.CheckNodeVersionForLinuxArm32(preferredVersion, deprecateArm32: true); | ||
|
|
||
| bool isArm32 = RuntimeInformation.ProcessArchitecture == Architecture.Arm || | ||
| Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")?.Contains("ARM") == true; | ||
| bool isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); | ||
|
|
||
| if (isArm32 && isLinux) | ||
| { | ||
| Assert.Equal("node20", nodeVersion); | ||
| Assert.NotNull(warningMessage); | ||
| Assert.Contains("deprecated", warningMessage); | ||
| Assert.Contains("no longer be supported", warningMessage); | ||
| } | ||
| else | ||
| { | ||
| Assert.Equal("node24", nodeVersion); | ||
| Assert.Null(warningMessage); | ||
| } |
Comment on lines
+423
to
+434
| // On non-ARM32 platforms, action should be upgraded to node24 | ||
| // and tracked in UpgradedToNode24Actions, NOT in DeprecatedNode20Actions | ||
| bool isArm32Linux = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture == System.Runtime.InteropServices.Architecture.Arm && | ||
| System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux); | ||
|
|
||
| if (!isArm32Linux) | ||
| { | ||
| Assert.Equal("node24", handler.Data.NodeVersion); | ||
| Assert.Contains("actions/checkout@v4", upgradedActions); | ||
| Assert.DoesNotContain("actions/checkout@v4", deprecatedActions); | ||
| } | ||
| } |
Comment on lines
74
to
+85
| // 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 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.UseNode24ByDefaultFlag) ?? false; | ||
| bool requireNode24 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.RequireNode24Flag) ?? false; | ||
| bool deprecateArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.DeprecateLinuxArm32Flag) ?? false; | ||
| bool killArm32 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.KillLinuxArm32Flag) ?? false; | ||
|
|
||
| var (nodeVersion, configWarningMessage) = NodeUtil.DetermineActionsNodeVersion(environment, useNode24ByDefault, requireNode24); | ||
| var (finalNodeVersion, platformWarningMessage) = NodeUtil.CheckNodeVersionForLinuxArm32(nodeVersion); | ||
| var (finalNodeVersion, platformWarningMessage) = NodeUtil.CheckNodeVersionForLinuxArm32(nodeVersion, deprecateArm32, killArm32); | ||
|
|
Comment on lines
+68
to
+72
| // Track Node.js 20 actions for deprecation annotation | ||
| if (string.Equals(nodeData.NodeVersion, Constants.Runner.NodeMigration.Node20, StringComparison.InvariantCultureIgnoreCase)) | ||
| { | ||
| bool warnOnNode20 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.WarnOnNode20Flag) ?? false; | ||
| if (warnOnNode20) | ||
| { | ||
| string actionName = GetActionName(action); | ||
| if (!string.IsNullOrEmpty(actionName)) | ||
| { | ||
| executionContext.Global.DeprecatedNode20Actions?.Add(actionName); | ||
| } | ||
| } | ||
| } | ||
| // Note: tracking happens before potential upgrade to node24 | ||
| // Actions that get upgraded will be moved to UpgradedToNode24Actions below | ||
| bool warnOnNode20 = executionContext.Global.Variables?.GetBoolean(Constants.Runner.NodeMigration.WarnOnNode20Flag) ?? false; | ||
| string actionName = GetActionName(action); |
| { | ||
| var sortedActions = context.Global.DeprecatedNode20Actions.OrderBy(a => a, StringComparer.OrdinalIgnoreCase); | ||
| var actionsList = string.Join(", ", sortedActions); | ||
| var deprecationMessage = $"Node.js 20 actions are deprecated. The following actions are running on Node.js 20 and may not work as expected: {actionsList}. Actions will be forced to run with Node.js 24 by default starting June 2nd, 2026. Please check if updated versions of these actions are available that support Node.js 24. To opt into Node.js 24 now, set the FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true environment variable on the runner or in your workflow file. Once Node.js 24 becomes the default, you can temporarily opt out by setting ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true. For more information see: {Constants.Runner.NodeMigration.Node20DeprecationUrl}"; |
a3c3706 to
3bd3bff
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When we flip
UseNode24ByDefault, actions targeting node20 get forced to node24 and we show an annotation saying which ones were forced over. On linux-arm32 we can't do that since there's no node24 binary, so instead we show a deprecation warning and keep them on node20 for now.Added two new feature flags for the arm32 side:
actions_runner_deprecate_linux_arm32- warns that arm32 is going away, keeps running on node20actions_runner_kill_linux_arm32- for when we actually want to stop supporting it, fails the stepAlso split the tracking so upgraded-to-node24 actions and still-on-node20 actions get separate annotations instead of lumping them together.
Date for arm32 EOL is TBD, placeholder is October 2026, need to align on this still