@ximion
Copy link
Owner

ximion commented Sep 9, 2021

This is a proposal for splitting the release information out of the main MetaInfo files for applications, to allow them to be updated independently.
This, if implemented, would be a major new feature and break a few assumptions, so it is AppStream 1.0 material even if implemented earlier.

Goals

The primary goal of optionally splitting out release metadata for projects that wish to do so is addressing issues like #240 where projects want to modify the release metadata for a bit of time after a release was made. It would also reduce the amount of content in a MetaInfo file significantly and possibly make the file a bit easier to handle and update.

We would also gain a very cheap way to check for software updates in a machine-readable way (that doesn't involve processing HTML pages).

Proposal

A new AppStream XML file format will be created, containing the <releases/> block from the existing MetaInfo specification.
These files must be installed by the software into /usr/share/metainfo/releases/%{id}.releases.xml where %{id} is the component-ID of the application that the release information belongs to.
Contents of this file may look like this:

<releases>
  <release type="stable" version="0.14.5" date="2021-08-28">
    <description>
      <p>This release adds features</p>
    </description>
  </release>
  <release type="stable" version="0.14.4" date="2021-06-22">
  </release>
  ...
</releases>

(refer to the releases tag specification for all details on what is possible)

If this release metadata file is split out from the main MetaInfo file, the MetaInfo file can contain an empty releases block, containing an URL that points to a web location where the continuously-updated release metadata lives:

<component type="generic">
  <id>org.example.app</id>
  ...
  <releases url="https://example.org/repo/org.example.app.releases.xml" />
</component>

If a metadata processing application encounters a MetaInfo file, it will do the following things in order to get release information:

  • If MetaInfo file contains a full filled-out <releases/> block it will be unconditionally used and preferred above all else
  • If no <releases/> block is present, look for a /usr/share/metainfo/releases/%{id}.releases.xml file and use that to get release metadata
  • If the releases tag has a url property, fetch the release information from the web URL and embed the new data in the generated output. If we can not fetch data from the URL, emit a warning and use the local data

This means that we will always have somewhat-usable release metadata (even if the URL goes down, we will always have the version number and release data, and possibly untranslated release descriptions).
If a release is processed by the collection metadata generator immediately after it was done, before people managing the release data at the remote URL had time to translate everything and add data, we will of course run into the current situation of having incomplete release descriptions.
Except this time, with an URL present that can be queried for new releases, an AppStream metadata generator can poll that URL periodically and incorporate any changes made (distributors probably only want to add metadata up to the version they offer in their archive).

Open Questions

Besides the general "Is this a good Idea?" there's a few details questions already:

  • Should the MetaInfo file explicitly mention that a release metadata file was installed externally? That would save us one stat() in a directory to check for existence of the file, and would follow the "explicit is better than implicit" rule AppStream has, but it would also be a lot clunkier.
  • Do we need to include a signature, so we can verify the authenticity of the by-URL referenced release file? A release file can contain downloadable artifacts, which do contain checksums, but there is no way for us to determine whether the data served there is actually legit or whether someone did get a hold of the domain and just swapped out the metadata file. Of course, this may be an artificial scenario, and won't affect Linux distributions (they split our artifacts), but it is something to consider.

Obviously, appstreamcli would gain support for reading and validating the new file format, and this would be an optional feature, so everything we currently have would remain working and does not need to change.

CC: @hughsie @pwithnall @Pointedstick