expo-release-it 0.1.0 → 0.1.2
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/build/command/build.js +156 -94
- package/build/command/build.js.map +1 -1
- package/build/command/bump.js +33 -27
- package/build/command/bump.js.map +1 -1
- package/build/command/init.js +161 -47
- package/build/command/init.js.map +1 -1
- package/build/command/pull.d.ts +5 -0
- package/build/command/pull.js +525 -0
- package/build/command/pull.js.map +1 -0
- package/build/command/submit.js +139 -84
- package/build/command/submit.js.map +1 -1
- package/build/command/upload.js +154 -104
- package/build/command/upload.js.map +1 -1
- package/build/index.js +414 -219
- package/build/index.js.map +1 -1
- package/build/util/FastlaneOption.js +9 -14
- package/build/util/FastlaneOption.js.map +1 -1
- package/build/util/FileUtil.d.ts +2 -1
- package/build/util/FileUtil.js +4 -0
- package/build/util/FileUtil.js.map +1 -1
- package/build/util/OptionHolder.d.ts +1 -3
- package/build/util/OptionHolder.js +7 -8
- package/build/util/OptionHolder.js.map +1 -1
- package/build/util/generateAppStoreConnectApiKeyFile.d.ts +3 -0
- package/build/util/{setup/promptCommonInputs.js → generateAppStoreConnectApiKeyFile.js} +36 -20
- package/build/util/generateAppStoreConnectApiKeyFile.js.map +1 -0
- package/build/util/injectTemplatePlaceHolders.js +8 -11
- package/build/util/injectTemplatePlaceHolders.js.map +1 -1
- package/build/util/input/InqueryInputs.d.ts +7 -1
- package/build/util/input/InqueryInputs.js +51 -13
- package/build/util/input/InqueryInputs.js.map +1 -1
- package/build/util/iterateAllFiles.js.map +1 -1
- package/build/util/logger.d.ts +1 -0
- package/build/util/logger.js +1 -0
- package/build/util/logger.js.map +1 -1
- package/build/util/{VersionUtil.js → setup/VersionUtil.js} +9 -9
- package/build/util/setup/VersionUtil.js.map +1 -0
- package/build/util/setup/execShellScript.d.ts +19 -0
- package/build/util/setup/execShellScript.js +19 -0
- package/build/util/setup/execShellScript.js.map +1 -0
- package/build/util/{hydrateKeyholderFileValues.js → setup/hydrateKeyholderFileValues.js} +14 -10
- package/build/util/setup/hydrateKeyholderFileValues.js.map +1 -0
- package/build/util/setup/prepareAndroid.js +64 -37
- package/build/util/setup/prepareAndroid.js.map +1 -1
- package/build/util/setup/prepareIos.js +63 -35
- package/build/util/setup/prepareIos.js.map +1 -1
- package/build/util/setup/setup.d.ts +2 -1
- package/build/util/setup/setup.js +30 -25
- package/build/util/setup/setup.js.map +1 -1
- package/build/util/spinner.d.ts +3 -0
- package/build/util/spinner.js +14 -0
- package/build/util/spinner.js.map +1 -0
- package/build/util/throwError.js +1 -0
- package/build/util/throwError.js.map +1 -1
- package/package.json +5 -5
- package/template/android/Gemfile +1 -1
- package/template/android/fastlane/Fastfile +2 -2
- package/template/ios/Gemfile +2 -1
- package/template/ios/fastlane/Appfile +0 -2
- package/template/ios/fastlane/Fastfile +20 -3
- package/build/util/VersionUtil.js.map +0 -1
- package/build/util/hydrateKeyholderFileValues.js.map +0 -1
- package/build/util/setup/promptCommonInputs.d.ts +0 -3
- package/build/util/setup/promptCommonInputs.js.map +0 -1
- package/template/ios/fastlane/Matchfile +0 -5
- /package/build/util/{VersionUtil.d.ts → setup/VersionUtil.d.ts} +0 -0
- /package/build/util/{hydrateKeyholderFileValues.d.ts → setup/hydrateKeyholderFileValues.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../package.json","../../src/util/FileUtil.ts","../../src/util/OptionHolder.ts","../../src/util/input/InqueryInputs.ts","../../src/util/setup/hydrateKeyholderFileValues.ts","../../src/util/logger.ts","../../src/util/throwError.ts","../../src/util/setup/VersionUtil.ts","../../src/util/EnvUtil.ts","../../src/util/setup/setup.ts","../../src/util/setup/execShellScript.ts","../../src/util/iterateAllFiles.ts","../../src/util/injectTemplatePlaceHolders.ts","../../src/util/spinner.ts","../../src/util/setup/prepareIos.ts","../../src/util/setup/prepareAndroid.ts","../../src/util/generateAppStoreConnectApiKeyFile.ts","../../src/command/pull.ts"],"sourcesContent":["{\n \"name\": \"expo-release-it\",\n \"module\": \"src/index.ts\",\n \"type\": \"module\",\n \"version\": \"0.1.1\",\n \"license\": \"MIT\",\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"yarn run build && NODE_ENV=development node bin/expo-release-it.mjs\",\n \"release\": \"yarn build && release-it\",\n \"android\": \"expo run:android\",\n \"ios\": \"expo run:ios\",\n \"t\": \"tsc --noEmit -p .\"\n },\n \"dependencies\": {\n \"@inquirer/prompts\": \"^7.4.1\",\n \"@mj-studio/js-util\": \"^1.1.20\",\n \"chalk\": \"^5.4.1\",\n \"commander\": \"^13.1.0\",\n \"execa\": \"^9.5.2\",\n \"fs-extra\": \"^11.3.0\",\n \"ora\": \"^8.2.0\",\n \"react\": \"18.3.1\",\n \"react-native\": \"0.76.9\",\n \"semver\": \"^7.7.1\",\n \"url\": \"^0.11.4\"\n },\n \"devDependencies\": {\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/semver\": \"^7.7.0\",\n \"prettier\": \"3.5.3\",\n \"release-it\": \"^19.0.1\",\n \"tiny-glob\": \"^0.2.9\",\n \"tsup\": \"^8.4.0\",\n \"typescript\": \"^5.8.3\"\n },\n \"workspaces\": [\n \"example\"\n ],\n \"bin\": \"./bin/expo-release-it.mjs\",\n \"files\": [\n \"build\",\n \"package.json\",\n \"bin\",\n \"template\"\n ],\n \"packageManager\": \"yarn@4.9.1\"\n}\n","import fs from 'fs-extra';\nimport * as path from 'path';\n\nexport const join = path.join;\nexport const resolve = path.resolve;\n\nexport function exist(path: string) {\n return fs.existsSync(path);\n}\n\nexport function isDir(path: string) {\n return exist(path) && fs.lstatSync(path).isDirectory();\n}\n\nexport function relativePath(from: string, to: string) {\n return path.relative(from, to);\n}\n\nexport function isFile(path: string) {\n return exist(path) && fs.lstatSync(path).isFile();\n}\n\nexport function read(path: string) {\n return fs.readFileSync(path, { encoding: 'utf8' });\n}\n\nexport function readdir(path: string) {\n return fs.readdirSync(path);\n}\n\n// you should require when possible(optimized in js)\nexport function readJsonSlow(path: string) {\n return fs.readJSONSync(path);\n}\n\nexport function write(p: string, content: string) {\n const dir = path.dirname(p);\n if (!exist(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n return fs.writeFileSync(p, content);\n}\nexport function copy(src: string, dest: string, options?: fs.CopyOptionsSync) {\n fs.copySync(src, dest, options);\n}\nexport function move(src: string, dest: string, options?: fs.MoveOptions) {\n fs.moveSync(src, dest, options);\n}\n\nexport function writeJson(path: string, json: any) {\n return write(path, JSON.stringify(json, null, 2));\n}\n\nexport function remove(path: string) {\n if (!exist(path)) {\n return;\n }\n\n if (fs.lstatSync(path).isDirectory()) {\n return fs.rmSync(path, { force: true, recursive: true });\n } else {\n return fs.rmSync(path, { force: true });\n }\n}\n\nexport async function iterateDir(path: string, fn: (file: string) => Promise<void> | void) {\n if (!isDir(path)) {\n return;\n }\n\n for (const file of fs.readdirSync(path)) {\n await fn(file);\n }\n}\n","import pkgJson from '../../package.json';\nimport { resolve } from './FileUtil';\nimport { fileURLToPath } from 'url';\n\n/**\n * CLI Comprehensive options\n * Each values can be empty by command and timing.\n */\nexport const OptionHolder: {\n // cli specific options\n cli: {\n // cli version\n version: string;\n // cli project root directory\n rootDir: string;\n // cli template source directory\n templateDir: string;\n };\n input: {\n platform: 'android' | 'ios';\n uploadMetadata: boolean;\n androidOutput: 'apk' | 'aab';\n pod: boolean;\n };\n keyholderMap: {\n ios_app_identifier: string;\n ios_developer_team_id: string;\n ios_match_git_url: string;\n ios_app_store_connect_api_key_id: string;\n ios_app_store_connect_api_key_issuer_id: string;\n ios_xcode_project_target: string;\n ios_match_password: string;\n\n android_keystore_store_password: string;\n android_keystore_key_alias: string;\n android_keystore_key_password: string;\n android_package_name: string;\n };\n templateDirNames: string[];\n // dest project root directory\n projectDir: string;\n // dest project output of init command direcotry\n outputOfInitDir: string;\n keyDir: string;\n keyholderFilePath: string;\n tempDir: string;\n versionName: string;\n versionCode: string;\n} = {\n cli: {\n version: pkgJson.version,\n rootDir: resolve(fileURLToPath(import.meta.url), '../..'),\n templateDir: resolve(fileURLToPath(import.meta.url), '../../template'),\n },\n input: {} as any,\n keyholderMap: {} as any,\n templateDirNames: ['key'],\n projectDir: '',\n outputOfInitDir: '',\n keyDir: '',\n keyholderFilePath: '',\n versionName: '',\n versionCode: '',\n tempDir: '',\n};\n","import { OptionHolder } from '../OptionHolder';\nimport { select } from '@inquirer/prompts';\nimport { is } from '@mj-studio/js-util';\nimport chalk from 'chalk';\n\nexport const InqueryInputs = {\n platform: async () => {\n if (!OptionHolder.input.platform) {\n OptionHolder.input.platform = await select({\n message: constructInquirerFormattedMessage({\n name: 'Platform',\n explanation: `Platform to run action`,\n }),\n choices: [\n { name: 'ios', value: 'ios', description: 'Release ios' },\n { name: 'android', value: 'android', description: 'Release android' },\n ],\n });\n }\n },\n podinstall: async () => {\n if (OptionHolder.input.platform === 'ios') {\n OptionHolder.input.pod = await select({\n message: constructInquirerFormattedMessage({\n name: 'Install CocoaPods?',\n }),\n choices: [\n { name: 'yes', value: true, description: 'Install pods before release' },\n { name: 'no', value: false, description: 'Skip pods install' },\n ],\n });\n }\n },\n androidBuildOutput: async () => {\n if (OptionHolder.input.platform === 'android') {\n if (!OptionHolder.input.androidOutput) {\n OptionHolder.input.androidOutput = await select({\n message: constructInquirerFormattedMessage({\n name: 'Android output artifact type',\n }),\n choices: [\n { name: 'aab', value: 'aab', description: 'Build as App bundle' },\n { name: 'apk', value: 'apk', description: 'Build as APK' },\n ],\n });\n }\n }\n },\n uploadMetadata: async () => {\n if (!is.boolean(OptionHolder.input.uploadMetadata)) {\n OptionHolder.input.uploadMetadata = await select({\n message: constructInquirerFormattedMessage({\n name: 'Upload Metadata(screenshot, title, description, ...)',\n }),\n choices: [\n { name: 'yes', value: true, description: 'Upload' },\n { name: 'no', value: false, description: \"Don't Upload\" },\n ],\n });\n }\n },\n};\n\nexport function constructInquirerFormattedMessage({\n example,\n explanation,\n referUrl,\n name,\n}: {\n name: string;\n explanation?: string;\n example?: string;\n referUrl?: string;\n}) {\n let ret = `${chalk.bold(name)}`;\n if (explanation) {\n ret += `\\n\\n${chalk.italic.blue(explanation)}`;\n }\n if (example) {\n ret += `\\n${chalk.italic(`${chalk.greenBright('example :')} ${example}`)}`;\n }\n if (referUrl) {\n ret += `\\n${chalk.italic(`${chalk.greenBright('references :')} ${chalk.underline.blue(referUrl)}`)}`;\n }\n\n if (explanation) {\n ret += '\\n';\n if (example || referUrl) {\n ret += '\\n';\n }\n }\n\n return ret;\n}\n","import { OptionHolder } from '../OptionHolder';\nimport { readJsonSlow, exist } from '../FileUtil';\n\nexport async function hydrateKeyholderFileValues() {\n if (exist(OptionHolder.keyholderFilePath)) {\n Object.assign(OptionHolder.keyholderMap, readJsonSlow(OptionHolder.keyholderFilePath));\n }\n}\n","import chalk from 'chalk';\n\nexport const logger = {\n success: (...msg: any[]) => console.log(chalk.green(`✔ ${msg.join(', ')}`)),\n done: (...msg: any[]) => console.log(chalk.green(`✔ ${msg.join(', ')} - Done`)),\n error: (...msg: any[]) => console.log(chalk.red(`✖ ${msg.join(', ')}`)),\n warn: (...msg: any[]) => console.log(chalk.yellow(`⚠ ${msg.join(', ')}`)),\n info: (...msg: any[]) => console.log(chalk.cyan(`ℹ ${msg.join(', ')}`)),\n title: (...msg: any[]) => console.log(chalk.bold.blue(`\\n${msg.join(', ')}`)),\n dim: (...msg: any[]) => console.log(chalk.dim(msg.join(', '))),\n};\n","import { logger } from './logger';\n\nexport function throwError(message: string, e?: any): never {\n if (e) {\n logger.error(message, e);\n } else {\n logger.error(message);\n }\n process.exit(1);\n}\n","import { OptionHolder } from '../OptionHolder';\nimport { throwError } from '../throwError';\nimport semver from 'semver';\nimport { readdir, read, readJsonSlow, write, writeJson, resolve } from '../FileUtil';\n\nexport async function parseBinaryVersions() {\n const files = readdir(OptionHolder.projectDir);\n\n const jsConfigFiles = ['app.config.ts', 'app.config.js', 'app.config.cjs', 'app.config.mjs'];\n const jsonConfigFile = 'app.json';\n\n for (const jsConfigFile of jsConfigFiles) {\n if (files.includes(jsConfigFile)) {\n await parseFromJsConfigFile(jsConfigFile);\n return;\n }\n }\n\n if (files.includes(jsonConfigFile)) {\n await parseFromJsonConfigFile(jsonConfigFile);\n return;\n }\n\n throwError('expo config file not found');\n\n async function parseFromJsConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n const content = read(filePath);\n\n const VERSION_NAME = /const VERSION_NAME = '(.*?)';/.exec(content)?.[1];\n const VERSION_CODE = /const VERSION_CODE = (.*?);/.exec(content)?.[1];\n\n if (!VERSION_NAME) {\n throwError('cannot parse version name');\n }\n if (!VERSION_CODE) {\n throwError('cannot parse version code');\n }\n\n if (!semver.valid(VERSION_NAME)) {\n throwError('VERSION_NAME is not a valid semver format');\n }\n\n OptionHolder.versionName = VERSION_NAME;\n OptionHolder.versionCode = VERSION_CODE;\n }\n\n async function parseFromJsonConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n const json = readJsonSlow(filePath);\n\n const versionName = json.expo?.version + '';\n const iosVersionCode = json.expo?.ios?.buildNumber + '';\n const androidVersionCode = json.expo?.android?.versionCode + '';\n\n if (!/\\d+/.test(iosVersionCode)) {\n throwError('app.json expo.ios.buildNumber is not an integer');\n }\n\n if (!/\\d+/.test(androidVersionCode)) {\n throwError('app.json expo.android.versionCode is not an integer');\n }\n\n if (iosVersionCode !== androidVersionCode) {\n throwError('app.json expo.ios.buildNumber is not equal with expo.android.versionCode');\n }\n\n if (!semver.valid(versionName)) {\n throwError('VERSION_NAME is not a valid semver format');\n }\n\n OptionHolder.versionName = versionName;\n OptionHolder.versionCode = iosVersionCode;\n }\n}\n\nexport async function injectBinaryVersions({\n versionCode,\n versionName,\n}: {\n versionName: string;\n versionCode: string;\n}) {\n const files = readdir(OptionHolder.projectDir);\n\n const jsConfigFiles = ['app.config.ts', 'app.config.js', 'app.config.cjs', 'app.config.mjs'];\n const jsonConfigFile = 'app.json';\n\n for (const jsConfigFile of jsConfigFiles) {\n if (files.includes(jsConfigFile)) {\n await injectToJsConfigFile(jsConfigFile);\n return;\n }\n }\n\n if (files.includes(jsonConfigFile)) {\n await injectToJsonConfigFile(jsonConfigFile);\n return;\n }\n\n throwError('expo config file not found');\n\n async function injectToJsConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n let content = read(filePath);\n\n content = content.replace(\n /const VERSION_NAME = '(.*?)';/,\n `const VERSION_NAME = '${versionName}';`,\n );\n content = content.replace(\n /const VERSION_CODE = (.*?);/,\n `const VERSION_CODE = ${versionCode};`,\n );\n\n write(filePath, content);\n }\n\n async function injectToJsonConfigFile(filename: string) {\n const filePath = resolve(OptionHolder.projectDir, filename);\n const json = readJsonSlow(filePath);\n\n json.expo.version = versionName;\n json.expo.ios.buildNumber = versionCode;\n json.expo.android.versionCode = +versionCode;\n\n writeJson(filePath, json);\n }\n}\n","export const isDev = process.env.NODE_ENV === 'development';\nexport const isWin = process.platform.startsWith('win');\n","import { hydrateKeyholderFileValues } from './hydrateKeyholderFileValues';\nimport { parseBinaryVersions } from './VersionUtil';\nimport { OptionHolder } from '../OptionHolder';\nimport { isDev } from '../EnvUtil';\nimport { resolve } from '../FileUtil';\n\nexport async function setup() {\n await setupBasicOptions();\n await hydrateKeyholderFileValues();\n await parseBinaryVersions();\n}\n\nexport async function setupBasicOptions() {\n OptionHolder.projectDir = isDev ? resolve('example') : resolve('.');\n OptionHolder.outputOfInitDir = resolve(OptionHolder.projectDir, 'expo-release-it');\n OptionHolder.keyDir = resolve(OptionHolder.outputOfInitDir, 'key');\n OptionHolder.keyholderFilePath = resolve(OptionHolder.outputOfInitDir, 'keyholder.json');\n OptionHolder.tempDir = resolve(OptionHolder.outputOfInitDir, '.temp');\n}\n","import { execa, type Options } from 'execa';\n\nexport const exe = execa({\n stdin: 'pipe',\n stdout: 'inherit',\n stderr: 'inherit',\n shell: false,\n});\n\nexport const yesShell = <OptionsType extends Options>(\n command: string,\n args: string[] = [],\n options: OptionsType,\n) => {\n const subProcess = exe(command, args, { ...options, stdin: 'pipe' });\n subProcess.stdin?.write('y\\n');\n subProcess.stdin?.end();\n return subProcess;\n};\n","import { readdir, isFile, isDir, join } from './FileUtil';\n\nexport async function iterateAllFiles(root: string, callback: (filePath: string) => Promise<void>) {\n await go(root);\n\n async function go(dirPath: string) {\n const paths = readdir(dirPath).map((f) => join(dirPath, f));\n\n for (const p of paths) {\n if (isFile(p)) {\n await callback(p);\n } else if (isDir(p)) {\n await go(p);\n }\n }\n }\n}\n","import { iterateAllFiles } from './iterateAllFiles';\nimport { read, relativePath, write } from './FileUtil';\nimport { OptionHolder } from './OptionHolder';\nimport * as path from 'node:path';\n\nexport async function injectTemplatePlaceHolders(root: string) {\n await iterateAllFiles(root, async (filePath: string) => {\n const dirPath = path.dirname(filePath);\n let content = read(filePath);\n for (const [key, value] of Object.entries(OptionHolder.keyholderMap)) {\n content = content.replaceAll(`{{${key}}}`, value);\n }\n // dynamic replacements\n content = content.replaceAll(\n '{{key_dir_relative_path}}',\n relativePath(dirPath, OptionHolder.keyDir),\n );\n write(filePath, content);\n });\n}\n","import { oraPromise } from 'ora';\nimport chalk from 'chalk';\n\nexport async function spinner<T>(text: string, promise: Promise<T>): Promise<T> {\n return oraPromise(promise, {\n text,\n successText: chalk.green(`${text} - Done`),\n failText: chalk.red(`${text} - Failed`),\n });\n}\n","import { remove, resolve, iterateDir, copy } from '../FileUtil';\nimport { OptionHolder } from '../OptionHolder';\nimport { injectTemplatePlaceHolders } from '../injectTemplatePlaceHolders';\nimport { spinner } from '../spinner';\nimport { exe, yesShell } from './execShellScript';\nimport { logger } from '../logger';\n\nexport async function prepareIos() {\n const srcDir = resolve(OptionHolder.cli.templateDir, 'ios');\n const destDir = resolve(OptionHolder.projectDir, 'ios');\n\n await yesShell('expo', ['prebuild', '-p', 'ios', '--no-install'], {\n cwd: OptionHolder.projectDir,\n });\n logger.success('Expo Prebuild - Done');\n\n await spinner(\n 'Inject templates',\n iterateDir(srcDir, async (file) => {\n const filePath = resolve(srcDir, file);\n remove(resolve(destDir, file));\n copy(filePath, resolve(destDir, file));\n }),\n );\n\n await spinner(\n 'Hydrate template placeholders',\n injectTemplatePlaceHolders(resolve(destDir, 'fastlane')),\n );\n\n await exe({ cwd: destDir })`bundle install`;\n logger.success('Bunder Install - Done');\n}\n","import { resolve, remove, iterateDir, copy, read, write, relativePath } from '../FileUtil';\nimport { OptionHolder } from '../OptionHolder';\nimport { injectTemplatePlaceHolders } from '../injectTemplatePlaceHolders';\nimport { spinner } from '../spinner';\nimport { exe, yesShell } from './execShellScript';\nimport { logger } from '../logger';\n\nexport async function prepareAndroid() {\n const srcDir = resolve(OptionHolder.cli.templateDir, 'android');\n const destDir = resolve(OptionHolder.projectDir, 'android');\n\n await yesShell('expo', ['prebuild', '-p', 'android', '--no-install'], {\n cwd: OptionHolder.projectDir,\n });\n logger.success('Expo Prebuild - Done');\n\n await spinner(\n 'Inject Templates',\n iterateDir(srcDir, async (file) => {\n const filePath = resolve(srcDir, file);\n remove(resolve(destDir, file));\n copy(filePath, resolve(destDir, file));\n }),\n );\n\n await spinner('Overwrite Android Release Signing Config', replaceAndroidSigningConfig(destDir));\n\n await spinner(\n 'Hydrate template placeholders',\n injectTemplatePlaceHolders(resolve(destDir, 'fastlane')),\n );\n\n await exe({ cwd: destDir })`bundle install`;\n logger.success('Bunder Install - Done');\n}\n\nasync function replaceAndroidSigningConfig(destDir: string) {\n const buildGradleDirPath = resolve(destDir, 'app');\n const buildGradlePath = resolve(destDir, 'app', 'build.gradle');\n const {\n android_keystore_store_password,\n android_keystore_key_alias,\n android_keystore_key_password,\n } = OptionHolder.keyholderMap;\n\n const content = read(buildGradlePath).replace(\n /signingConfigs.*?{.*?debug.*?{.*?}.*?}/s,\n `\n signingConfigs {\n debug {\n storeFile file('${relativePath(buildGradleDirPath, resolve(OptionHolder.outputOfInitDir, 'key', 'android_release_keystore.jks'))}')\n storePassword '${android_keystore_store_password}'\n keyAlias '${android_keystore_key_alias}'\n keyPassword '${android_keystore_key_password}'\n }\n }\n `,\n );\n write(buildGradlePath, content);\n}\n","import { OptionHolder } from './OptionHolder';\nimport { resolve, read, writeJson, join } from './FileUtil';\n\nexport function generateAppStoreConnectApiKeyFile() {\n const json = {\n key: read(resolve(OptionHolder.keyDir, 'ios_testflight_upload_api_key.p8')),\n key_id: OptionHolder.keyholderMap.ios_app_store_connect_api_key_id,\n issuer_id: OptionHolder.keyholderMap.ios_app_store_connect_api_key_issuer_id,\n };\n const file = join(OptionHolder.tempDir, 'app_store_connect_api.json');\n writeJson(file, json);\n return file;\n}\n","import { OptionHolder } from '../util/OptionHolder';\nimport { InqueryInputs } from '../util/input/InqueryInputs';\nimport { setup } from '../util/setup/setup';\nimport { join, move } from '../util/FileUtil';\nimport { exe } from '../util/setup/execShellScript';\nimport { prepareIos } from '../util/setup/prepareIos';\nimport { prepareAndroid } from '../util/setup/prepareAndroid';\nimport { generateAppStoreConnectApiKeyFile } from '../util/generateAppStoreConnectApiKeyFile';\n\nexport async function pull({ options }: { options: any }) {\n Object.assign(OptionHolder.input, options);\n await setup();\n await promptInputs();\n\n if (OptionHolder.input.platform === 'ios') {\n await pullIosMetadata();\n } else {\n await pullAndroidMetadata();\n }\n}\n\nasync function promptInputs() {\n await InqueryInputs.platform();\n}\n\nasync function pullIosMetadata() {\n await prepareIos();\n const iosDir = join(OptionHolder.projectDir, 'ios');\n const exeEnv = exe({\n cwd: iosDir,\n env: {\n MATCH_PASSWORD: OptionHolder.keyholderMap.ios_match_password,\n },\n });\n\n await exeEnv('bundle', [\n 'exec',\n 'fastlane',\n 'deliver',\n 'download_metadata',\n '-f',\n '--api_key_path',\n generateAppStoreConnectApiKeyFile(),\n ]);\n\n await exeEnv('bundle', [\n 'exec',\n 'fastlane',\n 'deliver',\n 'download_screenshots',\n '-f',\n '--api_key_path',\n generateAppStoreConnectApiKeyFile(),\n ]);\n\n const metadataSrcDir = join(iosDir, 'fastlane/metadata');\n const screenshotsSrcDir = join(iosDir, 'fastlane/screenshots');\n\n const metadataDestDir = join(OptionHolder.outputOfInitDir, 'metadata/ios/metadata');\n const screenshotsDestDir = join(OptionHolder.outputOfInitDir, 'metadata/ios/screenshots');\n\n move(metadataSrcDir, metadataDestDir);\n move(screenshotsSrcDir, screenshotsDestDir);\n}\n\nasync function pullAndroidMetadata() {\n await prepareAndroid();\n const androidDir = join(OptionHolder.projectDir, 'android');\n\n await exe('bundle', ['exec', 'fastlane', 'supply', 'init'], { cwd: androidDir });\n}\n"],"mappings":"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","names":["join","resolve","path","resolve","chalk","resolve","resolve","join","path","chalk","resolve","resolve","resolve","join","join"]}
|
package/build/command/submit.js
CHANGED
|
@@ -3,11 +3,11 @@ var package_default = {
|
|
|
3
3
|
name: "expo-release-it",
|
|
4
4
|
module: "src/index.ts",
|
|
5
5
|
type: "module",
|
|
6
|
-
version: "0.
|
|
6
|
+
version: "0.1.1",
|
|
7
7
|
license: "MIT",
|
|
8
8
|
scripts: {
|
|
9
9
|
build: "tsup",
|
|
10
|
-
dev: "
|
|
10
|
+
dev: "yarn run build && NODE_ENV=development node bin/expo-release-it.mjs",
|
|
11
11
|
release: "yarn build && release-it",
|
|
12
12
|
android: "expo run:android",
|
|
13
13
|
ios: "expo run:ios",
|
|
@@ -18,15 +18,15 @@ var package_default = {
|
|
|
18
18
|
"@mj-studio/js-util": "^1.1.20",
|
|
19
19
|
chalk: "^5.4.1",
|
|
20
20
|
commander: "^13.1.0",
|
|
21
|
+
execa: "^9.5.2",
|
|
21
22
|
"fs-extra": "^11.3.0",
|
|
23
|
+
ora: "^8.2.0",
|
|
22
24
|
react: "18.3.1",
|
|
23
25
|
"react-native": "0.76.9",
|
|
24
26
|
semver: "^7.7.1",
|
|
25
|
-
url: "^0.11.4"
|
|
26
|
-
zx: "^8.5.3"
|
|
27
|
+
url: "^0.11.4"
|
|
27
28
|
},
|
|
28
29
|
devDependencies: {
|
|
29
|
-
"@types/bun": "latest",
|
|
30
30
|
"@types/fs-extra": "^11.0.4",
|
|
31
31
|
"@types/semver": "^7.7.0",
|
|
32
32
|
prettier: "3.5.3",
|
|
@@ -114,37 +114,27 @@ var OptionHolder = {
|
|
|
114
114
|
input: {},
|
|
115
115
|
keyholderMap: {},
|
|
116
116
|
templateDirNames: ["key"],
|
|
117
|
-
iosBundleIdentifier: "",
|
|
118
|
-
androidPackageName: "",
|
|
119
117
|
projectDir: "",
|
|
120
118
|
outputOfInitDir: "",
|
|
121
119
|
keyDir: "",
|
|
122
120
|
keyholderFilePath: "",
|
|
123
121
|
versionName: "",
|
|
124
|
-
versionCode: ""
|
|
122
|
+
versionCode: "",
|
|
123
|
+
tempDir: ""
|
|
125
124
|
};
|
|
126
125
|
|
|
127
|
-
// src/util/
|
|
128
|
-
var isDev = process.env.NODE_ENV === "development";
|
|
129
|
-
var isWin = process.platform.startsWith("win");
|
|
130
|
-
|
|
131
|
-
// src/util/setup/promptCommonInputs.ts
|
|
132
|
-
async function promptCommonInputs() {
|
|
133
|
-
OptionHolder.projectDir = isDev ? resolve2("example") : resolve2(".");
|
|
134
|
-
OptionHolder.outputOfInitDir = resolve2(OptionHolder.projectDir, "expo-release-it");
|
|
135
|
-
OptionHolder.keyDir = resolve2(OptionHolder.outputOfInitDir, "key");
|
|
136
|
-
OptionHolder.keyholderFilePath = resolve2(OptionHolder.outputOfInitDir, "keyholder.json");
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// src/util/hydrateKeyholderFileValues.ts
|
|
126
|
+
// src/util/setup/hydrateKeyholderFileValues.ts
|
|
140
127
|
async function hydrateKeyholderFileValues() {
|
|
141
|
-
|
|
128
|
+
if (exist(OptionHolder.keyholderFilePath)) {
|
|
129
|
+
Object.assign(OptionHolder.keyholderMap, readJsonSlow(OptionHolder.keyholderFilePath));
|
|
130
|
+
}
|
|
142
131
|
}
|
|
143
132
|
|
|
144
133
|
// src/util/logger.ts
|
|
145
134
|
import chalk from "chalk";
|
|
146
135
|
var logger = {
|
|
147
136
|
success: (...msg) => console.log(chalk.green(`\u2714 ${msg.join(", ")}`)),
|
|
137
|
+
done: (...msg) => console.log(chalk.green(`\u2714 ${msg.join(", ")} - Done`)),
|
|
148
138
|
error: (...msg) => console.log(chalk.red(`\u2716 ${msg.join(", ")}`)),
|
|
149
139
|
warn: (...msg) => console.log(chalk.yellow(`\u26A0 ${msg.join(", ")}`)),
|
|
150
140
|
info: (...msg) => console.log(chalk.cyan(`\u2139 ${msg.join(", ")}`)),
|
|
@@ -163,7 +153,7 @@ function throwError(message, e) {
|
|
|
163
153
|
process.exit(1);
|
|
164
154
|
}
|
|
165
155
|
|
|
166
|
-
// src/util/VersionUtil.ts
|
|
156
|
+
// src/util/setup/VersionUtil.ts
|
|
167
157
|
import semver from "semver";
|
|
168
158
|
async function parseBinaryVersions() {
|
|
169
159
|
const files = readdir(OptionHolder.projectDir);
|
|
@@ -220,15 +210,26 @@ async function parseBinaryVersions() {
|
|
|
220
210
|
}
|
|
221
211
|
}
|
|
222
212
|
|
|
213
|
+
// src/util/EnvUtil.ts
|
|
214
|
+
var isDev = process.env.NODE_ENV === "development";
|
|
215
|
+
var isWin = process.platform.startsWith("win");
|
|
216
|
+
|
|
223
217
|
// src/util/setup/setup.ts
|
|
224
218
|
async function setup() {
|
|
225
|
-
await
|
|
219
|
+
await setupBasicOptions();
|
|
226
220
|
await hydrateKeyholderFileValues();
|
|
227
221
|
await parseBinaryVersions();
|
|
228
222
|
}
|
|
223
|
+
async function setupBasicOptions() {
|
|
224
|
+
OptionHolder.projectDir = isDev ? resolve2("example") : resolve2(".");
|
|
225
|
+
OptionHolder.outputOfInitDir = resolve2(OptionHolder.projectDir, "expo-release-it");
|
|
226
|
+
OptionHolder.keyDir = resolve2(OptionHolder.outputOfInitDir, "key");
|
|
227
|
+
OptionHolder.keyholderFilePath = resolve2(OptionHolder.outputOfInitDir, "keyholder.json");
|
|
228
|
+
OptionHolder.tempDir = resolve2(OptionHolder.outputOfInitDir, ".temp");
|
|
229
|
+
}
|
|
229
230
|
|
|
230
231
|
// src/command/submit.ts
|
|
231
|
-
import
|
|
232
|
+
import chalk4 from "chalk";
|
|
232
233
|
|
|
233
234
|
// src/util/calculateElapsed.ts
|
|
234
235
|
import { padZero } from "@mj-studio/js-util";
|
|
@@ -239,12 +240,6 @@ function calculateElapsed(t) {
|
|
|
239
240
|
return `${minutes}:${padZero(seconds)}`;
|
|
240
241
|
}
|
|
241
242
|
|
|
242
|
-
// src/command/submit.ts
|
|
243
|
-
import { spinner as spinner3, $ as $3 } from "zx";
|
|
244
|
-
|
|
245
|
-
// src/util/setup/prepareAndroid.ts
|
|
246
|
-
import { spinner, $ } from "zx";
|
|
247
|
-
|
|
248
243
|
// src/util/iterateAllFiles.ts
|
|
249
244
|
async function iterateAllFiles(root, callback) {
|
|
250
245
|
await go(root);
|
|
@@ -261,7 +256,7 @@ async function iterateAllFiles(root, callback) {
|
|
|
261
256
|
}
|
|
262
257
|
|
|
263
258
|
// src/util/injectTemplatePlaceHolders.ts
|
|
264
|
-
import
|
|
259
|
+
import * as path2 from "node:path";
|
|
265
260
|
async function injectTemplatePlaceHolders(root) {
|
|
266
261
|
await iterateAllFiles(root, async (filePath) => {
|
|
267
262
|
const dirPath = path2.dirname(filePath);
|
|
@@ -277,25 +272,55 @@ async function injectTemplatePlaceHolders(root) {
|
|
|
277
272
|
});
|
|
278
273
|
}
|
|
279
274
|
|
|
275
|
+
// src/util/spinner.ts
|
|
276
|
+
import { oraPromise } from "ora";
|
|
277
|
+
import chalk2 from "chalk";
|
|
278
|
+
async function spinner(text, promise) {
|
|
279
|
+
return oraPromise(promise, {
|
|
280
|
+
text,
|
|
281
|
+
successText: chalk2.green(`${text} - Done`),
|
|
282
|
+
failText: chalk2.red(`${text} - Failed`)
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// src/util/setup/execShellScript.ts
|
|
287
|
+
import { execa } from "execa";
|
|
288
|
+
var exe = execa({
|
|
289
|
+
stdin: "pipe",
|
|
290
|
+
stdout: "inherit",
|
|
291
|
+
stderr: "inherit",
|
|
292
|
+
shell: false
|
|
293
|
+
});
|
|
294
|
+
var yesShell = (command, args = [], options) => {
|
|
295
|
+
const subProcess = exe(command, args, { ...options, stdin: "pipe" });
|
|
296
|
+
subProcess.stdin?.write("y\n");
|
|
297
|
+
subProcess.stdin?.end();
|
|
298
|
+
return subProcess;
|
|
299
|
+
};
|
|
300
|
+
|
|
280
301
|
// src/util/setup/prepareAndroid.ts
|
|
281
302
|
async function prepareAndroid() {
|
|
282
303
|
const srcDir = resolve2(OptionHolder.cli.templateDir, "android");
|
|
283
304
|
const destDir = resolve2(OptionHolder.projectDir, "android");
|
|
305
|
+
await yesShell("expo", ["prebuild", "-p", "android", "--no-install"], {
|
|
306
|
+
cwd: OptionHolder.projectDir
|
|
307
|
+
});
|
|
308
|
+
logger.success("Expo Prebuild - Done");
|
|
284
309
|
await spinner(
|
|
285
|
-
"
|
|
286
|
-
() =>
|
|
310
|
+
"Inject Templates",
|
|
311
|
+
iterateDir(srcDir, async (file) => {
|
|
312
|
+
const filePath = resolve2(srcDir, file);
|
|
313
|
+
remove(resolve2(destDir, file));
|
|
314
|
+
copy(filePath, resolve2(destDir, file));
|
|
315
|
+
})
|
|
287
316
|
);
|
|
288
|
-
|
|
289
|
-
await
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
})
|
|
294
|
-
logger.success("
|
|
295
|
-
await replaceAndroidSigningConfig(destDir);
|
|
296
|
-
logger.success("Overwrite Android Release Signing Config");
|
|
297
|
-
await injectTemplatePlaceHolders(resolve2(destDir, "fastlane"));
|
|
298
|
-
logger.success("Hydrate template placeholders");
|
|
317
|
+
await spinner("Overwrite Android Release Signing Config", replaceAndroidSigningConfig(destDir));
|
|
318
|
+
await spinner(
|
|
319
|
+
"Hydrate template placeholders",
|
|
320
|
+
injectTemplatePlaceHolders(resolve2(destDir, "fastlane"))
|
|
321
|
+
);
|
|
322
|
+
await exe({ cwd: destDir })`bundle install`;
|
|
323
|
+
logger.success("Bunder Install - Done");
|
|
299
324
|
}
|
|
300
325
|
async function replaceAndroidSigningConfig(destDir) {
|
|
301
326
|
const buildGradleDirPath = resolve2(destDir, "app");
|
|
@@ -322,33 +347,41 @@ async function replaceAndroidSigningConfig(destDir) {
|
|
|
322
347
|
}
|
|
323
348
|
|
|
324
349
|
// src/util/setup/prepareIos.ts
|
|
325
|
-
import { $ as $2, spinner as spinner2 } from "zx";
|
|
326
350
|
async function prepareIos() {
|
|
327
351
|
const srcDir = resolve2(OptionHolder.cli.templateDir, "ios");
|
|
328
352
|
const destDir = resolve2(OptionHolder.projectDir, "ios");
|
|
329
|
-
await
|
|
330
|
-
|
|
331
|
-
() => $2`cd ${OptionHolder.projectDir} && expo prebuild -p ios --no-install`
|
|
332
|
-
);
|
|
333
|
-
logger.success("expo prebuild");
|
|
334
|
-
await iterateDir(srcDir, async (file) => {
|
|
335
|
-
const filePath = resolve2(srcDir, file);
|
|
336
|
-
remove(resolve2(destDir, file));
|
|
337
|
-
copy(filePath, resolve2(destDir, file));
|
|
353
|
+
await yesShell("expo", ["prebuild", "-p", "ios", "--no-install"], {
|
|
354
|
+
cwd: OptionHolder.projectDir
|
|
338
355
|
});
|
|
339
|
-
logger.success("
|
|
340
|
-
await
|
|
341
|
-
|
|
356
|
+
logger.success("Expo Prebuild - Done");
|
|
357
|
+
await spinner(
|
|
358
|
+
"Inject templates",
|
|
359
|
+
iterateDir(srcDir, async (file) => {
|
|
360
|
+
const filePath = resolve2(srcDir, file);
|
|
361
|
+
remove(resolve2(destDir, file));
|
|
362
|
+
copy(filePath, resolve2(destDir, file));
|
|
363
|
+
})
|
|
364
|
+
);
|
|
365
|
+
await spinner(
|
|
366
|
+
"Hydrate template placeholders",
|
|
367
|
+
injectTemplatePlaceHolders(resolve2(destDir, "fastlane"))
|
|
368
|
+
);
|
|
369
|
+
await exe({ cwd: destDir })`bundle install`;
|
|
370
|
+
logger.success("Bunder Install - Done");
|
|
342
371
|
}
|
|
343
372
|
|
|
344
373
|
// src/util/input/InqueryInputs.ts
|
|
345
374
|
import { select } from "@inquirer/prompts";
|
|
346
375
|
import { is } from "@mj-studio/js-util";
|
|
376
|
+
import chalk3 from "chalk";
|
|
347
377
|
var InqueryInputs = {
|
|
348
378
|
platform: async () => {
|
|
349
379
|
if (!OptionHolder.input.platform) {
|
|
350
380
|
OptionHolder.input.platform = await select({
|
|
351
|
-
message:
|
|
381
|
+
message: constructInquirerFormattedMessage({
|
|
382
|
+
name: "Platform",
|
|
383
|
+
explanation: `Platform to run action`
|
|
384
|
+
}),
|
|
352
385
|
choices: [
|
|
353
386
|
{ name: "ios", value: "ios", description: "Release ios" },
|
|
354
387
|
{ name: "android", value: "android", description: "Release android" }
|
|
@@ -359,7 +392,9 @@ var InqueryInputs = {
|
|
|
359
392
|
podinstall: async () => {
|
|
360
393
|
if (OptionHolder.input.platform === "ios") {
|
|
361
394
|
OptionHolder.input.pod = await select({
|
|
362
|
-
message:
|
|
395
|
+
message: constructInquirerFormattedMessage({
|
|
396
|
+
name: "Install CocoaPods?"
|
|
397
|
+
}),
|
|
363
398
|
choices: [
|
|
364
399
|
{ name: "yes", value: true, description: "Install pods before release" },
|
|
365
400
|
{ name: "no", value: false, description: "Skip pods install" }
|
|
@@ -371,7 +406,9 @@ var InqueryInputs = {
|
|
|
371
406
|
if (OptionHolder.input.platform === "android") {
|
|
372
407
|
if (!OptionHolder.input.androidOutput) {
|
|
373
408
|
OptionHolder.input.androidOutput = await select({
|
|
374
|
-
message:
|
|
409
|
+
message: constructInquirerFormattedMessage({
|
|
410
|
+
name: "Android output artifact type"
|
|
411
|
+
}),
|
|
375
412
|
choices: [
|
|
376
413
|
{ name: "aab", value: "aab", description: "Build as App bundle" },
|
|
377
414
|
{ name: "apk", value: "apk", description: "Build as APK" }
|
|
@@ -383,7 +420,9 @@ var InqueryInputs = {
|
|
|
383
420
|
uploadMetadata: async () => {
|
|
384
421
|
if (!is.boolean(OptionHolder.input.uploadMetadata)) {
|
|
385
422
|
OptionHolder.input.uploadMetadata = await select({
|
|
386
|
-
message:
|
|
423
|
+
message: constructInquirerFormattedMessage({
|
|
424
|
+
name: "Upload Metadata(screenshot, title, description, ...)"
|
|
425
|
+
}),
|
|
387
426
|
choices: [
|
|
388
427
|
{ name: "yes", value: true, description: "Upload" },
|
|
389
428
|
{ name: "no", value: false, description: "Don't Upload" }
|
|
@@ -392,13 +431,41 @@ var InqueryInputs = {
|
|
|
392
431
|
}
|
|
393
432
|
}
|
|
394
433
|
};
|
|
434
|
+
function constructInquirerFormattedMessage({
|
|
435
|
+
example,
|
|
436
|
+
explanation,
|
|
437
|
+
referUrl,
|
|
438
|
+
name
|
|
439
|
+
}) {
|
|
440
|
+
let ret = `${chalk3.bold(name)}`;
|
|
441
|
+
if (explanation) {
|
|
442
|
+
ret += `
|
|
443
|
+
|
|
444
|
+
${chalk3.italic.blue(explanation)}`;
|
|
445
|
+
}
|
|
446
|
+
if (example) {
|
|
447
|
+
ret += `
|
|
448
|
+
${chalk3.italic(`${chalk3.greenBright("example :")} ${example}`)}`;
|
|
449
|
+
}
|
|
450
|
+
if (referUrl) {
|
|
451
|
+
ret += `
|
|
452
|
+
${chalk3.italic(`${chalk3.greenBright("references :")} ${chalk3.underline.blue(referUrl)}`)}`;
|
|
453
|
+
}
|
|
454
|
+
if (explanation) {
|
|
455
|
+
ret += "\n";
|
|
456
|
+
if (example || referUrl) {
|
|
457
|
+
ret += "\n";
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return ret;
|
|
461
|
+
}
|
|
395
462
|
|
|
396
463
|
// src/util/FastlaneOption.ts
|
|
397
464
|
function getAndroidFastlaneOptions() {
|
|
398
465
|
return [
|
|
466
|
+
...Object.entries(OptionHolder.keyholderMap).map(([k, v]) => `${k}:${v}`),
|
|
399
467
|
`version_name:${OptionHolder.versionName}`,
|
|
400
468
|
`version_code:${OptionHolder.versionCode}`,
|
|
401
|
-
`package_name:${OptionHolder.androidPackageName}`,
|
|
402
469
|
`upload_metadata:${OptionHolder.input.uploadMetadata}`,
|
|
403
470
|
`aab_path:${resolve2(OptionHolder.outputOfInitDir, "output", "android", "aab", "app-release.aab")}`,
|
|
404
471
|
`apk_path:${resolve2(OptionHolder.outputOfInitDir, "output", "android", "apk", "app-release.apk")}`,
|
|
@@ -408,13 +475,9 @@ function getAndroidFastlaneOptions() {
|
|
|
408
475
|
}
|
|
409
476
|
function getIosFastlaneOptions() {
|
|
410
477
|
return [
|
|
478
|
+
...Object.entries(OptionHolder.keyholderMap).map(([k, v]) => `${k}:${v}`),
|
|
411
479
|
`version_name:${OptionHolder.versionName}`,
|
|
412
480
|
`version_code:${OptionHolder.versionCode}`,
|
|
413
|
-
`ios_app_identifier:${OptionHolder.iosBundleIdentifier}`,
|
|
414
|
-
`ios_xcode_project_target:${OptionHolder.keyholderMap.ios_xcode_project_target}`,
|
|
415
|
-
`ios_developer_team_id:${OptionHolder.keyholderMap.ios_developer_team_id}`,
|
|
416
|
-
`ios_app_store_connect_api_key_id:${OptionHolder.keyholderMap.ios_app_store_connect_api_key_id}`,
|
|
417
|
-
`ios_app_store_connect_api_key_issuer_id:${OptionHolder.keyholderMap.ios_app_store_connect_api_key_issuer_id}`,
|
|
418
481
|
`api_key_filepath:${resolve2(OptionHolder.keyDir, "ios_testflight_upload_api_key.p8")}`,
|
|
419
482
|
`upload_metadata:${OptionHolder.input.uploadMetadata}`,
|
|
420
483
|
`ipa_path:${resolve2(OptionHolder.outputOfInitDir, "output", "ios", "app.ipa")}`,
|
|
@@ -433,10 +496,10 @@ async function submit({ options }) {
|
|
|
433
496
|
logger.info(`Version: ${OptionHolder.versionName}(${OptionHolder.versionCode})`);
|
|
434
497
|
if (OptionHolder.input.platform === "ios") {
|
|
435
498
|
await submitIos();
|
|
436
|
-
logger.success(`Appstore Review Submitted ${
|
|
499
|
+
logger.success(`Appstore Review Submitted ${chalk4.bold.inverse(calculateElapsed(startTime))}`);
|
|
437
500
|
} else {
|
|
438
501
|
await submitAndroid();
|
|
439
|
-
logger.success(`Playstore Review Submitted ${
|
|
502
|
+
logger.success(`Playstore Review Submitted ${chalk4.bold.inverse(calculateElapsed(startTime))}`);
|
|
440
503
|
}
|
|
441
504
|
}
|
|
442
505
|
async function promptInputs() {
|
|
@@ -444,31 +507,23 @@ async function promptInputs() {
|
|
|
444
507
|
await InqueryInputs.uploadMetadata();
|
|
445
508
|
}
|
|
446
509
|
async function submitAndroid() {
|
|
447
|
-
const $$ = $3({
|
|
448
|
-
verbose: false,
|
|
449
|
-
cwd: resolve2(OptionHolder.projectDir, "android")
|
|
450
|
-
});
|
|
451
510
|
await prepareAndroid();
|
|
452
511
|
await fastlane();
|
|
453
512
|
async function fastlane() {
|
|
454
|
-
await
|
|
455
|
-
|
|
456
|
-
|
|
513
|
+
await exe({
|
|
514
|
+
cwd: resolve2(OptionHolder.projectDir, "android")
|
|
515
|
+
})`bundle exec fastlane sumbit ${getIosFastlaneOptions()}`;
|
|
457
516
|
}
|
|
458
517
|
}
|
|
459
518
|
async function submitIos() {
|
|
460
519
|
const iosDir = resolve2(OptionHolder.projectDir, "ios");
|
|
461
|
-
const $$ = $3({
|
|
462
|
-
verbose: false,
|
|
463
|
-
cwd: iosDir
|
|
464
|
-
});
|
|
465
520
|
await prepareIos();
|
|
466
521
|
await fastlane();
|
|
467
522
|
async function fastlane() {
|
|
468
|
-
await spinner3("Bundler Install", () => $$`bundle install`);
|
|
469
|
-
logger.success("Bundler Install");
|
|
470
523
|
remove(resolve2(iosDir, ".xcode.env.local"));
|
|
471
|
-
await
|
|
524
|
+
await exe({
|
|
525
|
+
cwd: iosDir
|
|
526
|
+
})`bundle exec fastlane submit ${getAndroidFastlaneOptions()}`;
|
|
472
527
|
}
|
|
473
528
|
}
|
|
474
529
|
export {
|