Changelog and What's new: CHANGELOG.md cut into each release, shown in the update band, a What's new card and once after updating
CHANGELOG.md keeps an Unreleased section (user-facing changes add a line in the same commit); tool/release.sh cuts it into the version, the manifest gets a structured "changes" field next to the one-line "notes" older apps read, and the Gitea release text is that section. The app's update band shows the top items, What's new opens a card (Added / Changed / Fixed), and the first start after an update shows it once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ec0849eb01
commit
638a30e16c
22 files changed
+1637
-58
No files matched your search
@@ -78,18 +78,50 @@ const _stagingDir = '.update-staging';
|
||||
const _backupDir = '.update-backup';
|
||||
const _downloadFile = '.update-download';
|
||||
|
||||
/// What a release changed, in the words of CHANGELOG.md: the manifest's
|
||||
/// `changes` ({"added": [...], "changed": [...], "fixed": [...]}).
|
||||
/// Manifests from before it have only `notes`.
|
||||
class ReleaseChanges {
|
||||
final List<String> added;
|
||||
final List<String> changed;
|
||||
final List<String> fixed;
|
||||
const ReleaseChanges({this.added = const [], this.changed = const [], this.fixed = const []});
|
||||
|
||||
/// Null for anything that is not a map, or one with no items; entries
|
||||
/// that are not strings (or blank) are dropped, unknown keys ignored.
|
||||
static ReleaseChanges? fromJson(Object? json) {
|
||||
if (json is! Map) return null;
|
||||
List<String> list(String key) => List.unmodifiable([
|
||||
if (json[key] case final List l)
|
||||
for (final item in l)
|
||||
if (item is String && item.trim().isNotEmpty) item.trim(),
|
||||
]);
|
||||
final c = ReleaseChanges(added: list('added'), changed: list('changed'), fixed: list('fixed'));
|
||||
return c.isEmpty ? null : c;
|
||||
}
|
||||
|
||||
Map<String, Object?> toJson() => {'added': added, 'changed': changed, 'fixed': fixed};
|
||||
|
||||
bool get isEmpty => added.isEmpty && changed.isEmpty && fixed.isEmpty;
|
||||
int get length => added.length + changed.length + fixed.length;
|
||||
}
|
||||
|
||||
class UpdateManifest {
|
||||
final String version;
|
||||
final int protocol;
|
||||
final String url;
|
||||
final String? sha256;
|
||||
/// One line for every app (1.2.x and 1.3.x show only this).
|
||||
final String notes;
|
||||
/// Null in manifests from before the changelog (show [notes] then).
|
||||
final ReleaseChanges? changes;
|
||||
const UpdateManifest(
|
||||
{required this.version,
|
||||
required this.protocol,
|
||||
required this.url,
|
||||
this.sha256,
|
||||
required this.notes});
|
||||
required this.notes,
|
||||
this.changes});
|
||||
|
||||
// `assets` maps platform → archive URL. Top-level `url` is the Linux
|
||||
// tarball, kept for builds from before `assets` existed (<= 0.2.1).
|
||||
@@ -115,7 +147,8 @@ class UpdateManifest {
|
||||
protocol: protocol,
|
||||
url: url,
|
||||
sha256: sha is String && sha.isNotEmpty ? sha : null,
|
||||
notes: (json['notes'] as String?) ?? '');
|
||||
notes: json['notes'] is String ? json['notes'] as String : '',
|
||||
changes: ReleaseChanges.fromJson(json['changes']));
|
||||
}
|
||||
|
||||
// Newer wire protocol: this build can't join servers running it.
|
||||
|
||||
Reference in new issue
Block a user