mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 10:27:33 +00:00
* feat(mobile): ship Android as dev.orca.app and check updates by install source Android becomes dev.orca.app, the package already live on Google Play; iOS keeps com.stably.orca.mobile. The move screens and the "Orca (old)" label stay keyed to the old package, so they never show in the new app. The app asks Android who installed it. A Play install gets its updates from Play, so it runs no GitHub check, hides "Check for updates" and points the update wall at Google Play. Any other install checks GitHub for android-v releases; the old package keeps mobile-android-v. * ci(mobile): release dev.orca.app to Play and publish Google's signed APK An android-v tag (or a manual run) builds the AAB with the upload key and sends it to Play's internal track. It then downloads the universal APK Google signed for that versionCode, fails unless its V3.0 signer is Google's app signing key, and publishes it as the android-v GitHub pre-release. Play and GitHub installs are the same signed app. A manual run with publish_github_release off only validates the bundle with Play. The orca.dev APK bump job is gone: the site builds its link from mobile-android-v, so it stays on the last old-app APK, which sends people to the new app.
98 lines
3.1 KiB
JavaScript
98 lines
3.1 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import process from 'node:process'
|
|
|
|
const mobileRoot = path.resolve(import.meta.dirname, '..')
|
|
const appConfigPath = process.env.MOBILE_APP_CONFIG_PATH || path.join(mobileRoot, 'app.json')
|
|
const androidTagRefPrefix = 'refs/tags/android-v'
|
|
const semverPattern = /^\d+\.\d+\.\d+$/
|
|
|
|
function input(name) {
|
|
return (process.env[name] || '').trim()
|
|
}
|
|
|
|
function truthy(value) {
|
|
return ['1', 'true', 'yes', 'on'].includes(value.trim().toLowerCase())
|
|
}
|
|
|
|
function fail(message) {
|
|
console.error(message)
|
|
process.exit(1)
|
|
}
|
|
|
|
function validateSemver(version, name) {
|
|
if (!semverPattern.test(version)) {
|
|
fail(`${name} must use x.y.z format`)
|
|
}
|
|
}
|
|
|
|
function writeOutput(name, value) {
|
|
const outputPath = process.env.GITHUB_OUTPUT
|
|
if (!outputPath) {
|
|
return
|
|
}
|
|
|
|
fs.appendFileSync(outputPath, `${name}=${value}\n`)
|
|
}
|
|
|
|
const config = JSON.parse(fs.readFileSync(appConfigPath, 'utf8'))
|
|
const expo = config.expo || fail('app.json is missing expo config')
|
|
const android = expo.android || fail('app.json is missing expo.android config')
|
|
const currentVersion = String(expo.version || '').trim()
|
|
validateSemver(currentVersion, 'Current mobile version')
|
|
|
|
const currentVersionCode = Number(android.versionCode)
|
|
if (!Number.isSafeInteger(currentVersionCode) || currentVersionCode <= 0) {
|
|
fail('Current Android versionCode must be a positive integer')
|
|
}
|
|
|
|
const githubRef = input('GITHUB_REF')
|
|
const tagVersion = githubRef.startsWith(androidTagRefPrefix)
|
|
? githubRef.slice(androidTagRefPrefix.length)
|
|
: ''
|
|
const requestedVersion = input('MOBILE_ANDROID_RELEASE_VERSION')
|
|
const bumpPatch = truthy(input('MOBILE_ANDROID_BUMP_PATCH_VERSION'))
|
|
|
|
if (tagVersion) {
|
|
validateSemver(tagVersion, 'Android release tag version')
|
|
}
|
|
|
|
if (requestedVersion) {
|
|
validateSemver(requestedVersion, 'MOBILE_ANDROID_RELEASE_VERSION')
|
|
}
|
|
|
|
if (bumpPatch) {
|
|
fail('MOBILE_ANDROID_BUMP_PATCH_VERSION is no longer supported; commit mobile/app.json first')
|
|
}
|
|
|
|
if (tagVersion && tagVersion !== currentVersion) {
|
|
fail('Android release tag version must match the committed mobile app version')
|
|
}
|
|
|
|
if (requestedVersion && requestedVersion !== currentVersion) {
|
|
fail('MOBILE_ANDROID_RELEASE_VERSION must match the committed mobile app version')
|
|
}
|
|
|
|
const requestedVersionCode = input('MOBILE_ANDROID_VERSION_CODE')
|
|
const bumpVersionCode = truthy(input('MOBILE_ANDROID_BUMP_VERSION_CODE'))
|
|
|
|
if (requestedVersionCode || bumpVersionCode) {
|
|
// Android rejects lower versionCode; bump dev builds too or shipped APKs block local installs.
|
|
fail('Android versionCode changes must be committed in mobile/app.json before release')
|
|
}
|
|
|
|
const tag = `android-v${currentVersion}`
|
|
const publishRelease =
|
|
githubRef.startsWith(androidTagRefPrefix) || truthy(input('MOBILE_ANDROID_PUBLISH_RELEASE'))
|
|
|
|
writeOutput('version', currentVersion)
|
|
writeOutput('android_version_code', String(currentVersionCode))
|
|
writeOutput('tag', tag)
|
|
writeOutput('publish_release', publishRelease ? 'true' : 'false')
|
|
|
|
console.log(`Prepared Orca Mobile Android ${currentVersion} (${currentVersionCode})`)
|
|
console.log(`Release tag: ${tag}`)
|
|
console.log(`Publish GitHub Release: ${publishRelease ? 'yes' : 'no'}`)
|