-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AutoUpdater (NSIS) - Feature Request - Custom URLs Don't Work with Restful APIs #5927
Comments
I'm in a very similar situation with blob stores that can only be accessed via pre-determined IDs. Adding the ability to set custom URLs for each respective file request, i.e. |
I'm very interested in your configuration and the implementation behind it, as it seems akin to what I've been wanting to do with my project for over a year. |
@mmaietta It's actually fairly simple in .NET Web API. Probably even simpler in Node + Express.
/* Implementation of electron-builder/electron-updater UpdateInfo */
public class ElectronUpdateInfo
{
public string FileName { get; set; }
// We can use a ternary to determine channel. E.g., Version.Contains("-beta") ? "beta" : "latest"
public string Version { get; set; }
public IList<ElectronUpdateFileInfo> Files { get; set; }
public string ReleaseDate { get; set; }
} /* Implementation of electron-builder/electron-updater UpdateInfo */
public class ElectronUpdateFileInfo
{
public long DownloadId { get; set; }
public string Sha512 { get; set; }
public long Size { get; set; }
// Used for the custom download url
public string Url => $"https://app.example.com/downloads/{DownloadId}/download";
}
public class Download : BaseEntity
{
public string Name { get; set; }
public string Description { get; set; }
public string Content { get; set; }
public byte[] ContentKey { get; set; }
public string Sha512Checksum { get; set; } // Crucial.
}
publish: [
{
provider: 'generic',
// electron-updater will append ${channel}.yml to the end of this URL. Part of the request is to optionally disable this.
url: `${baseUrl}/api/downloads/update/${platform}`,
channel: someBoolean ? 'latest' : 'beta'
}
<rule name="Rewrite Desktop Update">
<match url="api/downloads/update/(darwin|win32)/(latest|beta).yml$" />
<action type="Rewrite" url="api/downloads/update/(darwin|win32)/(latest|beta)" />
</rule>
var sb = new StringBuilder();
sb.Append($"version: {updateInfo.Version}\n");
sb.Append("files:\n");
foreach (var updateFileInfo in updateInfo.Files)
{
sb.Append($" - url: {updateFileInfo.Url}\n");
sb.Append($" sha512: {updateFileInfo.Sha512}\n");
sb.Append($" size: {updateFileInfo.Size}\n");
}
sb.Append($"releaseDate: '{updateInfo.ReleaseDate}'");
return sb.ToString(); // The endpoint is configured to return Content-Type `text/x-yaml`. Very important! An example response tested with Postman returns: version: 1.234.5
files:
- url: https://app.example.com/api/downloads/1/download
sha512: gmib0kbkMXtuwF6QVINTSrOSis2Gc3Ux591n+P4y6IKmseH1QdU6VHPi4u7HNldPbGRI1us8PQLKHAeLr4vDWw==
size: 8675312
releaseDate: '2021-05-28T04:32:22.478Z' To answer your questions:
We do this a little backwards. Each dist+blockmap gets it's own URL since we build the URL from the DownloadId after uploading it. So if we upload release
Assuming we upload release
Technically neither. Our CI pipeline builds the binaries then sends a request to our API to upload them to our server via a route @ In summary:
Hope this helps! Like I said, it's probably way easier in Node + Express.
|
Thank you for the detailed write-up! I appreciate it I feel like this could be solved in a different manner, one which doesn't require working with the expectations I found this magic code all the Provider's use. Bintray and Generic Providers simply ignore the electron-builder/packages/electron-updater/src/providers/Provider.ts Lines 135 to 156 in ef704a1
We'd then also add an additional optional electron-builder/packages/builder-util-runtime/src/updateInfo.ts Lines 20 to 25 in ef704a1
It's possible this could all be solved by opening |
Hey @mmaietta ! I like both of your ideas:
That said, I just noticed that
Would adding |
I never realized there was a Looking into that further, it seems you can actually completely custom-ize the electron-builder/packages/app-builder-lib/src/publish/PublishManager.ts Lines 333 to 346 in 8bf39ab
Example: electron-builder/packages/electron-publish/src/publisher.ts Lines 71 to 76 in 8bf39ab
I imagine that should allow you to upload each file separately to different URLs as you require? The downside is that a custom I suppose we can mirror the approach the custom publisher was using via a dynamic require to accept a
What are your thoughts? |
Agree with your idea, and that's the feature I just looking for. Maybe we can configure two providers 'generic' and 'custom', then use 'generic' for updater, and use 'custom' for publish? |
@djbreen7, take a look at this new custom provider that can use to define your own |
Thanks @mmaietta! Might be a while before I can dive back and test, but looks promising. |
Our web application manages several downloadable files that are stored in azure storage accounts. We restrict access to our storage accounts to only our api. Each download has an ID that we use for our downloadable files without the file name. For example:
/api/downloads/{id}/download
We can upload our
{application}.exe
and{application}.exe.blockmap
, but they will each have a different ID. For example:/api/downloads/1/download
- application.exe/api/downloads/2/download
- application.exe.blockmapUnfortunately, this is hard to adapt to with electron-updater because it has no option (that I'm aware of) to omit the filename. So when I set
publish.url
tohttp://localhost:3000/api/downloads/update/{platform}/{channel}
with a generic provider, electron-updater changes it tohttp://localhost:3000/api/downloads/update/{platform}/{channel}/{channel}.yml
which is not desirable.It would be nice to be able to specify each url without interference from electron-updater. It would be even nicer to prevent electron-updater from trying to append the filename since the endpoints can provide the correct MIME type to satisfy the updater.
Current Workaround:
We created a route that returns yaml in the same format as expected
/api/downloads/update/{platform}/{channel}
and added a rewrite rule in iis. This allows us to fake our way through checking for updates (though I have a feeling we'll run into issues on the SHA512 checksum):This endpoint checks our storage account for the latest release for the given channel and builds the download URL with the correct ID:
This only works so far. electron-updater appears to be satisfied with the yaml and downloads the .exe, but it then tries to download a blockmap from:
http://localhost:3000/api/downloads/1/download.blockmap
rather thanhttp://localhost:3000/api/downloads/2/download
Suggested Improvement
The text was updated successfully, but these errors were encountered: