Skip to content
Merged
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
30 changes: 28 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ env:
# every dispatched format was unreachable on macOS, including one that never
# reads the staged tree. Staging is a service to the provider in 2026.9.11.2,
# and `dist-apple` has been unreachable, not broken, since it was written.
MCPP_VERSION: 2026.9.12.3
MCPP_VERSION: 2026.9.13.1
# PINNED, AND WITHOUT IT THE CACHE BELOW CACHED NOTHING.
#
# A released mcpp is self-contained: with no `MCPP_HOME`, `mcpp self env`
Expand Down Expand Up @@ -1127,7 +1127,11 @@ jobs:
# --target wasm32-emscripten` -- see `tests/web-consumer/
# check-web-plan.sh`'s own header for the host-toolchain defect this
# needed fixed first (mcpp commit 23974c5e, #622 e2e 657) and the
# MCPP_VERSION this step therefore needs at least. `mcpp toolchain
# MCPP_VERSION this step therefore needs at least. Since 0.9.0 the same
# pin is also the floor for `${mcpp.self}` and `mcpp stage`'s argument
# shape as an engine contract (design record
# `2026-09-13-four-upstream-asks-from-a-ui-framework.md`, §4), which
# `dist-web`'s two copy steps now use in place of `cp`. `mcpp toolchain
# install` first, because this job's `~/.mcpp` cache does not carry
# the emsdk payload the way the local sandbox this member was
# developed against does.
Expand All @@ -1137,6 +1141,14 @@ jobs:
- name: dist-web produces a static directory, and node runs it
working-directory: tests/web-consumer
run: MCPP="$MCPP" ./check-web-plan.sh

# P3's own criterion: a second, no-op pack copies nothing, which `cp`
# could never give and `${mcpp.self} stage --verify content` gives for
# free. A sibling script, not an addition to the one above, so that
# one keeps passing exactly as it did before this batch.
- name: dist-web's second pack copies nothing
working-directory: tests/web-consumer
run: MCPP="$MCPP" ./check-web-idempotent.sh
# `kind = "app"` on `*-linux-android` links a shared object (#622 A3),
# so this fixture's own toolchain resolution provisions `xim:android-
# ndk` for `--target x86_64-linux-android` exactly as mcpp's own CI
Expand Down Expand Up @@ -1195,6 +1207,20 @@ jobs:
|| { echo "FAIL: minSdkVersion is not 24 (this fixture's own min_api_level)"; cat -A badging.log | head -12; exit 1; }
echo "ok: dist-apk level 0 -- a signed, aapt2-readable APK carrying the native library, the deployed asset and the run sidecar"

# P1/P2's own criteria (design record §3.5 / §9.2), beside the step
# above rather than folded into it: (a) level 0 with no template is
# 0.8.0's manifest byte-for-byte; (b) a template's own permission and
# receiver reach the linked apk; (c),(d) a template missing a required
# token, or naming an unknown one, is refused at plan time, checked on
# build.mcpp's own stdout/stderr since mcpp discards it on a plan-time
# refusal's exit code of 0 (the script's own header says why); (e) two
# Java roots, one under this project and one a sibling directory
# reached by an absolute path, dex into one file carrying classes from
# both.
- name: dist-apk's manifest template and Java roots, (a) to (e)
working-directory: tests/apk-consumer
run: MCPP="$MCPP" ./check-apk-features.sh

# Compiles the device unit on a machine with no GPU: the clang route
# produces sm_89 code from the payload toolkit. Running it needs a
# device, so the run is of the CPU variant, which the same seam serves.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ engine's own module family and is not used here.
| `dist-appimage` | `mcpp.dist.appimage` | 2026.9.11.1 | `xim:appimagetool`, which this feature declares on the `cfg(linux)` axis. Linux only. Turns the tree `mcpp pack` staged into one AppImage: the staged bundle is already an AppDir bar three files, so the member writes an `AppRun`, a `.desktop` entry and an icon into it and invokes one tool -- it never copies or re-lays-out a tree that can be hundreds of megabytes |
| `dist-wix` | `mcpp.dist.wix` | 2026.9.11.1 | `xim:wix`, which this feature declares on the Windows target axis; the .NET 6 runtime the tool needs is a Windows component the payload does not carry, and `wix --version` names it when it is missing. Windows only. Renders a `.wxs` and passes the program in as a preprocessor variable, because a bind path that resolves to nothing is silent |
| `dist-apple` | `mcpp.dist.apple` | 2026.9.11.2 (macOS), 2026.9.12.3 (iOS) | the base macOS install (`ditto`, and `codesign` only when an identity is given). macOS: `Contents/`-shaped, as always. iOS (`aarch64-ios-sim`, `aarch64-ios`): a flat bundle at the same call site -- no separate feature, no separate module -- with `MinimumOSVersion` from `mcpp::min_platform_version()` (#622 A11), `CFBundleSupportedPlatforms` read from `env == "sim"`, `UIDeviceFamily`, `LSRequiresIPhoneOS`, and a directory of flat PNGs listed under `CFBundleIcons` in place of macOS's single `.icns` file. Signing is skipped on the simulator row (`options::identity` is ignored, with a `mcpp::warning` naming why) and unchanged on the device row. The iOS row is measured end to end on `macos-15`: a real `mcpp build`, `mcpp pack --format app` and `mcpp run` against `aarch64-ios-sim`, through `xim:apple-simulator-tools`' `simctl-run`. **The macOS floor is one release higher than its siblings** and the reason is not this member: under 2026.9.11.1 `mcpp pack` staged before dispatching and let a staging failure fail the command, so on a Mach-O program -- which the built-in closure walk refuses, because it uses `LD_TRACE_LOADED_OBJECTS` and dyld answers that by running the program -- every dispatched format was unreachable, including one that reads no staged tree. 2026.9.11.2 makes staging a service to the provider |
| `dist-web` | `mcpp.dist.web` | 2026.9.12.3, the release that carries #622: the `.js` launcher and the staged stem family, `mcpp::deploy`, and the build program's host compiler under the Web row | nothing beyond mcpp: `wasm32-emscripten` only. Copies `${mcpp.stage_dir}/bin/` -- the `.js` launcher, the implicit `.wasm`, the `.data` when present, and every `mcpp::deploy`'d file, all of which #622 A5 and A4 already stage there -- to `<out_dir>/web/`, dropping the `bin/` prefix a browser has no use for, and writes an `index.html` rendered from a project template or a built-in default that loads the script with a plain `<script src>`. **POSIX hosts only for now**: each file is copied with one `cp SRC DST` action (argv only, no shell), and `cp` does not exist on Windows; a portable copier is future work this member does not need yet |
| `dist-apk` | `mcpp.dist.apk` | 2026.9.12.3, the release that carries #622's engine additions (`kind = "app"`, `mcpp::deploy`, `mcpp::min_platform_version`) | `xim:android-build-tools`, `xim:android-platform` (versioned by API level, read back for `targetSdkVersion`), `xim:jdk-temurin` (`javac`/`jar`; `android-build-tools`' own runtime dependency provisions a JDK for its OWN wrappers only), `xim:android-debug-keystore`, all on the `cfg(env = "android")` axis. Generates `AndroidManifest.xml` and signs with the published Android debug key by default. Level 0 needs no Java (`hasCode="false"`, `android.app.NativeActivity`); `options::java_sources` adds `javac` + `d8` and a real `<activity>`. Android only -- an `app` target is a shared object on this row (#622 A3), and this member reads its native library from the staged tree and whatever `mcpp::deploy` placed beside the ordinary build's link output, because Android's own closure stages neither the dependency set nor the deployed files (see `dist/apk.cppm`'s header). CI packages both level 0 and level 1 and checks the archive (`libc++_shared.so` bundled only when the closure's `NEEDED` entries require it, `mcpp::deploy`'d files under `assets/`); the runner has no emulator or device, so the two rows that actually run were measured locally on 2026-09-12, through `adb-run`, against a KVM-accelerated x86_64 emulator and a physical arm64-v8a phone, both printing `1-2-3` and exiting 0 |
| `dist-web` | `mcpp.dist.web` | 2026.9.13.1, the release that carries `${mcpp.self}` and `mcpp stage`'s argument shape as an engine contract (`stage --verify content --output <dst> <src>`) -- what lets this member's copy run on every host mcpp does, Windows included, in place of the `cp` this member used through 0.8.0 | nothing beyond mcpp: `wasm32-emscripten` only. Copies `${mcpp.stage_dir}/bin/` -- the `.js` launcher, the implicit `.wasm`, the `.data` when present, and every `mcpp::deploy`'d file, all of which #622 A5 and A4 already stage there -- to `<out_dir>/web/`, dropping the `bin/` prefix a browser has no use for, and writes an `index.html` rendered from a project template or a built-in default that loads the script with a plain `<script src>`. Each staged file and the rendered page are copied with `${mcpp.self} stage --verify content --output <dst> <src>`, the same copier every `stage_file` edge in `build.ninja` already runs -- no host-specific copy tool, no plan-time `create_directories` (`stage` creates the destination's parent), and a second `mcpp pack --format web` with nothing changed copies nothing |
| `dist-apk` | `mcpp.dist.apk` | 2026.9.13.1, raised alongside `dist-web` in the same 0.9.0 release: this member's own manifest-template and Java-array changes ask nothing new of the engine, but this collection publishes one package at one version, and this is the release CI verifies it under from here on | `xim:android-build-tools`, `xim:android-platform` (versioned by API level, read back for `targetSdkVersion`), `xim:jdk-temurin` (`javac`/`jar`; `android-build-tools`' own runtime dependency provisions a JDK for its OWN wrappers only), `xim:android-debug-keystore`, all on the `cfg(env = "android")` axis. Generates `AndroidManifest.xml` and signs with the published Android debug key by default. Level 0 needs no Java (`hasCode="false"`, `android.app.NativeActivity`); `options::java_sources` adds `javac` + `d8` and a real `<activity>`. `options::manifest_template` renders a project manifest with six tokens substituted verbatim; `{{application_id}}` and `{{activity}}` are required always and `{{lib_name}}` at level 0, each refused by name at plan time when missing (naming `assets/mcpp-run.json`, which `adb-run` reads them from too) or when the template names an unknown token; empty renders 0.8.0's manifest byte-identically. `options::java_sources` is an array: one `javac` over every root's `.java` files and one `d8` over the result, so a project's own sources and a path dependency's join without being merged into one directory first, and `rerun_if_changed_glob` is declared only for a root under `mcpp::manifest_dir()` -- a dependency root's files are already inputs of the `javac` action and its version is already in the build's fingerprint. Android only -- an `app` target is a shared object on this row (#622 A3), and this member reads its native library from the staged tree and whatever `mcpp::deploy` placed beside the ordinary build's link output, because Android's own closure stages neither the dependency set nor the deployed files (see `dist/apk.cppm`'s header). CI packages both level 0 and level 1 and checks the archive (`libc++_shared.so` bundled only when the closure's `NEEDED` entries require it, `mcpp::deploy`'d files under `assets/`); the runner has no emulator or device, so the two rows that actually run were measured locally on 2026-09-12, through `adb-run`, against a KVM-accelerated x86_64 emulator and a physical arm64-v8a phone, both printing `1-2-3` and exiting 0 |

### Each rule brings its own environment

Expand Down
Loading
Loading