@otalan/cli 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to `@otalan/cli` will be documented in this file.
4
4
 
5
+ ## 1.2.0 - 2026-05-08
6
+
7
+ ### Changed
8
+
9
+ - Switch `otalan publish` to the direct-upload release contract: create JSON upload metadata, upload the ZIP to the returned signed URL, complete the ingest, then poll validation.
10
+ - Stream the local ZIP through Bun's disk-backed file body during signed uploads instead of loading the full archive into memory.
11
+ - Send the full generated Otalan Expo satellite manifest as `expoManifest` during publish instead of only raw Expo config.
12
+ - Use the Expo `runtimeVersion` as the release `nativeVersion` sent to the API, matching the current Expo update matching contract.
13
+ - Use the release bundle `publishedAt` timestamp for bundle lists, status summaries, rollback prompts, and published bundle ID hints.
14
+
5
15
  ## 1.1.1 - 2026-05-07
6
16
 
7
17
  ### Changed
package/README.md CHANGED
@@ -105,7 +105,7 @@ otalan bundle --target expo --platform ios --bundle-id 1.0.5
105
105
  otalan publish --channel production
106
106
  ```
107
107
 
108
- `otalan bundle --target expo` runs `bunx expo export` itself, exports into a temporary project-local `.otalan/expo-export-*` folder, packages the exported JS bundle and assets, and stores the resolved Expo config in the Otalan manifest for publish. You do not need to create a `dist/` or `www/` folder before running it.
108
+ `otalan bundle --target expo` runs `bunx expo export` itself, exports into a temporary project-local `.otalan/expo-export-*` folder, packages the exported JS bundle and assets, and stores the generated Otalan satellite manifest for publish. You do not need to create a `dist/` or `www/` folder before running it.
109
109
  `otalan publish` waits for server-side validation to finish before it returns.
110
110
 
111
111
  ## CI/CD Usage
@@ -222,7 +222,7 @@ Example project config:
222
222
  }
223
223
  ```
224
224
 
225
- `otalan.config.json` only links the repo to an Otalan project/app. Bundle and release targeting data such as `target`, `platform`, `nativeVersion`, and `bundleId` live in `.otalan/bundle/manifest.json`.
225
+ `otalan.config.json` only links the repo to an Otalan project/app. Bundle and release targeting data such as `target`, `platform`, `nativeVersion`, `runtimeVersion`, and `bundleId` live in `.otalan/bundle/manifest.json`.
226
226
 
227
227
  ## Command Reference
228
228
 
@@ -335,7 +335,7 @@ Current behavior:
335
335
  - pass `--input-dir <path>` to package a different Capacitor web output folder
336
336
  - Expo runs `bunx expo export --platform <platform>` into a temporary project-local `.otalan/expo-export-*` folder
337
337
  - Expo does not require a prebuilt `dist/` or `www/` folder
338
- - Expo stores the resolved Expo app config in `.otalan/bundle/manifest.json` so publish can forward it for `extra.expoClient`
338
+ - Expo stores the generated Otalan satellite manifest in `.otalan/bundle/manifest.json`, including `launchAsset`, `assets`, `runtimeVersion`, `bundleId`, and `expoConfig`
339
339
  - both outputs produce a ZIP plus `manifest.json`
340
340
  - `--platform` is required so the CLI exports the selected platform and resolves the correct native/runtime version
341
341
 
@@ -346,6 +346,7 @@ Native version defaults:
346
346
  - Capacitor Android reads `versionName` from `android/app/build.gradle` or `build.gradle.kts`
347
347
  - Expo reads the selected platform version from Expo config and falls back to the top-level Expo `version`
348
348
  - Expo runtimeVersion reads `--runtime-version`, Expo export metadata, or Expo config runtimeVersion policies/strings; if none are present, the CLI falls back to the resolved native version
349
+ - Expo publishes use `runtimeVersion` as the Otalan release `nativeVersion` because Expo update checks send `expo-runtime-version`
349
350
  - `--native-version` overrides auto-detection
350
351
 
351
352
  For Expo projects, the recommended app config is:
@@ -400,7 +401,7 @@ otalan bundle --target expo --platform ios --bundle-from-package
400
401
 
401
402
  Publishes the current bundle output with rollout metadata.
402
403
 
403
- `otalan publish` uses the `bundleId`, `platform`, and `nativeVersion` already stored in `.otalan/bundle/manifest.json`. To release `1.0.5`, set it when you run `otalan bundle --bundle-id 1.0.5`.
404
+ `otalan publish` uses the `bundleId`, `platform`, and release version stored in `.otalan/bundle/manifest.json`. Capacitor uses `nativeVersion`; Expo uses `runtimeVersion`. To release `1.0.5`, set it when you run `otalan bundle --bundle-id 1.0.5`.
404
405
 
405
406
  Current behavior:
406
407
 
@@ -412,7 +413,8 @@ Current behavior:
412
413
  - `--rollout-percent` accepts an integer from `0` to `100`
413
414
  - `--optional` marks the update as non-mandatory
414
415
  - `--release-notes` attaches release notes to the published bundle
415
- - Expo publish forwards the stored Expo app config when present
416
+ - Expo publish forwards the full generated Otalan satellite manifest when present
417
+ - Expo publish sends `runtimeVersion` as the API `nativeVersion` and normalizes the serialized `expoManifest.nativeVersion` to the same value for server validation
416
418
  - Otalan validates the release ZIP before the publish completes
417
419
 
418
420
  Default flow:
@@ -433,7 +435,14 @@ Optional update:
433
435
  otalan publish --channel production --optional
434
436
  ```
435
437
 
436
- This uses `POST /v1/releases/create` and waits for `GET /v1/releases/ingests/:id` to reach `ready` before returning success.
438
+ This uses the direct-upload release flow:
439
+
440
+ 1. `POST /v1/releases/create` with JSON metadata for the release and local ZIP, including `expoManifest` for Expo bundles
441
+ 2. `PUT` the ZIP bytes directly to the returned `uploadUrl` with the exact returned `Content-Type`
442
+ 3. `POST /v1/releases/ingests/:id/complete`
443
+ 4. poll `GET /v1/releases/ingests/:id` until the ingest reaches `ready` or `failed`
444
+
445
+ The ZIP is opened as a disk-backed `Bun.file` and passed directly to the signed `PUT`; `otalan publish` does not load the full archive into memory first.
437
446
 
438
447
  If validation fails, `otalan publish` exits non-zero and prints the ingest failure reason when the API provides one. This makes the command safe to use directly in CI/CD pipelines.
439
448
 
@@ -441,6 +450,8 @@ If validation fails, `otalan publish` exits non-zero and prints the ingest failu
441
450
 
442
451
  Lists remote bundles for the current app so you can choose a bundle for rollback or rollout operations.
443
452
 
453
+ Remote bundle tables display the API `publishedAt` timestamp, not the bundle row `createdAt` timestamp.
454
+
444
455
  Default resolution order:
445
456
 
446
457
  1. `--native-version`
@@ -466,6 +477,8 @@ otalan rollback --bundle-id 1.0.0-web.1 --platform ios --channel production
466
477
 
467
478
  Shows the active bundle for the selected release tuple.
468
479
 
480
+ The active bundle summary displays `publishedAt` as `Published at`.
481
+
469
482
  `status` also uses the same native-version default order as `bundles`.
470
483
 
471
484
  ```bash
@@ -487,7 +500,7 @@ otalan status --platform ios --channel production
487
500
  }
488
501
  ```
489
502
 
490
- ### Expo Manifest
503
+ ### Expo Satellite Manifest
491
504
 
492
505
  ```json
493
506
  {
@@ -510,6 +523,8 @@ otalan status --platform ios --channel production
510
523
  }
511
524
  ```
512
525
 
526
+ For Expo publishes, `otalan publish` serializes this file and sends it to `/v1/releases/create` as `expoManifest`.
527
+
513
528
  ## Maintainer Release Checklist
514
529
 
515
530
  Before publishing a public package release: