Test builds: tool/dev_release.sh builds Linux here and publishes to a dev prerelease that dev builds update from
X.Y.Z-dev.N builds read the dev prerelease's manifest as well as the stable one and take the newer, so a tester gets each test build through the normal update and lands back on stable at the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1b0a3db439
commit
ab133dd82f
9 files changed
+228
-23
No files matched your search
@@ -28,6 +28,11 @@ final _log = createLogger('update');
|
||||
const updateManifestUrl =
|
||||
'https://git.senkochan.moe/Foxyz/sync_replay_project/raw/branch/main/updates/manifest.json';
|
||||
|
||||
/// Test builds (`tool/dev_release.sh`): one Gitea prerelease, tag `dev`,
|
||||
/// whose assets each run replaces. Only dev builds read it.
|
||||
const devManifestUrl =
|
||||
'https://git.senkochan.moe/Foxyz/sync_replay_project/releases/download/dev/manifest.json';
|
||||
|
||||
const appVersion = String.fromEnvironment('APP_VERSION',
|
||||
defaultValue: '0.0.0-dev');
|
||||
|
||||
@@ -161,6 +166,34 @@ Future<UpdateManifest> fetchManifest(
|
||||
}
|
||||
}
|
||||
|
||||
/// A test build (`1.1.3-dev.4`); `0.0.0-dev` (a dev run) is not one.
|
||||
bool isDevBuild(String version) => version.contains('-dev.');
|
||||
|
||||
/// The manifest to update from: the stable one, and for a [isDevBuild]
|
||||
/// also the dev one, whichever is newer (either alone if the other fails).
|
||||
/// A release outranks its own test builds, so testers return to stable.
|
||||
Future<UpdateManifest> fetchLatestManifest(
|
||||
{HttpClient? http,
|
||||
String currentVersion = appVersion,
|
||||
String url = updateManifestUrl,
|
||||
String devUrl = devManifestUrl}) async {
|
||||
final stable = fetchManifest(http: http, url: url);
|
||||
if (!isDevBuild(currentVersion)) return stable;
|
||||
stable.ignore(); // awaited below; don't let an early failure go uncaught
|
||||
final dev = await fetchManifest(http: http, url: devUrl)
|
||||
.then<UpdateManifest?>((m) => m, onError: (Object e) {
|
||||
_log.warning('dev manifest: $e');
|
||||
return null;
|
||||
});
|
||||
if (dev == null) return stable;
|
||||
try {
|
||||
final s = await stable;
|
||||
return isNewerVersion(s.version, dev.version) ? dev : s;
|
||||
} catch (_) {
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
|
||||
typedef DownloadProgress = void Function(int received, int? total);
|
||||
|
||||
Future<void> downloadFile(String url, File dest,
|
||||
@@ -538,7 +571,8 @@ Future<int> runUpgrade(
|
||||
stdout.writeln('$program $currentVersion (proto ${RelayConstants.protoVersion})');
|
||||
late final UpdateManifest manifest;
|
||||
try {
|
||||
manifest = await fetchManifest(http: http, url: manifestUrl);
|
||||
manifest = await fetchLatestManifest(
|
||||
http: http, currentVersion: currentVersion, url: manifestUrl);
|
||||
} catch (e) {
|
||||
stdout.writeln('update check failed: $e');
|
||||
return 1;
|
||||
|
||||
@@ -208,6 +208,35 @@ void main() {
|
||||
}
|
||||
});
|
||||
|
||||
test('dev builds also read the dev manifest, the newer wins', () async {
|
||||
final versions = {'/stable': '1.1.2', '/dev': '1.1.3-dev.2'};
|
||||
final http = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
|
||||
http.listen((req) async {
|
||||
final v = versions[req.uri.path];
|
||||
if (v == null) {
|
||||
req.response.statusCode = 404;
|
||||
} else {
|
||||
req.response.write(jsonEncode(
|
||||
{'version': v, 'protocol': 1, 'url': 'http://x/$v.tar.gz'}));
|
||||
}
|
||||
await req.response.close();
|
||||
});
|
||||
final base = 'http://127.0.0.1:${http.port}';
|
||||
Future<String> latest(String current) async => (await fetchLatestManifest(
|
||||
currentVersion: current, url: '$base/stable', devUrl: '$base/dev'))
|
||||
.version;
|
||||
try {
|
||||
expect(await latest('1.1.2'), '1.1.2'); // stable builds never see dev
|
||||
expect(await latest('1.1.3-dev.1'), '1.1.3-dev.2');
|
||||
versions['/stable'] = '1.1.3'; // the release outranks its test builds
|
||||
expect(await latest('1.1.3-dev.2'), '1.1.3');
|
||||
versions.remove('/stable');
|
||||
expect(await latest('1.1.3-dev.1'), '1.1.3-dev.2');
|
||||
} finally {
|
||||
await http.close(force: true);
|
||||
}
|
||||
});
|
||||
|
||||
group('upgrade flow', () {
|
||||
late Directory work;
|
||||
late _Server server;
|
||||
|
||||
Reference in new issue
Block a user