expo-release 2.0.0 → 2.2.1
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 +269 -11
- package/action.yml +11 -0
- package/dist/args.d.ts +49 -9
- package/dist/cli.js +178 -171
- package/dist/index.js +132 -134
- package/dist/operate.d.ts +2 -0
- package/dist/run.d.ts +4 -0
- package/dist/runtime/error-boundary.d.ts +27 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.js +214 -0
- package/dist/runtime/ota.d.ts +19 -0
- package/dist/runtime/push.d.ts +70 -0
- package/dist/source-maps.d.ts +8 -0
- package/package.json +45 -8
- package/src/args.ts +129 -250
- package/src/cli.ts +78 -41
- package/src/operate.ts +19 -1
- package/src/run.ts +33 -4
- package/src/runtime/error-boundary.ts +51 -0
- package/src/runtime/index.ts +19 -0
- package/src/runtime/ota.ts +54 -0
- package/src/runtime/push.ts +243 -0
- package/src/source-maps.ts +61 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as Notifications from 'expo-notifications';
|
|
2
|
+
/** Async key-value store. AsyncStorage and expo-secure-store adapters fit. */
|
|
3
|
+
export interface KeyValueStorage {
|
|
4
|
+
getItem(key: string): Promise<string | null>;
|
|
5
|
+
setItem(key: string, value: string): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export interface PushNotificationsOptions {
|
|
8
|
+
/** Remembers that the one-time prompt ran. */
|
|
9
|
+
storage: KeyValueStorage;
|
|
10
|
+
/** Saves this device's Expo push token on your backend; `null` removes it. */
|
|
11
|
+
registerDevice: (token: string | null) => Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Explains push before the OS dialog. Resolve `true` to continue. Without
|
|
14
|
+
* it, `prompt()` goes straight to the OS dialog.
|
|
15
|
+
*/
|
|
16
|
+
confirm?: () => Promise<boolean>;
|
|
17
|
+
/** Push is off: the app runs on a simulator or the user denied permission. */
|
|
18
|
+
onUnavailable?: (reason: 'not-a-device' | 'denied') => void;
|
|
19
|
+
onError?: (message: string, error: unknown) => void;
|
|
20
|
+
/** Defaults to what expo-notifications reads from the app config. */
|
|
21
|
+
projectId?: string;
|
|
22
|
+
/** Android channel `default`, needed for heads-up notifications. */
|
|
23
|
+
androidChannel?: Notifications.NotificationChannelInput;
|
|
24
|
+
/** How notifications show while the app is in the foreground. */
|
|
25
|
+
foregroundBehavior?: Notifications.NotificationBehavior;
|
|
26
|
+
storageKey?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface NotificationListeners {
|
|
29
|
+
onReceived?: (notification: Notifications.Notification) => void;
|
|
30
|
+
/** Also called with the response that launched the app, if any. */
|
|
31
|
+
onResponse?: (response: Notifications.NotificationResponse) => void;
|
|
32
|
+
}
|
|
33
|
+
export type PushNotifications = ReturnType<typeof createPushNotifications>;
|
|
34
|
+
/**
|
|
35
|
+
* expo-notifications behind one object: permission flow, Expo push token and
|
|
36
|
+
* device registration. Create it once at module level.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createPushNotifications(options: PushNotificationsOptions): {
|
|
39
|
+
getPermissionStatus: () => Promise<Notifications.NotificationPermissionsStatus>;
|
|
40
|
+
hasPrompted: () => Promise<boolean>;
|
|
41
|
+
requestPermissions: () => Promise<boolean>;
|
|
42
|
+
getPushToken: () => Promise<string | null>;
|
|
43
|
+
syncToken: () => Promise<boolean>;
|
|
44
|
+
/**
|
|
45
|
+
* Asks for push once per install (after sign-in, say), then registers the
|
|
46
|
+
* token. Never throws; concurrent calls share one dialog.
|
|
47
|
+
*/
|
|
48
|
+
prompt(): Promise<boolean>;
|
|
49
|
+
/** Turns push on from settings. Resolves whether it is on. */
|
|
50
|
+
enable(): Promise<boolean>;
|
|
51
|
+
/** Removes this device's token from your backend. */
|
|
52
|
+
disable(): Promise<void>;
|
|
53
|
+
/** Subscribes to notifications. Returns the unsubscribe function. */
|
|
54
|
+
listen({ onReceived, onResponse }: NotificationListeners): () => void;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Push state for a settings screen. `enabled` is the user's saved preference;
|
|
58
|
+
* while it is on, the token is re-registered on mount.
|
|
59
|
+
*/
|
|
60
|
+
export declare function usePushNotifications(push: PushNotifications, { enabled }?: {
|
|
61
|
+
enabled?: boolean;
|
|
62
|
+
}): {
|
|
63
|
+
permission: Notifications.NotificationPermissionsStatus | null;
|
|
64
|
+
isEnabled: boolean;
|
|
65
|
+
isLoading: boolean;
|
|
66
|
+
prompt: () => Promise<boolean>;
|
|
67
|
+
enable: () => Promise<boolean>;
|
|
68
|
+
disable: () => Promise<void>;
|
|
69
|
+
refresh: () => Promise<void>;
|
|
70
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ReleasePlatform } from './args';
|
|
2
|
+
export declare const SOURCE_MAP_OUTPUT_DIR = "dist";
|
|
3
|
+
export declare function expoCommand(...args: string[]): string[];
|
|
4
|
+
export declare function sourceMapExportCommand(platform: ReleasePlatform): string[];
|
|
5
|
+
export declare function sourceMapUpdateArgs(): string[];
|
|
6
|
+
export declare function mergeUpdateArgs(extra: string[] | undefined, exportSourceMaps: boolean): string[];
|
|
7
|
+
export declare function defaultHasSourceMaps(directory?: string): Promise<boolean>;
|
|
8
|
+
export declare function assertSourceMaps(hasSourceMaps?: () => Promise<boolean>): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-release",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Fingerprint-driven Expo EAS release: OTA update or native store build",
|
|
3
|
+
"version": "2.2.1",
|
|
4
|
+
"description": "Fingerprint-driven Expo EAS release: OTA update or native store build, plus app runtime helpers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.js",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -39,25 +39,62 @@
|
|
|
39
39
|
"bun": "./src/index.ts",
|
|
40
40
|
"import": "./dist/index.js",
|
|
41
41
|
"default": "./dist/index.js"
|
|
42
|
+
},
|
|
43
|
+
"./runtime": {
|
|
44
|
+
"types": "./dist/runtime/index.d.ts",
|
|
45
|
+
"import": "./dist/runtime/index.js",
|
|
46
|
+
"default": "./dist/runtime/index.js"
|
|
42
47
|
}
|
|
43
48
|
},
|
|
44
49
|
"scripts": {
|
|
45
50
|
"build": "bun run build:js && bun run build:types",
|
|
46
|
-
"build:js": "bun build ./src/index.ts ./src/cli.ts --outdir ./dist --target bun --packages external",
|
|
51
|
+
"build:js": "bun build ./src/index.ts ./src/cli.ts --outdir ./dist --target bun --packages external && bun build ./src/runtime/index.ts --outdir ./dist/runtime --target browser --packages external",
|
|
47
52
|
"build:types": "tsgo -p tsconfig.build.json",
|
|
48
53
|
"prepublishOnly": "bun run build",
|
|
49
|
-
"publish:patch": "npm version patch && npm publish",
|
|
50
|
-
"publish:minor": "npm version minor && npm publish",
|
|
51
|
-
"publish:major": "npm version major && npm publish",
|
|
52
54
|
"test": "bun test",
|
|
53
55
|
"lint": "bun run typecheck && bun biome check",
|
|
54
56
|
"lint:write": "bun run typecheck && bun biome check --write",
|
|
55
|
-
"typecheck": "tsgo --noEmit"
|
|
57
|
+
"typecheck": "tsgo --noEmit && tsgo --noEmit -p tsconfig.runtime.json",
|
|
58
|
+
"verify:package": "node scripts/verify-package.mjs"
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"hanzio": "^3.1.0",
|
|
62
|
+
"zod": "^4.3.6"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"expo-device": ">=55",
|
|
66
|
+
"expo-notifications": ">=55",
|
|
67
|
+
"expo-updates": ">=55",
|
|
68
|
+
"react": ">=19"
|
|
69
|
+
},
|
|
70
|
+
"peerDependenciesMeta": {
|
|
71
|
+
"expo-device": {
|
|
72
|
+
"optional": true
|
|
73
|
+
},
|
|
74
|
+
"expo-notifications": {
|
|
75
|
+
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"expo-updates": {
|
|
78
|
+
"optional": true
|
|
79
|
+
},
|
|
80
|
+
"react": {
|
|
81
|
+
"optional": true
|
|
82
|
+
}
|
|
56
83
|
},
|
|
57
84
|
"devDependencies": {
|
|
58
85
|
"@biomejs/biome": "^2.4.6",
|
|
59
86
|
"@types/bun": "latest",
|
|
87
|
+
"@types/react": "~19.2.0",
|
|
60
88
|
"@typescript/native-preview": "^7.0.0-dev.20260306.1",
|
|
89
|
+
"expo-device": "~55.0.10",
|
|
90
|
+
"expo-notifications": "~55.0.14",
|
|
91
|
+
"expo-updates": "~55.0.16",
|
|
92
|
+
"react": "19.2.0",
|
|
61
93
|
"typescript": "^5.7.0"
|
|
62
|
-
}
|
|
94
|
+
},
|
|
95
|
+
"homepage": "https://github.com/HansKristoffer/expo-release#readme",
|
|
96
|
+
"bugs": {
|
|
97
|
+
"url": "https://github.com/HansKristoffer/expo-release/issues"
|
|
98
|
+
},
|
|
99
|
+
"packageManager": "bun@1.4.2"
|
|
63
100
|
}
|
package/src/args.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { CommandContext } from 'hanzio/cli'
|
|
2
|
+
import { z } from 'zod'
|
|
2
3
|
|
|
3
4
|
export const DEFAULT_IMPACT_PATHS = ['apps/expo/'] as const
|
|
4
5
|
|
|
@@ -31,6 +32,7 @@ export type ReleaseOptions = {
|
|
|
31
32
|
preUpdate?: string
|
|
32
33
|
postUpdate?: string
|
|
33
34
|
updateExtraArgs?: string
|
|
35
|
+
exportSourceMaps: boolean
|
|
34
36
|
group?: string
|
|
35
37
|
runtimeVersion?: string
|
|
36
38
|
message?: string
|
|
@@ -38,76 +40,133 @@ export type ReleaseOptions = {
|
|
|
38
40
|
dryRun: boolean
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
43
|
+
// Every flag falls back to an EXPO_RELEASE_* variable: the composite action passes its inputs that way.
|
|
44
|
+
const text = (env: string) =>
|
|
45
|
+
z
|
|
46
|
+
.string()
|
|
47
|
+
.transform((value) => value.trim() || undefined)
|
|
48
|
+
.optional()
|
|
49
|
+
.meta({ env: `EXPO_RELEASE_${env}` })
|
|
50
|
+
|
|
51
|
+
// `--auto-submit false` takes a value, so these are not boolean switches.
|
|
52
|
+
const trueFalse = (env: string, fallback: 'true' | 'false') =>
|
|
53
|
+
z
|
|
54
|
+
.enum(['true', 'false'])
|
|
55
|
+
.default(fallback)
|
|
56
|
+
.transform((value) => value === 'true')
|
|
57
|
+
.meta({ env: `EXPO_RELEASE_${env}` })
|
|
58
|
+
|
|
59
|
+
export const releaseFlags = z
|
|
60
|
+
.object({
|
|
61
|
+
profile: z
|
|
62
|
+
.string()
|
|
63
|
+
.trim()
|
|
64
|
+
.min(1)
|
|
65
|
+
.meta({ env: 'EXPO_RELEASE_PROFILE' })
|
|
66
|
+
.describe('EAS build profile, also the default update channel'),
|
|
67
|
+
base: text('BASE').describe(
|
|
68
|
+
'Git base SHA for the impact diff (falls back to GITHUB_EVENT_BEFORE)'
|
|
69
|
+
),
|
|
70
|
+
head: text('HEAD').describe(
|
|
71
|
+
'Git head SHA for the impact diff (falls back to GITHUB_SHA)'
|
|
72
|
+
),
|
|
73
|
+
platform: z
|
|
74
|
+
.enum(['ios', 'android'])
|
|
75
|
+
.default('ios')
|
|
76
|
+
.meta({ env: 'EXPO_RELEASE_PLATFORM' })
|
|
77
|
+
.describe('Native platform'),
|
|
78
|
+
impactPaths: z
|
|
79
|
+
.string()
|
|
80
|
+
.default(DEFAULT_IMPACT_PATHS.join(','))
|
|
81
|
+
.transform((value, ctx) => {
|
|
82
|
+
const paths = value
|
|
83
|
+
.split(',')
|
|
84
|
+
.map((path) => path.trim())
|
|
85
|
+
.filter(Boolean)
|
|
86
|
+
if (paths.length === 0)
|
|
87
|
+
ctx.addIssue({
|
|
88
|
+
code: 'custom',
|
|
89
|
+
message: 'At least one --impact-paths entry is required'
|
|
90
|
+
})
|
|
91
|
+
return paths
|
|
92
|
+
})
|
|
93
|
+
.meta({ env: 'EXPO_RELEASE_IMPACT_PATHS' })
|
|
94
|
+
.describe('Comma-separated repo-root paths that count as an Expo change'),
|
|
95
|
+
ignoreExpoImpact: trueFalse('IGNORE_EXPO_IMPACT', 'false').describe(
|
|
96
|
+
'Check the fingerprint even when no impact path changed'
|
|
97
|
+
),
|
|
98
|
+
operation: z
|
|
99
|
+
.enum([
|
|
100
|
+
'deploy',
|
|
101
|
+
'force-native',
|
|
102
|
+
'retry-ota',
|
|
103
|
+
'republish',
|
|
104
|
+
'rollback-embedded'
|
|
105
|
+
])
|
|
106
|
+
.default('deploy')
|
|
107
|
+
.meta({ env: 'EXPO_RELEASE_OPERATION' })
|
|
108
|
+
.describe('What to run'),
|
|
109
|
+
deployType: z
|
|
110
|
+
.enum(['none', 'ota', 'native'])
|
|
111
|
+
.default('none')
|
|
112
|
+
.meta({ env: 'EXPO_RELEASE_DEPLOY_TYPE' })
|
|
113
|
+
.describe('Decision type for operate'),
|
|
114
|
+
channel: text('CHANNEL').describe(
|
|
115
|
+
'EAS Update channel (default: the profile)'
|
|
116
|
+
),
|
|
117
|
+
environment: text('ENVIRONMENT').describe(
|
|
118
|
+
'EAS environment for eas update (required for Expo SDK 55+)'
|
|
119
|
+
),
|
|
120
|
+
autoSubmit: trueFalse('AUTO_SUBMIT', 'true').describe(
|
|
121
|
+
'Pass --auto-submit on native builds'
|
|
122
|
+
),
|
|
123
|
+
preUpdate: text('PRE_UPDATE').describe(
|
|
124
|
+
'Shell command run before eas update'
|
|
125
|
+
),
|
|
126
|
+
postUpdate: text('POST_UPDATE').describe(
|
|
127
|
+
'Shell command run after a successful eas update'
|
|
128
|
+
),
|
|
129
|
+
updateExtraArgs: text('UPDATE_EXTRA_ARGS').describe(
|
|
130
|
+
'Extra tokens appended to eas update'
|
|
131
|
+
),
|
|
132
|
+
exportSourceMaps: trueFalse('EXPORT_SOURCE_MAPS', 'false').describe(
|
|
133
|
+
'On OTA, expo export with external source maps, then publish dist'
|
|
134
|
+
),
|
|
135
|
+
group: text('GROUP').describe('Update group ID for --operation republish'),
|
|
136
|
+
runtimeVersion: text('RUNTIME_VERSION').describe(
|
|
137
|
+
'Runtime version for rollback-embedded (default: the fingerprint)'
|
|
138
|
+
),
|
|
139
|
+
message: text('MESSAGE').describe('Override the eas update message'),
|
|
140
|
+
fingerprint: text('FINGERPRINT').describe(
|
|
141
|
+
'Fingerprint hash to use instead of generating one'
|
|
142
|
+
),
|
|
143
|
+
dryRun: z
|
|
144
|
+
.boolean()
|
|
145
|
+
.meta({ env: 'EXPO_RELEASE_DRY_RUN' })
|
|
146
|
+
.describe('Print mutating EAS commands without running them')
|
|
147
|
+
})
|
|
148
|
+
.superRefine((flags, ctx) => {
|
|
149
|
+
if (flags.operation === 'republish' && !flags.group)
|
|
150
|
+
ctx.addIssue({
|
|
151
|
+
code: 'custom',
|
|
152
|
+
path: ['group'],
|
|
153
|
+
message: 'required by --operation republish'
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
export type ReleaseFlags = z.output<typeof releaseFlags>
|
|
158
|
+
|
|
159
|
+
export function toReleaseOptions(
|
|
160
|
+
command: CommandName,
|
|
161
|
+
{ context: flags, env }: CommandContext<ReleaseFlags>
|
|
162
|
+
): ReleaseOptions {
|
|
163
|
+
return {
|
|
164
|
+
...flags,
|
|
165
|
+
command,
|
|
166
|
+
base: flags.base ?? env.GITHUB_EVENT_BEFORE,
|
|
167
|
+
head: flags.head ?? env.GITHUB_SHA,
|
|
168
|
+
channel: flags.channel ?? flags.profile
|
|
109
169
|
}
|
|
110
|
-
throw new Error(USAGE)
|
|
111
170
|
}
|
|
112
171
|
|
|
113
172
|
export function needsDecide(operation: Operation): boolean {
|
|
@@ -136,183 +195,3 @@ export function shouldIgnoreExpoImpact(
|
|
|
136
195
|
options.operation === 'deploy'
|
|
137
196
|
)
|
|
138
197
|
}
|
|
139
|
-
|
|
140
|
-
export function parseReleaseOptions(
|
|
141
|
-
args: string[],
|
|
142
|
-
env: NodeJS.ProcessEnv = process.env
|
|
143
|
-
): ReleaseOptions {
|
|
144
|
-
let values: {
|
|
145
|
-
profile?: string
|
|
146
|
-
base?: string
|
|
147
|
-
head?: string
|
|
148
|
-
platform?: string
|
|
149
|
-
'impact-paths'?: string
|
|
150
|
-
'ignore-expo-impact'?: string
|
|
151
|
-
operation?: string
|
|
152
|
-
'deploy-type'?: string
|
|
153
|
-
channel?: string
|
|
154
|
-
environment?: string
|
|
155
|
-
'auto-submit'?: string
|
|
156
|
-
'pre-update'?: string
|
|
157
|
-
'post-update'?: string
|
|
158
|
-
'update-extra-args'?: string
|
|
159
|
-
group?: string
|
|
160
|
-
'runtime-version'?: string
|
|
161
|
-
message?: string
|
|
162
|
-
fingerprint?: string
|
|
163
|
-
'dry-run'?: boolean
|
|
164
|
-
}
|
|
165
|
-
let positionals: string[]
|
|
166
|
-
|
|
167
|
-
try {
|
|
168
|
-
const parsed = parseArgs({
|
|
169
|
-
args,
|
|
170
|
-
allowPositionals: true,
|
|
171
|
-
strict: true,
|
|
172
|
-
options: {
|
|
173
|
-
profile: { type: 'string' },
|
|
174
|
-
base: { type: 'string' },
|
|
175
|
-
head: { type: 'string' },
|
|
176
|
-
platform: { type: 'string' },
|
|
177
|
-
'impact-paths': { type: 'string' },
|
|
178
|
-
'ignore-expo-impact': { type: 'string' },
|
|
179
|
-
operation: { type: 'string' },
|
|
180
|
-
'deploy-type': { type: 'string' },
|
|
181
|
-
channel: { type: 'string' },
|
|
182
|
-
environment: { type: 'string' },
|
|
183
|
-
'auto-submit': { type: 'string' },
|
|
184
|
-
'pre-update': { type: 'string' },
|
|
185
|
-
'post-update': { type: 'string' },
|
|
186
|
-
'update-extra-args': { type: 'string' },
|
|
187
|
-
group: { type: 'string' },
|
|
188
|
-
'runtime-version': { type: 'string' },
|
|
189
|
-
message: { type: 'string' },
|
|
190
|
-
fingerprint: { type: 'string' },
|
|
191
|
-
'dry-run': { type: 'boolean', default: false }
|
|
192
|
-
}
|
|
193
|
-
})
|
|
194
|
-
values = parsed.values
|
|
195
|
-
positionals = parsed.positionals
|
|
196
|
-
} catch (error) {
|
|
197
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
198
|
-
throw new Error(`${USAGE}\n${message}`)
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (positionals.length > 1) {
|
|
202
|
-
throw new Error(USAGE)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const command = parseCommandName(
|
|
206
|
-
positionals[0] ?? fromEnv(env, 'EXPO_RELEASE_COMMAND')
|
|
207
|
-
)
|
|
208
|
-
const profile = firstDefined(
|
|
209
|
-
values.profile,
|
|
210
|
-
fromEnv(env, 'EXPO_RELEASE_PROFILE')
|
|
211
|
-
)
|
|
212
|
-
if (!profile) {
|
|
213
|
-
throw new Error(USAGE)
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const operation = parseOperation(
|
|
217
|
-
firstDefined(values.operation, fromEnv(env, 'EXPO_RELEASE_OPERATION'))
|
|
218
|
-
)
|
|
219
|
-
const group = optionalString(
|
|
220
|
-
firstDefined(values.group, fromEnv(env, 'EXPO_RELEASE_GROUP'))
|
|
221
|
-
)
|
|
222
|
-
if (operation === 'republish' && !group) {
|
|
223
|
-
throw new Error(
|
|
224
|
-
'Usage: --operation republish requires --group <update-group-id>'
|
|
225
|
-
)
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const channel =
|
|
229
|
-
firstDefined(values.channel, fromEnv(env, 'EXPO_RELEASE_CHANNEL')) ??
|
|
230
|
-
profile
|
|
231
|
-
|
|
232
|
-
return {
|
|
233
|
-
command,
|
|
234
|
-
profile,
|
|
235
|
-
base: optionalString(
|
|
236
|
-
firstDefined(
|
|
237
|
-
values.base,
|
|
238
|
-
fromEnv(env, 'EXPO_RELEASE_BASE'),
|
|
239
|
-
fromEnv(env, 'GITHUB_EVENT_BEFORE')
|
|
240
|
-
)
|
|
241
|
-
),
|
|
242
|
-
head: optionalString(
|
|
243
|
-
firstDefined(
|
|
244
|
-
values.head,
|
|
245
|
-
fromEnv(env, 'EXPO_RELEASE_HEAD'),
|
|
246
|
-
fromEnv(env, 'GITHUB_SHA')
|
|
247
|
-
)
|
|
248
|
-
),
|
|
249
|
-
platform: parsePlatform(
|
|
250
|
-
firstDefined(values.platform, fromEnv(env, 'EXPO_RELEASE_PLATFORM'))
|
|
251
|
-
),
|
|
252
|
-
impactPaths: parseImpactPaths(
|
|
253
|
-
firstDefined(
|
|
254
|
-
values['impact-paths'],
|
|
255
|
-
fromEnv(env, 'EXPO_RELEASE_IMPACT_PATHS')
|
|
256
|
-
)
|
|
257
|
-
),
|
|
258
|
-
ignoreExpoImpact: parseBoolean(
|
|
259
|
-
firstDefined(
|
|
260
|
-
values['ignore-expo-impact'],
|
|
261
|
-
fromEnv(env, 'EXPO_RELEASE_IGNORE_EXPO_IMPACT')
|
|
262
|
-
),
|
|
263
|
-
false
|
|
264
|
-
),
|
|
265
|
-
operation,
|
|
266
|
-
deployType: parseDeployType(
|
|
267
|
-
firstDefined(
|
|
268
|
-
values['deploy-type'],
|
|
269
|
-
fromEnv(env, 'EXPO_RELEASE_DEPLOY_TYPE')
|
|
270
|
-
)
|
|
271
|
-
),
|
|
272
|
-
channel,
|
|
273
|
-
environment: optionalString(
|
|
274
|
-
firstDefined(values.environment, fromEnv(env, 'EXPO_RELEASE_ENVIRONMENT'))
|
|
275
|
-
),
|
|
276
|
-
autoSubmit: parseBoolean(
|
|
277
|
-
firstDefined(
|
|
278
|
-
values['auto-submit'],
|
|
279
|
-
fromEnv(env, 'EXPO_RELEASE_AUTO_SUBMIT')
|
|
280
|
-
),
|
|
281
|
-
true
|
|
282
|
-
),
|
|
283
|
-
preUpdate: optionalString(
|
|
284
|
-
firstDefined(
|
|
285
|
-
values['pre-update'],
|
|
286
|
-
fromEnv(env, 'EXPO_RELEASE_PRE_UPDATE')
|
|
287
|
-
)
|
|
288
|
-
),
|
|
289
|
-
postUpdate: optionalString(
|
|
290
|
-
firstDefined(
|
|
291
|
-
values['post-update'],
|
|
292
|
-
fromEnv(env, 'EXPO_RELEASE_POST_UPDATE')
|
|
293
|
-
)
|
|
294
|
-
),
|
|
295
|
-
updateExtraArgs: optionalString(
|
|
296
|
-
firstDefined(
|
|
297
|
-
values['update-extra-args'],
|
|
298
|
-
fromEnv(env, 'EXPO_RELEASE_UPDATE_EXTRA_ARGS')
|
|
299
|
-
)
|
|
300
|
-
),
|
|
301
|
-
group,
|
|
302
|
-
runtimeVersion: optionalString(
|
|
303
|
-
firstDefined(
|
|
304
|
-
values['runtime-version'],
|
|
305
|
-
fromEnv(env, 'EXPO_RELEASE_RUNTIME_VERSION')
|
|
306
|
-
)
|
|
307
|
-
),
|
|
308
|
-
message: optionalString(
|
|
309
|
-
firstDefined(values.message, fromEnv(env, 'EXPO_RELEASE_MESSAGE'))
|
|
310
|
-
),
|
|
311
|
-
fingerprint: optionalString(
|
|
312
|
-
firstDefined(values.fingerprint, fromEnv(env, 'EXPO_RELEASE_FINGERPRINT'))
|
|
313
|
-
),
|
|
314
|
-
dryRun:
|
|
315
|
-
values['dry-run'] === true ||
|
|
316
|
-
parseBoolean(fromEnv(env, 'EXPO_RELEASE_DRY_RUN'), false)
|
|
317
|
-
}
|
|
318
|
-
}
|