@fireota/cli 0.4.0 → 0.5.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/README.md +117 -117
- package/bin/fireota.mjs +527 -433
- package/lib/ci.mjs +53 -53
- package/lib/init.mjs +334 -334
- package/lib/project.mjs +78 -78
- package/lib/signing.mjs +48 -48
- package/package.json +40 -40
package/README.md
CHANGED
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="https://raw.githubusercontent.com/Sujay-Dynamisch/FireOTA/main/public/logo-mark.png" alt="FireOTA" width="96" />
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<h1 align="center">FireOTA CLI</h1>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
Build FireOTA update packages and publish React Native over-the-air releases from a terminal or CI.<br />
|
|
9
|
-
Works with <a href="https://www.npmjs.com/package/@fireota/react-native"><code>@fireota/react-native</code></a>.
|
|
10
|
-
</p>
|
|
11
|
-
|
|
12
|
-
<p align="center">
|
|
13
|
-
<a href="https://www.npmjs.com/package/@fireota/cli"><img alt="@fireota/cli" src="https://img.shields.io/npm/v/@fireota/cli?label=%40fireota%2Fcli" /></a>
|
|
14
|
-
<a href="https://www.npmjs.com/package/@fireota/react-native"><img alt="@fireota/react-native" src="https://img.shields.io/npm/v/@fireota/react-native?label=%40fireota%2Freact-native" /></a>
|
|
15
|
-
<img alt="license" src="https://img.shields.io/badge/license-MIT-blue" />
|
|
16
|
-
</p>
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
> **Beta (0.x).** Requires Node.js 18.17+.
|
|
21
|
-
|
|
22
|
-
## Setup
|
|
23
|
-
|
|
24
|
-
```sh
|
|
25
|
-
npm install --save-dev @fireota/cli
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Set two environment variables (an admin creates the API key in FireOTA → API keys):
|
|
29
|
-
|
|
30
|
-
```sh
|
|
31
|
-
FIREOTA_URL=https://ota.example.com
|
|
32
|
-
FIREOTA_API_KEY=fota_sk_live_...
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Scopes: `release.write` (create, upload), `release.publish` (publish, pause, roll back), `rollout.write` (change rollout). Check a key with `npx fireota whoami`.
|
|
36
|
-
|
|
37
|
-
Optional defaults: `FIREOTA_APP_ID`, `FIREOTA_CHANNEL`, `FIREOTA_RUNTIME`.
|
|
38
|
-
|
|
39
|
-
## Publish in one command
|
|
40
|
-
|
|
41
|
-
Run from your React Native project root:
|
|
42
|
-
|
|
43
|
-
```sh
|
|
44
|
-
npx fireota publish --app YOUR_APP_ID --platform all --runtime 1.3.0 \
|
|
45
|
-
--channel production --rollout 10 --message "Fix checkout crash"
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
This runs the React Native bundler, compiles Hermes bytecode when Hermes is enabled, packs the images next to the bundle, creates the update, uploads it to your Firebase Storage (checksum verified) and publishes it. `--platform all` builds Android and iOS and publishes them as one update group.
|
|
49
|
-
|
|
50
|
-
- **Updates are identified by their ID**, like Expo. `--version` is only an optional label (e.g. `1.3.1-hotfix`).
|
|
51
|
-
- `--runtime` must equal the runtime version of the store build that should receive the update. Bump it whenever native code changes.
|
|
52
|
-
- Retries are safe: the same inputs never create a duplicate update, and finished steps are skipped.
|
|
53
|
-
- `--json` prints a machine-readable result; the exit code is 1 on any error.
|
|
54
|
-
|
|
55
|
-
## Code signing (optional)
|
|
56
|
-
|
|
57
|
-
```sh
|
|
58
|
-
npx fireota signing generate --out ./fireota-keys # fireota-private.pem stays with you
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Paste `fireota-public.pem` into the dashboard (app → Code signing), pass the same public key to `FireOTA.configure({ codeSigningCertificate })`, and publish with `--private-key ./fireota-keys/fireota-private.pem` (in CI: the `FIREOTA_SIGNING_KEY` secret holding the PEM text, or `FIREOTA_SIGNING_KEY_PATH`). The signature covers the package's SHA-256 plus runtime and platform; the server and the app both reject updates that don't match.
|
|
62
|
-
|
|
63
|
-
## Commands
|
|
64
|
-
|
|
65
|
-
```text
|
|
66
|
-
fireota init [--app <appId>] [--server-url <url>] [--channel production] [--dry-run]
|
|
67
|
-
fireota publish --app <appId> --platform <android|ios|all> [--runtime <x.y.z>] --message "…"
|
|
68
|
-
[--channel production] [--rollout 10] [--version <label>] [--mandatory] [--native ">=1.4.0"]
|
|
69
|
-
[--file update.fota] [--private-key key.pem] [--json]
|
|
70
|
-
fireota bundle --platform <android|ios> [--entry index.js] [--out update.fota] [--hermes auto|on|off]
|
|
71
|
-
fireota whoami
|
|
72
|
-
fireota signing generate [--out ./fireota-keys]
|
|
73
|
-
fireota release create --app <appId> --platform <p> --runtime <r> [--message m] [--version v] [--channel c]
|
|
74
|
-
fireota release upload <releaseId> --file update.fota [--private-key key.pem]
|
|
75
|
-
fireota release publish <releaseId> [--rollout 100]
|
|
76
|
-
fireota release rollout <releaseId> --percentage <0-100>
|
|
77
|
-
fireota release pause <releaseId>
|
|
78
|
-
fireota release rollback <releaseId> --reason "…" [--target <releaseId>]
|
|
79
|
-
fireota releases [--app <appId>] [--json]
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## CI/CD
|
|
83
|
-
|
|
84
|
-
The same command works on every CI. Commit, branch and build number are detected automatically on GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins, Azure DevOps, CircleCI, Bitrise, Buildkite, Travis, TeamCity, Codemagic and AWS CodeBuild; anywhere else set `FIREOTA_GIT_SHA`, `FIREOTA_GIT_BRANCH` and `FIREOTA_BUILD_NUMBER`. Ready-made pipeline files for each tool are in the dashboard under **CI/CD**.
|
|
85
|
-
|
|
86
|
-
GitHub Actions:
|
|
87
|
-
|
|
88
|
-
```yaml
|
|
89
|
-
- run: npx fireota publish --app ${{ vars.FIREOTA_APP_ID }} --platform android --runtime 1.3.0 --channel beta --message "${{ github.event.head_commit.message }}"
|
|
90
|
-
env:
|
|
91
|
-
FIREOTA_URL: ${{ vars.FIREOTA_URL }}
|
|
92
|
-
FIREOTA_API_KEY: ${{ secrets.FIREOTA_API_KEY }}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Jenkins (declarative):
|
|
96
|
-
|
|
97
|
-
```groovy
|
|
98
|
-
environment {
|
|
99
|
-
FIREOTA_URL = 'https://ota.example.com'
|
|
100
|
-
FIREOTA_API_KEY = credentials('fireota-api-key')
|
|
101
|
-
}
|
|
102
|
-
steps {
|
|
103
|
-
sh 'npm ci && npx fireota publish --app "$APP_ID" --platform android --runtime 1.3.0 --message "$(git log -1 --pretty=%s)"'
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Bitbucket Pipelines:
|
|
108
|
-
|
|
109
|
-
```yaml
|
|
110
|
-
script:
|
|
111
|
-
- npm ci
|
|
112
|
-
- npx fireota publish --app "$FIREOTA_APP_ID" --platform android --runtime 1.3.0 --message "$(git log -1 --pretty=%s)"
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## License
|
|
116
|
-
|
|
117
|
-
MIT
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/Sujay-Dynamisch/FireOTA/main/public/logo-mark.png" alt="FireOTA" width="96" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">FireOTA CLI</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
Build FireOTA update packages and publish React Native over-the-air releases from a terminal or CI.<br />
|
|
9
|
+
Works with <a href="https://www.npmjs.com/package/@fireota/react-native"><code>@fireota/react-native</code></a>.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/@fireota/cli"><img alt="@fireota/cli" src="https://img.shields.io/npm/v/@fireota/cli?label=%40fireota%2Fcli" /></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/@fireota/react-native"><img alt="@fireota/react-native" src="https://img.shields.io/npm/v/@fireota/react-native?label=%40fireota%2Freact-native" /></a>
|
|
15
|
+
<img alt="license" src="https://img.shields.io/badge/license-MIT-blue" />
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
> **Beta (0.x).** Requires Node.js 18.17+.
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
npm install --save-dev @fireota/cli
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Set two environment variables (an admin creates the API key in FireOTA → API keys):
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
FIREOTA_URL=https://ota.example.com
|
|
32
|
+
FIREOTA_API_KEY=fota_sk_live_...
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Scopes: `release.write` (create, upload), `release.publish` (publish, pause, roll back), `rollout.write` (change rollout). Check a key with `npx fireota whoami`.
|
|
36
|
+
|
|
37
|
+
Optional defaults: `FIREOTA_APP_ID`, `FIREOTA_CHANNEL`, `FIREOTA_RUNTIME`.
|
|
38
|
+
|
|
39
|
+
## Publish in one command
|
|
40
|
+
|
|
41
|
+
Run from your React Native project root:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npx fireota publish --app YOUR_APP_ID --platform all --runtime 1.3.0 \
|
|
45
|
+
--channel production --rollout 10 --message "Fix checkout crash"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This runs the React Native bundler, compiles Hermes bytecode when Hermes is enabled, packs the images next to the bundle, creates the update, uploads it to your Firebase Storage (checksum verified) and publishes it. `--platform all` builds Android and iOS and publishes them as one update group.
|
|
49
|
+
|
|
50
|
+
- **Updates are identified by their ID**, like Expo. `--version` is only an optional label (e.g. `1.3.1-hotfix`).
|
|
51
|
+
- `--runtime` must equal the runtime version of the store build that should receive the update. Bump it whenever native code changes.
|
|
52
|
+
- Retries are safe: the same inputs never create a duplicate update, and finished steps are skipped.
|
|
53
|
+
- `--json` prints a machine-readable result; the exit code is 1 on any error.
|
|
54
|
+
|
|
55
|
+
## Code signing (optional)
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
npx fireota signing generate --out ./fireota-keys # fireota-private.pem stays with you
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Paste `fireota-public.pem` into the dashboard (app → Code signing), pass the same public key to `FireOTA.configure({ codeSigningCertificate })`, and publish with `--private-key ./fireota-keys/fireota-private.pem` (in CI: the `FIREOTA_SIGNING_KEY` secret holding the PEM text, or `FIREOTA_SIGNING_KEY_PATH`). The signature covers the package's SHA-256 plus runtime and platform; the server and the app both reject updates that don't match.
|
|
62
|
+
|
|
63
|
+
## Commands
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
fireota init [--app <appId>] [--server-url <url>] [--channel production] [--dry-run]
|
|
67
|
+
fireota publish --app <appId> --platform <android|ios|all> [--runtime <x.y.z>] --message "…"
|
|
68
|
+
[--channel production] [--rollout 10] [--version <label>] [--mandatory] [--native ">=1.4.0"]
|
|
69
|
+
[--file update.fota] [--private-key key.pem] [--json]
|
|
70
|
+
fireota bundle --platform <android|ios> [--entry index.js] [--out update.fota] [--hermes auto|on|off]
|
|
71
|
+
fireota whoami
|
|
72
|
+
fireota signing generate [--out ./fireota-keys]
|
|
73
|
+
fireota release create --app <appId> --platform <p> --runtime <r> [--message m] [--version v] [--channel c]
|
|
74
|
+
fireota release upload <releaseId> --file update.fota [--private-key key.pem]
|
|
75
|
+
fireota release publish <releaseId> [--rollout 100]
|
|
76
|
+
fireota release rollout <releaseId> --percentage <0-100>
|
|
77
|
+
fireota release pause <releaseId>
|
|
78
|
+
fireota release rollback <releaseId> --reason "…" [--target <releaseId>]
|
|
79
|
+
fireota releases [--app <appId>] [--json]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## CI/CD
|
|
83
|
+
|
|
84
|
+
The same command works on every CI. Commit, branch and build number are detected automatically on GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins, Azure DevOps, CircleCI, Bitrise, Buildkite, Travis, TeamCity, Codemagic and AWS CodeBuild; anywhere else set `FIREOTA_GIT_SHA`, `FIREOTA_GIT_BRANCH` and `FIREOTA_BUILD_NUMBER`. Ready-made pipeline files for each tool are in the dashboard under **CI/CD**.
|
|
85
|
+
|
|
86
|
+
GitHub Actions:
|
|
87
|
+
|
|
88
|
+
```yaml
|
|
89
|
+
- run: npx fireota publish --app ${{ vars.FIREOTA_APP_ID }} --platform android --runtime 1.3.0 --channel beta --message "${{ github.event.head_commit.message }}"
|
|
90
|
+
env:
|
|
91
|
+
FIREOTA_URL: ${{ vars.FIREOTA_URL }}
|
|
92
|
+
FIREOTA_API_KEY: ${{ secrets.FIREOTA_API_KEY }}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Jenkins (declarative):
|
|
96
|
+
|
|
97
|
+
```groovy
|
|
98
|
+
environment {
|
|
99
|
+
FIREOTA_URL = 'https://ota.example.com'
|
|
100
|
+
FIREOTA_API_KEY = credentials('fireota-api-key')
|
|
101
|
+
}
|
|
102
|
+
steps {
|
|
103
|
+
sh 'npm ci && npx fireota publish --app "$APP_ID" --platform android --runtime 1.3.0 --message "$(git log -1 --pretty=%s)"'
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Bitbucket Pipelines:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
script:
|
|
111
|
+
- npm ci
|
|
112
|
+
- npx fireota publish --app "$FIREOTA_APP_ID" --platform android --runtime 1.3.0 --message "$(git log -1 --pretty=%s)"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT
|