Files
paseo/packages/app/native-release-version.js
Anton LazarevandMohamed Boudra f6288629ff Fastlane metadata format for F-Droid releases (#2501)
* add f-droid metadata support

* share version code calculation with website

* preserve blockquoted sections in changelogs

* refactor(android): simplify stable F-Droid metadata

Generate store changelogs only for stable releases and keep native version-code ownership in the existing release module.

* test(android): run F-Droid changelog suite in CI

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-08-25 23:37:54 +02:00

64 lines
1.9 KiB
JavaScript

const versionPattern = /^(\d+)\.(\d+)\.(\d+)(?:-beta\.(\d+))?$/;
const stableIosBuildSlot = 999;
const FDROID_ABI_VERSION_CODE_SUFFIXES = {
"armeabi-v7a": 1,
"arm64-v8a": 2,
x86: 3,
x86_64: 4,
};
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 * 10 + 9 > 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),
};
}
function getFdroidVersionCodes(version) {
const { androidVersionCode } = getNativeReleaseVersion(version);
return Object.entries(FDROID_ABI_VERSION_CODE_SUFFIXES).map(([abi, suffix]) => ({
abi,
versionCode: androidVersionCode * 10 + suffix,
}));
}
module.exports = {
FDROID_ABI_VERSION_CODE_SUFFIXES,
getFdroidVersionCodes,
getNativeReleaseVersion,
};