Skip to content
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
21 changes: 20 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ jobs:

- name: Install cross
if: matrix.use_cross
run: cargo install cross --locked
run: cargo install cross --version 0.2.5 --locked

- name: Build
run: ${{ matrix.use_cross && 'cross' || 'cargo' }} build --target ${{ matrix.target }} ${{ matrix.features }} --examples
Expand All @@ -159,6 +159,16 @@ jobs:
run: ${{ matrix.use_cross && 'cross' || 'cargo' }} test --target ${{ matrix.target }} ${{ matrix.features }}
shell: bash

- name: Build Node addon (wasm2c)
if: ${{ !matrix.use_cross }}
run: node npm/scripts/build-native.js ${{ matrix.target }}
shell: bash

- name: Test Node addon
if: ${{ !matrix.use_cross }}
run: node npm/test/smoke.js
shell: bash

- name: Build proxytester (release)
run: ${{ matrix.use_cross && 'cross' || 'cargo' }} build --release --target ${{ matrix.target }} ${{ matrix.artifact_features }} --example proxytester
shell: bash
Expand Down Expand Up @@ -547,10 +557,13 @@ jobs:
| tar xz --strip-components=1 -C "$HOME/wabt"
echo "$HOME/wabt/bin" >> "$GITHUB_PATH"
- run: cargo fmt --check
- run: cargo fmt --manifest-path npm/native/Cargo.toml --check
- run: cargo clippy --all-features --all-targets -- -D warnings
- run: cargo clippy --manifest-path npm/native/Cargo.toml --all-targets -- -D warnings
- run: cargo doc --no-deps --all-features
env:
RUSTDOCFLAGS: -D warnings
- run: npm run verify:packages

licenses:
name: licenses (deny + notices)
Expand Down Expand Up @@ -582,4 +595,10 @@ jobs:
echo "::error::ThirdPartyNotices.txt is out of date. Run: cargo about generate --all-features about.hbs > ThirdPartyNotices.txt"
exit 1
fi
cargo about generate --manifest-path npm/native/Cargo.toml --config about.toml \
--locked --fail --output-file npm/ThirdPartyNotices.generated.txt npm/about.hbs
if ! diff -u -B -w npm/ThirdPartyNotices.txt npm/ThirdPartyNotices.generated.txt; then
echo "::error::npm/ThirdPartyNotices.txt is out of date. Run: cargo about generate --manifest-path npm/native/Cargo.toml --config about.toml --locked --fail --output-file npm/ThirdPartyNotices.txt npm/about.hbs"
exit 1
fi

5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@
# CI drops pregenerated wasm2c output here for cross builds (see build.rs
# OS_PROXY_RESOLVER_PAC_GUEST_C_DIR and .github/workflows/ci.yml).
/pac-wasm-guest/generated
# Direct Cargo commands against the Node binding use its local target dir.
/npm/native/target
/npm/platforms/*/*.node
/npm/platforms/*/LICENSE.txt
/npm/platforms/*/ThirdPartyNotices.txt
11 changes: 11 additions & 0 deletions Cross.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,14 @@

[build.env]
passthrough = ["OS_PROXY_RESOLVER_PAC_GUEST_C_DIR"]

# Pin the cross-compilation CI toolchains instead of inheriting whatever images
# a future `cross` release selects. These images use glibc 2.23.
[target.x86_64-unknown-linux-gnu]
image = "ghcr.io/cross-rs/x86_64-unknown-linux-gnu:0.2.5"

[target.aarch64-unknown-linux-gnu]
image = "ghcr.io/cross-rs/aarch64-unknown-linux-gnu:0.2.5"

[target.armv7-unknown-linux-gnueabihf]
image = "ghcr.io/cross-rs/armv7-unknown-linux-gnueabihf:0.2.5"
40 changes: 37 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,43 @@ The benchmark cross-checks all engines and fails if the embedded backends
(byte-identical engine sources) disagree on any URL; it also reports the size
of the embedded AOT-compiled guest module.

Builds as both `rlib` and `cdylib`. Release automation with `cargo-dist` is a
natural fit (the CI matrix below already covers the seven targets) but is not
wired up yet.
Builds as both `rlib` and `cdylib`.

## Node.js package

`@vscode/os-proxy-resolver` exposes the resolver through Node-API, with
prebuilt addons for Windows and macOS x64/arm64 and glibc Linux
x64/arm64/armhf. The public package selects a platform-specific optional
dependency at runtime, so consumers install only the addon they need. Every
addon uses the `pac-engine-wasm2c` backend; consumers do not need Rust, a C
compiler, or WABT installed.

Linux addons are built with the pinned glibc 2.28 sysroots from the shared
`vscode-engineering` npm pipeline and then inspected with that toolchain's
`objdump`; publishing fails if any final `.node` artifact requires a GLIBC
symbol newer than 2.28. This keeps them compatible with VS Code's glibc 2.28
desktop baseline.

```js
const { resolveProxy, ProxyResolver } = require('@vscode/os-proxy-resolver');

const proxies = await resolveProxy('https://example.com/');
const resolver = new ProxyResolver();
const subscription = resolver.onChange(() => { /* proxy config changed */ });
resolver.offChange(subscription);
resolver.close();
```

Resolution is dispatched to libuv's worker pool because PAC fetching, WPAD,
DNS, and operating-system APIs can block. The addon uses Node-API rather than
the Electron ABI, so the same binary works in supported Node.js and Electron
versions.

The Azure Pipeline in [`azure-pipelines/publish.yml`](azure-pipelines/publish.yml)
uses the shared `vscode-engineering` npm-package template. It publishes all
seven native packages before the facade, with independent switches for npm
and the VS Code Azure Artifacts feed. Keep the version in the root and all
platform `package.json` files identical; `npm run verify:packages` checks this.

## CI

Expand Down
172 changes: 172 additions & 0 deletions azure-pipelines/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
name: $(Date:yyyyMMdd)$(Rev:.r)

trigger:
branches:
include:
- main
pr: none

resources:
repositories:
- repository: templates
type: github
name: microsoft/vscode-engineering
ref: main
endpoint: Monaco

parameters:
- name: publishPackage
displayName: Publish @vscode/os-proxy-resolver packages to npm
type: boolean
default: false
- name: publishPackageToAzureArtifacts
displayName: Publish @vscode/os-proxy-resolver packages to Azure Artifacts
type: boolean
default: false

extends:
template: azure-pipelines/npm-package/pipeline.yml@templates
parameters:
npmPackages:
- name: os-proxy-resolver-win32-x64-msvc
packagePlatform: Windows
rustTargets: x86_64-pc-windows-msvc
workingDirectory: npm/platforms/win32-x64-msvc
publishPackage: ${{ parameters.publishPackage }}
publishPackageToAzureArtifacts: ${{ parameters.publishPackageToAzureArtifacts }}
skipAPIScan: true
ghCreateTag: false
ghCreateRelease: false
testPlatforms: {}
buildSteps:
- template: azure-pipelines/steps/build-windows-addon.yml@self
parameters:
target: x86_64-pc-windows-msvc
test: true

- name: os-proxy-resolver-win32-arm64-msvc
dependsOn: os-proxy-resolver-win32-x64-msvc
packagePlatform: Windows
rustTargets: aarch64-pc-windows-msvc
workingDirectory: npm/platforms/win32-arm64-msvc
publishPackage: ${{ parameters.publishPackage }}
publishPackageToAzureArtifacts: ${{ parameters.publishPackageToAzureArtifacts }}
skipAPIScan: true
ghCreateTag: false
ghCreateRelease: false
testPlatforms: {}
buildSteps:
# The shared package template uses a Windows x64 agent. This addon is
# runtime-tested on the native windows-11-arm GitHub CI runner.
- template: azure-pipelines/steps/build-windows-addon.yml@self
parameters:
target: aarch64-pc-windows-msvc

- name: os-proxy-resolver-darwin-x64
dependsOn: os-proxy-resolver-win32-arm64-msvc
packagePlatform: MacOS
rustTargets: x86_64-apple-darwin
workingDirectory: npm/platforms/darwin-x64
publishPackage: ${{ parameters.publishPackage }}
publishPackageToAzureArtifacts: ${{ parameters.publishPackageToAzureArtifacts }}
skipAPIScan: true
ghCreateTag: false
ghCreateRelease: false
testPlatforms: {}
buildSteps:
- template: azure-pipelines/steps/build-macos-addon.yml@self
parameters:
target: x86_64-apple-darwin
test: true

- name: os-proxy-resolver-darwin-arm64
dependsOn: os-proxy-resolver-darwin-x64
packagePlatform: MacOS
rustTargets: aarch64-apple-darwin
workingDirectory: npm/platforms/darwin-arm64
publishPackage: ${{ parameters.publishPackage }}
publishPackageToAzureArtifacts: ${{ parameters.publishPackageToAzureArtifacts }}
skipAPIScan: true
ghCreateTag: false
ghCreateRelease: false
testPlatforms: {}
buildSteps:
# The shared package template uses a macOS x64 agent. This addon is
# runtime-tested on the native macOS arm64 GitHub CI runner.
- template: azure-pipelines/steps/build-macos-addon.yml@self
parameters:
target: aarch64-apple-darwin

- name: os-proxy-resolver-linux-x64-gnu
dependsOn: os-proxy-resolver-darwin-arm64
packagePlatform: Linux
rustTargets: x86_64-unknown-linux-gnu
workingDirectory: npm/platforms/linux-x64-gnu
publishPackage: ${{ parameters.publishPackage }}
publishPackageToAzureArtifacts: ${{ parameters.publishPackageToAzureArtifacts }}
skipAPIScan: true
ghCreateTag: false
ghCreateRelease: false
testPlatforms: {}
buildSteps:
- template: azure-pipelines/common/steps/setup-linux-toolchains.yml@templates
parameters:
arch: x64
nodeVersion: 22.x
- template: azure-pipelines/steps/build-linux-addon.yml@self
parameters:
target: x86_64-unknown-linux-gnu
test: true

- name: os-proxy-resolver-linux-arm64-gnu
dependsOn: os-proxy-resolver-linux-x64-gnu
packagePlatform: Linux
rustTargets: aarch64-unknown-linux-gnu
workingDirectory: npm/platforms/linux-arm64-gnu
publishPackage: ${{ parameters.publishPackage }}
publishPackageToAzureArtifacts: ${{ parameters.publishPackageToAzureArtifacts }}
skipAPIScan: true
ghCreateTag: false
ghCreateRelease: false
testPlatforms: {}
buildSteps:
- template: azure-pipelines/common/steps/setup-linux-toolchains.yml@templates
parameters:
arch: arm64
nodeVersion: 22.x
- template: azure-pipelines/steps/build-linux-addon.yml@self
parameters:
target: aarch64-unknown-linux-gnu
test: true

- name: os-proxy-resolver-linux-arm-gnueabihf
dependsOn: os-proxy-resolver-linux-arm64-gnu
packagePlatform: Linux
rustTargets: armv7-unknown-linux-gnueabihf
workingDirectory: npm/platforms/linux-arm-gnueabihf
publishPackage: ${{ parameters.publishPackage }}
publishPackageToAzureArtifacts: ${{ parameters.publishPackageToAzureArtifacts }}
skipAPIScan: true
ghCreateTag: false
ghCreateRelease: false
testPlatforms: {}
buildSteps:
- template: azure-pipelines/common/steps/setup-linux-toolchains.yml@templates
parameters:
arch: arm
nodeVersion: 22.x
- template: azure-pipelines/steps/build-linux-addon.yml@self
parameters:
target: armv7-unknown-linux-gnueabihf
test: true

- name: os-proxy-resolver
dependsOn: os-proxy-resolver-linux-arm-gnueabihf
workingDirectory: .
publishPackage: ${{ parameters.publishPackage }}
publishPackageToAzureArtifacts: ${{ parameters.publishPackageToAzureArtifacts }}
skipAPIScan: true
testPlatforms: {}
buildSteps:
- script: npm run verify:packages
displayName: Verify package versions
39 changes: 39 additions & 0 deletions azure-pipelines/steps/build-linux-addon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
parameters:
- name: target
type: string
- name: test
type: boolean
default: false

steps:
- bash: |
set -e
mkdir -p "$(Agent.TempDirectory)/wabt" pac-wasm-guest/generated
curl -sSL "https://github.com/WebAssembly/wabt/releases/download/1.0.41/wabt-1.0.41-linux-x64.tar.gz" \
| tar xz --strip-components=1 -C "$(Agent.TempDirectory)/wabt"
"$(Agent.TempDirectory)/wabt/bin/wasm2c" pac-wasm-guest/pac_guest.wasm --module-name pac_guest \
-o pac-wasm-guest/generated/pac_guest.c
OS_PROXY_RESOLVER_PAC_GUEST_C_DIR=pac-wasm-guest/generated \
npm/scripts/build-linux-native.sh ${{ parameters.target }}
displayName: Build Linux addon

- ${{ if parameters.test }}:
- ${{ if eq(parameters.target, 'x86_64-unknown-linux-gnu') }}:
- script: npm run test:npm
displayName: Test Linux x64 addon
- ${{ else }}:
- bash: |
set -e
sudo docker run --rm --privileged \
tonistiigi/binfmt:qemu-v10.0.4@sha256:8f58e6214f4cc9dc83ce8f5acad1ece508eb6b20e696a8c1e9f274481982c541 \
--install arm64,arm
case '${{ parameters.target }}' in
aarch64-unknown-linux-gnu) platform=linux/arm64 ;;
armv7-unknown-linux-gnueabihf) platform=linux/arm/v7 ;;
*) echo 'Unsupported emulated target: ${{ parameters.target }}' >&2; exit 2 ;;
esac
sudo docker run --rm --platform "$platform" \
-v "$(Build.SourcesDirectory):/workspace" -w /workspace \
node:22.22.0-bookworm@sha256:20a424ecd1d2064a44e12fe287bf3dae443aab31dc5e0c0cb6c74bef9c78911c \
node npm/test/smoke.js
displayName: Test Linux ARM addon under QEMU
16 changes: 16 additions & 0 deletions azure-pipelines/steps/build-macos-addon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
parameters:
- name: target
type: string
- name: test
type: boolean
default: false

steps:
- bash: |
set -e
brew install wabt
wasm2c --version
node npm/scripts/build-native.js ${{ parameters.target }}
${{ if parameters.test }}:
npm run test:npm
displayName: ${{ parameters.test && 'Build and test macOS addon' || 'Build macOS addon' }}
25 changes: 25 additions & 0 deletions azure-pipelines/steps/build-windows-addon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
parameters:
- name: target
type: string
- name: test
type: boolean
default: false

steps:
- pwsh: |
$ErrorActionPreference = "Stop"
$wabt = "$(Agent.TempDirectory)/wabt"
New-Item -ItemType Directory -Force $wabt | Out-Null
curl.exe -sSL "https://github.com/WebAssembly/wabt/releases/download/1.0.41/wabt-1.0.41-windows-x64.tar.gz" -o "$wabt/wabt.tar.gz"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
tar.exe -xzf "$wabt/wabt.tar.gz" --strip-components=1 -C $wabt
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
$env:OS_PROXY_RESOLVER_WASM2C = "$wabt/bin/wasm2c.exe"
& $env:OS_PROXY_RESOLVER_WASM2C --version
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
node npm/scripts/build-native.js ${{ parameters.target }}
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
${{ if parameters.test }}:
npm run test:npm
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
displayName: ${{ parameters.test && 'Build and test Windows addon' || 'Build Windows addon' }}
Loading
Loading