99 lines
3.2 KiB
JavaScript
99 lines
3.2 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/mobile-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) {
|
|
// Why: Android rejects lower versionCode installs; release-only bumps leave
|
|
// committed dev builds behind shipped APKs and break local testing.
|
|
fail('Android versionCode changes must be committed in mobile/app.json before release')
|
|
}
|
|
|
|
const tag = `mobile-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'}`)
|