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

Put web viewer on npm #4003

Merged
merged 39 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
86d67b0
more build options for `re_build_web_viewer`
jprochazk Oct 25, 2023
910e256
create web-viewer package
jprochazk Oct 25, 2023
8353226
update readme
jprochazk Oct 25, 2023
a29d1b3
publish .d.ts files for the viewer js/wasm
jprochazk Oct 25, 2023
bc78dee
ellipsis
jprochazk Oct 25, 2023
bf905e9
WASM -> Wasm
jprochazk Oct 25, 2023
a291e4c
Merge branch 'main' into jan/npm-web-viewer
jprochazk Oct 25, 2023
b3e5cb5
Merge branch 'main' into jan/npm-web-viewer
jprochazk Oct 31, 2023
bc3e49a
update readme
jprochazk Oct 31, 2023
167dc06
add react module
jprochazk Oct 31, 2023
c0ad49b
add versioning script
jprochazk Oct 31, 2023
94d6da7
bump versions
jprochazk Oct 31, 2023
9f1e85d
add publish script + move into `scripts` directory
jprochazk Oct 31, 2023
466481b
append to parent element
jprochazk Oct 31, 2023
0cf8a2f
bump versions
jprochazk Oct 31, 2023
10366a6
Merge branch 'main' into jan/npm-web-viewer
jprochazk Nov 1, 2023
ecfc2e8
add `:debug` build script
jprochazk Nov 1, 2023
dcf329f
Merge branch 'main' into jan/npm-web-viewer
jprochazk Nov 2, 2023
a9be091
put packages in a common dir
jprochazk Nov 2, 2023
f08e132
build on PR
jprochazk Nov 2, 2023
e07079e
fix versioning script
jprochazk Nov 2, 2023
a9c455e
bump to `0.11.0-alpha.1+dev`
jprochazk Nov 2, 2023
74b7783
manually bump versions to preserve build metadata
jprochazk Nov 2, 2023
17daeb8
build on node 20
jprochazk Nov 2, 2023
76bd144
add npm publish workflow
jprochazk Nov 2, 2023
100d99a
update npm versions in release
jprochazk Nov 2, 2023
e3e134b
note about version lockstep
jprochazk Nov 2, 2023
6a7da29
add dependencies to publish-npm job + comment artifacts
jprochazk Nov 2, 2023
83d7043
update dependency versions
jprochazk Nov 2, 2023
5ba7e0b
strip build metadata from dependency version
jprochazk Nov 2, 2023
faa57fa
Merge branch 'main' into jan/npm-web-viewer
jprochazk Nov 2, 2023
650bf55
fix publishing script
jprochazk Nov 2, 2023
3b664a9
bump versions
jprochazk Nov 2, 2023
8da79d6
bump version + fix type checking
jprochazk Nov 2, 2023
a96693c
fix lint
jprochazk Nov 2, 2023
a33e3a9
change concurrency key
jprochazk Nov 2, 2023
2be6a1d
Merge branch 'main' into jan/npm-web-viewer
jprochazk Nov 2, 2023
c7edc18
Merge branch 'main' into jan/npm-web-viewer
jprochazk Nov 3, 2023
75c1c97
fix readme screenshots
jprochazk Nov 3, 2023
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
8 changes: 8 additions & 0 deletions .github/workflows/on_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ jobs:
RRD_ARTIFACT_NAME: linux-rrd-fast
secrets: inherit

build-js:
name: "Build JS"
if: github.event.pull_request.head.repo.owner.login == 'rerun-io'
uses: ./.github/workflows/reusable_build_npm.yml
with:
CONCURRENCY: pr-${{ github.event.pull_request.number }}
secrets: inherit

build-rerun_c-and-upload:
name: "Build & Upload rerun_c (Linux x64)"
if: github.event.pull_request.head.repo.owner.login == 'rerun-io'
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ jobs:
fetch-depth: 0
token: ${{ secrets.RERUN_BOT_TOKEN }}

- uses: actions/setup-node@v4
with:
node-version: 18

- name: Set up Python
uses: actions/setup-python@v2
with:
Expand Down Expand Up @@ -130,6 +134,10 @@ jobs:
echo "current=$current" >> "$GITHUB_OUTPUT"
echo "final=$final" >> "$GITHUB_OUTPUT"

- name: Update NPM versions
run: |
node rerun_js/web-viewer/scripts/version.mjs ${{ steps.versioning.outputs.current }}

- name: "Taplo fmt"
run: taplo fmt

Expand Down Expand Up @@ -248,6 +256,15 @@ jobs:
concurrency: ${{ github.ref_name }}
secrets: inherit

publish-npm:
name: "Publish to NPM"
needs: [version]
uses: ./.github/workflows/reusable_publish_npm.yml
with:
release-commit: ${{ needs.version.outputs.release-commit }}
concurrency: ${{ github.ref_name }}
secrets: inherit

update-latest-branch:
name: "Update Latest Branch"
if: inputs.release-type == 'final'
Expand All @@ -259,6 +276,7 @@ jobs:
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-npm,
]
runs-on: ubuntu-latest
steps:
Expand All @@ -284,6 +302,7 @@ jobs:
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-npm,
]
runs-on: ubuntu-latest
steps:
Expand All @@ -292,6 +311,15 @@ jobs:
with:
token: ${{ secrets.RERUN_BOT_TOKEN }}

- uses: actions/setup-node@v4
with:
node-version: 18

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.11

- name: Install dependencies
run: |
python3 -m pip install -r scripts/ci/requirements-crates.txt
Expand All @@ -307,6 +335,10 @@ jobs:
python3 scripts/ci/crates.py version --bump auto
echo "version=$(python3 scripts/ci/crates.py get-version)" >> "$GITHUB_OUTPUT"

- name: Update NPM versions
run: |
node rerun_js/web-viewer/scripts/version.mjs ${{ steps.update-version.outputs.version }}

- name: "Taplo fmt"
run: taplo fmt

Expand All @@ -327,6 +359,7 @@ jobs:
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-npm,
]
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -355,11 +388,13 @@ jobs:
fi
wheels_link="https://pypi.org/project/rerun-sdk/${{ needs.version.outputs.current }}"
crates_link="https://crates.io/crates/rerun/${{ needs.version.outputs.current }}"
npm_link="https://www.npmjs.com/package/@rerun-io/web-viewer/v/${{ needs.version.outputs.current }}"
rs_docs_link="https://docs.rs/rerun/${{ needs.version.outputs.current }}"
cpp_sdk_zip_link="https://build.rerun.io/commit/$short_commit_hash/rerun_cpp_sdk.zip"

pip_install="pip install rerun-sdk==${{ needs.version.outputs.current }}"
cargo_install="cargo install rerun-cli@${{ needs.version.outputs.current }}"
npm_install="npm install @rerun-io/web-viewer@${{ needs.version.outputs.current }}"

cat <<EOF > comment-body.txt
Version ${{ needs.version.outputs.current }} published successfully.
Expand All @@ -369,6 +404,7 @@ jobs:
| [web app]($web_app_link) | |
| [wheels]($wheels_link) | $pip_install |
| [crates]($crates_link) | $cargo_install |
| [npm]($npm_link) | $npm_install |
| [docs]($rerun_io_docs_link) | |
| [py docs]($py_docs_link) | |
| [rs docs]($rs_docs_link) | |
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/reusable_build_npm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Reusable Build Web

on:
workflow_call:
inputs:
CONCURRENCY:
required: true
type: string

concurrency:
group: ${{ inputs.CONCURRENCY }}-build-js
cancel-in-progress: true

env:
# web_sys_unstable_apis is required to enable the web_sys clipboard API which egui_web uses
# https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html
# https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html
RUSTFLAGS: --cfg=web_sys_unstable_apis --deny warnings

# See https://github.com/ericseppanen/cargo-cranky/issues/8
RUSTDOCFLAGS: --deny warnings --deny rustdoc::missing_crate_level_docs

jobs:
build:
name: Build
permissions:
contents: "read"
id-token: "write"

runs-on: ubuntu-latest-16-cores

container:
image: rerunio/ci_docker:0.10.0

steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || '' }}

- uses: actions/setup-node@v4
with:
node-version: '20.x'

- name: Set up Rust
uses: ./.github/actions/setup-rust
with:
cache_key: "build-web"
# Cache will be produced by `reusable_checks/rs-check-wasm`
save_cache: false
workload_identity_provider: ${{ secrets.GOOGLE_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }}

- name: Install dependencies
run: |
node rerun_js/web-viewer/scripts/install.mjs

- name: Build package
run: |
node rerun_js/web-viewer/scripts/build.mjs

72 changes: 72 additions & 0 deletions .github/workflows/reusable_publish_npm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Build and publish NPM

on:
workflow_call:
inputs:
concurrency:
type: string
required: true
release-commit:
description: "Commit to release"
type: string
required: true

concurrency:
group: ${{ inputs.concurrency }}-publish-npm
cancel-in-progress: true

permissions:
contents: "write"
id-token: "write"

jobs:
get-commit-sha:
name: Get Commit Sha
runs-on: ubuntu-latest
outputs:
short-sha: ${{ steps.get-short-sha.outputs.short-sha }}
full-sha: ${{ steps.get-full-sha.outputs.full-sha }}
steps:
- name: "Set short-sha"
id: get-short-sha
run: echo "short-sha=$(echo ${{ inputs.release-commit }} | cut -c1-7)" >> $GITHUB_OUTPUT

- name: "Set full-sha"
id: get-full-sha
run: echo "full-sha=${{ inputs.release-commit }}" >> $GITHUB_OUTPUT

build:
runs-on: ubuntu-latest-16-cores
needs: [get-commit-sha]
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.release-commit }}

- uses: actions/setup-node@v4
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'

- name: Set up Rust
uses: ./.github/actions/setup-rust
with:
cache_key: "build-web"
save_cache: false
workload_identity_provider: ${{ secrets.GOOGLE_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }}

- name: Install dependencies
run: |
node rerun_js/web-viewer/scripts/install.mjs

- name: Build package
run: |
node rerun_js/web-viewer/scripts/build.mjs

- name: Publish package
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
node rerun_js/web-viewer/scripts/publish.mjs

88 changes: 67 additions & 21 deletions crates/re_build_web_viewer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,67 @@
//! Build the Rerun web-viewer .wasm and generate the .js bindings for it.

use anyhow::Context as _;
use cargo_metadata::camino::Utf8PathBuf;
use cargo_metadata::camino::{Utf8Path, Utf8PathBuf};

pub fn workspace_root() -> Utf8PathBuf {
cargo_metadata::MetadataCommand::new()
.manifest_path(concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml"))
.features(cargo_metadata::CargoOpt::NoDefaultFeatures)
.no_deps()
.exec()
.unwrap()
.workspace_root
}

pub fn default_build_dir() -> Utf8PathBuf {
workspace_root().join("web_viewer")
}

fn target_directory() -> Utf8PathBuf {
let metadata = cargo_metadata::MetadataCommand::new()
.manifest_path("./Cargo.toml")
.manifest_path(concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml"))
.features(cargo_metadata::CargoOpt::NoDefaultFeatures)
.exec()
.unwrap();
metadata.target_directory
}

/// Build `re_viewer` as Wasm, generate .js bindings for it, and place it all into the `./web_viewer` folder.
pub fn build(release: bool, webgpu: bool) -> anyhow::Result<()> {
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Profile {
Release,
Debug,
}

impl Profile {
pub fn as_str(&self) -> &'static str {
match self {
Profile::Release => "release",
Profile::Debug => "debug",
}
}
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Backend {
WebGL,
WebGPU,
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Target {
Browser,
Module,
}

/// Build `re_viewer` as Wasm, generate .js bindings for it, and place it all into the `build_dir` folder.
pub fn build(
profile: Profile,
backend: Backend,
target: Target,
build_dir: &Utf8Path,
) -> anyhow::Result<()> {
std::env::set_current_dir(workspace_root())?;

eprintln!("Building web viewer wasm…");
eprintln!("We assume you've already run ./scripts/setup_web.sh");

Expand All @@ -30,8 +78,6 @@ pub fn build(release: bool, webgpu: bool) -> anyhow::Result<()> {
let root_dir = target_wasm_dir.parent().unwrap();

// Where we will place the final .wasm and .js artifacts.
let build_dir = root_dir.join("web_viewer");

assert!(
build_dir.exists(),
"Failed to find dir {build_dir}. CWD: {:?}, CARGO_MANIFEST_DIR: {:?}",
Expand Down Expand Up @@ -63,12 +109,11 @@ pub fn build(release: bool, webgpu: bool) -> anyhow::Result<()> {
target_wasm_dir.as_str(),
"--no-default-features",
]);
if webgpu {
cmd.arg("--features=analytics");
} else {
cmd.arg("--features=analytics,webgl");
}
if release {
match backend {
Backend::WebGL => cmd.arg("--features=analytics,webgl"),
Backend::WebGPU => cmd.arg("--features=analytics"),
};
if profile == Profile::Release {
cmd.arg("--release");
}

Expand All @@ -95,21 +140,22 @@ pub fn build(release: bool, webgpu: bool) -> anyhow::Result<()> {
// --------------------------------------------------------------------------------
eprintln!("Generating JS bindings for wasm…");

let build = if release { "release" } else { "debug" };
let build = profile.as_str();

let target_wasm_path = target_wasm_dir
.join("wasm32-unknown-unknown")
.join(build)
.join(format!("{crate_name}.wasm"));

// wasm-bindgen --target web target_wasm_path --no-typescript --out-name target_name --out-dir build_dir
if let Err(err) = wasm_bindgen_cli_support::Bindgen::new()
.no_modules(true)?
let mut bindgen_cmd = wasm_bindgen_cli_support::Bindgen::new();
bindgen_cmd
.input_path(target_wasm_path.as_str())
.typescript(false)
.out_name(crate_name)
.generate(build_dir.as_str())
{
.out_name(crate_name);
match target {
Target::Browser => bindgen_cmd.no_modules(true)?.typescript(false),
Target::Module => bindgen_cmd.no_modules(false)?.typescript(true),
};
if let Err(err) = bindgen_cmd.generate(build_dir.as_str()) {
if err
.to_string()
.starts_with("cannot import from modules (`env`")
Expand All @@ -127,7 +173,7 @@ pub fn build(release: bool, webgpu: bool) -> anyhow::Result<()> {

// --------------------------------------------------------------------------------

if release {
if profile == Profile::Release {
eprintln!("Optimizing wasm with wasm-opt…");

// to get wasm-opt: apt/brew/dnf install binaryen
Expand Down
Loading
Loading