Skip to content

Commit 60f75eb

Browse files
authored
Adds a dotnet API (#46)
* Adds a dotnet API Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com> * feat: add asynchronous tool registration and examples Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com> * Address .NET SDK review feedback * Use trusted publishing for NuGet release * Build sandbox runtimes before dotnet lint * Delete dotnet-sdk-plan document Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com> --------- Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
1 parent 87d44a3 commit 60f75eb

67 files changed

Lines changed: 8057 additions & 187 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/copilot-instructions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
- When running examples in this repository, use the `Justfile` recipes instead of invoking `cargo run` or `python` directly.
44
- Use `just examples` from the repository root to run the full example suite.
5-
- To run examples for a specific sandbox, use module-scoped recipes: `just wasm examples`, `just js examples`, `just python examples`.
5+
- To run examples for a specific sandbox, use module-scoped recipes: `just wasm examples`, `just js examples`, `just python examples`, `just dotnet examples`.
66
- Use `just build` from the repository root to build all subprojects and SDKs.
77
- Reason: the example commands depend on `WIT_WORLD` being set to `src/wasm_sandbox/wit/sandbox-world.wasm`; the `Justfile` handles that setup.
88

99
Make things cross-platform where possible (window/mac/linux). Mac supprot for hyperlight isn't avaliable yet but is coming.
1010

1111
- **After changing WIT interfaces**: you must run `just build` (or at minimum rebuild the guest `.wasm` and `.aot` files) before running examples. The pre-compiled guest binaries embed the WIT signature; a mismatch causes "Host function vector parameter missing length" errors at runtime.
1212

13-
- **Formatting and linting**: always use `just fmt` and `just fmt-check` from the repository root instead of invoking `cargo fmt`, `ruff format`, or `ruff check` directly. The Justfile recipes run multiple tools in sequence (e.g. `ruff format` + `ruff check --fix` for Python) and missing a step causes CI failures.
13+
- **Formatting and linting**: always use `just fmt` and `just fmt-check` from the repository root instead of invoking `cargo fmt`, `ruff format`, `ruff check`, or `dotnet format` directly. The Justfile recipes run multiple tools in sequence and missing a step causes CI failures.

.github/workflows/ci.yml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,81 @@ jobs:
9999
- name: Run examples
100100
run: just wasm examples
101101

102+
dotnet-sdk:
103+
name: .NET SDK (${{ matrix.os }})
104+
runs-on: ${{ matrix.os }}
105+
strategy:
106+
matrix:
107+
os: [ubuntu-latest, windows-latest]
108+
steps:
109+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
110+
111+
- uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
112+
with:
113+
toolchain: nightly, 1.94
114+
components: rustfmt, clippy
115+
rustflags: ""
116+
117+
- uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
118+
with:
119+
dotnet-version: '8.0.x'
120+
121+
- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
122+
123+
- name: Install Python
124+
run: uv python install 3.12
125+
126+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
127+
with:
128+
node-version: "latest"
129+
cache: npm
130+
cache-dependency-path: src/wasm_sandbox/guests/javascript/package-lock.json
131+
132+
- name: Install just
133+
run: cargo install --locked just
134+
135+
- name: Install clang (Linux)
136+
if: runner.os == 'Linux'
137+
run: sudo apt-get update && sudo apt-get install -y clang
138+
139+
- name: Install LLVM (Windows)
140+
if: runner.os == 'Windows'
141+
run: choco install llvm -y
142+
143+
- name: Enable KVM
144+
if: runner.os == 'Linux' && !env.ACT
145+
run: |
146+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
147+
sudo udevadm control --reload-rules
148+
sudo udevadm trigger --name-match=kvm
149+
sudo chmod 666 /dev/kvm
150+
151+
- name: Build sandbox runtimes
152+
run: |
153+
just wasm build
154+
just js build
155+
156+
- name: Format check
157+
run: just dotnet fmt-check
158+
159+
- name: Lint
160+
run: just dotnet lint
161+
162+
- name: Build
163+
run: just dotnet build
164+
165+
- name: Test Rust FFI
166+
run: just dotnet test-rust
167+
168+
- name: Test .NET
169+
run: just dotnet test-dotnet
170+
171+
- name: Run examples
172+
run: just dotnet examples
173+
174+
- name: Package test
175+
run: just dotnet package-test
176+
102177
python-sdk:
103178
name: Python SDK (${{ matrix.os }})
104179
runs-on: ${{ matrix.os }}

.github/workflows/publish.yml

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Publish Python SDK
1+
name: Publish Python SDK & .NET SDK
22

33
on:
44
push:
@@ -112,3 +112,103 @@ jobs:
112112

113113
- name: Publish to PyPI
114114
run: just python python-publish
115+
116+
# Build the Windows native library for the .NET P/Invoke NuGet package.
117+
dotnet-build-windows:
118+
if: ${{ !github.event.act }}
119+
name: Build Windows .NET native library
120+
runs-on: windows-latest
121+
steps:
122+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
123+
124+
- uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
125+
with:
126+
cache-key: release-windows-dotnet
127+
rustflags: ""
128+
129+
- name: Install just
130+
run: cargo install --locked just
131+
132+
- name: Install LLVM
133+
run: choco install llvm -y
134+
135+
- name: Build sandbox runtimes
136+
run: |
137+
just wasm build release
138+
just js build release
139+
140+
- name: Build Windows native library
141+
run: just dotnet build-rust release
142+
143+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
144+
with:
145+
name: dotnet-native-windows
146+
path: target/release/hyperlight_sandbox_dotnet_ffi.dll
147+
148+
# Build and publish .NET NuGet packages.
149+
dotnet-publish:
150+
if: ${{ !github.event.act }}
151+
name: Publish .NET NuGet packages
152+
needs: [dotnet-build-windows]
153+
runs-on: ubuntu-latest
154+
environment:
155+
name: nuget
156+
permissions:
157+
contents: read
158+
id-token: write
159+
steps:
160+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
161+
162+
- uses: actions-rust-lang/setup-rust-toolchain@150fca883cd4034361b621bd4e6a9d34e5143606 # v1.15.4
163+
with:
164+
cache-key: release
165+
rustflags: ""
166+
167+
- uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
168+
with:
169+
dotnet-version: '8.0.x'
170+
171+
- name: Install just
172+
run: cargo install --locked just
173+
174+
- name: Install clang
175+
run: sudo apt-get update && sudo apt-get install -y clang
176+
177+
- name: Enable KVM
178+
run: |
179+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
180+
sudo udevadm control --reload-rules
181+
sudo udevadm trigger --name-match=kvm
182+
sudo chmod 666 /dev/kvm
183+
184+
- name: Build sandbox runtimes
185+
run: |
186+
just wasm build release
187+
just js build release
188+
189+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
190+
with:
191+
name: dotnet-native-windows
192+
path: target/release
193+
194+
- name: Build and pack
195+
run: just dotnet dist
196+
197+
- name: Package test
198+
run: just dotnet package-test release
199+
200+
- name: Verify NuGet native assets
201+
run: |
202+
unzip -l dist/dotnetsdk/Hyperlight.HyperlightSandbox.PInvoke.*.nupkg | grep -F "runtimes/linux-x64/native/libhyperlight_sandbox_dotnet_ffi.so"
203+
unzip -l dist/dotnetsdk/Hyperlight.HyperlightSandbox.PInvoke.*.nupkg | grep -F "runtimes/win-x64/native/hyperlight_sandbox_dotnet_ffi.dll"
204+
205+
- name: NuGet login
206+
uses: NuGet/login@ebc737b6fc418a6ca0073cf116ec8dc156d8b81e # v1
207+
id: nuget-login
208+
with:
209+
user: ${{ vars.NUGET_USER }}
210+
211+
- name: Publish to NuGet
212+
env:
213+
NUGET_API_KEY: ${{ steps.nuget-login.outputs.NUGET_API_KEY }}
214+
run: just dotnet publish

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,12 @@ wheels/
1616
pip-wheel-metadata/
1717
src/sdk/python/wasm_backend/Cargo.lock
1818
src/sdk/python/hyperlight_js_backend/Cargo.lock
19+
src/sdk/dotnet/ffi/Cargo.lock
1920
docs/end-user-overview-slides.html
21+
22+
# dotnet
23+
[Bb]in/
24+
[Oo]bj/
25+
.vs/
26+
*.user
27+
*.nupkg

0 commit comments

Comments
 (0)