@otalan/cli 1.1.0 → 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,23 @@
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
+
15
+ ## 1.1.1 - 2026-05-07
16
+
17
+ ### Changed
18
+
19
+ - Remove unsupported target mentions from public documentation, CLI help, and package metadata.
20
+ - Document official support for Capacitor 7 and 8, and Expo SDK 54 and 55.
21
+
5
22
  ## 1.1.0 - 2026-05-07
6
23
 
7
24
  ### Added
@@ -13,7 +30,7 @@ All notable changes to `@otalan/cli` will be documented in this file.
13
30
  - Let `otalan login` reuse the saved API URL and keep the saved CI key from a masked prompt.
14
31
  - Export Expo bundles into a project-local `.otalan/expo-export-*` folder so Expo accepts the output path.
15
32
  - Fall back to the resolved native version when Expo runtimeVersion is not configured or present in export metadata.
16
- - Clarify Capacitor and Expo / React Native bundling behavior in CLI help and README.
33
+ - Clarify Capacitor and Expo bundling behavior in CLI help and README.
17
34
 
18
35
  ## 1.0.9 - 2026-05-06
19
36
 
@@ -87,7 +104,7 @@ Initial public release of the Otalan CLI.
87
104
  ### Added
88
105
 
89
106
  - Capacitor OTA bundle packaging from built web assets.
90
- - Expo / React Native OTA bundle packaging through `expo export`.
107
+ - Expo OTA bundle packaging through `expo export`.
91
108
  - Release publishing with rollout metadata and server-side validation polling.
92
109
  - Bundle listing, active bundle status, and rollback commands.
93
110
  - CI key login, project initialization, and API connectivity doctor checks.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # `@otalan/cli`
2
2
 
3
- Otalan CLI for bundling and publishing OTA update releases for Capacitor and Expo / React Native apps.
3
+ Otalan CLI for bundling and publishing OTA update releases for Capacitor and Expo apps.
4
4
 
5
5
  Website: [otalan.com](https://otalan.com)
6
6
 
@@ -21,6 +21,15 @@ The npm package ships a Bun-based CLI entrypoint, not standalone native binaries
21
21
  - Windows support is experimental until the CLI release flow is validated on Windows.
22
22
  - Native compile scripts exist for macOS, Linux, and Windows maintainers, but the compiled binaries are not included in the npm package.
23
23
 
24
+ ## App Framework Support
25
+
26
+ Officially supported app targets and versions:
27
+
28
+ - Capacitor 7 and 8 with `--target capacitor`
29
+ - Expo SDK 54 and 55 with `--target expo`
30
+
31
+ Other app targets and older framework versions may work, but they are not officially supported for the moment.
32
+
24
33
  ## Install
25
34
 
26
35
  Recommended:
@@ -70,7 +79,7 @@ otalan publish --channel production
70
79
  `otalan bundle --target capacitor` packages existing built web assets. By default it reads `dist/` first, then `www/`; pass `--input-dir <path>` if your build outputs somewhere else. Your app build must run first.
71
80
  `otalan publish` waits for server-side validation to finish before it returns.
72
81
 
73
- ### Expo / React Native
82
+ ### Expo
74
83
 
75
84
  1. Log in with your CI key:
76
85
 
@@ -96,7 +105,7 @@ otalan bundle --target expo --platform ios --bundle-id 1.0.5
96
105
  otalan publish --channel production
97
106
  ```
98
107
 
99
- `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.
100
109
  `otalan publish` waits for server-side validation to finish before it returns.
101
110
 
102
111
  ## CI/CD Usage
@@ -126,7 +135,7 @@ otalan publish --channel production
126
135
 
127
136
  Use your normal app build command before `otalan bundle`. The CLI then packages the built web output from `dist/` or `www/` by default; pass `--input-dir <path>` if your Capacitor web output uses another folder.
128
137
 
129
- ### CI/CD Example: Expo / React Native
138
+ ### CI/CD Example: Expo
130
139
 
131
140
  ```bash
132
141
  bun install --frozen-lockfile
@@ -137,7 +146,7 @@ otalan bundle --target expo --platform ios --bundle-from-package
137
146
  otalan publish --channel production
138
147
  ```
139
148
 
140
- This runs `bunx expo export` through the CLI, using a temporary project-local `.otalan/expo-export-*` folder, packages the exported OTA assets, and publishes the resulting bundle through Otalan's validation pipeline. Do not add a separate web build step just to create `dist/` or `www/` for Expo / React Native.
149
+ This runs `bunx expo export` through the CLI, using a temporary project-local `.otalan/expo-export-*` folder, packages the exported OTA assets, and publishes the resulting bundle through Otalan's validation pipeline. Do not add a separate web build step just to create `dist/` or `www/` for Expo.
141
150
 
142
151
  ### GitHub Actions Example
143
152
 
@@ -173,7 +182,7 @@ jobs:
173
182
  Adjust the build step and bundle target for your app:
174
183
 
175
184
  - Capacitor: keep your web build step and use `--target capacitor`
176
- - Expo / React Native: remove the web build step if not needed and use `--target expo`
185
+ - Expo: remove the web build step if not needed and use `--target expo`
177
186
 
178
187
  ## What It Does
179
188
 
@@ -181,7 +190,7 @@ Adjust the build step and bundle target for your app:
181
190
  - checks API connectivity and CI key context
182
191
  - generates CI and OTA key material locally for dashboard import
183
192
  - links the current repo to an Otalan app
184
- - bundles Capacitor or Expo / React Native OTA output
193
+ - bundles Capacitor or Expo OTA output
185
194
  - publishes a bundle with rollout metadata
186
195
  - lists published bundles
187
196
  - rolls back to an older bundle
@@ -213,7 +222,7 @@ Example project config:
213
222
  }
214
223
  ```
215
224
 
216
- `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`.
217
226
 
218
227
  ## Command Reference
219
228
 
@@ -311,7 +320,7 @@ otalan bundle --target capacitor --platform ios
311
320
  otalan bundle --target capacitor --platform ios --input-dir build
312
321
  ```
313
322
 
314
- Expo / React Native:
323
+ Expo:
315
324
 
316
325
  ```bash
317
326
  otalan bundle --target expo --platform ios
@@ -319,12 +328,14 @@ otalan bundle --target expo --platform ios
319
328
 
320
329
  Current behavior:
321
330
 
331
+ - Official support covers Capacitor 7 and 8, and Expo SDK 54 and 55
332
+ - Other app targets and older framework versions may work, but they are not officially supported for the moment
322
333
  - Capacitor packages prebuilt web assets; it does not run your app build command
323
334
  - without `--input-dir`, Capacitor checks `dist/` first and then `www/`
324
335
  - pass `--input-dir <path>` to package a different Capacitor web output folder
325
- - Expo / React Native runs `bunx expo export --platform <platform>` into a temporary project-local `.otalan/expo-export-*` folder
326
- - Expo / React Native does not require a prebuilt `dist/` or `www/` folder
327
- - Expo stores the resolved Expo app config in `.otalan/bundle/manifest.json` so publish can forward it for `extra.expoClient`
336
+ - Expo runs `bunx expo export --platform <platform>` into a temporary project-local `.otalan/expo-export-*` folder
337
+ - Expo does not require a prebuilt `dist/` or `www/` folder
338
+ - Expo stores the generated Otalan satellite manifest in `.otalan/bundle/manifest.json`, including `launchAsset`, `assets`, `runtimeVersion`, `bundleId`, and `expoConfig`
328
339
  - both outputs produce a ZIP plus `manifest.json`
329
340
  - `--platform` is required so the CLI exports the selected platform and resolves the correct native/runtime version
330
341
 
@@ -335,6 +346,7 @@ Native version defaults:
335
346
  - Capacitor Android reads `versionName` from `android/app/build.gradle` or `build.gradle.kts`
336
347
  - Expo reads the selected platform version from Expo config and falls back to the top-level Expo `version`
337
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`
338
350
  - `--native-version` overrides auto-detection
339
351
 
340
352
  For Expo projects, the recommended app config is:
@@ -389,7 +401,7 @@ otalan bundle --target expo --platform ios --bundle-from-package
389
401
 
390
402
  Publishes the current bundle output with rollout metadata.
391
403
 
392
- `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`.
393
405
 
394
406
  Current behavior:
395
407
 
@@ -401,7 +413,8 @@ Current behavior:
401
413
  - `--rollout-percent` accepts an integer from `0` to `100`
402
414
  - `--optional` marks the update as non-mandatory
403
415
  - `--release-notes` attaches release notes to the published bundle
404
- - 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
405
418
  - Otalan validates the release ZIP before the publish completes
406
419
 
407
420
  Default flow:
@@ -422,7 +435,14 @@ Optional update:
422
435
  otalan publish --channel production --optional
423
436
  ```
424
437
 
425
- 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.
426
446
 
427
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.
428
448
 
@@ -430,6 +450,8 @@ If validation fails, `otalan publish` exits non-zero and prints the ingest failu
430
450
 
431
451
  Lists remote bundles for the current app so you can choose a bundle for rollback or rollout operations.
432
452
 
453
+ Remote bundle tables display the API `publishedAt` timestamp, not the bundle row `createdAt` timestamp.
454
+
433
455
  Default resolution order:
434
456
 
435
457
  1. `--native-version`
@@ -455,6 +477,8 @@ otalan rollback --bundle-id 1.0.0-web.1 --platform ios --channel production
455
477
 
456
478
  Shows the active bundle for the selected release tuple.
457
479
 
480
+ The active bundle summary displays `publishedAt` as `Published at`.
481
+
458
482
  `status` also uses the same native-version default order as `bundles`.
459
483
 
460
484
  ```bash
@@ -476,7 +500,7 @@ otalan status --platform ios --channel production
476
500
  }
477
501
  ```
478
502
 
479
- ### Expo Manifest
503
+ ### Expo Satellite Manifest
480
504
 
481
505
  ```json
482
506
  {
@@ -499,6 +523,8 @@ otalan status --platform ios --channel production
499
523
  }
500
524
  ```
501
525
 
526
+ For Expo publishes, `otalan publish` serializes this file and sends it to `/v1/releases/create` as `expoManifest`.
527
+
502
528
  ## Maintainer Release Checklist
503
529
 
504
530
  Before publishing a public package release:
@@ -521,7 +547,7 @@ bun pm pack --dry-run
521
547
  ## Notes
522
548
 
523
549
  - This is a Bun-based CLI published on npm.
524
- - Expo / React Native bundling uses `bunx expo ...`.
550
+ - Expo bundling uses `bunx expo ...`.
525
551
  - Default API URL is `https://api.otalan.com`.
526
552
  - Publishing, rollback, status, and `bundles` expect a CI key and an active app.
527
553
  - Release commands print the organization and project resolved from the CI key before continuing.