Skip to content

Commit 12a521d

Browse files
author
Dylan
authored
feat(node): use multiple versions of node, can run old and new toolchains and default behaviour is not broken (#3125)
1 parent bdb77ea commit 12a521d

File tree

11 files changed

+234
-10
lines changed

11 files changed

+234
-10
lines changed

WORKSPACE

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,28 @@ load("@build_bazel_integration_testing//tools:repositories.bzl", "bazel_binaries
167167

168168
# Depend on the Bazel binaries
169169
bazel_binaries(versions = SUPPORTED_BAZEL_VERSIONS)
170+
171+
# Importing rules_nodejs to use with nodejs_binary and nodejs_test as they transition to using toolchains
172+
# provided by these rules
173+
174+
local_repository(
175+
name = "rules_nodejs",
176+
path = ".",
177+
)
178+
179+
load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains", "rules_nodejs_dependencies")
180+
181+
# This just gives us bazel-skylib
182+
rules_nodejs_dependencies()
183+
184+
# The order matters because Bazel will provide the first registered toolchain when a rule asks Bazel to select it
185+
# This applies to the resolved_toolchain
186+
nodejs_register_toolchains(
187+
name = "node15",
188+
node_version = "15.14.0",
189+
)
190+
191+
nodejs_register_toolchains(
192+
name = "node16",
193+
node_version = "16.9.0",
194+
)

docs/Built-ins.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ Defaults to `"1.22.11"`
263263

264264
<pre>
265265
nodejs_binary(<a href="#nodejs_binary-name">name</a>, <a href="#nodejs_binary-chdir">chdir</a>, <a href="#nodejs_binary-configuration_env_vars">configuration_env_vars</a>, <a href="#nodejs_binary-data">data</a>, <a href="#nodejs_binary-default_env_vars">default_env_vars</a>, <a href="#nodejs_binary-entry_point">entry_point</a>, <a href="#nodejs_binary-env">env</a>,
266-
<a href="#nodejs_binary-link_workspace_root">link_workspace_root</a>, <a href="#nodejs_binary-templated_args">templated_args</a>)
266+
<a href="#nodejs_binary-link_workspace_root">link_workspace_root</a>, <a href="#nodejs_binary-node">node</a>, <a href="#nodejs_binary-templated_args">templated_args</a>)
267267
</pre>
268268

269269
Runs some JavaScript code in NodeJS.
@@ -397,6 +397,12 @@ If source files need to be required then they can be copied to the bin_dir with
397397

398398
Defaults to `False`
399399

400+
<h4 id="nodejs_binary-node">node</h4>
401+
402+
(*<a href="https://bazel.build/docs/build-ref.html#labels">Label</a>*)
403+
404+
Defaults to `@nodejs//:node_bin`
405+
400406
<h4 id="nodejs_binary-templated_args">templated_args</h4>
401407

402408
(*List of strings*): Arguments which are passed to every execution of the program.
@@ -485,7 +491,7 @@ Defaults to `[]`
485491

486492
<pre>
487493
nodejs_test(<a href="#nodejs_test-name">name</a>, <a href="#nodejs_test-chdir">chdir</a>, <a href="#nodejs_test-configuration_env_vars">configuration_env_vars</a>, <a href="#nodejs_test-data">data</a>, <a href="#nodejs_test-default_env_vars">default_env_vars</a>, <a href="#nodejs_test-entry_point">entry_point</a>, <a href="#nodejs_test-env">env</a>,
488-
<a href="#nodejs_test-expected_exit_code">expected_exit_code</a>, <a href="#nodejs_test-link_workspace_root">link_workspace_root</a>, <a href="#nodejs_test-templated_args">templated_args</a>)
494+
<a href="#nodejs_test-expected_exit_code">expected_exit_code</a>, <a href="#nodejs_test-link_workspace_root">link_workspace_root</a>, <a href="#nodejs_test-node">node</a>, <a href="#nodejs_test-templated_args">templated_args</a>)
489495
</pre>
490496

491497

@@ -651,6 +657,12 @@ If source files need to be required then they can be copied to the bin_dir with
651657

652658
Defaults to `False`
653659

660+
<h4 id="nodejs_test-node">node</h4>
661+
662+
(*<a href="https://bazel.build/docs/build-ref.html#labels">Label</a>*)
663+
664+
Defaults to `@nodejs//:node_bin`
665+
654666
<h4 id="nodejs_test-templated_args">templated_args</h4>
655667

656668
(*List of strings*): Arguments which are passed to every execution of the program.

docs/Cypress.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ Defaults to `None`
125125

126126
<pre>
127127
cypress_web_test(<a href="#cypress_web_test-name">name</a>, <a href="#cypress_web_test-chdir">chdir</a>, <a href="#cypress_web_test-config_file">config_file</a>, <a href="#cypress_web_test-configuration_env_vars">configuration_env_vars</a>, <a href="#cypress_web_test-cypress_npm_package">cypress_npm_package</a>, <a href="#cypress_web_test-data">data</a>,
128-
<a href="#cypress_web_test-default_env_vars">default_env_vars</a>, <a href="#cypress_web_test-entry_point">entry_point</a>, <a href="#cypress_web_test-env">env</a>, <a href="#cypress_web_test-expected_exit_code">expected_exit_code</a>, <a href="#cypress_web_test-link_workspace_root">link_workspace_root</a>,
128+
<a href="#cypress_web_test-default_env_vars">default_env_vars</a>, <a href="#cypress_web_test-entry_point">entry_point</a>, <a href="#cypress_web_test-env">env</a>, <a href="#cypress_web_test-expected_exit_code">expected_exit_code</a>, <a href="#cypress_web_test-link_workspace_root">link_workspace_root</a>, <a href="#cypress_web_test-node">node</a>,
129129
<a href="#cypress_web_test-plugin_file">plugin_file</a>, <a href="#cypress_web_test-srcs">srcs</a>, <a href="#cypress_web_test-templated_args">templated_args</a>)
130130
</pre>
131131

@@ -250,6 +250,12 @@ If source files need to be required then they can be copied to the bin_dir with
250250

251251
Defaults to `False`
252252

253+
<h4 id="cypress_web_test-node">node</h4>
254+
255+
(*<a href="https://bazel.build/docs/build-ref.html#labels">Label</a>*)
256+
257+
Defaults to `@nodejs//:node_bin`
258+
253259
<h4 id="cypress_web_test-plugin_file">plugin_file</h4>
254260

255261
(*<a href="https://bazel.build/docs/build-ref.html#labels">Label</a>*): Your cypress plugin file. See https://docs.cypress.io/guides/tooling/plugins-guide

e2e/core/BUILD.bazel

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,89 @@ diff_test(
158158
file1 = "actual3",
159159
file2 = "expected_ast.json",
160160
)
161+
162+
################################################
163+
# Tests and setup for the toolchain changes
164+
165+
# Create file for use in test cases later to get the version of node that is run
166+
write_file(
167+
name = "version",
168+
out = "version.js",
169+
content = ["require('fs').writeFileSync(process.argv[2], process.version)"],
170+
)
171+
172+
# Used in nodejs_bianry later to help see which version of node is run
173+
write_file(
174+
name = "binary_version",
175+
out = "binary_version.js",
176+
content = ["console.log(process.version)"],
177+
)
178+
179+
# Files used in test cases later that contain the correct nodejs version
180+
# that is imported into the workspace.
181+
write_file(
182+
name = "write_node_version_15",
183+
out = "expected_node_15",
184+
content = ["v15.14.0"],
185+
)
186+
187+
write_file(
188+
name = "write_node_version_16",
189+
out = "expected_node_16",
190+
content = ["v16.9.0"],
191+
)
192+
193+
# To see what nodejs version is used by default
194+
my_nodejs(
195+
name = "run_no_toolchain",
196+
out = "thing_no_toolchain",
197+
entry_point = "version.js",
198+
)
199+
200+
# this tests to make sure that the first version imported in the workspace is used as default
201+
diff_test(
202+
name = "node_version_default_toolchain_test",
203+
file1 = "write_node_version_15",
204+
file2 = "thing_no_toolchain",
205+
)
206+
207+
# Output contains the version number of node that is used.
208+
# This is used in tests later to verify the toolchain specified is resolved correctly
209+
my_nodejs(
210+
name = "run_15",
211+
out = "thing_toolchain_15",
212+
entry_point = "version.js",
213+
# using the select statement will download toolchains for all three platforms
214+
# you can also just provide an individual toolchain if you don't want to download them all
215+
toolchain = select({
216+
"@bazel_tools//src/conditions:linux_x86_64": "@node15_linux_amd64//:node_toolchain",
217+
"@bazel_tools//src/conditions:darwin": "@node15_darwin_amd64//:node_toolchain",
218+
"@bazel_tools//src/conditions:windows": "@node15_windows_amd64//:node_toolchain",
219+
}),
220+
)
221+
222+
# Section of test the verify the toolchain work as expected matching node version used with expected
223+
diff_test(
224+
name = "test_node_version_15",
225+
file1 = "write_node_version_15",
226+
file2 = "thing_toolchain_15",
227+
)
228+
229+
my_nodejs(
230+
name = "run_16",
231+
out = "thing_toolchain_16",
232+
entry_point = "version.js",
233+
# using the select statement will download toolchains for all three platforms
234+
# you can also just provide an individual toolchain if you don't want to download them all
235+
toolchain = select({
236+
"@bazel_tools//src/conditions:linux_x86_64": "@node16_linux_amd64//:node_toolchain",
237+
"@bazel_tools//src/conditions:darwin": "@node16_darwin_amd64//:node_toolchain",
238+
"@bazel_tools//src/conditions:windows": "@node16_windows_amd64//:node_toolchain",
239+
}),
240+
)
241+
242+
diff_test(
243+
name = "test_node_version_16",
244+
file1 = "write_node_version_16",
245+
file2 = "thing_toolchain_16",
246+
)

e2e/core/WORKSPACE

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
44

55
http_archive(
66
name = "rules_nodejs",
7-
sha256 = "a54a01b883beff66da057a1a9afc3be83de566d8ba78f5139f9b370026af5868",
8-
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/4.4.0/rules_nodejs-core-4.4.0.tar.gz"],
7+
sha256 = "8f4a19de1eb16b57ac03a8e9b78344b44473e0e06b0510cec14a81f6adfdfc25",
8+
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/4.4.6/rules_nodejs-core-4.4.6.tar.gz"],
99
)
1010

1111
# Note: skylib 1.1.1 has some bug on Windows with diff_test, which we use in this example
@@ -18,6 +18,13 @@ http_archive(
1818

1919
load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains")
2020

21+
# The order matters because Bazel will provide the first registered toolchain when a rule asks Bazel to select it
22+
# This applies to the resolved_toolchain
23+
nodejs_register_toolchains(
24+
name = "node15",
25+
node_version = "15.14.0",
26+
)
27+
2128
nodejs_register_toolchains(
2229
name = "node16",
2330
node_version = "16.9.0",

e2e/core/defs.bzl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
"Simple rule to test nodejs toolchain"
22

33
def _my_nodejs_impl(ctx):
4-
toolchain = ctx.toolchains["@rules_nodejs//nodejs:toolchain_type"].nodeinfo
4+
if ctx.attr.toolchain:
5+
toolchain = ctx.attr.toolchain[platform_common.ToolchainInfo].nodeinfo
6+
else:
7+
toolchain = ctx.toolchains["@rules_nodejs//nodejs:toolchain_type"].nodeinfo
58
ctx.actions.run(
69
inputs = toolchain.tool_files + [ctx.file.entry_point],
710
executable = toolchain.target_tool_path,
@@ -15,6 +18,7 @@ my_nodejs = rule(
1518
attrs = {
1619
"entry_point": attr.label(allow_single_file = True),
1720
"out": attr.output(),
21+
"toolchain": attr.label(),
1822
},
1923
toolchains = ["@rules_nodejs//nodejs:toolchain_type"],
2024
)

internal/node/node.bzl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,9 @@ fi
248248
#
249249
# Rules such as nodejs_image should use only ctx.toolchains["@build_bazel_rules_nodejs//toolchains/node:toolchain_type"].nodeinfo
250250
# when building the image as that will reflect the selected --platform.
251-
node_tool_files = ctx.files._node[:]
251+
node_tool_files = ctx.files.node[:]
252+
253+
# this should be resolved the same as above
252254
node_tool_files.extend(ctx.toolchains["@build_bazel_rules_nodejs//toolchains/node:toolchain_type"].nodeinfo.tool_files)
253255

254256
node_tool_files.append(ctx.file._link_modules_script)
@@ -258,7 +260,7 @@ fi
258260
node_tool_files.append(ctx.file._lcov_merger_script)
259261
node_tool_files.append(node_modules_manifest)
260262

261-
is_builtin = ctx.attr._node.label.workspace_name in ["nodejs_%s" % p for p in BUILT_IN_NODE_PLATFORMS]
263+
is_builtin = ctx.attr.node.label.workspace_name in ["nodejs_%s" % p for p in BUILT_IN_NODE_PLATFORMS]
262264

263265
runfiles = runfiles[:]
264266
runfiles.extend(node_tool_files)
@@ -317,7 +319,7 @@ fi
317319
"TEMPLATED_repository_args": _to_manifest_path(ctx, ctx.file._repository_args),
318320
"TEMPLATED_require_patch_script": _to_manifest_path(ctx, ctx.outputs.require_patch_script),
319321
"TEMPLATED_runfiles_helper_script": _to_manifest_path(ctx, ctx.file._runfile_helpers_main),
320-
"TEMPLATED_vendored_node": "" if is_builtin else strip_external(ctx.file._node.path),
322+
"TEMPLATED_vendored_node": "" if is_builtin else strip_external(ctx.file.node.path),
321323
}
322324

323325
# TODO when we have "link_all_bins" we will only need to look in one place for the entry point
@@ -591,7 +593,7 @@ Predefined genrule variables are not supported in this context.
591593
default = Label("//internal/node:loader.js"),
592594
allow_single_file = True,
593595
),
594-
"_node": attr.label(
596+
"node": attr.label(
595597
default = Label("@nodejs//:node_bin"),
596598
allow_single_file = True,
597599
),

internal/node/test/BUILD.bazel

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,3 +537,70 @@ generated_file_test(
537537
generated = ":protractor_directory_artifacts_version.out",
538538
tags = ["requires-runfiles"],
539539
)
540+
541+
# Targets that can help with debugging and ensuring that node versions can be specified
542+
# for nodejs_binary and nodejs_test
543+
# Used in nodejs_bianry later to help see which version of node is run
544+
write_file(
545+
name = "binary_version",
546+
out = "binary_version.js",
547+
content = ["console.log(process.version)"],
548+
)
549+
550+
nodejs_binary(
551+
name = "main_default_toolchain",
552+
entry_point = "binary_version.js",
553+
)
554+
555+
nodejs_binary(
556+
name = "main_toolchain_15",
557+
entry_point = "binary_version.js",
558+
# using the select statement will download toolchains for all three platforms
559+
# you can also just provide an individual toolchain if you don't want to download them all
560+
node = select({
561+
"@bazel_tools//src/conditions:linux_x86_64": "@node15_linux_amd64//:node_toolchain",
562+
"@bazel_tools//src/conditions:darwin": "@node15_darwin_amd64//:node_toolchain",
563+
"@bazel_tools//src/conditions:windows": "@node15_windows_amd64//:node_toolchain",
564+
}),
565+
)
566+
567+
nodejs_binary(
568+
name = "main_toolchain_16",
569+
entry_point = "binary_version.js",
570+
# using the select statement will download toolchains for all three platforms
571+
# you can also just provide an individual toolchain if you don't want to download them all
572+
node = select({
573+
"@bazel_tools//src/conditions:linux_x86_64": "@node16_linux_amd64//:node_toolchain",
574+
"@bazel_tools//src/conditions:darwin": "@node16_darwin_amd64//:node_toolchain",
575+
"@bazel_tools//src/conditions:windows": "@node16_windows_amd64//:node_toolchain",
576+
}),
577+
)
578+
579+
nodejs_test(
580+
name = "main_default_toolchain_test",
581+
entry_point = "toolchain_test_default.js",
582+
)
583+
584+
nodejs_test(
585+
name = "main_toolchain_15_test",
586+
entry_point = "toolchain_test_v15.14.0.js",
587+
# using the select statement will download toolchains for all three platforms
588+
# you can also just provide an individual toolchain if you don't want to download them all
589+
node = select({
590+
"@bazel_tools//src/conditions:linux_x86_64": "@node15_linux_amd64//:node_toolchain",
591+
"@bazel_tools//src/conditions:darwin": "@node15_darwin_amd64//:node_toolchain",
592+
"@bazel_tools//src/conditions:windows": "@node15_windows_amd64//:node_toolchain",
593+
}),
594+
)
595+
596+
nodejs_test(
597+
name = "main_toolchain_16_test",
598+
entry_point = "toolchain_test_v16.js",
599+
# using the select statement will download toolchains for all three platforms
600+
# you can also just provide an individual toolchain if you don't want to download them all
601+
node = select({
602+
"@bazel_tools//src/conditions:linux_x86_64": "@node16_linux_amd64//:node_toolchain",
603+
"@bazel_tools//src/conditions:darwin": "@node16_darwin_amd64//:node_toolchain",
604+
"@bazel_tools//src/conditions:windows": "@node16_windows_amd64//:node_toolchain",
605+
}),
606+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const version = 'v16.5.0';
2+
if (version !== process.version) {
3+
console.error(`there is a mismatch with the nodejs toolchain called and used for nodejs_binary: expected: ${version}, found: ${process.version}`);
4+
process.exitCode = 1;
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const version = 'v15.14.0';
2+
if (version !== process.version) {
3+
console.error(`there is a mismatch with the nodejs toolchain called and used for nodejs_binary: expected: ${version}, found: ${process.version}`);
4+
process.exitCode = 1;
5+
}

0 commit comments

Comments
 (0)