chore(bazel): enable rules_esbuild sandbox with object-inspect workaround (#61969)

Sandbox escapes be-gone

## Test plan

Tested in CI and locally with `bazel build //client/...` as well as a
lot of blood, sweat n tears tearing through failed sandboxes

## Changelog
This commit is contained in:
Noah S-C 2024-06-05 15:34:29 +01:00 committed by GitHub
parent d61368d2b5
commit 4a93f29755
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 86 additions and 367 deletions

View File

@ -258,6 +258,12 @@ swc_register_toolchains(
# rules_esbuild setup ===========================
http_archive(
name = "aspect_rules_esbuild",
patch_args = ["-p1"],
patches = [
# Includes https://github.com/aspect-build/rules_esbuild/pull/201 as well as a fix for
# object-inspect being weird, see the comments in the patch for further links.
"//third_party/rules_esbuild:sandbox-plugin-fixes.patch",
],
sha256 = "ef7163a2e8e319f8a9a70560788dd899126aebf3538c76f8bc1f0b4b52ba4b56",
strip_prefix = "rules_esbuild-0.21.0-rc1",
url = "https://github.com/aspect-build/rules_esbuild/releases/download/v0.21.0-rc1/rules_esbuild-v0.21.0-rc1.tar.gz",

View File

@ -60,7 +60,7 @@ npm_package(
js_library(
name = "fetch-mock",
srcs = ["src/fetch.js"],
declarations = ["src/fetch.js"],
types = ["src/fetch.js"],
visibility = ["//visibility:public"],
deps = [
"//:node_modules/node-fetch",

View File

@ -4,8 +4,6 @@ load("@aspect_rules_esbuild//esbuild:defs.bzl", _esbuild = "esbuild")
def esbuild(name, **kwargs):
_esbuild(
name,
# TODO: work through build failures when sandbox plugin is enabled so that bundling is hermetic
bazel_sandbox_plugin = False,
**kwargs
)
@ -14,8 +12,6 @@ def esbuild_web_app(name, **kwargs):
_esbuild(
name = bundle_name,
# TODO: work through build failures when sandbox plugin is enabled so that bundling is hermetic
bazel_sandbox_plugin = False,
**kwargs
)

View File

@ -49,8 +49,6 @@ def mocha_test(name, tests, deps = [], args = [], data = [], env = {}, is_percy_
".node": "copy",
},
},
# TODO: work through build failures when sandbox plugin is enabled so that bundling is hermetic
bazel_sandbox_plugin = False,
)
args = [

View File

@ -452,6 +452,21 @@
"ws": "*"
}
},
"mz": {
"dependencies": {
"graceful-fs": "*"
}
},
"follow-redirects": {
"dependencies": {
"debug": "*"
}
},
"debug": {
"dependencies": {
"supports-color": "*"
}
},
"@graphql-codegen/cli@5": {
"peerDependencies": {
"@graphql-codegen/typescript": "*",

File diff suppressed because it is too large Load Diff

1
third_party/rules_esbuild/BUILD.bazel vendored Normal file
View File

@ -0,0 +1 @@
exports_files(glob(["**"]))

View File

@ -0,0 +1,47 @@
diff --git a/esbuild/private/plugins/bazel-sandbox.js b/esbuild/private/plugins/bazel-sandbox.js
index c58b668..0ba6cff 100644
--- a/esbuild/private/plugins/bazel-sandbox.js
+++ b/esbuild/private/plugins/bazel-sandbox.js
@@ -24,7 +24,15 @@ function bazelSandboxPlugin() {
}
otherOptions.pluginData.executedSandboxPlugin = true
- return await resolveInExecroot(build, importPath, otherOptions)
+ const res = await resolveInExecroot(build, importPath, otherOptions)
+ // Needed due to an issue with esbuild when it comes to plguins + `"browser": false` in package.json
+ // that manifests with object-inspect package.
+ // https://github.com/evanw/esbuild/issues/2970
+ // https://github.com/evanw/esbuild/issues/2123
+ if (res.path.endsWith('util.inspect')) {
+ res.path = res.path + ".js"
+ }
+ return res
}
)
},
@@ -48,8 +56,25 @@ async function resolveInExecroot(build, importPath, otherOptions) {
return result
}
+ return correctImportPath(result, otherOptions, false)
+}
+
+function correctImportPath(result, otherOptions, firstEntry) {
// If esbuild attempts to leave the execroot, map the path back into the execroot.
if (!result.path.startsWith(execroot)) {
+ // A relative path that is marked as external. If it was not marked as external, it would error in the build.resolve call.
+ // We need to make it an absolute path from its importer and then re-attempt correcting it to be within the execroot.
+ if (result.path.startsWith("..")) {
+ const absPath = path.resolve(otherOptions.importer, result.path)
+ if (!!process.env.JS_BINARY__LOG_DEBUG) {
+ console.error(
+ `DEBUG: [bazel-sandbox] relative & external path found ${result.path}, making absolute relative to its importer ${otherOptions.importer} and then reattempting making it relative to the execroot (${execroot}): ${absPath}`
+ )
+ }
+ result.path = absPath
+ return correctImportPath(result, otherOptions, true)
+ }
+
// If it tried to leave bazel-bin, error out completely.
if (!result.path.includes(bindir)) {
throw new Error(