expo-release 2.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kristoffer Hansen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,375 @@
1
+ # expo-release
2
+
3
+ Fingerprint-driven Expo releases: compare the current EAS fingerprint to **existing native builds**, then either publish an OTA or queue a native build (optionally auto-submitted to TestFlight or Play).
4
+
5
+ This is not “last OTA on the channel vs current fingerprint.” A new runtime needs a matching native binary before installs can receive OTAs for that fingerprint.
6
+
7
+ ```
8
+ Push / dispatch
9
+ │
10
+ ▼
11
+ decide — git diff + eas fingerprint:generate + eas build:list
12
+ │
13
+ ├─ no matching impact paths → skip
14
+ ├─ finished native build with this fingerprint → eas update
15
+ ├─ matching native build in progress → OTA only
16
+ ├─ newest matching build errored → fail (use force-native after fixing)
17
+ └─ no matching native build → eas build --auto-submit --no-wait
18
+ ```
19
+
20
+ ## Install
21
+
22
+ Use the composite action. The package is not published to npm.
23
+
24
+ ```yaml
25
+ uses: HansKristoffer/expo-release@v2
26
+ ```
27
+
28
+ The action runs `bun ${{ github.action_path }}/src/cli.ts`. The caller must already have checked out the repo (`fetch-depth: 0`), installed Bun, set up EAS, and installed workspace dependencies.
29
+
30
+ Pin `eas-cli` with `expo/expo-github-action`. The CLI invokes `eas` from `PATH` (override with `EAS_BIN` for local tests), so that pin is the version that actually runs.
31
+
32
+ ## Setup checklist
33
+
34
+ - [ ] GitHub secret `EXPO_TOKEN` from https://expo.dev/settings/access-tokens
35
+ - [ ] `runtimeVersion: { policy: 'fingerprint' }` and `expo-updates` in the Expo app
36
+ - [ ] `eas.json` channel on each profile you deploy (production, staging, …)
37
+ - [ ] `eas.json` submit config when you use `--auto-submit`:
38
+ - iOS: `submit.<profile>.ios.ascAppId`
39
+ - Android: `submit.<profile>.android.serviceAccountKeyPath`
40
+ - [ ] EAS credentials (`eas credentials` from the Expo app directory)
41
+ - [ ] At least one finished native build **per profile and platform** on the current fingerprint. The first run against a new app always queues a native build.
42
+ - [ ] `--environment` on every OTA for Expo SDK 55+
43
+ - [ ] Add lockfiles (`bun.lock`, `package-lock.json`) to `impact-paths` if a dependency bump should trigger a fingerprint check. The default `apps/expo/` path does not include the workspace lockfile.
44
+
45
+ ## GitHub Action
46
+
47
+ Copy this workflow into `.github/workflows/expo-release.yml`. Replace the marked consumer-specific bits.
48
+
49
+ ```yaml
50
+ # =============================================================================
51
+ # Expo Release
52
+ # =============================================================================
53
+ # Fingerprint decides OTA vs native store build. Push to main deploys production
54
+ # when Expo paths change. Manual dispatch can force a native build or recover
55
+ # an OTA.
56
+ # =============================================================================
57
+
58
+ name: Expo Release
59
+
60
+ on:
61
+ push:
62
+ branches: [main]
63
+ paths:
64
+ - apps/expo/** # consumer: also list shared packages if needed
65
+ - bun.lock # consumer: include if lockfile changes native deps
66
+ workflow_dispatch:
67
+ inputs:
68
+ operation:
69
+ description: Recovery/deployment operation
70
+ required: true
71
+ default: deploy
72
+ type: choice
73
+ options:
74
+ - deploy
75
+ - force-native
76
+ - retry-ota
77
+ - republish
78
+ - rollback-embedded
79
+ group:
80
+ description: Update group ID (required for republish)
81
+ required: false
82
+ type: string
83
+ runtime-version:
84
+ description: Runtime version (optional for rollback-embedded)
85
+ required: false
86
+ type: string
87
+
88
+ concurrency:
89
+ group: expo-release-production-${{ github.ref }}
90
+ cancel-in-progress: false
91
+
92
+ permissions:
93
+ contents: read
94
+
95
+ jobs:
96
+ release:
97
+ name: production
98
+ runs-on: ubuntu-latest
99
+ timeout-minutes: 45
100
+ env:
101
+ # consumer: only if app.config.ts requires public URLs at eval time
102
+ EXPO_PUBLIC_API_URL: https://example.com
103
+ EXPO_PUBLIC_PLATFORM_URL: https://example.com
104
+ steps:
105
+ - name: Checkout
106
+ uses: actions/checkout@v7
107
+ with:
108
+ fetch-depth: 0
109
+
110
+ - name: Setup Bun
111
+ uses: oven-sh/setup-bun@v2
112
+ with:
113
+ bun-version-file: .bun-version
114
+
115
+ - name: Setup Node
116
+ uses: actions/setup-node@v7
117
+ with:
118
+ node-version: 22.12.0
119
+
120
+ - name: Restore Bun workspace cache
121
+ uses: actions/cache@v6
122
+ with:
123
+ path: |
124
+ node_modules
125
+ packages/*/node_modules
126
+ apps/*/node_modules
127
+ key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
128
+ restore-keys: |
129
+ ${{ runner.os }}-bun-
130
+
131
+ - name: Setup Expo and EAS
132
+ uses: expo/expo-github-action@v8
133
+ with:
134
+ eas-version: 16.32.0
135
+ token: ${{ secrets.EXPO_TOKEN }}
136
+
137
+ - name: Install dependencies
138
+ run: bun install --frozen-lockfile
139
+
140
+ - name: Expo release
141
+ uses: HansKristoffer/expo-release@v2
142
+ with:
143
+ command: release
144
+ profile: production
145
+ operation: ${{ github.event.inputs.operation || 'deploy' }}
146
+ environment: production
147
+ impact-paths: apps/expo/
148
+ working-directory: apps/expo
149
+ group: ${{ github.event.inputs.group }}
150
+ runtime-version: ${{ github.event.inputs.runtime-version }}
151
+ env:
152
+ # Set variant keys on the action step (or the job). They must reach
153
+ # fingerprint:generate, build:list, eas build, and eas update.
154
+ APP_VARIANT: production
155
+ SECRETS_ENV: production
156
+ APS_ENVIRONMENT: production
157
+ ```
158
+
159
+ A manual `deploy` from `workflow_dispatch` ignores the impact diff. That is intentional: dispatch after an unrelated commit should still release, not silently skip.
160
+
161
+ ### Action inputs
162
+
163
+ | Input | Default | Notes |
164
+ |-------|---------|--------|
165
+ | `command` | `release` | `release` (decide + operate), `decide` (PR checks), or `operate` |
166
+ | `profile` | `production` | EAS build profile; default update channel |
167
+ | `operation` | `deploy` | See recovery operations below |
168
+ | `deploy-type` | `none` | Used only when `command` is `operate` |
169
+ | `base` / `head` | event before / `GITHUB_SHA` | Git range for the impact diff |
170
+ | `impact-paths` | `apps/expo/` | Comma-separated repo-root prefixes |
171
+ | `environment` | _(empty)_ | Passed to `eas update`. Required for Expo SDK 55+ |
172
+ | `channel` | same as `profile` | EAS Update channel |
173
+ | `platform` | `ios` | `ios` or `android`. Passed through to `eas update` and `eas build` |
174
+ | `auto-submit` | `true` | Native builds use `--auto-submit` |
175
+ | `working-directory` | `apps/expo` | Where `eas` runs |
176
+ | `pre-update` | _(empty)_ | Shell command before `eas update` (OTA only) |
177
+ | `post-update` | _(empty)_ | Shell command after a successful `eas update` (OTA only) |
178
+ | `update-extra-args` | _(empty)_ | Extra tokens appended to `eas update` |
179
+ | `group` | _(empty)_ | Required when `operation` is `republish` |
180
+ | `runtime-version` | current fingerprint | Used when `operation` is `rollback-embedded` |
181
+ | `message` | `{profile} {sha} (fp {hash})` | Override the generated `eas update` message |
182
+ | `dry-run` | `false` | Print mutating EAS commands without executing them |
183
+
184
+ ### Action outputs
185
+
186
+ | Output | Notes |
187
+ |--------|--------|
188
+ | `deploy_type` | Stable PR-check type: `none`, `ota`, `native` |
189
+ | `native_build_pending` | `true` when a matching native build is still in progress |
190
+ | `fingerprint` | Current EAS fingerprint hash |
191
+ | `build_id` / `build_url` | Matching EAS build, if any |
192
+ | `result` | Operate result (`skipped`, `ota`, `native-build`, `recovery`) |
193
+
194
+ ### PR checks (decide only)
195
+
196
+ PR jobs should not operate. Use `command: decide` and comment or gate on `deploy_type`:
197
+
198
+ ```yaml
199
+ - uses: HansKristoffer/expo-release@v2
200
+ id: decision
201
+ with:
202
+ command: decide
203
+ profile: pr-preview # or production
204
+ base: ${{ steps.merge-base.outputs.sha }}
205
+ head: ${{ github.sha }}
206
+ env:
207
+ APP_VARIANT: staging
208
+ SECRETS_ENV: staging
209
+ APS_ENVIRONMENT: production
210
+ ```
211
+
212
+ Then use `${{ steps.decision.outputs.deploy_type }}` (`none` / `ota` / `native`).
213
+
214
+ The CLI writes the same JSON to stdout, including `deployType`:
215
+
216
+ ```bash
217
+ bun "${{ github.action_path }}/src/cli.ts" decide \
218
+ --base "$BASE" --head "$HEAD" --profile production
219
+ ```
220
+
221
+ `Bun.spawn` inherits process env. Set variant keys on the **action step or the job**, never on decide alone. When `app.config.ts` switches slug or bundle identifier on `APP_VARIANT`, every EAS command (`fingerprint:generate`, `build:list`, `eas build`, `eas update`) resolves a different project from that config.
222
+
223
+ ### OTA hooks
224
+
225
+ `pre-update`, `post-update`, and `update-extra-args` run only on the OTA path (`deploy` + `ota`, and `retry-ota`). Skip, native builds, republish, and rollback ignore them. Hook commands inherit process env. A non-zero hook exit fails operate; `post-update` does not run if `eas update` fails.
226
+
227
+ Production apps that export Hermes maps first set them only on the production operate step:
228
+
229
+ ```yaml
230
+ - uses: HansKristoffer/expo-release@v2
231
+ with:
232
+ command: release
233
+ profile: production
234
+ environment: production
235
+ pre-update: bun scripts/release/export-hermes.ts
236
+ update-extra-args: --input-dir dist --skip-bundler
237
+ post-update: bunx posthog-cli hermes upload --directory dist
238
+ env:
239
+ APP_VARIANT: production
240
+ SECRETS_ENV: production
241
+ APS_ENVIRONMENT: production
242
+ ```
243
+
244
+ `export-hermes.ts` is app-owned (typically `expo export --source-maps external` plus a Hermes `.map` check). Staging stays a default `eas update`.
245
+
246
+ ### Recovery operations
247
+
248
+ | Operation | Effect |
249
+ |-----------|--------|
250
+ | `deploy` | Same as a push: decide, then OTA or native build |
251
+ | `force-native` | Queue a native build (skip decide). Use this after fixing a failed fingerprint build. |
252
+ | `retry-ota` | Publish an OTA even if the diff has no impact paths |
253
+ | `republish` | `eas update:republish --group <id>`. Copy the group ID from the Expo dashboard. |
254
+ | `rollback-embedded` | `eas update:roll-back-to-embedded` with `--runtime-version` (defaults to the current fingerprint) |
255
+
256
+ ### Dry run
257
+
258
+ `--dry-run` still runs `git diff`, `eas fingerprint:generate`, and `eas build:list` so the decision is real. It only prints `eas update`, `eas build`, recovery commands, and OTA hooks.
259
+
260
+ ```yaml
261
+ - uses: HansKristoffer/expo-release@v2
262
+ with:
263
+ command: release
264
+ profile: production
265
+ environment: production
266
+ dry-run: 'true'
267
+ ```
268
+
269
+ ## Multiple apps (staging and production)
270
+
271
+ Use one job per profile, or a matrix. Each profile needs its own finished native build before OTAs work. One `EXPO_TOKEN` covers multiple projects under the same Expo account; separate accounts or orgs need separate secrets.
272
+
273
+ Put the **profile in the concurrency group**. Two profiles deploying from the same ref should not serialize:
274
+
275
+ ```yaml
276
+ concurrency:
277
+ group: expo-release-${{ matrix.profile }}-${{ github.ref }}
278
+ cancel-in-progress: false
279
+ ```
280
+
281
+ ### Two jobs, one branch each
282
+
283
+ ```yaml
284
+ on:
285
+ push:
286
+ branches: [main, develop]
287
+
288
+ jobs:
289
+ production:
290
+ if: github.ref == 'refs/heads/main'
291
+ # ... setup steps ...
292
+ steps:
293
+ - uses: HansKristoffer/expo-release@v2
294
+ with:
295
+ profile: production
296
+ environment: production
297
+ channel: production
298
+ env:
299
+ APP_VARIANT: production
300
+
301
+ staging:
302
+ if: github.ref == 'refs/heads/develop'
303
+ # ... setup steps ...
304
+ steps:
305
+ - uses: HansKristoffer/expo-release@v2
306
+ with:
307
+ profile: staging
308
+ environment: staging
309
+ channel: staging
310
+ env:
311
+ APP_VARIANT: staging
312
+ ```
313
+
314
+ ### One job, matrix
315
+
316
+ ```yaml
317
+ strategy:
318
+ fail-fast: false
319
+ matrix:
320
+ include:
321
+ - profile: production
322
+ environment: production
323
+ variant: production
324
+ - profile: staging
325
+ environment: staging
326
+ variant: staging
327
+
328
+ steps:
329
+ - uses: HansKristoffer/expo-release@v2
330
+ with:
331
+ profile: ${{ matrix.profile }}
332
+ environment: ${{ matrix.environment }}
333
+ channel: ${{ matrix.profile }}
334
+ env:
335
+ APP_VARIANT: ${{ matrix.variant }}
336
+ ```
337
+
338
+ `channel` defaults to `profile`. If two profiles should publish to the same channel, set `channel` explicitly and keep `profile` as the EAS build profile.
339
+
340
+ ## CLI
341
+
342
+ ```bash
343
+ expo-release release \
344
+ --base <sha> --head <sha> --profile production \
345
+ [--platform ios] \
346
+ [--impact-paths apps/expo/,packages/conductor/] \
347
+ [--environment production] \
348
+ [--dry-run]
349
+
350
+ expo-release decide \
351
+ --base <sha> --head <sha> --profile production \
352
+ [--platform ios] \
353
+ [--impact-paths apps/expo/,packages/conductor/] \
354
+ [--ignore-expo-impact true]
355
+
356
+ expo-release operate \
357
+ --profile production \
358
+ --deploy-type <none|ota|native> \
359
+ --operation <deploy|force-native|retry-ota|republish|rollback-embedded> \
360
+ [--channel production] [--environment production] \
361
+ [--platform ios] [--auto-submit true] \
362
+ [--group <update-group-id>] \
363
+ [--runtime-version <hash>] \
364
+ [--message "custom message"] \
365
+ [--pre-update "bun scripts/release/export-hermes.ts"] \
366
+ [--update-extra-args "--input-dir dist --skip-bundler"] \
367
+ [--post-update "bunx posthog-cli hermes upload --directory dist"]
368
+ ```
369
+
370
+ `release` is decide + operate (same as the action default). `force-native`, `republish`, and `rollback-embedded` skip decide. `decide` prints JSON including `deployType` and `nativeBuildPending`. When `GITHUB_OUTPUT` is set, decide writes `deploy_type`, `native_build_pending`, `changed`, `fingerprint`, `build_id`, `build_url`. Operate writes `result`.
371
+
372
+ ```bash
373
+ # local
374
+ bun src/cli.ts decide --base HEAD^ --head HEAD --profile production
375
+ ```
package/action.yml ADDED
@@ -0,0 +1,162 @@
1
+ name: Expo Release
2
+ description: Fingerprint-driven EAS OTA or native store build
3
+ author: Kristoffer Hansen
4
+
5
+ inputs:
6
+ command:
7
+ description: release (decide + operate), decide only, or operate only
8
+ required: false
9
+ default: release
10
+ profile:
11
+ description: EAS build profile (also used as the default update channel)
12
+ required: false
13
+ default: production
14
+ operation:
15
+ description: deploy, force-native, retry-ota, republish, or rollback-embedded
16
+ required: false
17
+ default: deploy
18
+ deploy-type:
19
+ description: Decision type when command is operate (none, ota, native)
20
+ required: false
21
+ default: none
22
+ base:
23
+ description: Git base SHA for the impact diff. Defaults to github.event.before.
24
+ required: false
25
+ default: ''
26
+ head:
27
+ description: Git head SHA for the impact diff. Defaults to GITHUB_SHA.
28
+ required: false
29
+ default: ''
30
+ impact-paths:
31
+ description: Comma-separated repo-root paths that count as an Expo change
32
+ required: false
33
+ default: apps/expo/
34
+ environment:
35
+ description: EAS environment passed to eas update. Required for Expo SDK 55+.
36
+ required: false
37
+ default: ''
38
+ channel:
39
+ description: EAS Update channel. Defaults to the profile name.
40
+ required: false
41
+ default: ''
42
+ platform:
43
+ description: Native platform (ios or android)
44
+ required: false
45
+ default: ios
46
+ auto-submit:
47
+ description: Pass --auto-submit on native builds
48
+ required: false
49
+ default: 'true'
50
+ working-directory:
51
+ description: Directory to run EAS commands from
52
+ required: false
53
+ default: apps/expo
54
+ pre-update:
55
+ description: Shell command to run before eas update (OTA path only)
56
+ required: false
57
+ default: ''
58
+ post-update:
59
+ description: Shell command to run after a successful eas update (OTA path only)
60
+ required: false
61
+ default: ''
62
+ update-extra-args:
63
+ description: Extra tokens appended to eas update (e.g. --input-dir dist --skip-bundler)
64
+ required: false
65
+ default: ''
66
+ group:
67
+ description: Update group ID required by operation=republish
68
+ required: false
69
+ default: ''
70
+ runtime-version:
71
+ description: Runtime version for rollback-embedded. Defaults to the current fingerprint.
72
+ required: false
73
+ default: ''
74
+ message:
75
+ description: Override the generated eas update message
76
+ required: false
77
+ default: ''
78
+ dry-run:
79
+ description: Print mutating EAS commands without executing them
80
+ required: false
81
+ default: 'false'
82
+
83
+ outputs:
84
+ deploy_type:
85
+ description: Stable PR-check type (none, ota, native)
86
+ value: ${{ steps.release.outputs.deploy_type }}
87
+ native_build_pending:
88
+ description: Whether a matching native build is still in progress
89
+ value: ${{ steps.release.outputs.native_build_pending }}
90
+ fingerprint:
91
+ description: Current EAS fingerprint hash
92
+ value: ${{ steps.release.outputs.fingerprint }}
93
+ build_id:
94
+ description: Matching EAS build id, if any
95
+ value: ${{ steps.release.outputs.build_id }}
96
+ build_url:
97
+ description: Matching EAS build URL, if any
98
+ value: ${{ steps.release.outputs.build_url }}
99
+ result:
100
+ description: Operate result (skipped, ota, native-build, recovery)
101
+ value: ${{ steps.release.outputs.result }}
102
+
103
+ runs:
104
+ using: composite
105
+ steps:
106
+ - name: Expo release
107
+ id: release
108
+ working-directory: ${{ inputs.working-directory }}
109
+ shell: bash
110
+ env:
111
+ ACTION_PATH: ${{ github.action_path }}
112
+ EXPO_RELEASE_COMMAND: ${{ inputs.command }}
113
+ EXPO_RELEASE_PROFILE: ${{ inputs.profile }}
114
+ EXPO_RELEASE_OPERATION: ${{ inputs.operation }}
115
+ EXPO_RELEASE_DEPLOY_TYPE: ${{ inputs.deploy-type }}
116
+ EXPO_RELEASE_BASE: ${{ inputs.base }}
117
+ EXPO_RELEASE_HEAD: ${{ inputs.head }}
118
+ EXPO_RELEASE_IMPACT_PATHS: ${{ inputs.impact-paths }}
119
+ EXPO_RELEASE_ENVIRONMENT: ${{ inputs.environment }}
120
+ EXPO_RELEASE_CHANNEL: ${{ inputs.channel }}
121
+ EXPO_RELEASE_PLATFORM: ${{ inputs.platform }}
122
+ EXPO_RELEASE_AUTO_SUBMIT: ${{ inputs.auto-submit }}
123
+ EXPO_RELEASE_PRE_UPDATE: ${{ inputs.pre-update }}
124
+ EXPO_RELEASE_POST_UPDATE: ${{ inputs.post-update }}
125
+ EXPO_RELEASE_UPDATE_EXTRA_ARGS: ${{ inputs.update-extra-args }}
126
+ EXPO_RELEASE_GROUP: ${{ inputs.group }}
127
+ EXPO_RELEASE_RUNTIME_VERSION: ${{ inputs.runtime-version }}
128
+ EXPO_RELEASE_MESSAGE: ${{ inputs.message }}
129
+ EXPO_RELEASE_DRY_RUN: ${{ inputs.dry-run }}
130
+ GITHUB_EVENT_BEFORE: ${{ github.event.before }}
131
+ run: bun "$ACTION_PATH/src/cli.ts"
132
+
133
+ - name: Publish job summary
134
+ if: always()
135
+ shell: bash
136
+ env:
137
+ COMMAND: ${{ inputs.command }}
138
+ OPERATION: ${{ inputs.operation }}
139
+ PROFILE: ${{ inputs.profile }}
140
+ PLATFORM: ${{ inputs.platform }}
141
+ DEPLOY_TYPE: ${{ steps.release.outputs.deploy_type }}
142
+ RESULT: ${{ steps.release.outputs.result || 'did not run' }}
143
+ FINGERPRINT: ${{ steps.release.outputs.fingerprint }}
144
+ MATCHING_BUILD: ${{ steps.release.outputs.build_url || steps.release.outputs.build_id }}
145
+ NATIVE_PENDING: ${{ steps.release.outputs.native_build_pending }}
146
+ run: |
147
+ {
148
+ echo "## ${PROFILE} ${PLATFORM} ${COMMAND}"
149
+ echo ""
150
+ echo "- Command: \`$COMMAND\`"
151
+ echo "- Operation: \`$OPERATION\`"
152
+ echo "- Result: \`$RESULT\`"
153
+ if [[ -n "$DEPLOY_TYPE" ]]; then
154
+ echo "- Deploy type: \`$DEPLOY_TYPE\`"
155
+ echo "- Native build pending: \`${NATIVE_PENDING:-false}\`"
156
+ echo "- Fingerprint: \`${FINGERPRINT:-none}\`"
157
+ echo "- Matching build: ${MATCHING_BUILD:-none}"
158
+ fi
159
+ if [[ "$COMMAND" == "release" ]]; then
160
+ echo "- New native builds are submitted automatically when auto-submit is enabled (TestFlight on iOS, Play on Android)."
161
+ fi
162
+ } >> "$GITHUB_STEP_SUMMARY"
package/dist/args.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ export declare const DEFAULT_IMPACT_PATHS: readonly ['apps/expo/'];
2
+ export type ReleasePlatform = 'ios' | 'android';
3
+ export type CommandName = 'release' | 'decide' | 'operate';
4
+ export type Operation = 'deploy' | 'force-native' | 'retry-ota' | 'republish' | 'rollback-embedded';
5
+ export type DeployType = 'none' | 'ota' | 'native';
6
+ export type ReleaseOptions = {
7
+ command: CommandName;
8
+ profile: string;
9
+ base?: string;
10
+ head?: string;
11
+ platform: ReleasePlatform;
12
+ impactPaths: string[];
13
+ ignoreExpoImpact: boolean;
14
+ operation: Operation;
15
+ deployType: DeployType;
16
+ channel: string;
17
+ environment?: string;
18
+ autoSubmit: boolean;
19
+ preUpdate?: string;
20
+ postUpdate?: string;
21
+ updateExtraArgs?: string;
22
+ group?: string;
23
+ runtimeVersion?: string;
24
+ message?: string;
25
+ fingerprint?: string;
26
+ dryRun: boolean;
27
+ };
28
+ export declare const USAGE = "Usage: expo-release <release|decide|operate> --profile <profile> [--base <sha>] [--head <sha>] [--platform ios|android] [--impact-paths apps/expo/] [--operation deploy|force-native|retry-ota|republish|rollback-embedded] [--deploy-type none|ota|native] [--channel <channel>] [--environment <env>] [--group <id>] [--runtime-version <hash>] [--message <msg>] [--fingerprint <hash>] [--auto-submit true] [--pre-update <cmd>] [--post-update <cmd>] [--update-extra-args <args>] [--dry-run] [--ignore-expo-impact true]";
29
+ export declare function optionalString(value: string | undefined): string | undefined;
30
+ export declare function parseImpactPaths(value: string | undefined): string[];
31
+ export declare function parsePlatform(value: string | undefined): ReleasePlatform;
32
+ export declare function parseBoolean(value: string | undefined, fallback: boolean): boolean;
33
+ export declare function parseOperation(value: string | undefined): Operation;
34
+ export declare function parseDeployType(value: string | undefined): DeployType;
35
+ export declare function parseCommandName(value: string | undefined): CommandName;
36
+ export declare function needsDecide(operation: Operation): boolean;
37
+ export declare function shouldIgnoreExpoImpact(options: Pick<ReleaseOptions, 'ignoreExpoImpact' | 'operation'>): boolean;
38
+ export declare function parseReleaseOptions(args: string[], env?: NodeJS.ProcessEnv): ReleaseOptions;
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bun
2
+ export {};