Beta tags now reach external testers without per-release dashboard work. Reserve distinct native build slots so successive betas and the promoted stable build can coexist under one app version.
42 lines
1.5 KiB
JavaScript
42 lines
1.5 KiB
JavaScript
const versionPattern = /^(\d+)\.(\d+)\.(\d+)(?:-beta\.(\d+))?$/;
|
|
const stableIosBuildSlot = 999;
|
|
|
|
function getNativeReleaseVersion(version) {
|
|
const match = versionPattern.exec(version);
|
|
if (!match) {
|
|
throw new Error(`Cannot derive native release version from unsupported version: ${version}`);
|
|
}
|
|
|
|
const [, majorText, minorText, patchText, betaText] = match;
|
|
const major = Number(majorText);
|
|
const minor = Number(minorText);
|
|
const patch = Number(patchText);
|
|
const betaNumber = betaText === undefined ? null : Number(betaText);
|
|
|
|
if (minor > 999 || patch > 999) {
|
|
throw new Error(`Cannot derive collision-free native version from: ${version}`);
|
|
}
|
|
if (betaNumber !== null && (betaNumber < 1 || betaNumber >= stableIosBuildSlot)) {
|
|
throw new Error(`iOS beta number must be between 1 and 998: ${version}`);
|
|
}
|
|
|
|
const versionCode = major * 1_000_000 + minor * 1_000 + patch;
|
|
if (!Number.isSafeInteger(versionCode) || versionCode <= 0 || versionCode > 2_100_000_000) {
|
|
throw new Error(`Derived Android versionCode is out of range: ${versionCode}`);
|
|
}
|
|
|
|
const iosBuildSlot = betaNumber ?? stableIosBuildSlot;
|
|
const iosBuildNumber = versionCode * 1_000 + iosBuildSlot;
|
|
if (!Number.isSafeInteger(iosBuildNumber)) {
|
|
throw new Error(`Derived iOS buildNumber is out of range: ${iosBuildNumber}`);
|
|
}
|
|
|
|
return {
|
|
appVersion: `${major}.${minor}.${patch}`,
|
|
androidVersionCode: versionCode,
|
|
iosBuildNumber: String(iosBuildNumber),
|
|
};
|
|
}
|
|
|
|
module.exports = { getNativeReleaseVersion };
|