diff --git a/scripts/release-channel.test.mjs b/scripts/release-channel.test.mjs index 91e1eee030..856d6542eb 100644 --- a/scripts/release-channel.test.mjs +++ b/scripts/release-channel.test.mjs @@ -163,15 +163,15 @@ exclude = ["src/apps/relay-server", "OpenBitFun-Installer/src-tauri"] ); assert.match( readFileSync(path.join(root, 'src/apps/mobile/android/app/build.gradle.kts'), 'utf8'), - /versionName = "1\.1\.0-beta\.2"/, + /versionName = "1\.0\.0"/, ); assert.match( readFileSync(path.join(root, 'src/apps/mobile/ios/OpenBitFun/Info.plist'), 'utf8'), - /1\.1\.0-beta\.2<\/string>/, + /1\.0\.0<\/string>/, ); assert.match( readFileSync(path.join(root, 'src/apps/mobile/harmonyos/AppScope/app.json5'), 'utf8'), - /"versionName": "1\.1\.0-beta\.2"/, + /"versionName": "1\.0\.0"/, ); assert.match( readFileSync(path.join(root, 'Cargo.lock'), 'utf8'), diff --git a/scripts/set-build-version.mjs b/scripts/set-build-version.mjs index 03bdb0d70b..2aeff018af 100644 --- a/scripts/set-build-version.mjs +++ b/scripts/set-build-version.mjs @@ -51,22 +51,6 @@ export function setBuildVersion(root, version) { ); } - replaceVersion( - path.join(root, 'src/apps/mobile/android/app/build.gradle.kts'), - /^(\s*versionName\s*=\s*")[^"]+(".*)$/m, - `$1${version}$2`, - ); - replaceVersion( - path.join(root, 'src/apps/mobile/ios/OpenBitFun/Info.plist'), - /(CFBundleShortVersionString<\/key>\s*)[^<]+(<\/string>)/m, - `$1${version}$2`, - ); - replaceVersion( - path.join(root, 'src/apps/mobile/harmonyos/AppScope/app.json5'), - /^(\s*"versionName"\s*:\s*")[^"]+(".*)$/m, - `$1${version}$2`, - ); - syncCargoLock(root); } diff --git a/scripts/tauri-release-manifest.test.mjs b/scripts/tauri-release-manifest.test.mjs index 10c3e17213..12649040c0 100644 --- a/scripts/tauri-release-manifest.test.mjs +++ b/scripts/tauri-release-manifest.test.mjs @@ -7,12 +7,24 @@ import test from 'node:test'; const root = path.resolve(import.meta.dirname, '..'); -test('release version metadata is synchronized', () => { +test('desktop and mobile release metadata are synchronized within their own groups', () => { const version = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')).version; - const result = run('scripts/verify-release-version-sync.mjs', ['--version', version]); + const result = run('scripts/verify-release-version-sync.mjs', [ + '--version', version, + '--mobile-version', '1.0.0', + ]); assert.equal(result.status, 0, result.stderr); }); +test('mobile release metadata rejects drift within the mobile group', () => { + const result = run('scripts/verify-release-version-sync.mjs', [ + '--version', JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')).version, + '--mobile-version', '1.0.1', + ]); + assert.notEqual(result.status, 0); + assert.match(result.stderr, /expected mobile 1\.0\.1/); +}); + test('prepares a versioned custom Windows installer asset', () => { const temp = fs.mkdtempSync(path.join(os.tmpdir(), 'openbitfun-manual-installer-')); const assets = path.join(temp, 'assets', 'nested'); diff --git a/scripts/verify-release-version-sync.mjs b/scripts/verify-release-version-sync.mjs index 3b0343c4b2..22beaa0bba 100644 --- a/scripts/verify-release-version-sync.mjs +++ b/scripts/verify-release-version-sync.mjs @@ -2,6 +2,8 @@ import { readFileSync } from 'fs'; const args = parseArgs(process.argv.slice(2)); +// Desktop release workflows resolve their version from the root package. Mobile +// apps ship on their own cadence, so they form a separate consistency group. const expected = args.version || readJsonVersion('package.json'); const versions = new Map([ ['package.json', readJsonVersion('package.json')], @@ -15,6 +17,9 @@ const versions = new Map([ ['src/apps/relay-server/Cargo.toml', readTomlVersion('src/apps/relay-server/Cargo.toml', /version = "([^"]+)" # x-release-please-version/)], ['src/crates/services/relay-service/Cargo.toml', readTomlVersion('src/crates/services/relay-service/Cargo.toml', /^version = "([^"]+)"/m)], ['src/crates/services/page-function-runtime/Cargo.toml', readTomlVersion('src/crates/services/page-function-runtime/Cargo.toml', /^version = "([^"]+)"/m)], +]); + +const mobileVersions = new Map([ ['src/apps/mobile/android/app/build.gradle.kts', readTextVersion('src/apps/mobile/android/app/build.gradle.kts', /versionName\s*=\s*"([^"]+)"/)], ['src/apps/mobile/ios/OpenBitFun/Info.plist', readTextVersion('src/apps/mobile/ios/OpenBitFun/Info.plist', /CFBundleShortVersionString<\/key>\s*([^<]+)<\/string>/)], ['src/apps/mobile/harmonyos/AppScope/app.json5', readTextVersion('src/apps/mobile/harmonyos/AppScope/app.json5', /"versionName"\s*:\s*"([^"]+)"/)], @@ -26,13 +31,18 @@ if (!expected.includes('-')) { } const mismatches = [...versions].filter(([, version]) => version !== expected); -if (mismatches.length > 0) { - for (const [file, version] of mismatches) { - console.error(`[release-version] ${file}: expected ${expected}, found ${version}`); - } +const mobileExpected = args['mobile-version'] || mobileVersions.values().next().value; +const mobileMismatches = [...mobileVersions].filter(([, version]) => version !== mobileExpected); +for (const [file, version] of mismatches) { + console.error(`[release-version] ${file}: expected ${expected}, found ${version}`); +} +for (const [file, version] of mobileMismatches) { + console.error(`[release-version] ${file}: expected mobile ${mobileExpected}, found ${version}`); +} +if (mismatches.length > 0 || mobileMismatches.length > 0) { process.exit(1); } -console.log(`[release-version] OK: ${expected}`); +console.log(`[release-version] OK: desktop ${expected}; mobile ${mobileExpected}`); function readJsonVersion(file) { return JSON.parse(readFileSync(file, 'utf8')).version; diff --git a/src/apps/mobile/android/app/build.gradle.kts b/src/apps/mobile/android/app/build.gradle.kts index 2be050e060..e00be2a5db 100644 --- a/src/apps/mobile/android/app/build.gradle.kts +++ b/src/apps/mobile/android/app/build.gradle.kts @@ -27,7 +27,7 @@ android { minSdk = libs.versions.androidMinSdk.get().toInt() targetSdk = libs.versions.androidTargetSdk.get().toInt() versionCode = 1 - versionName = "1.0.2" + versionName = "1.0.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/src/apps/mobile/harmonyos/AppScope/app.json5 b/src/apps/mobile/harmonyos/AppScope/app.json5 index 875aad8576..29d9b62a23 100644 --- a/src/apps/mobile/harmonyos/AppScope/app.json5 +++ b/src/apps/mobile/harmonyos/AppScope/app.json5 @@ -4,8 +4,8 @@ // upgrades retain encrypted sessions, preferences, and watch handoff data. "bundleName": "com.bitfun.app", "vendor": "OpenBitFun", - "versionCode": 1, - "versionName": "1.0.2", // x-release-please-version + "versionCode": 4, + "versionName": "1.0.0", // x-release-please-version "buildVersion": "1", "icon": "$media:openbitfun_app_icon", "label": "$string:app_name", diff --git a/src/apps/mobile/ios/OpenBitFun/Info.plist b/src/apps/mobile/ios/OpenBitFun/Info.plist index cd18f8ee8a..dc38cd3ff8 100644 --- a/src/apps/mobile/ios/OpenBitFun/Info.plist +++ b/src/apps/mobile/ios/OpenBitFun/Info.plist @@ -13,9 +13,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0.2 + 1.0.0 CFBundleVersion - 1 + 2 CFBundleURLTypes