Bare standalone packaging — scripts/bare-standalone.cjs, make.cjs, hosts.cjs, prepare-pack.mjs (kernel sync, node_modules flatten, optional sshcrypto.node omit)
Release rolling / release (push) Failing after 1m32s
Release rolling / release (push) Failing after 1m32s
Entries + OTA — bin/bare-os-*.mjs + lib/bare-os-ota.mjs (pear-runtime, --no-updates / BARE_OS_OTA_DISABLE) Upgrade links on seeder/booter package.json Gitea rolling — .gitea/workflows/release-rolling.yml + scripts/gitea-rolling-release.sh (RELEASE_TOKEN) by-arch + pear-ci — scripts/pear-stage-by-arch.sh, ci/snapshot-*.json (PEAR_PRIMARY_KEY) pear run retired from npm/PM2/docs; see docs/BINARY-RELEASE.md
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# Binary releases (seeder + booter)
|
||||
|
||||
Host distribution is **Bare standalone binaries**, not `pear run` (removed in Pear v3).
|
||||
|
||||
## Artifacts
|
||||
|
||||
Gitea **`rolling`** release (every push to `main`, via `.gitea/workflows/release-rolling.yml`):
|
||||
|
||||
| Asset | Contents |
|
||||
|-------|----------|
|
||||
| `bare-os-seeder-<ver>-<host>.tar.gz` | `bare-os-seeder[.exe]` + `kernel/` |
|
||||
| `bare-os-booter-<ver>-<host>.tar.gz` | `bare-os-booter[.exe]` |
|
||||
| `by-arch-seeder.tar.gz` / `by-arch-booter.tar.gz` | Holepunch `by-arch/` trees for `pear install` / OTA |
|
||||
| `*.sha256` | Checksums |
|
||||
|
||||
Hosts (64-bit only): `linux-x64`, `linux-arm64`, `darwin-x64`, `darwin-arm64`, `win32-x64`, `win32-arm64`.
|
||||
|
||||
## Local build
|
||||
|
||||
```bash
|
||||
npm ci
|
||||
npm run maintainer:kernel-image # seeder needs current kernel/
|
||||
npm run make:seeder:linux-x64 # or: npm run make
|
||||
DRY_RUN=1 SKIP_PEAR_STAGE=1 bash scripts/gitea-rolling-release.sh
|
||||
```
|
||||
|
||||
Outputs under `out/bare-os-<product>-<host>/`.
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
# From a release tarball
|
||||
tar -xzf bare-os-seeder-0.1.0-linux-x64.tar.gz
|
||||
./bare-os-seeder --no-updates # disable OTA for this run
|
||||
|
||||
tar -xzf bare-os-booter-0.1.0-linux-x64.tar.gz
|
||||
./bare-os-booter --no-updates
|
||||
```
|
||||
|
||||
Dev from a git checkout (no packing):
|
||||
|
||||
```bash
|
||||
npm run os:seeder # bare packages/bare-os-seeder/index.js
|
||||
npm run os:booter
|
||||
# or bin entries with OTA wrapper:
|
||||
npm run os:seeder:bin
|
||||
npm run os:booter:bin
|
||||
```
|
||||
|
||||
## Pear install + OTA
|
||||
|
||||
Upgrade links (also `upgrade` in each package.json):
|
||||
|
||||
- Seeder: `pear://1ycyj65xxgn6c5cirhtnm8aokkrpe9dzibriszyfkmfggc3opjzy`
|
||||
- Booter: `pear://khtauzttriz8dpgrphj79rfy98iwoatqm59fnogtsdqk5f1kg6ao`
|
||||
|
||||
```bash
|
||||
pear install pear://1ycyj65xxgn6c5cirhtnm8aokkrpe9dzibriszyfkmfggc3opjzy
|
||||
pear install pear://khtauzttriz8dpgrphj79rfy98iwoatqm59fnogtsdqk5f1kg6ao
|
||||
```
|
||||
|
||||
Packaged binaries embed **`pear-runtime`**. Disable with `--no-updates` or `BARE_OS_OTA_DISABLE=1`.
|
||||
|
||||
CI stages `by-arch/` with **`pear-ci`** using secret **`PEAR_PRIMARY_KEY`** (64-char hex). Snapshots live in `ci/snapshot-seeder.json` and `ci/snapshot-booter.json`.
|
||||
|
||||
## Secrets
|
||||
|
||||
| Secret | Role |
|
||||
|--------|------|
|
||||
| `RELEASE_TOKEN` | Gitea release write for tag `rolling` |
|
||||
| `PEAR_PRIMARY_KEY` | pear-ci Corestore identity |
|
||||
| `GITEA_URL` | Optional forge base URL |
|
||||
|
||||
## Related
|
||||
|
||||
- Legacy channel notes: [PEAR-RUN.md](PEAR-RUN.md)
|
||||
- Guest Hyperdrive OTA / updater bridges: [deployment/OTA_AND_BUNDLES.md](deployment/OTA_AND_BUNDLES.md)
|
||||
+20
-103
@@ -1,123 +1,40 @@
|
||||
# Pear channels (staged and released)
|
||||
# Pear channels (legacy notes)
|
||||
|
||||
Commands were run from this repo with Pear CLI. Use these links with `pear run`. For day-to-day clone and npm workflow, see the [user manual](../users-manual/README.md) and [handbook ch.7](../handbook/07-operations-and-development.md).
|
||||
> **Host apps are no longer run with `pear run`.** Pear v3 removed that command.
|
||||
> Supported host path: **Bare standalone binaries** and **`pear install`** — see **[BINARY-RELEASE.md](BINARY-RELEASE.md)**.
|
||||
|
||||
---
|
||||
|
||||
## On this page
|
||||
|
||||
- [bare-os-seeder](#bare-os-seeder)
|
||||
- [bare-os-booter](#bare-os-booter)
|
||||
- [Re-staging after code changes](#re-staging-after-code-changes)
|
||||
- [Booter host env (Pear / shell)](#booter-host-env-pear--shell)
|
||||
- [Pear / import.meta.url](#pear--importmetaurl-fixed-in-tree)
|
||||
- [Staging node_modules (monorepo)](#staging-node_modules-monorepo)
|
||||
- [pear run vs pear release](#pear-run-vs-pear-release)
|
||||
The links below remain the **`upgrade`** / OTA channels for seeder and booter binaries (`by-arch` layout staged in CI). Do not use them with `pear run`.
|
||||
|
||||
---
|
||||
|
||||
## bare-os-seeder
|
||||
|
||||
- **Channel** — `bare-os-seeder`
|
||||
- **Key (unversioned)** — `pear://1ycyj65xxgn6c5cirhtnm8aokkrpe9dzibriszyfkmfggc3opjzy`
|
||||
- **Released length** — `4955` (updates whenever you run `pear release bare-os-seeder` again)
|
||||
- **Versioned link** — `pear://0.4955.1ycyj65xxgn6c5cirhtnm8aokkrpe9dzibriszyfkmfggc3opjzy`
|
||||
|
||||
```bash
|
||||
pear run pear://1ycyj65xxgn6c5cirhtnm8aokkrpe9dzibriszyfkmfggc3opjzy
|
||||
# or
|
||||
pear run pear://0.4955.1ycyj65xxgn6c5cirhtnm8aokkrpe9dzibriszyfkmfggc3opjzy
|
||||
```
|
||||
|
||||
**Seeder Pear bundle:** [`package.json`](packages/bare-os-seeder/package.json) lists **`kernel`** under **`pear.stage.include`** (the key Pear’s stager reads; some docs label it “includes”) because the tree is staged with **`fs`** APIs only (not **`import`**). Without it, **`pear run pear://…`** fails with **`kernel directory missing`** under the Pear swap path when using **`pear stage --compact`**. After syncing **`kernel/`** into **`packages/bare-os-seeder/kernel/`**, run **`pear stage bare-os-seeder`** again and **`pear release`**.
|
||||
- **Upgrade / install** — `pear://1ycyj65xxgn6c5cirhtnm8aokkrpe9dzibriszyfkmfggc3opjzy`
|
||||
- **Install** — `pear install pear://1ycyj65xxgn6c5cirhtnm8aokkrpe9dzibriszyfkmfggc3opjzy`
|
||||
- **Tarball** — `bare-os-seeder-<ver>-<host>.tar.gz` (includes `kernel/`)
|
||||
|
||||
## bare-os-booter
|
||||
|
||||
- **Channel** — `bare-os-booter`
|
||||
- **Key (unversioned)** — `pear://khtauzttriz8dpgrphj79rfy98iwoatqm59fnogtsdqk5f1kg6ao`
|
||||
- **Released length** — `27411` (updates whenever you run `pear release bare-os-booter` again)
|
||||
- **Versioned link** — `pear://0.27411.khtauzttriz8dpgrphj79rfy98iwoatqm59fnogtsdqk5f1kg6ao`
|
||||
|
||||
```bash
|
||||
pear run pear://khtauzttriz8dpgrphj79rfy98iwoatqm59fnogtsdqk5f1kg6ao
|
||||
# or
|
||||
pear run pear://0.27411.khtauzttriz8dpgrphj79rfy98iwoatqm59fnogtsdqk5f1kg6ao
|
||||
```
|
||||
|
||||
The booter entrypoint avoids **static** **`node:…`** imports (Bare cannot resolve them). Hashing uses **`bare-crypto`** (`createHash`); **`fs`** / **`path`** / **`url`** go through `**package.json` `imports**` maps to **`bare-fs`**, **`bare-path`**, **`bare-url`**. Dynamic **`import('node:readline')`** / **`import('node:console')`** stay in try/catch fallbacks only. Signed boot manifest verification uses **`#bare-os-boot-manifest-sig`**: under the **`bare`** condition Pear loads **`bare-os-boot-manifest-sig.bare.js`** plus a small **`.cjs`** bridge (no **`node:module`**); Node / **`brittle-node`** resolves **`default`** to **`bare-os-boot-manifest-sig.node.js`** with lazy **`require`** + **`createRequire`**. Optional **`BARE_OS_BIN_WORKER_OFFLOAD`** loads **`bare-os-bin-offload-worker.cjs`** via **dynamic** `**import('bare-module')`** and **`createRequire(import.meta.url)`** from [`kernel-runner.js`](packages/bare-os-booter/lib/kernel-runner.js) (never static **`node:module`**, which breaks **`pear://`** bundles).
|
||||
|
||||
**`ctx.bare` manifest under Pear:** [`bare-os-ctx-bare.js`](packages/bare-os-booter/lib/bare-os-ctx-bare.js) loads **`bare-module-manifest.json`** from disk on **`file:`** dev trees, but under **`pear://`** it uses the embedded module **[`bare-module-manifest.data.mjs`](packages/bare-os-booter/lib/bare-module-manifest.data.mjs)** (regenerated by **`npm run sync:bare-manifest`**). **`bare-fs`** passes **`URL`** objects through **`bare-url.fileURLToPath`**, which rejects non-**`file:`** schemes, so **`readFileSync(new URL('pear:…/bare-module-manifest.json'))`** is not reliable; the generated **`.mjs`** keeps the manifest in Pear’s traced module graph. Run **`npm run sync:bare-manifest`** (or at least **`node scripts/generate-bare-module-manifest-data.mjs`**) before **`pear stage`** whenever the JSON changes.
|
||||
- **Upgrade / install** — `pear://khtauzttriz8dpgrphj79rfy98iwoatqm59fnogtsdqk5f1kg6ao`
|
||||
- **Install** — `pear install pear://khtauzttriz8dpgrphj79rfy98iwoatqm59fnogtsdqk5f1kg6ao`
|
||||
- **Tarball** — `bare-os-booter-<ver>-<host>.tar.gz`
|
||||
|
||||
## Re-staging after code changes
|
||||
|
||||
From the **repo root**, when **`bare-module-manifest.json`** or the Holepunch catalog changed:
|
||||
|
||||
```bash
|
||||
npm run sync:bare-manifest
|
||||
npm run maintainer:kernel-image
|
||||
npm run make
|
||||
bash scripts/pear-stage-by-arch.sh
|
||||
# or full rolling publish:
|
||||
npm run release:rolling
|
||||
```
|
||||
|
||||
Then from the package directory:
|
||||
Legacy JS-tree `scripts/stage-release.sh` is deprecated.
|
||||
|
||||
```bash
|
||||
cd packages/bare-os-seeder
|
||||
pear stage bare-os-seeder --no-ask
|
||||
pear release bare-os-seeder
|
||||
## Booter host env (OTA / shell)
|
||||
|
||||
cd ../bare-os-booter
|
||||
pear stage bare-os-booter --no-ask
|
||||
pear release bare-os-booter
|
||||
```
|
||||
The booter still copies **`BARE_OS_*`** keys into the guest session. Host OTA for the **binary** uses embedded **`pear-runtime`** against `package.json` **`upgrade`**. Guest image OTA / reload bridges (`BARE_OS_PEAR_*`, `ctx.bareOsRequestPearReload`, updater delegate) are unchanged — see [OTA_AND_BUNDLES.md](deployment/OTA_AND_BUNDLES.md).
|
||||
|
||||
`pear stage --json` prints the latest `verlink` in the `addendum` line.
|
||||
## Staging node_modules (monorepo)
|
||||
|
||||
## Booter host env (Pear / shell)
|
||||
|
||||
The booter copies many **`BARE_OS_*`** keys into the session (see [developer-guide/02-the-context-object.md](../developer-guide/02-the-context-object.md) and [environment-and-posix-appendix.md](reference/environment-and-posix-appendix.md)). Notable additions for Pear hosts wiring **OTA** or **HTTP**:
|
||||
|
||||
- **`BARE_OS_PEAR_CHANNEL`**, **`BARE_OS_PEAR_RELEASE`**, **`PEAR_CHANNEL`** — mirrored into **`/run/bare-os/boot.json`**; pair with **`ctx.bareOsRequestPearReload(opts?)`** (async **`{ requested, hint, env }`**). With **`{ persistRequest: true }`**, the booter writes **`~/.bare-os/pear-reload.request`** and may emit **`process.emit('bare-os:pear-reload', …)`** on Node so a **`pear-runtime-updater`**-style host can swap the runtime without blocking the guest. Reloading the Pear **app** picks up a new **`bare-module-manifest.data.mjs`** only after you **re-stage and re-release the booter** (or run **`pear run --dev .`** with a fresh **`sync:bare-manifest`**); changing **`/lib/bare/bare-module-manifest.json`** on the system drive alone does not alter the Pear-embedded **`ctx.bare`** import list.
|
||||
- **`BARE_OS_HTTP_ALLOWLIST`**, **`BARE_OS_HTTP_DENYLIST`** — restrict delegated `**curl`/`wget**` when global **`fetch`** exists.
|
||||
- **`BARE_OS_TLS_PIN_SHA256`** — forwarded as **`init.bareOsCurlTls.pinnedSha256`** for host **`httpFetch`** implementations that implement pinning.
|
||||
- **`BARE_OS_BARE_MODULES`**, **`BARE_OS_BARE_DRIVE_BUNDLES`** — control **`ctx.bare`** (host dynamic imports + optional trusted bundles from **`/lib/bare/`** on the system drive). See **`man 7 bare-os-ctx-bare`** (after seeding) and [developer-guide/12-bare-modules-and-pear-ecosystem.md](../developer-guide/12-bare-modules-and-pear-ecosystem.md).
|
||||
- **`ctx.bareOsRequestMirror({ key?, label? })`**, **`ctx.bareOsExportPersonalSnapshot({ label? })`**, **`ctx.bareOsPearIpcEmit(channel, payload)`** — policy-gated host bridges (return hints / boolean success); on Node the booter emits **`bare-os:mirror-request`**, **`bare-os:export-personal-snapshot`**, and **`bare-os:pear-ipc`** for the embedding app to attach real mirror keys, run **corestore-snapshot**-style export, or forward **pear-ipc**-shaped payloads to the host UI.
|
||||
- **`BARE_OS_PEAR_UPDATER_MODULE`** — dynamic ESM loaded by **`ctx.bareOsPearUpdaterDelegate()`**; must stay Bare-compatible (no static **`node:`** imports). Copy **[`docs/examples/pear-updater-delegate-minimal.mjs`](docs/examples/pear-updater-delegate-minimal.mjs)** as a starting point; CI’s **`verify-pear-no-static-node-import`** also scans this example.
|
||||
|
||||
Re-seed **`/lib/bare`** after changing the manifest or bundle list: **`npm run build -w bare-os-bare-libs`** (also runs from the seeder when started via `node` / `file:` URL).
|
||||
|
||||
### pear-ipc alignment (embedded Pear)
|
||||
|
||||
Guest code should treat **`ctx.bareOsPearIpcEmit`** as a **thin forwarder**: the host decides how messages map to **[pear-ipc](https://github.com/holepunchto/pear-ipc)** (or your channel bridge). Use a small, versioned **`payload`** shape per **`channel`** (e.g. **`{ v: 1, type: '…', … }`**) and document both sides in your app; Bare OS does not ship a second IPC stack inside the image for this—duplex **`bareOsIpc`** remains the in-session FIFO/RPC surface (see **`duplexJsonRoundTrip`** in [developer-guide/02-the-context-object.md](../developer-guide/02-the-context-object.md)).
|
||||
|
||||
### Conservative pear-ipc advertisement
|
||||
|
||||
**`/proc/bare_os_features`** exposes **`pearIpcConservativeAdvertisement`** (**schema 2**) with **channel names only** — it does **not** assert that the embedding Pear host registered matching **`pear-ipc`** handlers. This stays aligned with conservative **`pear-runtime`** defaults: treat proc JSON as **hints**, verify host wiring in your app, then rely on **`ctx.bareOsPearIpcEmit`**.
|
||||
|
||||
## Pear / `import.meta.url` (fixed in tree)
|
||||
|
||||
Under `pear run`, `import.meta.url` is `pear://…`. Node-style `fileURLToPath(import.meta.url)` goes through `bare-url` and throws `INVALID_URL_SCHEME`. This repo follows the same idea as [pear-rti](https://github.com/holepunchto/pear-rti) (`holepunchto_repos/pear-rti/index.js`): use `global.Pear.constructor.RTI.mount`, then `Pear.config.swapDir`, then `process.cwd()`.
|
||||
|
||||
Shared helpers:
|
||||
|
||||
- Seeder: [packages/bare-os-seeder/lib/paths.js](packages/bare-os-seeder/lib/paths.js)
|
||||
- Booter: [packages/bare-os-booter/lib/paths.js](packages/bare-os-booter/lib/paths.js)
|
||||
|
||||
Kernel for Pear is vendored at `packages/bare-os-seeder/kernel/` (sync from repo `kernel/` when it changes).
|
||||
|
||||
## Staging `node_modules` (monorepo)
|
||||
|
||||
Hoisted deps live at the repo root. For `pear stage` to include runtime modules, use a symlink `packages/bare-os-seeder/node_modules` → `../../node_modules` and a **real directory copy** of `packages/bare-os-protocol` at `node_modules/bare-os-protocol` (workspace symlinks outside the package are not bundled correctly). The booter’s **`pear.stage.include`** is **`node_modules`** (the package-local tree built by **`scripts/ensure-pear-node-modules.mjs`**) so staged paths match Node/Bare resolution (`**node_modules/<pkg>**`). Including only **`../../node_modules`** mirrored those packages under **`../../node_modules/...`** keys, so **`require('bare-node-net')`** from **`bare-ssh2`** failed with **`MODULE_NOT_FOUND`**. **Naming (Holepunch):** **`bare-net`** is the [Bare TCP stack on npm](https://www.npmjs.com/package/bare-net); **`bare-node-net`** is the Node **`net`** API shim that depends on **`bare-net`** (see **`pear/init/templates/node-compat`** in holepunch-repos). **`bare-net`** and `**bare-node-***` are **vendored** under **`packages/bare-os-openssh/vendor/bare-node-shims/`** (refresh with **`node scripts/vendor-bare-node-shims.mjs`**) and referenced from **`bare-os-booter`** via **`file:`** so **`git clone`** includes them without depending on registry tarballs for those names. Vendored **`bare-ssh2`** is still copied into **`packages/bare-os-booter/node_modules/bare-ssh2`** by that script (and **`scripts/stage-release.sh`**). Re-stage after dependency or path helper changes.
|
||||
|
||||
**Bare/Pear runtime:** seeder sources must not import **`node:…`** specifiers (e.g. **`node:child_process`** is unresolved in Bare). Use **`bare-subprocess`** for sync spawn (see [`packages/bare-os-seeder/lib/pear-multisig-hint.js`](packages/bare-os-seeder/lib/pear-multisig-hint.js) and **`BARE_OS_HYPER_MULTISIG_VERIFY`**) and prefer **`import … from 'url'`** over **`node:url`** so `package.json` **`imports`** maps resolve to **`bare-url`**.
|
||||
|
||||
## `pear run` vs `pear release`
|
||||
|
||||
**Host (booter/seeder packages):** After `pear stage`, run `pear release <channel>` on the **host** so `pear run pear://<key>` resolves to the new length. See the versioned links in the sections above.
|
||||
|
||||
**Guest (booted Bare OS shell):** Use **`/bin/pear`** instead — no host Pear CLI required:
|
||||
|
||||
```bash
|
||||
pear stage
|
||||
pear release .
|
||||
pear seed .
|
||||
```
|
||||
|
||||
Then distribute with **`appstore install <name> pear://0.<length>.<key> --yes`** and **`appstore launch <name>`**. Full steps: **[guides/guest-pear-and-appstore-workflow.md](guides/guest-pear-and-appstore-workflow.md)**.
|
||||
`scripts/prepare-pack.mjs` (and `ensure-pear-node-modules.mjs`) flatten workspace deps before `bare-pack`. Prefer that over manual Pear staging.
|
||||
|
||||
Reference in New Issue
Block a user