Skip to content

Commit 97ea6fa

Browse files
avrabeclaude
andcommitted
feat: add enterprise mirror support for air-gap deployments
Implements Phase 1 of enterprise air-gap support (Issue #208) by adding configurable mirror URLs for all external dependencies via environment variables. Changes: - toolchains/secure_download.bzl: Add BAZEL_WASM_GITHUB_MIRROR support for wasm-tools, wit-bindgen, wac, wkg, wasmtime, wizer, wasi-sdk - toolchains/jco_toolchain.bzl: Add BAZEL_NODEJS_MIRROR and BAZEL_NPM_REGISTRY for Node.js downloads and npm packages - toolchains/tinygo_toolchain.bzl: Add BAZEL_GO_MIRROR and BAZEL_GOPROXY for Go SDK and module proxy configuration - .bazelrc: Document all mirror environment variables with examples Benefits: - Zero code changes required for default public URLs - Corporate mirror support for JFrog, Nexus, Harbor, Minio - All downloads maintain mandatory SHA256 checksum verification - Enables air-gap/offline builds in restricted environments Backward Compatible: All environment variables default to public URLs, ensuring existing builds continue to work without configuration. Issue: #208 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 55a6a0a commit 97ea6fa

File tree

5 files changed

+104
-19
lines changed

5 files changed

+104
-19
lines changed

.bazelrc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,39 @@ build --incompatible_strict_action_env
4646
build:clippy --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect
4747
build:clippy --output_groups=+clippy_checks
4848
build:clippy --@rules_rust//:clippy_flags=-D,warnings,-D,clippy::all,-D,clippy::correctness,-D,clippy::style,-D,clippy::complexity,-D,clippy::perf
49+
50+
# ============================================================================
51+
# Enterprise / Air-Gap Configuration
52+
# ============================================================================
53+
# The following environment variables allow you to configure corporate mirrors
54+
# for all external dependencies. This supports enterprise deployments with:
55+
# - Air-gap/offline builds
56+
# - Corporate artifact repositories (JFrog, Nexus, Harbor, Minio)
57+
# - Security scanning and compliance requirements
58+
#
59+
# To use corporate mirrors, set these in your environment or .bazelrc.user:
60+
#
61+
# GitHub Releases Mirror (for wasm-tools, wit-bindgen, wac, wkg, wasmtime, wizer, wasi-sdk):
62+
# build --action_env=BAZEL_WASM_GITHUB_MIRROR=https://artifactory.company.com/github
63+
#
64+
# Node.js Mirror (for jco toolchain):
65+
# build --action_env=BAZEL_NODEJS_MIRROR=https://artifactory.company.com/nodejs
66+
#
67+
# NPM Registry Mirror (for jco and componentize-js packages):
68+
# build --action_env=BAZEL_NPM_REGISTRY=https://artifactory.company.com/npm
69+
#
70+
# Go SDK Mirror (for TinyGo toolchain):
71+
# build --action_env=BAZEL_GO_MIRROR=https://artifactory.company.com/golang
72+
#
73+
# Go Module Proxy (for wit-bindgen-go and other Go dependencies):
74+
# build --action_env=BAZEL_GOPROXY=https://artifactory.company.com/go-proxy
75+
#
76+
# Example corporate configuration (.bazelrc.user):
77+
# build --action_env=BAZEL_WASM_GITHUB_MIRROR=https://nexus.corp.com/repository/github-proxy
78+
# build --action_env=BAZEL_NODEJS_MIRROR=https://nexus.corp.com/repository/nodejs-dist
79+
# build --action_env=BAZEL_NPM_REGISTRY=https://nexus.corp.com/repository/npm-group
80+
# build --action_env=BAZEL_GO_MIRROR=https://nexus.corp.com/repository/golang-dist
81+
# build --action_env=BAZEL_GOPROXY=https://nexus.corp.com/repository/go-proxy
82+
#
83+
# All downloads include mandatory SHA256 checksum verification for security.
84+
# See checksums/tools/*.json for the complete list of verified checksums.

MODULE.bazel.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

toolchains/jco_toolchain.bzl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,12 @@ def _jco_toolchain_repository_impl(repository_ctx):
9696
_create_jco_build_files(repository_ctx)
9797

9898
def _setup_downloaded_jco_tools(repository_ctx, platform, jco_version, node_version):
99-
"""Download hermetic Node.js and install jco via npm"""
99+
"""Download hermetic Node.js and install jco via npm
100+
101+
Supports configurable mirrors via environment variables for enterprise/air-gap deployments:
102+
- BAZEL_NODEJS_MIRROR: Override Node.js download URL (default: https://nodejs.org)
103+
- BAZEL_NPM_REGISTRY: Override npm registry URL (default: https://registry.npmjs.org)
104+
"""
100105

101106
# Get Node.js info from registry
102107
node_info = get_tool_info("nodejs", node_version, platform)
@@ -113,9 +118,13 @@ def _setup_downloaded_jco_tools(repository_ctx, platform, jco_version, node_vers
113118
platform,
114119
))
115120

116-
# Download Node.js
121+
# Get mirror configuration from environment (enterprise support)
122+
nodejs_mirror = repository_ctx.os.environ.get("BAZEL_NODEJS_MIRROR", "https://nodejs.org")
123+
npm_registry = repository_ctx.os.environ.get("BAZEL_NPM_REGISTRY", "https://registry.npmjs.org")
124+
125+
# Download Node.js from configurable mirror
117126
archive_name = "node-v{}-{}".format(node_version, node_info["url_suffix"])
118-
node_url = "https://nodejs.org/dist/v{}/{}".format(node_version, archive_name)
127+
node_url = "{}/dist/v{}/{}".format(nodejs_mirror, node_version, archive_name)
119128

120129
print("Downloading Node.js from: {}".format(node_url))
121130

@@ -170,6 +179,12 @@ def _setup_downloaded_jco_tools(repository_ctx, platform, jco_version, node_vers
170179
# Install jco using the hermetic npm
171180
print("Installing jco {} using hermetic npm...".format(jco_version))
172181

182+
# Configure npm to use custom registry if specified
183+
if npm_registry != "https://registry.npmjs.org":
184+
print("Configuring npm to use custom registry: {}".format(npm_registry))
185+
npmrc_content = "registry={}\n".format(npm_registry)
186+
repository_ctx.file("jco_workspace/.npmrc", npmrc_content)
187+
173188
# Create a local node_modules for jco
174189
# Set up environment so npm can find node binary
175190
node_dir = str(node_binary.dirname)

toolchains/secure_download.bzl

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
load("//checksums:registry.bzl", "get_github_repo", "get_tool_checksum", "get_tool_info")
44

55
def secure_download_tool(ctx, tool_name, version, platform):
6-
"""Download tool with mandatory checksum verification using central registry"""
6+
"""Download tool with mandatory checksum verification using central registry
7+
8+
Supports configurable mirrors via environment variables for enterprise/air-gap deployments.
9+
Set BAZEL_WASM_GITHUB_MIRROR to override default GitHub URL.
10+
"""
711

812
# Get verified checksum from central registry
913
expected_checksum = get_tool_checksum(tool_name, version, platform)
@@ -20,8 +24,11 @@ def secure_download_tool(ctx, tool_name, version, platform):
2024
if not tool_info:
2125
fail("SECURITY: Tool info not found for '{}' version '{}' platform '{}'".format(tool_name, version, platform))
2226

27+
# Get mirror configuration from environment (enterprise support)
28+
github_mirror = ctx.os.environ.get("BAZEL_WASM_GITHUB_MIRROR", "https://github.com")
29+
2330
# Download with verification
24-
url = _build_download_url(tool_name, version, platform, tool_info)
31+
url = _build_download_url(ctx, tool_name, version, platform, tool_info, github_mirror)
2532

2633
# Determine archive type from URL suffix
2734
archive_type = "zip" if tool_info.get("url_suffix", "").endswith(".zip") else "tar.gz"
@@ -32,8 +39,20 @@ def secure_download_tool(ctx, tool_name, version, platform):
3239
type = archive_type,
3340
)
3441

35-
def _build_download_url(tool_name, version, platform, tool_info):
36-
"""Build download URL using tool info from central registry"""
42+
def _build_download_url(ctx, tool_name, version, platform, tool_info, github_mirror):
43+
"""Build download URL using tool info from central registry
44+
45+
Args:
46+
ctx: Repository context
47+
tool_name: Name of the tool
48+
version: Version to download
49+
platform: Target platform
50+
tool_info: Tool metadata from registry
51+
github_mirror: Mirror URL for GitHub releases (enterprise support)
52+
53+
Returns:
54+
Download URL (either public GitHub or corporate mirror)
55+
"""
3756

3857
# Get GitHub repository from registry
3958
github_repo = get_github_repo(tool_name)
@@ -44,8 +63,9 @@ def _build_download_url(tool_name, version, platform, tool_info):
4463
if not url_suffix:
4564
fail("URL suffix not found for tool '{}' version '{}' platform '{}'".format(tool_name, version, platform))
4665

47-
# Build the URL using GitHub releases pattern
48-
return "https://github.com/{github_repo}/releases/download/v{version}/{tool_name}-{version}-{suffix}".format(
66+
# Build the URL using GitHub releases pattern with configurable mirror
67+
return "{mirror}/{github_repo}/releases/download/v{version}/{tool_name}-{version}-{suffix}".format(
68+
mirror = github_mirror,
4969
github_repo = github_repo,
5070
tool_name = tool_name,
5171
version = version,

toolchains/tinygo_toolchain.bzl

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ def _detect_host_platform(repository_ctx):
3030
fail("Unsupported operating system: {}".format(os_name))
3131

3232
def _download_go(repository_ctx, version, platform):
33-
"""Download hermetic Go SDK for TinyGo to use"""
33+
"""Download hermetic Go SDK for TinyGo to use
34+
35+
Supports configurable mirrors via environment variables for enterprise/air-gap deployments:
36+
- BAZEL_GO_MIRROR: Override Go SDK download URL (default: https://go.dev)
37+
"""
3438

3539
go_version = "1.25.3" # Latest stable Go version (1.25.0 doesn't exist)
3640

@@ -46,9 +50,12 @@ def _download_go(repository_ctx, version, platform):
4650
if not go_platform:
4751
fail("Unsupported platform for Go SDK: {}".format(platform))
4852

53+
# Get mirror configuration from environment (enterprise support)
54+
go_mirror = repository_ctx.os.environ.get("BAZEL_GO_MIRROR", "https://go.dev")
55+
4956
# Windows uses .zip, others use .tar.gz
5057
go_extension = ".zip" if platform == "windows_amd64" else ".tar.gz"
51-
go_url = "https://go.dev/dl/go{}.{}{}".format(go_version, go_platform, go_extension)
58+
go_url = "{}/dl/go{}.{}{}".format(go_mirror, go_version, go_platform, go_extension)
5259

5360
print("Downloading Go {} for TinyGo from: {}".format(go_version, go_url))
5461

@@ -182,19 +189,26 @@ def _setup_go_wit_bindgen(repository_ctx, go_binary):
182189
"""Install wit-bindgen-go Go tool for WIT binding generation
183190
184191
Installs go.bytecodealliance.org/wit/bindgen which provides 'go tool wit-bindgen-go'
192+
193+
Supports configurable Go proxy via environment variable for enterprise/air-gap deployments:
194+
- BAZEL_GOPROXY: Override Go module proxy (default: https://proxy.golang.org,direct)
185195
"""
186196

187197
print("Installing Go WIT binding tools...")
188198

189199
# Create bin directory first
190200
repository_ctx.file("bin/.gitkeep", "")
191201

202+
# Get Go proxy configuration from environment (enterprise support)
203+
goproxy = repository_ctx.os.environ.get("BAZEL_GOPROXY", "https://proxy.golang.org,direct")
204+
192205
# Set up Go environment for tool installation
193206
go_env = {
194207
"GOCACHE": str(repository_ctx.path("go_cache")),
195208
"GOPATH": str(repository_ctx.path("go_path")),
196209
"CGO_ENABLED": "0",
197210
"GO111MODULE": "on",
211+
"GOPROXY": goproxy,
198212
}
199213

200214
# Install wit-bindgen-go using hermetic Go - this provides 'go tool wit-bindgen-go'

0 commit comments

Comments
 (0)