Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!(node): add support for Node18, drop Node12, update Node16 #2257

Closed
wants to merge 14 commits into from
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ on:
jobs:
build:
strategy:
fail-fast: false
louis-bompart marked this conversation as resolved.
Show resolved Hide resolved
matrix:
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, win-arm64, osx-x64, osx-arm64 ]
include:
Expand Down
2 changes: 1 addition & 1 deletion docs/adrs/0361-wrapper-action.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Node Action Example:
name: 'My action with pre'
description: 'My action with pre'
runs:
using: 'node12'
using: 'node18'
pre: 'setup.js'
pre-if: 'success()' // Optional
main: 'index.js'
Expand Down
4 changes: 2 additions & 2 deletions docs/adrs/0549-composite-run-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ jobs:
- id: step1
uses: actions/setup-python@v1
- id: step2
uses: actions/setup-node@v2
- uses: actions/checkout@v2
uses: actions/setup-node@v3
- uses: actions/checkout@v3
- uses: user/composite@v1
- name: workflow step 1
run: echo hello world 3
Expand Down
2 changes: 1 addition & 1 deletion src/Misc/contentHash/externals/linux-arm
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6ed30a2c1ee403a610d63e82bb230b9ba846a9c25cec9e4ea8672fb6ed4e1a51
2cbf387e8d33f419d2bcc3c6a47fc02631991efcbe1552c06165caeeaa2ced0b
2 changes: 1 addition & 1 deletion src/Misc/contentHash/externals/linux-arm64
Original file line number Diff line number Diff line change
@@ -1 +1 @@
711c30c51ec52c9b7a9a2eb399d6ab2ab5ee1dc72de11879f2f36f919f163d78
a9c6d2ab06cf5b94e6d12b296f33b6fbdc752a289df0e4d92aa21b083ac6adba
2 changes: 1 addition & 1 deletion src/Misc/contentHash/externals/linux-x64
Original file line number Diff line number Diff line change
@@ -1 +1 @@
a49479ca4b4988a06c097e8d22c51fd08a11c13f40807366236213d0e008cf6a
fed054ebfb8d31ae73ad829daf469203ddd64bd6973d3edd8bde42bef1398cd2
2 changes: 1 addition & 1 deletion src/Misc/contentHash/externals/osx-arm64
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cc4708962a80325de0baa5ae8484e0cb9ae976ac6a4178c1c0d448b8c52bd7f7
06a53f49b46a7d4e2b19b18474bf82747204c08b1b557694857c5538daf4533c
2 changes: 1 addition & 1 deletion src/Misc/contentHash/externals/osx-x64
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8e97df75230b843462a9b4c578ccec604ee4b4a1066120c85b04374317fa372b
c9980a4725e39eb9e80891b82b930b6dd702e9d2c74ad7f4ba264983a44b45af
2 changes: 1 addition & 1 deletion src/Misc/contentHash/externals/win-arm64
Original file line number Diff line number Diff line change
@@ -1 +1 @@
e5dace2d41cc0682d096dcce4970079ad48ec7107e46195970eecfdb3df2acef
aa3c3063b550d38fe12b2ac9d3087163c754b426373f7b86fac95cae64826e83
2 changes: 1 addition & 1 deletion src/Misc/contentHash/externals/win-x64
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f75a671e5a188c76680739689aa75331a2c09d483dce9c80023518c48fd67a18
9c111dfbe45d0b62557bcee05e7aebf8a13d2d4ccedb396fc42c42505b8bf82a
24 changes: 13 additions & 11 deletions src/Misc/externals.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ PRECACHE=$2

NODE_URL=https://nodejs.org/dist
UNOFFICIAL_NODE_URL=https://unofficial-builds.nodejs.org/download/release
NODE12_VERSION="12.22.7"
NODE16_VERSION="16.13.0"
# https://github.com/nodejs/build/issues/2540
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To monitor: nodejs/build#3077
Win-arm64 official NodeJS build should be discussed in this meeting/issue

Copy link

@sxa sxa Nov 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI We're working towards it in nodejs/build#3046 but as always with a new platform it's dependent on people and systems to be able to elevate it to an official release, so for now pulling from the unofficial builds repo is the only way to get a versioned download from the nodejs project.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the heads-up @sxa , I somehow missed this one while digging up 馃槄

# https://github.com/nodejs/build/issues/2450#issuecomment-1281534815 latest 'unofficial'
NODE16_VERSION="16.18.0"
NODE18_VERSION="18.11.0"

get_abs_path() {
# exploits the fact that pwd will print abs path when no args
Expand Down Expand Up @@ -126,10 +128,10 @@ function acquireExternalTool() {

# Download the external tools only for Windows.
if [[ "$PACKAGERUNTIME" == "win-x64" || "$PACKAGERUNTIME" == "win-x86" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/$PACKAGERUNTIME/node.exe" node12/bin
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/$PACKAGERUNTIME/node.lib" node12/bin
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/$PACKAGERUNTIME/node.exe" node16/bin
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/$PACKAGERUNTIME/node.lib" node16/bin
acquireExternalTool "$NODE_URL/v${NODE18_VERSION}/$PACKAGERUNTIME/node.exe" node18/bin
acquireExternalTool "$NODE_URL/v${NODE18_VERSION}/$PACKAGERUNTIME/node.lib" node18/bin
if [[ "$PRECACHE" != "" ]]; then
acquireExternalTool "https://github.com/microsoft/vswhere/releases/download/2.6.7/vswhere.exe" vswhere
fi
Expand All @@ -147,29 +149,29 @@ fi

# Download the external tools only for OSX.
if [[ "$PACKAGERUNTIME" == "osx-x64" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-darwin-x64.tar.gz" node12 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-darwin-x64.tar.gz" node16 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE18_VERSION}/node-v${NODE18_VERSION}-darwin-x64.tar.gz" node18 fix_nested_dir
fi

if [[ "$PACKAGERUNTIME" == "osx-arm64" ]]; then
# node.js v12 doesn't support macOS on arm64.
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-darwin-arm64.tar.gz" node16 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE18_VERSION}/node-v${NODE18_VERSION}-darwin-arm64.tar.gz" node18 fix_nested_dir
fi

# Download the external tools for Linux PACKAGERUNTIMEs.
if [[ "$PACKAGERUNTIME" == "linux-x64" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-x64.tar.gz" node12 fix_nested_dir
acquireExternalTool "https://vstsagenttools.blob.core.windows.net/tools/nodejs/${NODE12_VERSION}/alpine/x64/node-v${NODE12_VERSION}-alpine-x64.tar.gz" node12_alpine
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-linux-x64.tar.gz" node16 fix_nested_dir
acquireExternalTool "https://vstsagenttools.blob.core.windows.net/tools/nodejs/${NODE16_VERSION}/alpine/x64/node-v${NODE16_VERSION}-alpine-x64.tar.gz" node16_alpine
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah so. I didn't find the version I needed in vstsagenttools.blob.core.windows.net
So I just replaced it with the good ol' build from bona fide NodeJS.

acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-linux-x64.tar.gz" node16_alpine
acquireExternalTool "$NODE_URL/v${NODE18_VERSION}/node-v${NODE18_VERSION}-linux-x64.tar.gz" node18 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE18_VERSION}/node-v${NODE18_VERSION}-linux-x64.tar.gz" node18_alpine
fi

if [[ "$PACKAGERUNTIME" == "linux-arm64" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-arm64.tar.gz" node12 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-linux-arm64.tar.gz" node16 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE18_VERSION}/node-v${NODE18_VERSION}-linux-arm64.tar.gz" node18 fix_nested_dir
fi

if [[ "$PACKAGERUNTIME" == "linux-arm" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-armv7l.tar.gz" node12 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-linux-armv7l.tar.gz" node16 fix_nested_dir
acquireExternalTool "$NODE_URL/v${NODE18_VERSION}/node-v${NODE18_VERSION}-linux-armv7l.tar.gz" node18 fix_nested_dir
fi
5 changes: 0 additions & 5 deletions src/Misc/layoutbin/update.sh.template
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,6 @@ if [[ "$currentplatform" == 'darwin' && restartinteractiverunner -eq 0 ]]; then
# we can't actually inspect the process using ps because it uses relative paths and doesn't follow symlinks
nodever="node16"
path=$(lsof -a -g "$procgroup" -F n | grep $nodever/bin/node | grep externals | tail -1 | cut -c2-)
if [[ $? -ne 0 || -z "$path" ]] # Fallback if RunnerService.js was started with node12
then
nodever="node12"
path=$(lsof -a -g "$procgroup" -F n | grep $nodever/bin/node | grep externals | tail -1 | cut -c2-)
fi
if [[ $? -eq 0 && -n "$path" ]]
then
# trim the last 5 characters of the path '/node'
Expand Down
4 changes: 1 addition & 3 deletions src/Runner.Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ public static class ReturnCode
public static class Features
{
public static readonly string DiskSpaceWarning = "runner.diskspace.warning";
public static readonly string Node12Warning = "DistributedTask.AddWarningToNode12Action";
public static readonly string UseContainerPathForTemplate = "DistributedTask.UseContainerPathForTemplate";
public static readonly string AllowRunnerContainerHooks = "DistributedTask.AllowRunnerContainerHooks";
}
Expand All @@ -164,7 +163,6 @@ public static class Features
public static readonly string UnsupportedCommandMessageDisabled = "The `{0}` command is disabled. Please upgrade to using Environment Files or opt into unsecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_COMMANDS` environment variable to `true`. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/";
public static readonly string UnsupportedStopCommandTokenDisabled = "You cannot use a endToken that is an empty string, the string 'pause-logging', or another workflow command. For more information see: https://docs.github.com/actions/learn-github-actions/workflow-commands-for-github-actions#example-stopping-and-starting-workflow-commands or opt into insecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_STOPCOMMAND_TOKENS` environment variable to `true`.";
public static readonly string UnsupportedSummarySize = "$GITHUB_STEP_SUMMARY upload aborted, supports content up to a size of {0}k, got {1}k. For more information see: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-markdown-summary";
public static readonly string Node12DetectedAfterEndOfLife = "Node.js 12 actions are deprecated. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/. Please update the following actions to use Node.js 16: {0}";
}

public static class RunnerEvent
Expand Down Expand Up @@ -242,7 +240,7 @@ public static class Agent
{
public static readonly string ToolsDirectory = "agent.ToolsDirectory";

// Set this env var to "node12" to downgrade the node version for internal functions (e.g hashfiles). This does NOT affect the version of node actions.
// Set this env var to forcefully set the node version for internal functions (e.g hashfiles). This does NOT affect the version of node actions.
public static readonly string ForcedInternalNodeVersion = "ACTIONS_RUNNER_FORCED_INTERNAL_NODE_VERSION";
public static readonly string ForcedActionsNodeVersion = "ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION";
}
Expand Down
9 changes: 2 additions & 7 deletions src/Runner.Common/Util/NodeUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,8 @@ namespace GitHub.Runner.Common.Util
{
public static class NodeUtil
{
private const string _defaultNodeVersion = "node16";

#if (OS_OSX || OS_WINDOWS) && ARM64
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node16" });
#else
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node12", "node16" });
#endif
private const string _defaultNodeVersion = "node18";
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node16", "node18" });

public static string GetInternalNodeVersion()
{
Expand Down
8 changes: 4 additions & 4 deletions src/Runner.Worker/ActionManifestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,8 @@ public ActionDefinitionData Load(IExecutionContext executionContext, string mani
};
}
}
else if (string.Equals(usingToken.Value, "node12", StringComparison.OrdinalIgnoreCase)||
string.Equals(usingToken.Value, "node16", StringComparison.OrdinalIgnoreCase))
else if (string.Equals(usingToken.Value, "node16", StringComparison.OrdinalIgnoreCase)||
string.Equals(usingToken.Value, "node18", StringComparison.OrdinalIgnoreCase))
{
if (string.IsNullOrEmpty(mainToken?.Value))
{
Expand Down Expand Up @@ -489,7 +489,7 @@ public ActionDefinitionData Load(IExecutionContext executionContext, string mani
}
else
{
throw new ArgumentOutOfRangeException($"'using: {usingToken.Value}' is not supported, use 'docker', 'node12' or 'node16' instead.");
throw new ArgumentOutOfRangeException($"'using: {usingToken.Value}' is not supported, use 'docker', 'node16' or 'node18' instead.");
}
}
else if (pluginToken != null)
Expand All @@ -500,7 +500,7 @@ public ActionDefinitionData Load(IExecutionContext executionContext, string mani
};
}

throw new NotSupportedException("Missing 'using' value. 'using' requires 'composite', 'docker', 'node12' or 'node16'.");
throw new NotSupportedException("Missing 'using' value. 'using' requires 'composite', 'docker', 'node16' or 'node18'.");
}

private void ConvertInputs(
Expand Down
5 changes: 0 additions & 5 deletions src/Runner.Worker/ExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -692,11 +692,6 @@ public void InitializeJob(Pipelines.AgentJobRequestMessage message, Cancellation

Global.Variables = new Variables(HostContext, variables);

if (Global.Variables.GetBoolean("DistributedTask.ForceInternalNodeVersionOnRunnerTo12") ?? false)
{
Environment.SetEnvironmentVariable(Constants.Variables.Agent.ForcedInternalNodeVersion, "node12");
}

// Environment variables shared across all actions
Global.EnvironmentVariables = new Dictionary<string, string>(VarUtil.EnvironmentVariableKeyComparer);

Expand Down
18 changes: 1 addition & 17 deletions src/Runner.Worker/Handlers/HandlerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,7 @@ public sealed class HandlerFactory : RunnerService, IHandlerFactory
else if (data.ExecutionType == ActionExecutionType.NodeJS)
{
handler = HostContext.CreateService<INodeScriptActionHandler>();
var nodeData = data as NodeJSActionExecutionData;

// With node12 EoL in 04/2022, we want to be able to uniformly upgrade all JS actions to node16 from the server
if (string.Equals(nodeData.NodeVersion, "node12", StringComparison.InvariantCultureIgnoreCase) &&
(executionContext.Global.Variables.GetBoolean("DistributedTask.ForceGithubJavascriptActionsToNode16") ?? false))
{
// The user can opt out of this behaviour by setting this variable to true, either setting 'env' in their workflow or as an environment variable on their machine
executionContext.Global.EnvironmentVariables.TryGetValue(Constants.Variables.Actions.AllowActionsUseUnsecureNodeVersion, out var workflowOptOut);
var isWorkflowOptOutSet = !string.IsNullOrEmpty(workflowOptOut);
var isLocalOptOut = StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable(Constants.Variables.Actions.AllowActionsUseUnsecureNodeVersion));
bool isOptOut = isWorkflowOptOutSet ? StringUtil.ConvertToBoolean(workflowOptOut) : isLocalOptOut;
if (!isOptOut)
{
nodeData.NodeVersion = "node16";
}
}
(handler as INodeScriptActionHandler).Data = nodeData;
(handler as INodeScriptActionHandler).Data = data as NodeJSActionExecutionData;
}
else if (data.ExecutionType == ActionExecutionType.Script)
{
Expand Down
35 changes: 0 additions & 35 deletions src/Runner.Worker/Handlers/NodeScriptActionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,6 @@ public async Task RunAsync(ActionRunStage stage)
workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work);
}

#if OS_OSX || OS_WINDOWS
if (string.Equals(Data.NodeVersion, "node12", StringComparison.OrdinalIgnoreCase) &&
Constants.Runner.PlatformArchitecture.Equals(Constants.Architecture.Arm64))
{
#if OS_OSX
ExecutionContext.Output($"The node12 is not supported on macOS ARM64 platform. Use node16 instead.");
#elif OS_WINDOWS
ExecutionContext.Output($"The node12 is not supported on windows ARM64 platform. Use node16 instead.");
#endif
Data.NodeVersion = "node16";
}
#endif
string forcedNodeVersion = System.Environment.GetEnvironmentVariable(Constants.Variables.Agent.ForcedActionsNodeVersion);

if (forcedNodeVersion == "node16" && Data.NodeVersion != "node16")
Expand All @@ -136,29 +124,6 @@ public async Task RunAsync(ActionRunStage stage)
// Remove environment variable that may cause conflicts with the node within the runner.
Environment.Remove("NODE_ICU_DATA"); // https://github.com/actions/runner/issues/795

if (Data.NodeVersion == "node12" && (ExecutionContext.Global.Variables.GetBoolean(Constants.Runner.Features.Node12Warning) ?? false))
{
var repoAction = Action as RepositoryPathReference;
var warningActions = new HashSet<string>();
if (ExecutionContext.Global.Variables.TryGetValue("Node12ActionsWarnings", out var node12Warnings))
{
warningActions = StringUtil.ConvertFromJson<HashSet<string>>(node12Warnings);
}

var repoActionFullName = "";
if (string.IsNullOrEmpty(repoAction.Name))
{
repoActionFullName = repoAction.Path; // local actions don't have a 'Name'
}
else
{
repoActionFullName = $"{repoAction.Name}/{repoAction.Path ?? string.Empty}".TrimEnd('/') + $"@{repoAction.Ref}";
}

warningActions.Add(repoActionFullName);
ExecutionContext.Global.Variables.Set("Node12ActionsWarnings", StringUtil.ConvertToJson(warningActions));
}

using (var stdoutManager = new OutputManager(ExecutionContext, ActionCommandManager))
using (var stderrManager = new OutputManager(ExecutionContext, ActionCommandManager))
{
Expand Down
6 changes: 0 additions & 6 deletions src/Runner.Worker/JobRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,6 @@ private async Task<TaskResult> CompleteJobAsync(IJobServer jobServer, IExecution
}
}

if (jobContext.Global.Variables.TryGetValue("Node12ActionsWarnings", out var node12Warnings))
{
var actions = string.Join(", ", StringUtil.ConvertFromJson<HashSet<string>>(node12Warnings));
jobContext.Warning(string.Format(Constants.Runner.Node12DetectedAfterEndOfLife, actions));
}

try
{
await ShutdownQueue(throwOnFailure: true);
Expand Down