Skip to content

gh-releases-zsync: don't match glob pattern against the browser_download_url #252

@bastimeyer

Description

@bastimeyer

I'm currently in the process of adding update information to my project's AppImage builds and have run into an issue with your AppImageUpdate and appimageupdatetool tools, which both select the wrong AppImage files when trying to update. This is caused by your lib using the entire download URL instead of the asset file names when matching the update glob pattern.

My project whose AppImage releases are built in the $project/$project-appimage GitHub repo provides two different kinds of AppImage flavors, one default one and one with a bundled dependency, which thus has a different prefix:

  • $project-$version-$otherdata_$arch.AppImage
  • $project_$bundle-$version-$otherdata_$arch.AppImage

All AppImage files (type 2 runtime) all have their correct .upd_info ELF section data, namely

  • gh-releases-zsync|$project|$project-appimage|latest|$project-*_x86_64.AppImage.zsync
  • gh-releases-zsync|$project|$project-appimage|latest|$project_$bundle-*_x86_64.AppImage.zsync

and the .zsync files point to the correct AppImage files as well (relative paths).

Using zsync2 with the individual .zsync file URLs from GitHub releases works fine. As mentioned above, the issue is with the selection of the release assets when using the .upd_info data.

I had a look at the logic for choosing the files according to the glob pattern, and found that the browser_download_url value is used from the JSON response of the GitHub API:

std::vector<std::string> matchingUrls;
for (const auto& asset : assets) {
const auto browserDownloadUrl = asset["browser_download_url"].get<std::string>();
if (fnmatch(pattern.c_str(), browserDownloadUrl.c_str(), 0) == 0) {
matchingUrls.emplace_back(browserDownloadUrl);
}
}

A download URL for the .zsync files will look like this:
https://github.com/$project/$project-appimage/releases/download/$tag/$project-$version-$otherdata_$arch.AppImage.zsync

Since the glob pattern of our default AppImage flavor is $project-*_$arch.AppImage.zsync, it also matches the download URL of the other flavors, because the $project-* part matches the repo name in the URL path. Then the list of all matches is sorted at the bottom, and the result is the wrong file.

Instead, the name value of the JSON response should be used, which is just the file name, so the repo name won't be taken into account when matching the glob pattern.
https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#get-the-latest-release

The spec explicitly says "Filename":
https://github.com/AppImage/AppImageSpec/blob/master/draft.md#github-releases

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions