Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: publish WASM web package #224

Merged
merged 5 commits into from
Mar 5, 2025
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
6 changes: 3 additions & 3 deletions .github/workflows/build-wasm.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and Publish WASM
name: Build WASM

on:
push:
Expand All @@ -21,7 +21,7 @@ on:
required: true

jobs:
build-and-publish-wasm:
build-wasm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
Expand All @@ -39,7 +39,7 @@ jobs:
- name: Build WASM
run: |
cd yggdrasilwasm
wasm-pack build --target nodejs
wasm-pack build --target web

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea what this works for? That looks pure browser based but node is definitely a thing we need

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we'll find out in practice.

From https://rustwasm.github.io/docs/wasm-pack/commands/build.html

Outputs JS that can be natively imported as an ES module in a browser, but the WebAssembly must be manually instantiated and loaded.

You can read about the different targets here: https://rustwasm.github.io/docs/wasm-bindgen/reference/deployment.html

I believe it should work for both browsers and Node-like runtimes, as long as we don't do browser-specific things in our WASM, which I'm pretty sure we won't.

It already works in our Bun e2e tests, which don't run on a browser environment.

- name: Set up Bun
uses: oven-sh/setup-bun@v2
Expand Down
48 changes: 48 additions & 0 deletions .github/workflows/publish-wasm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Publish WASM

on:
workflow_dispatch:
inputs:
version:
description: New version semver
required: true
type: string
tag:
description: NPM tag
required: false
type: string
default: 'latest'

jobs:
build-wasm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true

- name: Install wasm-pack
uses: jetli/[email protected]

- name: Build WASM
run: |
cd yggdrasilwasm
wasm-pack build --target web --scope unleash

publish-wasm:
needs: [build-wasm]
uses: Unleash/.github/.github/workflows/[email protected]
with:
version: ${{ github.event.inputs.version }}
tag: ${{ github.event.inputs.tag }}
working-directory: yggdrasilwasm/pkg
setup-command: "echo 'Skipping setup. Already done.'"
secrets:
NPM_ACCESS_TOKEN: ${{ secrets.NPM_TOKEN }}
UNLEASH_BOT_APP_ID: ${{ secrets.UNLEASH_BOT_APP_ID }}
UNLEASH_BOT_PRIVATE_KEY: ${{ secrets.UNLEASH_BOT_PRIVATE_KEY }}
4 changes: 2 additions & 2 deletions yggdrasilwasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "yggdrasil-engine"
version = "0.3.0"
name = "yggdrasil-wasm"
version = "0.3.1-beta.0"
authors = ["sighphyre <[email protected]>"]
repository = "https://github.com/unleash/yggdrasil"
description = "Direct WASM bindings to the Yggdrasil engine"
Expand Down
8 changes: 4 additions & 4 deletions yggdrasilwasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ Please note that this is an experimental project and the API is subject to chang
First, install the package:

```sh
$ yarn add @unleash/yggdrasil-engine
$ yarn add @unleash/yggdrasil-wasm
```

Then, you can use it in your code:

```ts
import yggdrasil from '../pkg/yggdrasil_engine'
import yggdrasil from '@unleash/yggdrasil-wasm'

const context = {
userId: '7'
Expand Down Expand Up @@ -66,10 +66,10 @@ This project uses wasm-bindgen to generate the Rust/JS bindings. To build the
project, run:

```sh
$ wasm-pack build --target nodejs
$ wasm-pack build --target web
```

There's also a set of integration tests in the `e2e-tests` directory, which will ensure that the WASM module can be loaded and used in Node JS and that calls to the engine are correctly managed. These must be run within the e2e-tests directory:
There's also a set of [Bun](https://bun.sh/) integration tests in the `e2e-tests` directory, which will ensure that the WASM module can be loaded and that calls to the engine are correctly managed. These must be run within the e2e-tests directory:

```sh
$ cd e2e-tests
Expand Down
28 changes: 15 additions & 13 deletions yggdrasilwasm/e2e-tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, beforeEach, test, expect } from 'bun:test'
import { Engine } from '../pkg/yggdrasil_engine'
import init, { Engine } from '../pkg/yggdrasil_wasm'

type BaseTest = {
toggleName: string
Expand All @@ -16,16 +16,16 @@ type VariantTest = BaseTest & {
}

type VariantResponse = {
featureEnabled: boolean,
payload: Record<string, string>,
enabled: boolean,
featureEnabled: boolean
payload: Record<string, string>
enabled: boolean
name: string
}

type LegacyVariantResponse = {
feature_enabled: boolean,
payload: Record<string, string>,
enabled: boolean,
feature_enabled: boolean
payload: Record<string, string>
enabled: boolean
name: string
}

Expand Down Expand Up @@ -57,6 +57,8 @@ const extractResult = <T>(response: Response): T => {
return response.value as T
}

await init()

describe('Client Spec Tests', () => {
test('Client Spec', async () => {
const basePath = '../../client-specification/specifications'
Expand Down Expand Up @@ -98,8 +100,8 @@ describe('Client Spec Tests', () => {

for (const variantTest of variantTests) {
const toggleName = variantTest.toggleName
const expectedResult = variantTest.expectedResult as any as LegacyVariantResponse;

const expectedResult =
variantTest.expectedResult as any as LegacyVariantResponse

test(`Variant Test: ${variantTest.description}`, () => {
const variantResponse = engine.checkVariant(
Expand All @@ -121,10 +123,10 @@ describe('Client Spec Tests', () => {
extractResult<VariantResponse>(variantResponse) ??
getDisabledVariant(featureEnabled)

expect(result.name).toBe(expectedResult.name);
expect(result.enabled).toBe(expectedResult.enabled);
expect(result.featureEnabled).toBe(expectedResult.feature_enabled);
expect(result.payload).toEqual(expectedResult.payload);
expect(result.name).toBe(expectedResult.name)
expect(result.enabled).toBe(expectedResult.enabled)
expect(result.featureEnabled).toBe(expectedResult.feature_enabled)
expect(result.payload).toEqual(expectedResult.payload)
})
}
})
Expand Down
Loading