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

Publish wasm API to npm #12317

Merged
merged 16 commits into from
Jul 17, 2024
49 changes: 49 additions & 0 deletions .github/workflows/publish-wasm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Build and publish ruff-api for wasm.
#
# Assumed to run as a subworkflow of .github/workflows/release.yml; specifically, as a publish
# job within `cargo-dist`.
name: "Build and publish wasm"

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

env:
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
CARGO_TERM_COLOR: always
RUSTUP_MAX_RETRIES: 10

jobs:
ruff_wasm:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
strategy:
matrix:
target: [web, bundler, nodejs]
steps:
- uses: actions/checkout@v4
- name: "Install Rust toolchain"
run: rustup target add wasm32-unknown-unknown
- uses: jetli/[email protected]
- uses: jetli/[email protected]
Comment on lines +35 to +36
Copy link
Member

Choose a reason for hiding this comment

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

Most our workflows use taiki-e/install-action for fast installation of cargo dependencies

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I stole this setup from the playground workflow, so might want to update both at some point

- name: "Run wasm-pack build"
run: wasm-pack build --target ${{ matrix.target }} crates/ruff_wasm
- uses: actions/setup-node@v4
with:
node-version: 18
registry-url: "https://registry.npmjs.org"
- name: "Rename generated package"
run: | # Replace the package name w/ jq
jq '.name="@astral-sh/ruff-wasm-${{ matrix.target }}"' crates/ruff_wasm/pkg/package.json > /tmp/package.json
mv /tmp/package.json crates/ruff_wasm/pkg
- run: cp LICENSE crates/ruff_wasm/pkg # wasm-pack does not put the LICENSE file in the pkg
- name: "Publish"
run: npm publish --provenance --access public crates/ruff_wasm/pkg
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
17 changes: 16 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,31 @@ jobs:
"id-token": "write"
"packages": "write"

custom-publish-wasm:
needs:
- plan
- host
if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}
uses: ./.github/workflows/publish-wasm.yml
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit
# publish jobs get escalated permissions
permissions:
"id-token": "write"
"packages": "write"

# Create a GitHub Release while uploading all files to it
announce:
needs:
- plan
- host
- custom-publish-pypi
- custom-publish-wasm
# use "always() && ..." to allow us to wait for all publish jobs while
# still allowing individual publish jobs to skip themselves (for prereleases).
# "host" however must run to completion, no skipping allowed!
if: ${{ always() && needs.host.result == 'success' && (needs.custom-publish-pypi.result == 'skipped' || needs.custom-publish-pypi.result == 'success') }}
if: ${{ always() && needs.host.result == 'success' && (needs.custom-publish-pypi.result == 'skipped' || needs.custom-publish-pypi.result == 'success') && (needs.custom-publish-wasm.result == 'skipped' || needs.custom-publish-wasm.result == 'success') }}
runs-on: "ubuntu-20.04"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ build-local-artifacts = false
# Local artifacts jobs to run in CI
local-artifacts-jobs = ["./build-binaries", "./build-docker"]
# Publish jobs to run in CI
publish-jobs = ["./publish-pypi"]
publish-jobs = ["./publish-pypi", "./publish-wasm"]
# Announcement jobs to run in CI
post-announce-jobs = ["./notify-dependents", "./publish-docs", "./publish-playground"]
# Custom permissions for GitHub Jobs
Expand Down
2 changes: 1 addition & 1 deletion crates/ruff_wasm/Cargo.toml
Copy link
Member

Choose a reason for hiding this comment

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

We need to add the Cargo.toml to

ruff/pyproject.toml

Lines 105 to 112 in 7a7c601

version_files = [
"README.md",
"docs/integrations.md",
"crates/ruff/Cargo.toml",
"crates/ruff_linter/Cargo.toml",
"scripts/benchmarks/pyproject.toml",
]

or it won't get automatically updated when doing the next release.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ruff_wasm"
version = "0.0.0"
version = "0.5.2"
publish = false
authors = { workspace = true }
edition = { workspace = true }
Expand Down
51 changes: 51 additions & 0 deletions crates/ruff_wasm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Ruff WASM

> **⚠️ WARNING: This API is experimental and may change at any time**

[**Docs**](https://docs.astral.sh/ruff/) | [**Playground**](https://play.ruff.rs/)
MichaReiser marked this conversation as resolved.
Show resolved Hide resolved

An extremely fast Python linter and code formatter, written in Rust.

This is a WASM version of the Ruff API which can be used to lint/format Python in a browser environment.

There are multiple versions for the different wasm-pack targets. See [here](https://rustwasm.github.io/docs/wasm-bindgen/reference/deployment.html) for more info on targets.

- [Bundler](https://www.npmjs.com/package/@astral-sh/ruff-wasm-bundler)
- [Web](https://www.npmjs.com/package/@astral-sh/ruff-wasm-web)
- [Node.js](https://www.npmjs.com/package/@astral-sh/ruff-wasm-nodejs)

## Usage

This example uses the wasm-pack web target and is known to work with Vite.

```ts
import init, { Workspace, type Diagnostic } from '@astral-sh/ruff-api';

const exampleDocument = `print('hello'); print("world")`

await init(); // Initializes WASM module

// These are default settings just to illustrate configuring Ruff
// Settings info: https://docs.astral.sh/ruff/settings
const workspace = new Workspace({
'line-length': 88,
'indent-width': 4,
format: {
'indent-style': 'space',
'quote-style': 'double',
},
lint: {
select: [
'E4',
'E7',
'E9',
'F'
],
},
});

// Will contain 1 diagnostic code for E702: Multiple statements on one line
const diagnostics: Diagnostic[] = workspace.check(exampleDocument);

const formatted = workspace.format(exampleDocument);
```
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,6 @@ version_files = [
"docs/integrations.md",
"crates/ruff/Cargo.toml",
"crates/ruff_linter/Cargo.toml",
"crates/ruff_wasm/Cargo.toml",
"scripts/benchmarks/pyproject.toml",
]
Loading