Skip to content

Commit

Permalink
Convert JS package to yarn workspace (#5160)
Browse files Browse the repository at this point in the history
### What

- [x] Move `web-viewer-react` package into its own folder at the same
level as `web-viewer`
- [x] Add a root `package.json` in `rerun_js` with `workspaces` property
pointing at the two packages
- [x] Update CI to use workspaces

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using newly built examples:
[app.rerun.io](https://app.rerun.io/pr/5160/index.html)
* Using examples from latest `main` build:
[app.rerun.io](https://app.rerun.io/pr/5160/index.html?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[app.rerun.io](https://app.rerun.io/pr/5160/index.html?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG
* [x] If applicable, add a new check to the [release
checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)!

- [PR Build Summary](https://build.rerun.io/pr/5160)
- [Docs
preview](https://rerun.io/preview/af65e980271dd584decd5ac1934443dd6a9fb86d/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/af65e980271dd584decd5ac1934443dd6a9fb86d/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)
  • Loading branch information
jprochazk authored Feb 14, 2024
1 parent 4476969 commit c7f415e
Show file tree
Hide file tree
Showing 24 changed files with 385 additions and 102 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/on_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
build-js:
name: "Build JS"
if: github.event.pull_request.head.repo.owner.login == 'rerun-io'
uses: ./.github/workflows/reusable_build_npm.yml
uses: ./.github/workflows/reusable_build_js.yml
with:
CONCURRENCY: pr-${{ github.event.pull_request.number }}
secrets: inherit
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ jobs:
echo "current=$current" >> "$GITHUB_OUTPUT"
echo "final=$final" >> "$GITHUB_OUTPUT"
- name: Update JS package versions
shell: bash
run: |
pixi run node rerun_js/scripts/version.mjs "${{ steps.versioning.outputs.current }}"
- name: Update rerun_c version
shell: bash
# Configuring CMake is enough to change the version on rerun.h!
Expand Down Expand Up @@ -264,6 +269,15 @@ jobs:
concurrency: ${{ github.ref_name }}
secrets: inherit

publish-js:
name: "Publish JS"
needs: [version]
uses: ./.github/workflows/reusable_publish_js.yml
with:
release-commit: ${{ needs.version.outputs.current }}
concurrency: ${{ github.ref_name }}
secrets: inherit

update-latest-branch:
name: "Update Latest Branch"
if: inputs.release-type == 'final'
Expand All @@ -276,6 +290,7 @@ jobs:
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-js,
]
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -304,6 +319,7 @@ jobs:
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-js,
]
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -348,6 +364,7 @@ jobs:
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-js,
github-release,
]
runs-on: ubuntu-latest
Expand Down Expand Up @@ -404,6 +421,7 @@ jobs:
publish-web,
publish-rerun_c,
publish-rerun-cli,
publish-js,
]
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -433,11 +451,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 @@ -447,6 +467,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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Reusable Build Web
name: Reusable Build JS

on:
workflow_call:
Expand Down Expand Up @@ -41,6 +41,9 @@ jobs:
with:
node-version: "20.x"

- name: Install Yarn
run: npm install -g yarn

- name: Set up Rust
uses: ./.github/actions/setup-rust
with:
Expand All @@ -50,10 +53,14 @@ jobs:
workload_identity_provider: ${{ secrets.GOOGLE_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }}

- uses: prefix-dev/setup-pixi@v0.3.0
with:
pixi-version: v0.13.0

- name: Install dependencies
shell: bash
run: node rerun_js/web-viewer/scripts/install.mjs
run: pixi run yarn --cwd rerun_js install

- name: Build package
shell: bash
run: node rerun_js/web-viewer/scripts/build.mjs
run: pixi run yarn --cwd rerun_js workspaces run build
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and publish NPM
name: Build and publish JS

on:
workflow_call:
Expand All @@ -12,7 +12,7 @@ on:
required: true

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

permissions:
Expand Down Expand Up @@ -48,7 +48,9 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: "20.x"
registry-url: "https://registry.npmjs.org"

- name: Install Yarn
run: npm install -g yarn

- name: Set up Rust
uses: ./.github/actions/setup-rust
Expand All @@ -67,4 +69,4 @@ jobs:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
shell: bash
run: |
pixi run node rerun_js/web-viewer/scripts/publish.mjs
pixi run node rerun_js/scripts/publish.mjs
2 changes: 1 addition & 1 deletion .prettierrc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ files = ["*.yml", "*.yaml"]
options = { tabWidth = 2 }

[[overrides]]
files = "*.js"
files = ["*.js", "*.mjs", "*.cjs"]
options = { semi = true, tabWidth = 2 }

[[overrides]]
Expand Down
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"ruff.lint.args": [
"--config=rerun_py/pyproject.toml"
],
"prettier.requireConfig": true,
"prettier.configPath": ".prettierrc.toml",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
Expand Down
17 changes: 11 additions & 6 deletions crates/re_build_web_viewer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ pub fn build(profile: Profile, target: Target, build_dir: &Utf8Path) -> anyhow::
// values that only make sense for the native target host, not for a wasm build.
cmd.env("CARGO_ENCODED_RUSTFLAGS", "--cfg=web_sys_unstable_apis");

eprintln!("> {cmd:?}");
eprintln!("{root_dir}> {cmd:?}");
let status = cmd
.current_dir(root_dir)
.status()
Expand Down Expand Up @@ -170,13 +170,18 @@ pub fn build(profile: Profile, target: Target, build_dir: &Utf8Path) -> anyhow::

// TODO(emilk): add `-g` to keep debug symbols; useful for profiling release builds in the in-browser profiler.
cmd.args([wasm_path.as_str(), "-O2", "--output", wasm_path.as_str()]);
eprintln!("{root_dir}> {cmd:?}");

eprintln!("> {cmd:?}");
let status = cmd
let output = cmd
.current_dir(root_dir)
.status()
.context("Failed to run wasm-opt")?;
assert!(status.success(), "Failed to run wasm-opt");
.output()
.context("Failed to run wasm-opt, it may not be installed")?;
if !output.status.success() {
eprintln!(
"Failed to run wasm-opt:\n{}",
String::from_utf8_lossy(&output.stderr)
);
}
}

// --------------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions rerun_js/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
**/node_modules
**/package-lock.json
15 changes: 15 additions & 0 deletions rerun_js/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"licenses": [
{
"type": "MIT"
},
{
"type": "Apache-2.0"
}
],
"private": true,
"workspaces": [
"web-viewer",
"web-viewer-react"
]
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
// @ts-check

import { execSync } from "node:child_process";
import { fileURLToPath } from "node:url";
import path from "node:path";
import fs from "node:fs";

/** @type {typeof execSync} */
export const $ = (cmd, opts) => execSync(cmd, { stdio: "inherit", ...opts });
export const $ = /** @type {typeof execSync} */ (
(cmd, opts) => {
console.log(`${opts.cwd ?? ""}> ${cmd}`);
return execSync(cmd, { stdio: "inherit", ...opts });
}
);
export const argv = process.argv.slice(2);
export const script_dir = path.dirname(fileURLToPath(import.meta.url));
export const packages = [{ path: "." }, { path: "react" }];

/**
* Logs `message` and exits with code `1`.
Expand All @@ -21,7 +27,7 @@ export function fail(message) {
/**
* Checks that `version` is valid according to semver.
*
* @type {(version: string) => bool}
* @type {(version: string) => boolean}
*/
export function isSemver(version) {
// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
Expand All @@ -45,15 +51,39 @@ export function stripSemverBuildMetadata(version) {
}
}

/**
* Returns the appropriate NPM package tag for `version`.
*
* @type {(version: string) => "alpha" | "rc" | "latest"}
*/
export function inferTag(version) {
/** @type {"alpha" | "rc" | "latest"} */
let tag = "latest";

const [, prerelease] = version.split("-");
if (prerelease) {
const [kind, n] = prerelease.split(".");
switch (kind) {
case "alpha":
tag = "alpha";
case "rc":
tag = "rc";
}
}

return tag;
}

/**
* Returns `true` if `package@version` is already published.
*
* @type {(packageName: string, version: string) => Promise<boolean>}
*/
export async function isPublished(packageName, version) {
const response = await fetch(`https://registry.npmjs.org/${packageName}/${version}`);
const response = await fetch(
`https://registry.npmjs.org/${packageName}/${version}`,
);
return response.status === 200;
}

export { path };

export { fs, path };
63 changes: 63 additions & 0 deletions rerun_js/scripts/publish.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env node
// @ts-check

import {
$,
fs,
script_dir,
path,
fail,
inferTag,
isPublished,
} from "./common.mjs";

const root_dir = path.resolve(script_dir, "..");

if (!process.env.NODE_AUTH_TOKEN) {
fail(
`"NODE_AUTH_TOKEN" env is not set. https://docs.npmjs.com/creating-and-viewing-access-tokens`,
);
}

/** @type {{ workspaces: string[] }} */
const root_package_json = JSON.parse(
fs.readFileSync(path.join(root_dir, "package.json"), "utf-8"),
);

const all_packages = await Promise.all(
root_package_json.workspaces.map(async (pkg) => {
const dir = path.join(root_dir, pkg);
const { name, version } = JSON.parse(
fs.readFileSync(path.join(dir, "package.json"), "utf-8"),
);
const published = await isPublished(name, version);

return { dir, name, version, published };
}),
);

const unpublished = all_packages.filter((pkg) => {
if (pkg.published) {
console.log(`${pkg.name}@${pkg.version} is already published`);
return false;
}
return true;
});

if (unpublished.length === 0) {
console.log("nothing to publish");
process.exit(0);
}

$(`yarn install`, { cwd: root_dir });

for (const pkg of unpublished) {
console.log(`building ${pkg.name}@${pkg.version}`);
$(`npm run build`, { cwd: pkg.dir });
}

for (const pkg of unpublished) {
console.log(`publishing ${pkg.name}@${pkg.version}`);
const tag = inferTag(pkg.version);
$(`npm publish --tag ${tag}`, { cwd: pkg.dir });
}
Loading

0 comments on commit c7f415e

Please sign in to comment.