feat(android): in-app updater (backend/Gitea APK), auto-bump versionCode
The app checks {backend}/api/apk/info on launch and, if a newer versionCode
than BuildConfig.VERSION_CODE is offered, shows an update dialog that
downloads {backend}/api/apk into a single wiped-each-time cache file and
hands it to the system installer (FileProvider + REQUEST_INSTALL_PACKAGES).
No APK hoarding; in-place install preserves data (stable signing key needed).
- backend /api/apk/info now returns versionCode (parsed from the release body).
- publish-apk.mjs auto-increments versionCode, sets versionName, and writes
versionCode/versionName into the Gitea release body.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
845f125d76
commit
2fd4d978d0
7 files changed
+175
-14
No files matched your search
@@ -508,10 +508,14 @@ async function _giteaApkAsset() {
|
||||
const rel = await _giteaApiJson(`/releases/tags/${encodeURIComponent(GITEA_APK_TAG)}`);
|
||||
const asset = (rel.assets || []).find(a => /\.apk$/i.test(a.name || ''));
|
||||
if (!asset) return null;
|
||||
// The publish script writes "versionCode=NN" into the release body so the in-app updater has a
|
||||
// reliable integer to compare against BuildConfig.VERSION_CODE.
|
||||
const vcMatch = /versionCode\s*[=:]\s*(\d+)/i.exec(rel.body || '');
|
||||
return {
|
||||
size: asset.size,
|
||||
url: asset.browser_download_url,
|
||||
version: rel.name || rel.tag_name || null,
|
||||
versionCode: vcMatch ? parseInt(vcMatch[1], 10) : null,
|
||||
updatedAt: new Date(asset.created_at || rel.published_at || Date.now()).getTime(),
|
||||
};
|
||||
}
|
||||
@@ -548,13 +552,14 @@ function _streamApkFromUrl(urlStr, res, redirectsLeft = 3) {
|
||||
app.get('/api/apk/info', async (req, res) => {
|
||||
try {
|
||||
const a = await _giteaApkAsset();
|
||||
if (a) return res.json({ available: true, size: a.size, updatedAt: a.updatedAt, version: a.version, source: 'gitea' });
|
||||
if (a) return res.json({ available: true, size: a.size, updatedAt: a.updatedAt, version: a.version, versionCode: a.versionCode, source: 'gitea' });
|
||||
} catch { /* fall through to local */ }
|
||||
fs.stat(APK_PATH, (err, st) => {
|
||||
if (err) return res.json({ available: false });
|
||||
let version = null;
|
||||
let version = null, versionCode = null;
|
||||
try { version = fs.readFileSync(APK_VER_PATH, 'utf8').trim() || null; } catch {}
|
||||
res.json({ available: true, size: st.size, updatedAt: st.mtimeMs, version, source: 'local' });
|
||||
try { versionCode = parseInt(fs.readFileSync(path.join(CONFIG.dataPath, 'novasonic.versioncode.txt'), 'utf8').trim(), 10) || null; } catch {}
|
||||
res.json({ available: true, size: st.size, updatedAt: st.mtimeMs, version, versionCode, source: 'local' });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user