expo-release-it 0.1.2 → 0.1.4
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 +133 -12
- package/build/command/build.js +135 -60
- package/build/command/build.js.map +1 -1
- package/build/command/bump.js +15 -18
- package/build/command/bump.js.map +1 -1
- package/build/command/init.js +13 -9
- package/build/command/init.js.map +1 -1
- package/build/command/pull.js +136 -50
- package/build/command/pull.js.map +1 -1
- package/build/command/submit.js +135 -55
- package/build/command/submit.js.map +1 -1
- package/build/command/upload.js +136 -56
- package/build/command/upload.js.map +1 -1
- package/build/index.js +194 -141
- package/build/index.js.map +1 -1
- package/build/util/FastlaneOption.js +10 -7
- package/build/util/FastlaneOption.js.map +1 -1
- package/build/util/MetadataSyncUtil.d.ts +4 -0
- package/build/util/MetadataSyncUtil.js +169 -0
- package/build/util/MetadataSyncUtil.js.map +1 -0
- package/build/util/OptionHolder.d.ts +2 -1
- package/build/util/OptionHolder.js +4 -2
- package/build/util/OptionHolder.js.map +1 -1
- package/build/util/generateAppStoreConnectApiKeyFile.js +5 -3
- package/build/util/generateAppStoreConnectApiKeyFile.js.map +1 -1
- package/build/util/injectTemplatePlaceHolders.js +14 -21
- package/build/util/injectTemplatePlaceHolders.js.map +1 -1
- package/build/util/input/InqueryInputs.d.ts +1 -0
- package/build/util/input/InqueryInputs.js +19 -2
- package/build/util/input/InqueryInputs.js.map +1 -1
- package/build/util/setup/VersionUtil.js +10 -12
- package/build/util/setup/VersionUtil.js.map +1 -1
- package/build/util/setup/hydrateKeyholderFileValues.js +4 -2
- package/build/util/setup/hydrateKeyholderFileValues.js.map +1 -1
- package/build/util/setup/prepareAndroid.js +56 -28
- package/build/util/setup/prepareAndroid.js.map +1 -1
- package/build/util/setup/prepareIos.js +61 -27
- package/build/util/setup/prepareIos.js.map +1 -1
- package/build/util/setup/setup.js +12 -8
- package/build/util/setup/setup.js.map +1 -1
- package/package.json +3 -1
- package/template/android/fastlane/Fastfile +2 -0
- package/template/android/fastlane/Appfile +0 -2
- package/template/android/fastlane/metadata/android/ko-KR/changelogs/default.txt +0 -1
- package/template/android/fastlane/metadata/android/ko-KR/full_description.txt +0 -0
- package/template/android/fastlane/metadata/android/ko-KR/short_description.txt +0 -0
- package/template/android/fastlane/metadata/android/ko-KR/title.txt +0 -0
- package/template/android/fastlane/metadata/android/ko-KR/video.txt +0 -0
- package/template/ios/fastlane/metadata/copyright.txt +0 -0
- package/template/ios/fastlane/metadata/ko/apple_tv_privacy_policy.txt +0 -0
- package/template/ios/fastlane/metadata/ko/description.txt +0 -0
- package/template/ios/fastlane/metadata/ko/keywords.txt +0 -0
- package/template/ios/fastlane/metadata/ko/marketing_url.txt +0 -0
- package/template/ios/fastlane/metadata/ko/name.txt +0 -0
- package/template/ios/fastlane/metadata/ko/privacy_url.txt +0 -0
- package/template/ios/fastlane/metadata/ko/promotional_text.txt +0 -0
- package/template/ios/fastlane/metadata/ko/release_notes.txt +0 -0
- package/template/ios/fastlane/metadata/ko/subtitle.txt +0 -0
- package/template/ios/fastlane/metadata/ko/support_url.txt +0 -0
- package/template/ios/fastlane/metadata/primary_category.txt +0 -0
- package/template/ios/fastlane/metadata/primary_first_sub_category.txt +0 -1
- package/template/ios/fastlane/metadata/primary_second_sub_category.txt +0 -1
- package/template/ios/fastlane/metadata/review_information/demo_password.txt +0 -0
- package/template/ios/fastlane/metadata/review_information/demo_user.txt +0 -0
- package/template/ios/fastlane/metadata/review_information/email_address.txt +0 -0
- package/template/ios/fastlane/metadata/review_information/first_name.txt +0 -0
- package/template/ios/fastlane/metadata/review_information/last_name.txt +0 -0
- package/template/ios/fastlane/metadata/review_information/notes.txt +0 -1
- package/template/ios/fastlane/metadata/review_information/phone_number.txt +0 -0
- package/template/ios/fastlane/metadata/secondary_category.txt +0 -1
- package/template/ios/fastlane/metadata/secondary_first_sub_category.txt +0 -1
- package/template/ios/fastlane/metadata/secondary_second_sub_category.txt +0 -1
- package/template/ios/fastlane/screenshots/README.txt +0 -30
- package/template/key/android_upload_certificate.pem +0 -2
- /package/template/key/{ios_testflight_upload_api_key.p8 → ios_app_store_connect_api_key.p8} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../package.json","../../src/util/FileUtil.ts","../../src/util/OptionHolder.ts","../../src/util/logger.ts","../../src/command/init.ts","../../src/util/input/InqueryInputs.ts","../../src/util/setup/hydrateKeyholderFileValues.ts","../../src/util/throwError.ts","../../src/util/setup/VersionUtil.ts","../../src/util/EnvUtil.ts","../../src/util/setup/setup.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 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 { OptionHolder } from '../util/OptionHolder';\nimport { logger } from '../util/logger';\nimport chalk from 'chalk';\nimport { input } from '@inquirer/prompts';\nimport { copy, join, writeJson } from '../util/FileUtil';\nimport { constructInquirerFormattedMessage } from '../util/input/InqueryInputs';\nimport { setup } from '../util/setup/setup';\n\nexport async function init({ options }: { options: any }) {\n Object.assign(OptionHolder.input, options);\n\n logger.info(`${chalk.inverse('expo-release-it')} Initialization Get Started`);\n\n await setup();\n await promptInputs();\n await copyTemplates();\n\n logger.success(\n `${chalk.inverse('expo-release-it')} Initialization Done. Check out generated 'expo-release-it' directory.`,\n );\n}\n\nasync function promptInputs() {\n /* ios */\n OptionHolder.keyholderMap.ios_app_identifier = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS Bundle Identifier',\n explanation: `The bundle identifier for your iOS standalone app. You make it up, but it needs to be unique on the App Store.\nThis means 'CFBundleIdentifier' in info.plist and 'ios.bundleIdentifier' in expo app config`,\n example: 'com.companyname.appname',\n referUrl: 'https://docs.expo.dev/versions/latest/config/app/#bundleidentifier',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_app_identifier,\n });\n\n OptionHolder.keyholderMap.ios_developer_team_id = await input({\n message: constructInquirerFormattedMessage({\n name: 'IOS Developer Team Id',\n explanation: `A unique alphanumeric string that identifies your Apple Developer Team`,\n example: '8A51ABC4H7',\n referUrl: 'https://developer.apple.com/account',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_developer_team_id,\n });\n\n OptionHolder.keyholderMap.ios_match_git_url = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS Fastlane Match Github URL',\n explanation: `The URL of the private Git repository where code signing certificates and profiles are stored for Fastlane Match.`,\n example: 'https://github.com/yourname/your-certificates-repo.git',\n referUrl: 'https://docs.fastlane.tools/actions/match/',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_match_git_url,\n });\n\n OptionHolder.keyholderMap.ios_match_password = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS Fastlane Match Passphrase',\n explanation: `When running match for the first time on a new machine, it will ask you for the passphrase for the Git repository. This is an additional layer of security: each of the files will be encrypted using openssl. Make sure to remember the password, as you'll need it when you run match on a different machine.`,\n example: 'yourpassphrase',\n referUrl: 'https://docs.fastlane.tools/actions/match/',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_match_password,\n });\n\n OptionHolder.keyholderMap.ios_app_store_connect_api_key_id = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS App Store Connect API Key ID',\n explanation: `ID of App Store Connect API key, used for authentication with Apple’s API.\nApp Store Connect API Key can be issued in ${chalk.underline.blue('https://appstoreconnect.apple.com/access/integrations/api')}`,\n example: '1A2BC3DE4F',\n referUrl: 'https://appstoreconnect.apple.com/access/integrations/api',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_app_store_connect_api_key_id,\n });\n\n OptionHolder.keyholderMap.ios_app_store_connect_api_key_issuer_id = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS App Store Connect API Key Issuer ID',\n explanation: `Identifies the issuer who created the authentication token.\nApp Store Connect API Key can be issued in ${chalk.underline.blue('https://appstoreconnect.apple.com/access/integrations/api')}`,\n example: 'abcd1234-5678-90ef-ghij-1234567890kl',\n referUrl: 'https://appstoreconnect.apple.com/access/integrations/api',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_app_store_connect_api_key_issuer_id,\n });\n\n OptionHolder.keyholderMap.ios_xcode_project_target = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS App Target Name',\n explanation: `A target in Xcode defines a product to build, including app, extension, or framework, with its own settings and build instructions.\nUsually, this is equivalent to {{name}}.xcodeproj in your ios directory`,\n example: 'app',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_xcode_project_target || 'app',\n });\n\n /* android */\n OptionHolder.keyholderMap.android_package_name = await input({\n message: constructInquirerFormattedMessage({\n name: 'Android Package Name',\n explanation: `The package name for your Android standalone app. You make it up, but it needs to be unique on the Play Store.`,\n example: 'com.companyname.appname',\n referUrl: 'https://docs.expo.dev/versions/latest/config/app/#package',\n }),\n required: true,\n default: OptionHolder.keyholderMap.android_package_name,\n });\n OptionHolder.keyholderMap.android_keystore_store_password = await input({\n message: constructInquirerFormattedMessage({\n name: 'Android Keystore Store Password',\n explanation: `Storage password used in android release keystore\nYou can issue your android release keystore following this guide: ${chalk.underline.blue('https://developer.android.com/studio/publish/app-signing.html#generate-key')}\nOr, you can do same thing with CLI: ${chalk.underline.blue('https://gist.github.com/henriquemenezes/70feb8fff20a19a65346e48786bedb8f')}`,\n referUrl: 'https://developer.android.com/studio/publish/app-signing.html#generate-key',\n }),\n required: true,\n default: OptionHolder.keyholderMap.android_keystore_store_password,\n });\n OptionHolder.keyholderMap.android_keystore_key_alias = await input({\n message: constructInquirerFormattedMessage({\n name: 'Android Keystore Key Alias',\n explanation: `Key alias used in android release keystore\nYou can issue your android release keystore following this guide: ${chalk.underline.blue('https://developer.android.com/studio/publish/app-signing.html#generate-key')}\nOr, you can do same thing with CLI: ${chalk.underline.blue('https://gist.github.com/henriquemenezes/70feb8fff20a19a65346e48786bedb8f')}`,\n referUrl: 'https://developer.android.com/studio/publish/app-signing.html#generate-key',\n }),\n required: true,\n default: OptionHolder.keyholderMap.android_keystore_key_alias,\n });\n OptionHolder.keyholderMap.android_keystore_key_password = await input({\n message: constructInquirerFormattedMessage({\n name: 'Android Keystore Key Password',\n explanation: `Key password used in android release keystore\nYou can issue your android release keystore following this guide: ${chalk.underline.blue('https://developer.android.com/studio/publish/app-signing.html#generate-key')}\nOr, you can do same thing with CLI: ${chalk.underline.blue('https://gist.github.com/henriquemenezes/70feb8fff20a19a65346e48786bedb8f')}`,\n referUrl: 'https://developer.android.com/studio/publish/app-signing.html#generate-key',\n }),\n required: true,\n default: OptionHolder.keyholderMap.android_keystore_key_password,\n });\n\n writeJson(OptionHolder.keyholderFilePath, OptionHolder.keyholderMap);\n}\n\nasync function copyTemplates() {\n for (const dir of OptionHolder.templateDirNames) {\n await copyDirRecursively(dir);\n }\n\n async function copyDirRecursively(dir: string) {\n const sourceDirPath = join(OptionHolder.cli.templateDir, dir);\n const destDirPath = join(OptionHolder.outputOfInitDir, dir);\n // don't overwirte key\n copy(sourceDirPath, destDirPath, { overwrite: dir !== 'key' });\n }\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 { 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"],"mappings":"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","names":["join","resolve","path","path","path","resolve","chalk","chalk","chalk","resolve","resolve","chalk","join"]}
|
|
1
|
+
{"version":3,"sources":["../../package.json","../../src/util/FileUtil.ts","../../src/util/OptionHolder.ts","../../src/util/logger.ts","../../src/command/init.ts","../../src/util/input/InqueryInputs.ts","../../src/util/setup/hydrateKeyholderFileValues.ts","../../src/util/throwError.ts","../../src/util/setup/VersionUtil.ts","../../src/util/EnvUtil.ts","../../src/util/setup/setup.ts"],"sourcesContent":["{\n \"name\": \"expo-release-it\",\n \"module\": \"src/index.ts\",\n \"type\": \"module\",\n \"version\": \"0.1.3\",\n \"license\": \"MIT\",\n \"homepage\": \"https://github.com/mym0404/expo-release-it\",\n \"repository\": \"https://github.com/mym0404/expo-release-it\",\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 platformAll: 'android' | 'ios' | 'all';\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 resourcesDir: 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 resourcesDir: '',\n keyDir: '',\n keyholderFilePath: '',\n versionName: '',\n versionCode: '',\n tempDir: '',\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 { OptionHolder } from '../util/OptionHolder';\nimport { logger } from '../util/logger';\nimport chalk from 'chalk';\nimport { input } from '@inquirer/prompts';\nimport { copy, join, writeJson } from '../util/FileUtil';\nimport { constructInquirerFormattedMessage } from '../util/input/InqueryInputs';\nimport { setup } from '../util/setup/setup';\n\nexport async function init({ options }: { options: any }) {\n Object.assign(OptionHolder.input, options);\n\n logger.info(`${chalk.inverse('expo-release-it')} Initialization Get Started`);\n\n await setup();\n await promptInputs();\n await copyTemplates();\n\n logger.success(\n `${chalk.inverse('expo-release-it')} Initialization Done. Check out generated 'expo-release-it' directory.`,\n );\n}\n\nasync function promptInputs() {\n /* ios */\n OptionHolder.keyholderMap.ios_app_identifier = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS Bundle Identifier',\n explanation: `The bundle identifier for your iOS standalone app. You make it up, but it needs to be unique on the App Store.\nThis means 'CFBundleIdentifier' in info.plist and 'ios.bundleIdentifier' in expo app config`,\n example: 'com.companyname.appname',\n referUrl: 'https://docs.expo.dev/versions/latest/config/app/#bundleidentifier',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_app_identifier,\n });\n\n OptionHolder.keyholderMap.ios_developer_team_id = await input({\n message: constructInquirerFormattedMessage({\n name: 'IOS Developer Team Id',\n explanation: `A unique alphanumeric string that identifies your Apple Developer Team`,\n example: '8A51ABC4H7',\n referUrl: 'https://developer.apple.com/account',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_developer_team_id,\n });\n\n OptionHolder.keyholderMap.ios_match_git_url = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS Fastlane Match Github URL',\n explanation: `The URL of the private Git repository where code signing certificates and profiles are stored for Fastlane Match.`,\n example: 'https://github.com/yourname/your-certificates-repo.git',\n referUrl: 'https://docs.fastlane.tools/actions/match/',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_match_git_url,\n });\n\n OptionHolder.keyholderMap.ios_match_password = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS Fastlane Match Passphrase',\n explanation: `When running match for the first time on a new machine, it will ask you for the passphrase for the Git repository. This is an additional layer of security: each of the files will be encrypted using openssl. Make sure to remember the password, as you'll need it when you run match on a different machine.`,\n example: 'yourpassphrase',\n referUrl: 'https://docs.fastlane.tools/actions/match/',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_match_password,\n });\n\n OptionHolder.keyholderMap.ios_app_store_connect_api_key_id = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS App Store Connect API Key ID',\n explanation: `ID of App Store Connect API key, used for authentication with Apple’s API.\nApp Store Connect API Key can be issued in ${chalk.underline.blue('https://appstoreconnect.apple.com/access/integrations/api')}`,\n example: '1A2BC3DE4F',\n referUrl: 'https://appstoreconnect.apple.com/access/integrations/api',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_app_store_connect_api_key_id,\n });\n\n OptionHolder.keyholderMap.ios_app_store_connect_api_key_issuer_id = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS App Store Connect API Key Issuer ID',\n explanation: `Identifies the issuer who created the authentication token.\nApp Store Connect API Key can be issued in ${chalk.underline.blue('https://appstoreconnect.apple.com/access/integrations/api')}`,\n example: 'abcd1234-5678-90ef-ghij-1234567890kl',\n referUrl: 'https://appstoreconnect.apple.com/access/integrations/api',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_app_store_connect_api_key_issuer_id,\n });\n\n OptionHolder.keyholderMap.ios_xcode_project_target = await input({\n message: constructInquirerFormattedMessage({\n name: 'iOS App Target Name',\n explanation: `A target in Xcode defines a product to build, including app, extension, or framework, with its own settings and build instructions.\nUsually, this is equivalent to {{name}}.xcodeproj in your ios directory`,\n example: 'app',\n }),\n required: true,\n default: OptionHolder.keyholderMap.ios_xcode_project_target || 'app',\n });\n\n /* android */\n OptionHolder.keyholderMap.android_package_name = await input({\n message: constructInquirerFormattedMessage({\n name: 'Android Package Name',\n explanation: `The package name for your Android standalone app. You make it up, but it needs to be unique on the Play Store.`,\n example: 'com.companyname.appname',\n referUrl: 'https://docs.expo.dev/versions/latest/config/app/#package',\n }),\n required: true,\n default: OptionHolder.keyholderMap.android_package_name,\n });\n OptionHolder.keyholderMap.android_keystore_store_password = await input({\n message: constructInquirerFormattedMessage({\n name: 'Android Keystore Store Password',\n explanation: `Storage password used in android release keystore\nYou can issue your android release keystore following this guide: ${chalk.underline.blue('https://developer.android.com/studio/publish/app-signing.html#generate-key')}\nOr, you can do same thing with CLI: ${chalk.underline.blue('https://gist.github.com/henriquemenezes/70feb8fff20a19a65346e48786bedb8f')}`,\n referUrl: 'https://developer.android.com/studio/publish/app-signing.html#generate-key',\n }),\n required: true,\n default: OptionHolder.keyholderMap.android_keystore_store_password,\n });\n OptionHolder.keyholderMap.android_keystore_key_alias = await input({\n message: constructInquirerFormattedMessage({\n name: 'Android Keystore Key Alias',\n explanation: `Key alias used in android release keystore\nYou can issue your android release keystore following this guide: ${chalk.underline.blue('https://developer.android.com/studio/publish/app-signing.html#generate-key')}\nOr, you can do same thing with CLI: ${chalk.underline.blue('https://gist.github.com/henriquemenezes/70feb8fff20a19a65346e48786bedb8f')}`,\n referUrl: 'https://developer.android.com/studio/publish/app-signing.html#generate-key',\n }),\n required: true,\n default: OptionHolder.keyholderMap.android_keystore_key_alias,\n });\n OptionHolder.keyholderMap.android_keystore_key_password = await input({\n message: constructInquirerFormattedMessage({\n name: 'Android Keystore Key Password',\n explanation: `Key password used in android release keystore\nYou can issue your android release keystore following this guide: ${chalk.underline.blue('https://developer.android.com/studio/publish/app-signing.html#generate-key')}\nOr, you can do same thing with CLI: ${chalk.underline.blue('https://gist.github.com/henriquemenezes/70feb8fff20a19a65346e48786bedb8f')}`,\n referUrl: 'https://developer.android.com/studio/publish/app-signing.html#generate-key',\n }),\n required: true,\n default: OptionHolder.keyholderMap.android_keystore_key_password,\n });\n\n writeJson(OptionHolder.keyholderFilePath, OptionHolder.keyholderMap);\n}\n\nasync function copyTemplates() {\n for (const dir of OptionHolder.templateDirNames) {\n await copyDirRecursively(dir);\n }\n\n async function copyDirRecursively(dir: string) {\n const sourceDirPath = join(OptionHolder.cli.templateDir, dir);\n const destDirPath = join(OptionHolder.resourcesDir, dir);\n // don't overwirte key\n copy(sourceDirPath, destDirPath, { overwrite: dir !== 'key' });\n }\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 platformAll: async () => {\n if (!OptionHolder.input.platformAll) {\n OptionHolder.input.platformAll = await select({\n message: constructInquirerFormattedMessage({\n name: 'Platform',\n explanation: `Platforms to run action`,\n }),\n choices: [\n { name: 'all', value: 'all', description: 'Both' },\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 { 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\nconst versionNameRegex = () => /const\\s+VERSION_NAME\\s*?=\\s*?['\"]([\\d\\.]*?)['\"]\\s*?;?/;\nconst versionCodeRegex = () => /const\\s+VERSION_CODE\\s*?=\\s*?(\\d+)\\s*?;?/;\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 = versionNameRegex().exec(content)?.[1];\n const VERSION_CODE = versionCodeRegex().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(versionNameRegex(), `const VERSION_NAME = '${versionName}';`);\n content = content.replace(versionCodeRegex(), `const VERSION_CODE = ${versionCode};`);\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.resourcesDir = resolve(OptionHolder.projectDir, 'expo-release-it');\n OptionHolder.keyDir = resolve(OptionHolder.resourcesDir, 'key');\n OptionHolder.keyholderFilePath = resolve(OptionHolder.resourcesDir, 'keyholder.json');\n OptionHolder.tempDir = resolve(OptionHolder.resourcesDir, '.temp');\n}\n"],"mappings":"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","names":["join","resolve","path","path","path","resolve","chalk","chalk","chalk","resolve","resolve","chalk","join"]}
|
package/build/command/pull.js
CHANGED
|
@@ -3,8 +3,10 @@ var package_default = {
|
|
|
3
3
|
name: "expo-release-it",
|
|
4
4
|
module: "src/index.ts",
|
|
5
5
|
type: "module",
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.3",
|
|
7
7
|
license: "MIT",
|
|
8
|
+
homepage: "https://github.com/mym0404/expo-release-it",
|
|
9
|
+
repository: "https://github.com/mym0404/expo-release-it",
|
|
8
10
|
scripts: {
|
|
9
11
|
build: "tsup",
|
|
10
12
|
dev: "yarn run build && NODE_ENV=development node bin/expo-release-it.mjs",
|
|
@@ -53,26 +55,26 @@ import fs from "fs-extra";
|
|
|
53
55
|
import * as path from "path";
|
|
54
56
|
var join2 = path.join;
|
|
55
57
|
var resolve2 = path.resolve;
|
|
56
|
-
function exist(
|
|
57
|
-
return fs.existsSync(
|
|
58
|
+
function exist(path2) {
|
|
59
|
+
return fs.existsSync(path2);
|
|
58
60
|
}
|
|
59
|
-
function isDir(
|
|
60
|
-
return exist(
|
|
61
|
+
function isDir(path2) {
|
|
62
|
+
return exist(path2) && fs.lstatSync(path2).isDirectory();
|
|
61
63
|
}
|
|
62
64
|
function relativePath(from, to) {
|
|
63
65
|
return path.relative(from, to);
|
|
64
66
|
}
|
|
65
|
-
function isFile(
|
|
66
|
-
return exist(
|
|
67
|
+
function isFile(path2) {
|
|
68
|
+
return exist(path2) && fs.lstatSync(path2).isFile();
|
|
67
69
|
}
|
|
68
|
-
function read(
|
|
69
|
-
return fs.readFileSync(
|
|
70
|
+
function read(path2) {
|
|
71
|
+
return fs.readFileSync(path2, { encoding: "utf8" });
|
|
70
72
|
}
|
|
71
|
-
function readdir(
|
|
72
|
-
return fs.readdirSync(
|
|
73
|
+
function readdir(path2) {
|
|
74
|
+
return fs.readdirSync(path2);
|
|
73
75
|
}
|
|
74
|
-
function readJsonSlow(
|
|
75
|
-
return fs.readJSONSync(
|
|
76
|
+
function readJsonSlow(path2) {
|
|
77
|
+
return fs.readJSONSync(path2);
|
|
76
78
|
}
|
|
77
79
|
function write(p, content) {
|
|
78
80
|
const dir = path.dirname(p);
|
|
@@ -84,27 +86,24 @@ function write(p, content) {
|
|
|
84
86
|
function copy(src, dest, options) {
|
|
85
87
|
fs.copySync(src, dest, options);
|
|
86
88
|
}
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
+
function writeJson(path2, json) {
|
|
90
|
+
return write(path2, JSON.stringify(json, null, 2));
|
|
89
91
|
}
|
|
90
|
-
function
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
function remove(path3) {
|
|
94
|
-
if (!exist(path3)) {
|
|
92
|
+
function remove(path2) {
|
|
93
|
+
if (!exist(path2)) {
|
|
95
94
|
return;
|
|
96
95
|
}
|
|
97
|
-
if (fs.lstatSync(
|
|
98
|
-
return fs.rmSync(
|
|
96
|
+
if (fs.lstatSync(path2).isDirectory()) {
|
|
97
|
+
return fs.rmSync(path2, { force: true, recursive: true });
|
|
99
98
|
} else {
|
|
100
|
-
return fs.rmSync(
|
|
99
|
+
return fs.rmSync(path2, { force: true });
|
|
101
100
|
}
|
|
102
101
|
}
|
|
103
|
-
async function iterateDir(
|
|
104
|
-
if (!isDir(
|
|
102
|
+
async function iterateDir(path2, fn) {
|
|
103
|
+
if (!isDir(path2)) {
|
|
105
104
|
return;
|
|
106
105
|
}
|
|
107
|
-
for (const file of fs.readdirSync(
|
|
106
|
+
for (const file of fs.readdirSync(path2)) {
|
|
108
107
|
await fn(file);
|
|
109
108
|
}
|
|
110
109
|
}
|
|
@@ -121,7 +120,7 @@ var OptionHolder = {
|
|
|
121
120
|
keyholderMap: {},
|
|
122
121
|
templateDirNames: ["key"],
|
|
123
122
|
projectDir: "",
|
|
124
|
-
|
|
123
|
+
resourcesDir: "",
|
|
125
124
|
keyDir: "",
|
|
126
125
|
keyholderFilePath: "",
|
|
127
126
|
versionName: "",
|
|
@@ -148,6 +147,21 @@ var InqueryInputs = {
|
|
|
148
147
|
});
|
|
149
148
|
}
|
|
150
149
|
},
|
|
150
|
+
platformAll: async () => {
|
|
151
|
+
if (!OptionHolder.input.platformAll) {
|
|
152
|
+
OptionHolder.input.platformAll = await select({
|
|
153
|
+
message: constructInquirerFormattedMessage({
|
|
154
|
+
name: "Platform",
|
|
155
|
+
explanation: `Platforms to run action`
|
|
156
|
+
}),
|
|
157
|
+
choices: [
|
|
158
|
+
{ name: "all", value: "all", description: "Both" },
|
|
159
|
+
{ name: "ios", value: "ios", description: "Release ios" },
|
|
160
|
+
{ name: "android", value: "android", description: "Release android" }
|
|
161
|
+
]
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
},
|
|
151
165
|
podinstall: async () => {
|
|
152
166
|
if (OptionHolder.input.platform === "ios") {
|
|
153
167
|
OptionHolder.input.pod = await select({
|
|
@@ -251,6 +265,8 @@ function throwError(message, e) {
|
|
|
251
265
|
|
|
252
266
|
// src/util/setup/VersionUtil.ts
|
|
253
267
|
import semver from "semver";
|
|
268
|
+
var versionNameRegex = () => /const\s+VERSION_NAME\s*?=\s*?['"]([\d\.]*?)['"]\s*?;?/;
|
|
269
|
+
var versionCodeRegex = () => /const\s+VERSION_CODE\s*?=\s*?(\d+)\s*?;?/;
|
|
254
270
|
async function parseBinaryVersions() {
|
|
255
271
|
const files = readdir(OptionHolder.projectDir);
|
|
256
272
|
const jsConfigFiles = ["app.config.ts", "app.config.js", "app.config.cjs", "app.config.mjs"];
|
|
@@ -269,8 +285,8 @@ async function parseBinaryVersions() {
|
|
|
269
285
|
async function parseFromJsConfigFile(filename) {
|
|
270
286
|
const filePath = resolve2(OptionHolder.projectDir, filename);
|
|
271
287
|
const content = read(filePath);
|
|
272
|
-
const VERSION_NAME =
|
|
273
|
-
const VERSION_CODE =
|
|
288
|
+
const VERSION_NAME = versionNameRegex().exec(content)?.[1];
|
|
289
|
+
const VERSION_CODE = versionCodeRegex().exec(content)?.[1];
|
|
274
290
|
if (!VERSION_NAME) {
|
|
275
291
|
throwError("cannot parse version name");
|
|
276
292
|
}
|
|
@@ -318,10 +334,10 @@ async function setup() {
|
|
|
318
334
|
}
|
|
319
335
|
async function setupBasicOptions() {
|
|
320
336
|
OptionHolder.projectDir = isDev ? resolve2("example") : resolve2(".");
|
|
321
|
-
OptionHolder.
|
|
322
|
-
OptionHolder.keyDir = resolve2(OptionHolder.
|
|
323
|
-
OptionHolder.keyholderFilePath = resolve2(OptionHolder.
|
|
324
|
-
OptionHolder.tempDir = resolve2(OptionHolder.
|
|
337
|
+
OptionHolder.resourcesDir = resolve2(OptionHolder.projectDir, "expo-release-it");
|
|
338
|
+
OptionHolder.keyDir = resolve2(OptionHolder.resourcesDir, "key");
|
|
339
|
+
OptionHolder.keyholderFilePath = resolve2(OptionHolder.resourcesDir, "keyholder.json");
|
|
340
|
+
OptionHolder.tempDir = resolve2(OptionHolder.resourcesDir, ".temp");
|
|
325
341
|
}
|
|
326
342
|
|
|
327
343
|
// src/util/setup/execShellScript.ts
|
|
@@ -355,18 +371,12 @@ async function iterateAllFiles(root, callback) {
|
|
|
355
371
|
}
|
|
356
372
|
|
|
357
373
|
// src/util/injectTemplatePlaceHolders.ts
|
|
358
|
-
import * as path2 from "node:path";
|
|
359
374
|
async function injectTemplatePlaceHolders(root) {
|
|
360
375
|
await iterateAllFiles(root, async (filePath) => {
|
|
361
|
-
const dirPath = path2.dirname(filePath);
|
|
362
376
|
let content = read(filePath);
|
|
363
377
|
for (const [key, value] of Object.entries(OptionHolder.keyholderMap)) {
|
|
364
378
|
content = content.replaceAll(`{{${key}}}`, value);
|
|
365
379
|
}
|
|
366
|
-
content = content.replaceAll(
|
|
367
|
-
"{{key_dir_relative_path}}",
|
|
368
|
-
relativePath(dirPath, OptionHolder.keyDir)
|
|
369
|
-
);
|
|
370
380
|
write(filePath, content);
|
|
371
381
|
});
|
|
372
382
|
}
|
|
@@ -382,6 +392,71 @@ async function spinner(text, promise) {
|
|
|
382
392
|
});
|
|
383
393
|
}
|
|
384
394
|
|
|
395
|
+
// src/util/MetadataSyncUtil.ts
|
|
396
|
+
import chalk4 from "chalk";
|
|
397
|
+
function copyIosMetadata(to) {
|
|
398
|
+
const iosDir = join2(OptionHolder.projectDir, "ios");
|
|
399
|
+
const nativeDir = join2(iosDir, "fastlane");
|
|
400
|
+
const metadataNativeDir = join2(nativeDir, "metadata");
|
|
401
|
+
const screenshotsNativeDir = join2(nativeDir, "screenshots");
|
|
402
|
+
const resourcesDir = join2(OptionHolder.resourcesDir, "metadata/ios");
|
|
403
|
+
const metadataResourcesDir = join2(resourcesDir, "metadata");
|
|
404
|
+
const screenshotsResourcesDir = join2(resourcesDir, "screenshots");
|
|
405
|
+
if (to === "resources") {
|
|
406
|
+
if (exist(metadataNativeDir) && exist(screenshotsNativeDir)) {
|
|
407
|
+
copy(metadataNativeDir, metadataResourcesDir);
|
|
408
|
+
copy(screenshotsNativeDir, screenshotsResourcesDir);
|
|
409
|
+
logger.done(
|
|
410
|
+
`iOS Metadata saved in ${chalk4.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}. You can edit inside contents.`
|
|
411
|
+
);
|
|
412
|
+
} else {
|
|
413
|
+
logger.warn(
|
|
414
|
+
`iOS Metadata not found in ${chalk4.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
} else {
|
|
418
|
+
if (exist(metadataResourcesDir) && exist(screenshotsResourcesDir)) {
|
|
419
|
+
copy(metadataResourcesDir, metadataNativeDir);
|
|
420
|
+
copy(screenshotsResourcesDir, screenshotsNativeDir);
|
|
421
|
+
logger.done(
|
|
422
|
+
`iOS Metadata copyed to ${chalk4.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`
|
|
423
|
+
);
|
|
424
|
+
} else {
|
|
425
|
+
logger.warn(
|
|
426
|
+
`iOS Metadata not found in ${chalk4.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}`
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function copyAndroidMetadata(to) {
|
|
432
|
+
const androidDir = join2(OptionHolder.projectDir, "android");
|
|
433
|
+
const nativeDir = join2(androidDir, "fastlane/metadata/android");
|
|
434
|
+
const resourcesDir = join2(OptionHolder.resourcesDir, "metadata/android");
|
|
435
|
+
if (to === "resouces") {
|
|
436
|
+
if (exist(nativeDir)) {
|
|
437
|
+
copy(nativeDir, resourcesDir);
|
|
438
|
+
logger.done(
|
|
439
|
+
`Android Metadata saved in ${chalk4.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}. You can edit inside contents.`
|
|
440
|
+
);
|
|
441
|
+
} else {
|
|
442
|
+
logger.warn(
|
|
443
|
+
`Android Metadata not found in ${chalk4.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
} else {
|
|
447
|
+
if (exist(resourcesDir)) {
|
|
448
|
+
copy(resourcesDir, nativeDir);
|
|
449
|
+
logger.done(
|
|
450
|
+
`Android Metadata copyed to ${chalk4.inverse(relativePath(OptionHolder.projectDir, nativeDir))}`
|
|
451
|
+
);
|
|
452
|
+
} else {
|
|
453
|
+
logger.warn(
|
|
454
|
+
`Android Metadata not found in ${chalk4.inverse(relativePath(OptionHolder.projectDir, resourcesDir))}`
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
385
460
|
// src/util/setup/prepareIos.ts
|
|
386
461
|
async function prepareIos() {
|
|
387
462
|
const srcDir = resolve2(OptionHolder.cli.templateDir, "ios");
|
|
@@ -402,8 +477,9 @@ async function prepareIos() {
|
|
|
402
477
|
"Hydrate template placeholders",
|
|
403
478
|
injectTemplatePlaceHolders(resolve2(destDir, "fastlane"))
|
|
404
479
|
);
|
|
405
|
-
await exe({ cwd: destDir })
|
|
480
|
+
await exe("bundle", ["install"], { cwd: destDir });
|
|
406
481
|
logger.success("Bunder Install - Done");
|
|
482
|
+
copyIosMetadata("native");
|
|
407
483
|
}
|
|
408
484
|
|
|
409
485
|
// src/util/setup/prepareAndroid.ts
|
|
@@ -427,8 +503,9 @@ async function prepareAndroid() {
|
|
|
427
503
|
"Hydrate template placeholders",
|
|
428
504
|
injectTemplatePlaceHolders(resolve2(destDir, "fastlane"))
|
|
429
505
|
);
|
|
430
|
-
await exe({ cwd: destDir })
|
|
506
|
+
await exe("bundle", ["install"], { cwd: destDir });
|
|
431
507
|
logger.success("Bunder Install - Done");
|
|
508
|
+
copyAndroidMetadata("native");
|
|
432
509
|
}
|
|
433
510
|
async function replaceAndroidSigningConfig(destDir) {
|
|
434
511
|
const buildGradleDirPath = resolve2(destDir, "app");
|
|
@@ -443,7 +520,7 @@ async function replaceAndroidSigningConfig(destDir) {
|
|
|
443
520
|
`
|
|
444
521
|
signingConfigs {
|
|
445
522
|
debug {
|
|
446
|
-
storeFile file('${relativePath(buildGradleDirPath, resolve2(OptionHolder.
|
|
523
|
+
storeFile file('${relativePath(buildGradleDirPath, resolve2(OptionHolder.resourcesDir, "key", "android_release.keystore"))}')
|
|
447
524
|
storePassword '${android_keystore_store_password}'
|
|
448
525
|
keyAlias '${android_keystore_key_alias}'
|
|
449
526
|
keyPassword '${android_keystore_key_password}'
|
|
@@ -457,7 +534,7 @@ async function replaceAndroidSigningConfig(destDir) {
|
|
|
457
534
|
// src/util/generateAppStoreConnectApiKeyFile.ts
|
|
458
535
|
function generateAppStoreConnectApiKeyFile() {
|
|
459
536
|
const json = {
|
|
460
|
-
key: read(resolve2(OptionHolder.keyDir, "
|
|
537
|
+
key: read(resolve2(OptionHolder.keyDir, "ios_app_store_connect_api_key.p8")),
|
|
461
538
|
key_id: OptionHolder.keyholderMap.ios_app_store_connect_api_key_id,
|
|
462
539
|
issuer_id: OptionHolder.keyholderMap.ios_app_store_connect_api_key_issuer_id
|
|
463
540
|
};
|
|
@@ -507,17 +584,26 @@ async function pullIosMetadata() {
|
|
|
507
584
|
"--api_key_path",
|
|
508
585
|
generateAppStoreConnectApiKeyFile()
|
|
509
586
|
]);
|
|
510
|
-
|
|
511
|
-
const screenshotsSrcDir = join2(iosDir, "fastlane/screenshots");
|
|
512
|
-
const metadataDestDir = join2(OptionHolder.outputOfInitDir, "metadata/ios/metadata");
|
|
513
|
-
const screenshotsDestDir = join2(OptionHolder.outputOfInitDir, "metadata/ios/screenshots");
|
|
514
|
-
move(metadataSrcDir, metadataDestDir);
|
|
515
|
-
move(screenshotsSrcDir, screenshotsDestDir);
|
|
587
|
+
copyIosMetadata("resources");
|
|
516
588
|
}
|
|
517
589
|
async function pullAndroidMetadata() {
|
|
518
590
|
await prepareAndroid();
|
|
519
591
|
const androidDir = join2(OptionHolder.projectDir, "android");
|
|
520
|
-
await exe(
|
|
592
|
+
await exe(
|
|
593
|
+
"bundle",
|
|
594
|
+
[
|
|
595
|
+
"exec",
|
|
596
|
+
"fastlane",
|
|
597
|
+
"supply",
|
|
598
|
+
"init",
|
|
599
|
+
"--json_key",
|
|
600
|
+
resolve2(OptionHolder.keyDir, "android_play_console_service_account.json"),
|
|
601
|
+
"--package_name",
|
|
602
|
+
OptionHolder.keyholderMap.android_package_name
|
|
603
|
+
],
|
|
604
|
+
{ cwd: androidDir }
|
|
605
|
+
);
|
|
606
|
+
copyAndroidMetadata("resouces");
|
|
521
607
|
}
|
|
522
608
|
export {
|
|
523
609
|
pull
|