@@ -86,14 +86,57 @@ jobs:
8686 VERSION_NAME=$(node -p "require('./package.json').version")
8787 fi
8888
89- # Generate version code from version string
90- # 2.0.0-beta.0 -> 2000000, 2.1.3 -> 2001003
91- MAJOR=$(echo "$VERSION_NAME" | cut -d. -f1)
92- MINOR=$(echo "$VERSION_NAME" | cut -d. -f2 | cut -d- -f1)
93- PATCH=$(echo "$VERSION_NAME" | cut -d. -f3 | cut -d- -f1)
94- PRE=$(echo "$VERSION_NAME" | grep -oP '(?<=\.)\d+$' || echo "0")
89+ # Generate a monotonic Android version code from semver.
90+ # 2.0.0-alpha.82 -> 200001082, 2.0.0-beta.0 -> 200003000,
91+ # 2.0.0 -> 200009000, 2.1.3 -> 201039000.
92+ VERSION_CODE=$(node - "$VERSION_NAME" <<'NODE'
93+ const version = process.argv[2];
94+ const match = version.match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+)(?:\.(\d+))?)?$/);
95+ if (!match) {
96+ console.error(`Invalid semver version: ${version}`);
97+ process.exit(1);
98+ }
9599
96- VERSION_CODE=$(( MAJOR * 1000000 + MINOR * 10000 + PATCH * 100 + PRE ))
100+ const [, majorRaw, minorRaw, patchRaw, prerelease, prereleaseRaw = "0"] =
101+ match;
102+ const major = Number(majorRaw);
103+ const minor = Number(minorRaw);
104+ const patch = Number(patchRaw);
105+ const prereleaseNumber = Number(prereleaseRaw);
106+ if (
107+ !Number.isInteger(major) ||
108+ !Number.isInteger(minor) ||
109+ !Number.isInteger(patch) ||
110+ !Number.isInteger(prereleaseNumber) ||
111+ prereleaseNumber < 0 ||
112+ prereleaseNumber > 999
113+ ) {
114+ console.error(`Invalid Android version component in ${version}`);
115+ process.exit(1);
116+ }
117+
118+ const channelOffsets = {
119+ alpha: 1000,
120+ beta: 3000,
121+ rc: 5000,
122+ nightly: 7000,
123+ };
124+ const channelOffset = prerelease
125+ ? (channelOffsets[prerelease] ?? 8000)
126+ : 9000;
127+ const code =
128+ major * 100000000 +
129+ minor * 1000000 +
130+ patch * 10000 +
131+ channelOffset +
132+ prereleaseNumber;
133+ if (code > 2100000000) {
134+ console.error(`Android versionCode ${code} exceeds Play Store limit`);
135+ process.exit(1);
136+ }
137+ console.log(code);
138+ NODE
139+ )
97140
98141 echo "name=$VERSION_NAME" >> "$GITHUB_OUTPUT"
99142 echo "code=$VERSION_CODE" >> "$GITHUB_OUTPUT"
0 commit comments