diff --git a/.github/actions/dapr4s-mill-plugin/action.yml b/.github/actions/dapr4s-mill-plugin/action.yml index edb3082..32153ad 100644 --- a/.github/actions/dapr4s-mill-plugin/action.yml +++ b/.github/actions/dapr4s-mill-plugin/action.yml @@ -1,13 +1,35 @@ name: dapr4s Mill plugin description: >- publishLocal the mill-dapr4s-wasm plugin that build.mill's header loads, from the dapr4s commit pinned in - wasm/dapr4s-wasm.env (cached per commit). Every job that runs ./mill needs it until the plugin is released. + wasm/dapr4s-wasm.env (cached per commit), and the unreleased mill-scalablytyped dapr4s's meta-build loads. + Every job that runs ./mill needs both until they are released. runs: using: composite steps: - name: Read the dapr4s pin (wasm/dapr4s-wasm.env) shell: bash run: grep -E '^[A-Z0-9_]+=' wasm/dapr4s-wasm.env >> "$GITHUB_ENV" + # dapr4s's meta-build loads an unreleased mill-scalablytyped: dapr4s's scripts/upstream-snapshot.sh (at the + # pinned commit) builds it from a pinned upstream commit and installs it locally. Cached by the script's hash. + # Mill itself is the released 1.3.1 (.mill-version). + - name: Fetch dapr4s's upstream-snapshot.sh + id: snapshot + shell: bash + run: | + f="$RUNNER_TEMP/upstream-snapshot.sh" + curl -fsSL --retry 3 -o "$f" \ + "https://raw.githubusercontent.com/sideeffffect/dapr4s/$DAPR4S_COMMIT/scripts/upstream-snapshot.sh" + chmod +x "$f" + echo "script=$f" >> "$GITHUB_OUTPUT" + echo "hash=$(sha256sum "$f" | cut -c1-16)" >> "$GITHUB_OUTPUT" + - name: Cache the upstream mill-scalablytyped snapshot + uses: actions/cache@v5 + with: + path: ~/.ivy2/local/com.github.lolgab + key: upstream-snapshot-${{ steps.snapshot.outputs.hash }} + - name: Build the upstream mill-scalablytyped snapshot + shell: bash + run: ${{ steps.snapshot.outputs.script }} - name: Cache the dapr4s Mill plugin (~/.ivy2/local) id: cache uses: actions/cache@v5 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 6eb5028..80841be 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -3,13 +3,13 @@ name: E2E Tests on: push: branches: [main, master] + # Every pull request, also those stacked on another PR's branch. pull_request: - branches: [main, master] jobs: format: runs-on: ubuntu-latest - timeout-minutes: 15 + timeout-minutes: 45 steps: - uses: actions/checkout@v5 @@ -246,14 +246,14 @@ jobs: # Mill plugin mill-dapr4s-wasm. dapr4s itself comes from Maven Central (dapr4s_sjs1_3 3.0.0); the plugin and the # small dapr4s wasm artifacts (dapr4s-wasm, dapr4s-wasm-glue(-exports), dapr4s-wasm-scalalib-overlay, # dapr4s-wasm-linker) come from a publishLocal of the dapr4s commit PINNED in wasm/dapr4s-wasm.env (a commit of - # https://github.com/sideeffffect/dapr4s/pull/45). Once they are released, the pin becomes a release version and + # https://github.com/sideeffffect/dapr4s/pull/47). Once they are released, the pin becomes a release version and # the dapr4s publish step goes away. # The components are composed with dapr-wasm-components 0.7.5 (compose.sh at the v0.7.5 tag) and run # in `wasmtime serve` next to a real daprd (dapr CLI, slim) + Redis (Docker); the e2e asserts their # real output, including 04's unchanged JVM caller calling the Wasm greeting-service. e2e-wasm: runs-on: ubuntu-latest - timeout-minutes: 45 + timeout-minutes: 90 name: e2e (wasm components) steps: @@ -319,7 +319,26 @@ jobs: dapr init --slim --runtime-version 1.17.7 echo "$HOME/.dapr/bin" >> "$GITHUB_PATH" - # The plugin + the five dapr4s wasm artifacts (incl. dapr4s-wasm-linker, compiled from scala-wasm's release + # dapr4s's meta-build loads an unreleased mill-scalablytyped: dapr4s's scripts/upstream-snapshot.sh (at the + # pinned commit) builds and installs it, cached by its hash. Mill itself is the released 1.3.1. + - name: Fetch dapr4s's upstream-snapshot.sh + id: snapshot + run: | + f="$RUNNER_TEMP/upstream-snapshot.sh" + curl -fsSL --retry 3 -o "$f" \ + "https://raw.githubusercontent.com/sideeffffect/dapr4s/$DAPR4S_COMMIT/scripts/upstream-snapshot.sh" + chmod +x "$f" + echo "script=$f" >> "$GITHUB_OUTPUT" + echo "hash=$(sha256sum "$f" | cut -c1-16)" >> "$GITHUB_OUTPUT" + - name: Cache the upstream mill-scalablytyped snapshot + uses: actions/cache@v5 + with: + path: ~/.ivy2/local/com.github.lolgab + key: upstream-snapshot-${{ steps.snapshot.outputs.hash }} + - name: Build the upstream mill-scalablytyped snapshot + run: ${{ steps.snapshot.outputs.script }} + + # The plugin + the five dapr4s wasm artifacts (incl. dapr4s-wasm-linker_2.13, compiled from scala-wasm's release # commit + dapr4s's patch) land in ~/.ivy2/local and are a pure function of the pinned dapr4s commit: cache # them under it. On a miss, wasm/scripts/publish-dapr4s-wasm.sh clones dapr4s at that commit and runs its # Mill publishLocal. It must run before the first ./mill here (build.mill's header loads the plugin). @@ -347,7 +366,7 @@ jobs: slides: runs-on: ubuntu-latest - timeout-minutes: 20 + timeout-minutes: 45 steps: - uses: actions/checkout@v5 diff --git a/AGENTS.md b/AGENTS.md index 7cb47fd..212020e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -120,8 +120,11 @@ Source files live under `src//` within each module directory, e.g.: - **Dapr CLI** and runtime: https://docs.dapr.io/getting-started/install-dapr-cli/ - **Redis** on `localhost:6379` — `docker run -d -p 6379:6379 redis:7` - **JVM ≥ 21** — `java -version` -- **Mill 1.3.x** — use the `./mill` launcher (it reads `.mill-version`). Mill >= 1.3.0 is required - for the Scala.js JSPI switch (see "Scala.js examples"). +- **Mill 1.3.1** — use the `./mill` launcher (it reads `.mill-version`). It is the Mill the dapr4s + plugin is built against, and the first release with + [com-lihaoyi/mill#7783](https://github.com/com-lihaoyi/mill/pull/7783) (Scala.js organization + + `ModuleKind.WasmComponent`). Mill >= 1.3.0 is required for the Scala.js JSPI switch (see "Scala.js + examples"). - **dapr4s published locally** (run once from the dapr4s repo): ``` cd ../scala-safe-dapr @@ -423,7 +426,7 @@ whole repository is one Mill build. directly) + `dapr4s-wasm` (the adapters), `dapr4s-wasm-glue(-exports)`, `dapr4s-wasm-scalalib-overlay`, `dapr4s-wasm-linker` and the plugin `mill-dapr4s-wasm`, which are **not released yet**: they come from a `publishLocal` of the dapr4s commit pinned in `wasm/dapr4s-wasm.env` (a commit of - [dapr4s PR #45](https://github.com/sideeffffect/dapr4s/pull/45)), at the version `build.mill`'s header pins. + [dapr4s PR #47](https://github.com/sideeffffect/dapr4s/pull/47)), at the version `build.mill`'s header pins. **Bootstrapping**: the header loads the plugin, so EVERY `./mill` command fails until it is in `~/.ivy2/local`. Run `wasm/scripts/publish-dapr4s-wasm.sh` (`plugin`, the default: only the plugin, needs git + Java) once after cloning; `all` also publishes the wasm artifacts `./mill wasm.e2e` needs @@ -460,10 +463,10 @@ whole repository is one Mill build. [scala-wasm#268](https://github.com/scala-wasm/scala-wasm/pull/268)); the linker drops WIT aliases (WIT re-embed, [scala-wasm#269](https://github.com/scala-wasm/scala-wasm/pull/269)); the fork's and mainline's core libraries do not evict each other (exclusions, [scala-wasm#271](https://github.com/scala-wasm/scala-wasm/pull/271)); - the nightly stdlib uses JS interop (`dapr4s-wasm-scalalib-overlay`); Mill has no Scala.js organization - setting / `ModuleKind.WasmComponent` ([mill#7783](https://github.com/com-lihaoyi/mill/pull/7783)) or - WIT-bindings task ([mill#7784](https://github.com/com-lihaoyi/mill/pull/7784)); no `main` in a reactor - (`ComponentRoot`). + the nightly stdlib uses JS interop (`dapr4s-wasm-scalalib-overlay`); Mill has no WIT-bindings task + ([mill#7784](https://github.com/com-lihaoyi/mill/pull/7784)); no `main` in a reactor (`ComponentRoot`). + (The Scala.js organization setting and `ModuleKind.WasmComponent`, + [mill#7783](https://github.com/com-lihaoyi/mill/pull/7783), are released in Mill 1.3.1 and used.) > The E2E (`Example14ObservabilityTest`) proves all three OpenTelemetry signals reach > SigNoz by asserting the funnel collector's own pipeline counters diff --git a/README.md b/README.md index 50360f8..3e55b17 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ published `dapr4s_sjs1_3` 3.0.0, whose Scala.js IR is linked into the component) (+ `-exports`; the Scala 2.13 WIT glue), `dapr4s-wasm-scalalib-overlay` and `dapr4s-wasm-linker`. **Prototype status.** The plugin and the artifacts are in -[dapr4s PR #45](https://github.com/sideeffffect/dapr4s/pull/45) (not released yet), hence the +[dapr4s PR #47](https://github.com/sideeffffect/dapr4s/pull/47) (not released yet), hence the `publishLocal` of the dapr4s commit pinned in `wasm/dapr4s-wasm.env` (at the version `build.mill`'s header pins). Because `build.mill`'s header loads the plugin, **every** `./mill` command needs it: `wasm/scripts/publish-dapr4s-wasm.sh` (default `plugin`: only the plugin, needs just git and Java) once @@ -120,9 +120,10 @@ mainline Scala 3 (a small Scala 2.13 glue); the linker cannot pass WIT params th plugin re-embeds the WIT world, [scala-wasm#269](https://github.com/scala-wasm/scala-wasm/pull/269)); the fork's and mainline's core libraries do not evict each other (the exclusions, [scala-wasm#271](https://github.com/scala-wasm/scala-wasm/pull/271)); JS interop in the nightly's Scala.js -stdlib (`dapr4s-wasm-scalalib-overlay`); Mill knows neither the fork's organization nor -`ModuleKind.WasmComponent` ([mill#7783](https://github.com/com-lihaoyi/mill/pull/7783)) nor WIT bindings -([mill#7784](https://github.com/com-lihaoyi/mill/pull/7784)). +stdlib (`dapr4s-wasm-scalalib-overlay`); Mill has no WIT-bindings task +([mill#7784](https://github.com/com-lihaoyi/mill/pull/7784)). (The fork's organization and +`ModuleKind.WasmComponent`, [mill#7783](https://github.com/com-lihaoyi/mill/pull/7783), are released in Mill +1.3.1 and used.) **Prerequisites**: JDK 25, Docker, the dapr CLI 1.15.1 + daprd 1.17.7 (`dapr init --slim`), [wasm-tools](https://github.com/bytecodealliance/wasm-tools) 1.261.0, diff --git a/build.mill b/build.mill index 5073afe..878ded6 100644 --- a/build.mill +++ b/build.mill @@ -1,4 +1,4 @@ -//| mvnDeps: ["com.github.sideeffffect::mill-dapr4s-wasm::3.0.0+35-0048d5b0-SNAPSHOT"] +//| mvnDeps: ["com.github.sideeffffect::mill-dapr4s-wasm::3.0.0+44-1493515a-SNAPSHOT"] // The dapr4s Mill plugin for WASI components (examples 18/19, `object wasm` below). Pinned to a dapr4s commit // (wasm/dapr4s-wasm.env) until it is released: run wasm/scripts/publish-dapr4s-wasm.sh once before the first // `./mill` (it publishLocal's the plugin from that commit; `all` also the wasm artifacts the components need). diff --git a/wasm/dapr4s-wasm.env b/wasm/dapr4s-wasm.env index e90d114..ae162f3 100644 --- a/wasm/dapr4s-wasm.env +++ b/wasm/dapr4s-wasm.env @@ -1,6 +1,8 @@ # The dapr4s commit the Mill plugin mill-dapr4s-wasm (build.mill's header) and the dapr4s wasm artifacts come from, -# until they are released: a commit of dapr4s PR #45 (https://github.com/sideeffffect/dapr4s/pull/45, branch -# build/mill). wasm/scripts/publish-dapr4s-wasm.sh publishLocal's them from it, at the version build.mill's header +# until they are released: a commit of dapr4s PR #47 (https://github.com/sideeffffect/dapr4s/pull/47, branch +# build/mill-upstream-snapshot: dapr4s on Mill 1.3.1 + the unreleased mill-scalablytyped that its +# scripts/upstream-snapshot.sh installs; this repository's .mill-version uses the same Mill). +# wasm/scripts/publish-dapr4s-wasm.sh publishLocal's them from it, at the version build.mill's header # pins (dapr4s derives it from git: +--SNAPSHOT), so the classpath is "Central dapr4s # + the local wasm artifacts": # - dapr4s itself: com.github.sideeffffect::dapr4s_sjs1_3:$DAPR4S_CORE_RELEASE from Maven Central (Scala.js IR, @@ -9,5 +11,5 @@ # glue), dapr4s-wasm-scalalib-overlay and dapr4s-wasm-linker. # Once released, this file goes away: the header pins a Maven Central release and CI stops building dapr4s. # Read by wasm/scripts/publish-dapr4s-wasm.sh and CI (.github/workflows/e2e.yml, .github/actions/dapr4s-mill-plugin). -DAPR4S_COMMIT=0048d5b0a880e74ea409af7a555c99749efe07b3 +DAPR4S_COMMIT=1493515a8e86918129b7625e9c1bc4fff44e1423 DAPR4S_CORE_RELEASE=3.0.0 diff --git a/wasm/scripts/publish-dapr4s-wasm.sh b/wasm/scripts/publish-dapr4s-wasm.sh index faa8515..ae0f9d5 100755 --- a/wasm/scripts/publish-dapr4s-wasm.sh +++ b/wasm/scripts/publish-dapr4s-wasm.sh @@ -33,9 +33,9 @@ artifacts=(mill-dapr4s-wasm_mill1_3) case "$what" in plugin) ;; all) - modules+=('wasm.lib[release].wall' wasm.glue wasm.glueExports wasm.scalalibOverlay wasm.linker) + modules+=('wasm.lib[release].wall' wasm.glue wasm.glueExports wasm.scalalibOverlay 'wasm.linker[2.13.18]') artifacts+=(dapr4s-wasm_sjs1_3 dapr4s-wasm-glue_sjs1_2.13 dapr4s-wasm-glue-exports_sjs1_2.13 - dapr4s-wasm-scalalib-overlay dapr4s-wasm-linker_2.12) + dapr4s-wasm-scalalib-overlay dapr4s-wasm-linker_2.13) ;; *) echo "usage: $0 [plugin|all]" >&2 @@ -58,6 +58,8 @@ if [[ ! -d "$dir/.git" ]]; then fi git -C "$dir" fetch --quiet --tags origin "$DAPR4S_COMMIT" 2>/dev/null || git -C "$dir" fetch --quiet --tags origin git -C "$dir" checkout --quiet --force "$DAPR4S_COMMIT" +# dapr4s builds with an unreleased mill-scalablytyped: install it first (idempotent). +"$dir/scripts/upstream-snapshot.sh" args=() for m in "${modules[@]}"; do [[ ${#args[@]} -gt 0 ]] && args+=(+)