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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support node.js 16 and bump node.js 12 version. #1439

Merged
merged 3 commits into from
Nov 18, 2021
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
12 changes: 10 additions & 2 deletions src/Misc/externals.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ PACKAGERUNTIME=$1
PRECACHE=$2

NODE_URL=https://nodejs.org/dist
NODE12_VERSION="12.13.1"
NODE12_VERSION="12.22.7"
NODE16_VERSION="16.13.0"

get_abs_path() {
# exploits the fact that pwd will print abs path when no args
Expand Down Expand Up @@ -126,6 +127,8 @@ function acquireExternalTool() {
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
if [[ "$PRECACHE" != "" ]]; then
acquireExternalTool "https://github.com/microsoft/vswhere/releases/download/2.6.7/vswhere.exe" vswhere
fi
Expand All @@ -134,18 +137,23 @@ 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
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-${NODE12_VERSION}-alpine-x64.tar.gz" node12_alpine
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
thboop marked this conversation as resolved.
Show resolved Hide resolved
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
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
fi
2 changes: 2 additions & 0 deletions src/Runner.Worker/ActionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,8 @@ public sealed class NodeJSActionExecutionData : ActionExecutionData
public string Pre { get; set; }

public string Post { get; set; }

public string NodeVersion { get; set; }
}

public sealed class PluginActionExecutionData : ActionExecutionData
Expand Down
6 changes: 4 additions & 2 deletions src/Runner.Worker/ActionManifestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,8 @@ private ActionExecutionData ConvertRuns(
};
}
}
else if (string.Equals(usingToken.Value, "node12", StringComparison.OrdinalIgnoreCase))
else if (string.Equals(usingToken.Value, "node12", StringComparison.OrdinalIgnoreCase)||
string.Equals(usingToken.Value, "node16", StringComparison.OrdinalIgnoreCase))
{
if (string.IsNullOrEmpty(mainToken?.Value))
{
Expand All @@ -461,6 +462,7 @@ private ActionExecutionData ConvertRuns(
{
return new NodeJSActionExecutionData()
{
NodeVersion = usingToken.Value,
Script = mainToken.Value,
Pre = preToken?.Value,
InitCondition = preIfToken?.Value ?? "always()",
Expand Down Expand Up @@ -490,7 +492,7 @@ private ActionExecutionData ConvertRuns(
}
else
{
throw new ArgumentOutOfRangeException($"'using: {usingToken.Value}' is not supported, use 'docker' or 'node12' instead.");
throw new ArgumentOutOfRangeException($"'using: {usingToken.Value}' is not supported, use 'docker', 'node12' or 'node16' instead.");
}
}
else if (pluginToken != null)
Expand Down
4 changes: 2 additions & 2 deletions src/Runner.Worker/Handlers/NodeScriptActionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public async Task RunAsync(ActionRunStage stage)
HasPreStep = Data.HasPre,
HasPostStep = Data.HasPost,
IsEmbedded = ExecutionContext.IsEmbedded,
Type = "node12"
Type = Data.NodeVersion
};
ExecutionContext.Root.ActionsStepsTelemetry.Add(telemetry);
}
Expand All @@ -99,7 +99,7 @@ public async Task RunAsync(ActionRunStage stage)
workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work);
}

var nodeRuntimeVersion = await StepHost.DetermineNodeRuntimeVersion(ExecutionContext);
var nodeRuntimeVersion = await StepHost.DetermineNodeRuntimeVersion(ExecutionContext, Data.NodeVersion);
string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), nodeRuntimeVersion, "bin", $"node{IOUtil.ExeExtension}");

// Format the arguments passed to node.
Expand Down
12 changes: 6 additions & 6 deletions src/Runner.Worker/Handlers/StepHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public interface IStepHost : IRunnerService

string ResolvePathForStepHost(string path);

Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext);
Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion);

Task<int> ExecuteAsync(string workingDirectory,
string fileName,
Expand Down Expand Up @@ -58,9 +58,9 @@ public string ResolvePathForStepHost(string path)
return path;
}

public Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext)
public Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
{
return Task.FromResult<string>("node12");
return Task.FromResult<string>(preferredVersion);
}

public async Task<int> ExecuteAsync(string workingDirectory,
Expand Down Expand Up @@ -123,7 +123,7 @@ public string ResolvePathForStepHost(string path)
}
}

public async Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext)
public async Task<string> DetermineNodeRuntimeVersion(IExecutionContext executionContext, string preferredVersion)
{
// Best effort to determine a compatible node runtime
// There may be more variation in which libraries are linked than just musl/glibc,
Expand All @@ -148,14 +148,14 @@ public async Task<string> DetermineNodeRuntimeVersion(IExecutionContext executio
var msg = $"JavaScript Actions in Alpine containers are only supported on x64 Linux runners. Detected {os} {arch}";
throw new NotSupportedException(msg);
}
nodeExternal = "node12_alpine";
nodeExternal = $"{preferredVersion}_alpine";
executionContext.Debug($"Container distribution is alpine. Running JavaScript Action with external tool: {nodeExternal}");
return nodeExternal;
}
}
}
// Optimistically use the default
nodeExternal = "node12";
nodeExternal = preferredVersion;
executionContext.Debug($"Running JavaScript Action with default external tool: {nodeExternal}");
return nodeExternal;
}
Expand Down
10 changes: 5 additions & 5 deletions src/Runner.Worker/action_yaml.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"runs": {
"one-of": [
"container-runs",
"node12-runs",
"node-runs",
"plugin-runs",
"composite-runs"
]
Expand Down Expand Up @@ -80,7 +80,7 @@
"loose-value-type": "string"
}
},
"node12-runs": {
"node-runs": {
"mapping": {
"properties": {
"using": "non-empty-string",
Expand Down Expand Up @@ -112,10 +112,10 @@
"item-type": "composite-step"
}
},
"composite-step":{
"composite-step": {
"one-of": [
"run-step",
"uses-step"
"uses-step"
]
},
"run-step": {
Expand Down Expand Up @@ -254,4 +254,4 @@
}
}
}
}
}
76 changes: 73 additions & 3 deletions src/Test/L0/Worker/ActionManagerL0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ public async void PrepareActions_CompositeActionWithActionfile_CompositePrestepN
};

//Act
var result = await _actionManager.PrepareActionsAsync(_ec.Object, actions);
var result = await _actionManager.PrepareActionsAsync(_ec.Object, actions);

//Assert
Assert.Equal(1, result.PreStepTracker.Count);
Expand Down Expand Up @@ -1288,7 +1288,7 @@ public void LoadsContainerActionDefinitionRegistry()
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void LoadsNodeActionDefinition()
public void LoadsNode12ActionDefinition()
{
try
{
Expand Down Expand Up @@ -1344,8 +1344,78 @@ public void LoadsNodeActionDefinition()
Assert.True(string.IsNullOrEmpty(inputDefaults["entryPoint"]));
Assert.NotNull(definition.Data.Execution); // execution

Assert.NotNull((definition.Data.Execution as NodeJSActionExecutionData));
Assert.NotNull(definition.Data.Execution as NodeJSActionExecutionData);
Assert.Equal("task.js", (definition.Data.Execution as NodeJSActionExecutionData).Script);
Assert.Equal("node12", (definition.Data.Execution as NodeJSActionExecutionData).NodeVersion);
}
finally
{
Teardown();
}
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void LoadsNode16ActionDefinition()
{
try
{
// Arrange.
Setup();
const string Content = @"
# Container action
name: 'Hello World'
description: 'Greet the world and record the time'
author: 'GitHub'
inputs:
greeting: # id of input
description: 'The greeting we choose - will print ""{greeting}, World!"" on stdout'
required: true
default: 'Hello'
entryPoint: # id of input
description: 'optional docker entrypoint overwrite.'
required: false
outputs:
time: # id of output
description: 'The time we did the greeting'
icon: 'hello.svg' # vector art to display in the GitHub Marketplace
color: 'green' # optional, decorates the entry in the GitHub Marketplace
runs:
using: 'node16'
main: 'task.js'
";
Pipelines.ActionStep instance;
string directory;
CreateAction(yamlContent: Content, instance: out instance, directory: out directory);

// Act.
Definition definition = _actionManager.LoadAction(_ec.Object, instance);

// Assert.
Assert.NotNull(definition);
Assert.Equal(directory, definition.Directory);
Assert.NotNull(definition.Data);
Assert.NotNull(definition.Data.Inputs); // inputs
Dictionary<string, string> inputDefaults = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (var input in definition.Data.Inputs)
{
var name = input.Key.AssertString("key").Value;
var value = input.Value.AssertScalar("value").ToString();

_hc.GetTrace().Info($"Default: {name} = {value}");
inputDefaults[name] = value;
}

Assert.Equal(2, inputDefaults.Count);
Assert.True(inputDefaults.ContainsKey("greeting"));
Assert.Equal("Hello", inputDefaults["greeting"]);
Assert.True(string.IsNullOrEmpty(inputDefaults["entryPoint"]));
Assert.NotNull(definition.Data.Execution); // execution

Assert.NotNull(definition.Data.Execution as NodeJSActionExecutionData);
Assert.Equal("task.js", (definition.Data.Execution as NodeJSActionExecutionData).Script);
Assert.Equal("node16", (definition.Data.Execution as NodeJSActionExecutionData).NodeVersion);
}
finally
{
Expand Down
44 changes: 44 additions & 0 deletions src/Test/L0/Worker/ActionManifestManagerL0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,50 @@ public void Load_NodeAction()
var nodeAction = result.Execution as NodeJSActionExecutionData;

Assert.Equal("main.js", nodeAction.Script);
Assert.Equal("node12", nodeAction.NodeVersion);
}
finally
{
Teardown();
}
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void Load_Node16Action()
{
try
{
//Arrange
Setup();

var actionManifest = new ActionManifestManager();
actionManifest.Initialize(_hc);

//Act
var result = actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "node16action.yml"));

//Assert
Assert.Equal("Hello World", result.Name);
Assert.Equal("Greet the world and record the time", result.Description);
Assert.Equal(2, result.Inputs.Count);
Assert.Equal("greeting", result.Inputs[0].Key.AssertString("key").Value);
Assert.Equal("Hello", result.Inputs[0].Value.AssertString("value").Value);
Assert.Equal("entryPoint", result.Inputs[1].Key.AssertString("key").Value);
Assert.Equal("", result.Inputs[1].Value.AssertString("value").Value);
Assert.Equal(1, result.Deprecated.Count);

Assert.True(result.Deprecated.ContainsKey("greeting"));
result.Deprecated.TryGetValue("greeting", out string value);
Assert.Equal("This property has been deprecated", value);

Assert.Equal(ActionExecutionType.NodeJS, result.Execution.ExecutionType);

var nodeAction = result.Execution as NodeJSActionExecutionData;

Assert.Equal("main.js", nodeAction.Script);
Assert.Equal("node16", nodeAction.NodeVersion);
}
finally
{
Expand Down
Loading