Skip to content
Draft
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
15 changes: 15 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,21 @@ updates:
patterns:
- "*"

# The wasm coreutils guest. Its lockfile pins what the committed
# artifacts/coreutils.wasm.xz was built from (uu_* = 0.12.0, reproducible
# hash in artifacts/MANIFEST), so a lockfile-only bump would desync the
# lockfile from the shipped bytes. Version updates are off
# (open-pull-requests-limit: 0); security updates still open PRs, and any
# bump means re-running guest/build.sh. See
# knowledge/runtimes/wasm-coreutils.md.
- package-ecosystem: "cargo"
directory: "/crates/bashkit-coreutils-wasm/guest"
schedule:
interval: "weekly"
open-pull-requests-limit: 0
commit-message:
prefix: "chore(deps)"

# npm / pnpm.
#
# Important decision: the five pnpm lockfiles in this repo had no
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,11 @@ jobs:
/tmp/http-diff/bin/pip install --quiet requests==2.34.2 httpx==0.28.1
/tmp/http-diff/bin/python crates/bashkit-cpython-wasm/guest/tests/differential.py

# uutils coreutils as wasm guests on the shared WASI host: unit,
# integration and security tests. Feature-gated like CPython.
- name: Run wasm coreutils tests
run: cargo test -p bashkit --features wasm-coreutils --lib --test integration -- wasm_coreutils wasi_host

# Same suites on the opt-in native-code build (`cpython-native`).
- name: Run CPython tests (native code)
run: cargo test -p bashkit --features cpython-native,http_client --lib --test integration -- cpython
Expand Down
45 changes: 42 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,50 @@ jobs:
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

# Publish bashkit-coreutils-wasm (optional dependency of bashkit's `wasm-coreutils`
# feature; must exist on crates.io before bashkit can be verified)
publish-bashkit-coreutils-wasm:
name: Publish bashkit-coreutils-wasm
runs-on: ubuntu-latest
environment: release
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Verify publish source is on main
run: |
git fetch --no-tags origin main:refs/remotes/origin/main
SOURCE_SHA=$(git rev-parse HEAD)
if ! git merge-base --is-ancestor "$SOURCE_SHA" origin/main; then
echo "Error: publish source $SOURCE_SHA is not reachable from origin/main"
exit 1
fi

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0

- name: Verify bashkit-coreutils-wasm package without credentials
run: |
cargo publish --dry-run -p bashkit-coreutils-wasm
# crates.io rejects crates over 10 MiB.
size=$(stat -c %s target/package/bashkit-coreutils-wasm-*.crate)
echo "crate size: $size bytes"
if [ "$size" -ge 10485760 ]; then
echo "Error: bashkit-coreutils-wasm crate exceeds the crates.io 10 MiB limit"
exit 1
fi

- name: Publish bashkit-coreutils-wasm to crates.io
run: cargo publish --no-verify -p bashkit-coreutils-wasm
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

# Publish bashkit (core library) to crates.io
publish-bashkit:
name: Publish bashkit
runs-on: ubuntu-latest
needs: publish-bashkit-cpython-wasm
needs: [publish-bashkit-cpython-wasm, publish-bashkit-coreutils-wasm]
environment: release
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -167,7 +206,7 @@ jobs:
verify-publish:
name: Verify published versions
runs-on: ubuntu-latest
needs: [publish-bashkit-cpython-wasm, publish-bashkit, publish-bashkit-cli, publish-bashkit-scripted-tool]
needs: [publish-bashkit-cpython-wasm, publish-bashkit-coreutils-wasm, publish-bashkit, publish-bashkit-cli, publish-bashkit-scripted-tool]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand All @@ -180,4 +219,4 @@ jobs:
run: |
EXPECTED=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
echo "Expected version: $EXPECTED"
python3 scripts/verify_crates_publish.py --expected "$EXPECTED" bashkit-cpython-wasm bashkit bashkit-cli bashkit-scripted-tool
python3 scripts/verify_crates_publish.py --expected "$EXPECTED" bashkit-cpython-wasm bashkit-coreutils-wasm bashkit bashkit-cli bashkit-scripted-tool
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Fix root cause. Unsure: read more code; if stuck, ask w/ short options. Unrecogn
| integrations/git-support | Sandboxed git operations on VFS |
| runtimes/python-builtin | Embedded Python via Monty, security, resource limits |
| runtimes/cpython-wasm | Real CPython 3.14 on WASI (Wizer snapshot, Pulley AOT), WASI-on-VFS host, limits |
| runtimes/wasm-coreutils | Real uutils coreutils as WASI guests (Pulley AOT) on the shared WASI host, gap-filling builtins |
| operations/eval | LLM eval study on the mira framework, dataset format, scoring |
| operations/oils-spec | Upstream Oils spec suite pass rate vs real bash (`just oils-spec`) |
| operations/maintenance | Pre-release maintenance requirements |
Expand Down
9 changes: 9 additions & 0 deletions Cargo.lock

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

33 changes: 33 additions & 0 deletions crates/bashkit-coreutils-wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# uutils/coreutils compiled to WebAssembly (wasm32-wasip1) as one multicall
# guest, compiled ahead of time to Wasmtime's Pulley bytecode. Consumed by
# bashkit's `wasm-coreutils` feature; see knowledge/runtimes/wasm-coreutils.md.
#
# Decisions:
# - The guest artifact is committed; `guest/build.sh` rebuilds it from the
# pinned uutils release. No network access at build or run time.
# - build.rs compiles it to Pulley once per build: no wasm is compiled at run
# time, and one output serves every 64-bit little-endian host.
# - wasmtime is pinned exactly (workspace): a `.cwasm` only loads into the
# same version with the same compile-affecting configuration.

[package]
name = "bashkit-coreutils-wasm"
version.workspace = true
edition.workspace = true
authors.workspace = true
repository.workspace = true
license = "MIT AND Apache-2.0 AND Unicode-3.0 AND Zlib"
description = "uutils coreutils compiled to WASI and precompiled to Pulley, for bashkit's sandboxed coreutils"
keywords = ["coreutils", "wasm", "sandbox", "bashkit"]
categories = ["wasm", "command-line-utilities"]
readme = "README.md"
# guest/ is its own Cargo package (excluded from packaging by Cargo); its
# sources live in the repository.
include = ["src/**", "build.rs", "artifacts/**", "README.md", "THIRD_PARTY_LICENSES.md"]

[dependencies]
wasmtime = { workspace = true }

[build-dependencies]
wasmtime = { workspace = true, features = ["cranelift", "parallel-compilation"] }
lzma-rs = "0.3"
41 changes: 41 additions & 0 deletions crates/bashkit-coreutils-wasm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# bashkit-coreutils-wasm

[uutils/coreutils](https://github.com/uutils/coreutils) 0.12 compiled to
WebAssembly (`wasm32-wasip1`) as one multicall guest, precompiled at build
time to Wasmtime's portable Pulley bytecode.

This crate ships bytes, not behavior: the precompiled module, the list of
utilities and the matching `wasmtime::Config`. It is consumed by
[bashkit](https://crates.io/crates/bashkit)'s `wasm-coreutils` feature, which
provides the WASI host over bashkit's virtual filesystem and the builtins:

```toml
[dependencies]
bashkit = { version = "0.18.2", features = ["wasm-coreutils"] }
```

## Contents

| Item | Description |
|------|-------------|
| `load_module(&engine)` | The guest as a `wasmtime::Module` (mapped in place on first load) |
| `engine_config()` / `engine()` | The compile-affecting Wasmtime configuration the module was built for |
| `UTILS` | Utility names the guest dispatches on (70, sorted) |
| `UUTILS_VERSION` | `0.12.0` |

Guest contract: a WASI command (`_start`); `argv[0]` names the utility;
`PWD` becomes the working directory; exactly one preopen, `/`, at fd 3; one
instance per call; the status comes from `proc_exit`.

## Rebuilding

The guest sources live in the bashkit repository under
`crates/bashkit-coreutils-wasm/guest/` (`utils.txt`, `gen.py`, `build.sh`).
`build.rs` compiles the committed `artifacts/coreutils.wasm.xz` to Pulley on
every build; no network access is needed at build or run time.

## License

Crate code and uutils: MIT. The embedded guest also contains code from
uutils' dependencies under MIT, Apache-2.0, Unicode-3.0 and Zlib terms; see
[THIRD_PARTY_LICENSES.md](THIRD_PARTY_LICENSES.md).
Loading
Loading