I'm using this issue to agree on a plan regarding the details behind the publication of the MusicPod MSIX. The result of it should likely be some sort of documentation plus some non-code related tasks, depending on the agreements we reach in the end. It's a very high level description of what I intend to do for this topic, but I'd like to be sure all that is welcome before starting. Otherwise, we can decide upon which parts or steps to remove from this master plan. Feel free to raise questions, disagree providing alternatives or simply propose removing stuff.
Rationale: Why packaging in the MSIX format
The current packaging solution for Windows presents hurdles to developers. Every "classic" packaging solution for Windows is niche, featuring their own description/programming languages and requiring third party tools to assemble them. The end result is usually a .msi or .exe that can be perceived from the user's perspective as just a random binary that asks for elevation of permissions to write to privileged locations such as C:\Program Files or the Windows Registry. It becomes harder to inspire trust if the developers don't sign their package with a executable signing certificate issued by a well-known CA (our case 😅 -- no offense ), as Windows shows the binary as originated from unknown sources.
Packaging MusicPod as MSIX has the following benefits:
- MSIX is somewhat sandboxed, confining the application into a form of application container (think of it like snaps for Windows), requires explicit capability declaration to access certain OS features and the installation destination is read-only, thus cannot be easily modified or tempered, thus harder to abuse [1].
- The package must always be signed, even if with a self-issued/self-signed certificate.
- MSIX is easier to be accepted to MS Store. More on MS Store later.
- MSIX can benefit from automatic App Installer file association on Windows 11, which results in automatic updates even if the app was not installed from the MS Store. More on that later.
- MSIX packaging tools are first-party, part of the Windows SDK, and we can count with a Dart package to abstract away lots of details. More on that later.
Specification: The birds-eye view
In my opinion we can provide the best user experience starting from installation time by:
- packaging MusicPod as an MSIX and
- submitting it to MS Store.
An application submitted to MS Store goes through a certification process that ends with the package being signed by the Store itself [2]. That signature means any Windows computer will consider the binary trusted and show it as a MS Store application rather than an unknown source, without the need for the user to manually trust the developers certificate. As developers we can manage that submission, download the signed package and host where we prefer (as an asset of a GitHub release page, for example). Doing so allows the users to either rely on MS Store for installing MusicPod or downloading from our page of choice. The end result is almost the same: a trusted package. It's totally possible to compile the app, create the package and submit it to MS Store automatically in CI. The downside of it is waiting for the MS Store to complete the certification (which can take from few hours to 3 business days) in order to download the signed package and update the release page to include the downloaded package as an asset. That step has to be manual.
Users installing the app from the Store get automatic updates for granted, and they are differential, meaning when a new package is published to the Store, rather than downloading the entirety of it, the Windows infra will download only the binary diffs (as you'd expect from a first party store). We can provide automatic updates even without the MS Store by leveraging the App Installer file. Specifically on Windows 11 an MSIX package can ship a .appinstaller file containing recipes for when and where to check for new versions of the application. On Windows 10 that feature requires the application to be installed via the .appinstaller file, but on Windows 11 any MSIX shipping that file is automatically associated [3]. So, our MSIX can point to the latest GitHub releases page and the OS will fetch that page checking for updates with the periodicity we define in that file. I have a demo app doing exactly that [4]. The less nice aspect of this feature is that it cannot implement differential updates, but MusicPod is unlikely to grow to hundreds of megabytes, thus users should be mostly fine with downloading the new version of the package in its entirety. By submitting to the MS Store and implementing the App Installer file we give users the choice of installing from the Store or directly from us with almost feature parity and the same security guarantees.
Publishing to MS Store requires creating an account in Microsoft Partner Center [5]. There are two types of accounts:
- Individual developer account. Free of charges, aimed for hobbyists and non-profit projects. Tied to a individual Microsoft Account, thus complicated to pass along, there is no clean way to plan ahead for successors.
- Corporate accounts. Requires documentation about the company and a one-time fee of 99 USD. Comes with all bells and whistles a company needs to manage the people and their roles in app management.
I believe we'd be fine with the individual account option, but highly recommend that as part of this initiative we put together a piece of documentation (like a wiki post) establishing the rules to get access to that account, so if in the future the bus factor hits or any unforeseeable event requires the community to take over this publication channel, we have defined clearly how to pass the credentials along. Since the individual account is tied to a Microsoft account, we'd need to create a shared account for the community which few selected people would have access to at any time. We should make sure at any time there are at least two people with access to the MS Partner Center portal for both trust/auditability as well as to mitigate the bus factor. I wish there was a cleaner way to do this, like linking a second account as the successor for a specific app, but to the best of my knowledge that's not possible. The same account works for multiple apps, so if we later decide that other apps from this community should also be published to MS Store, no new account set up is necessary.
Regarding the packaging activity itself, my plan is to leverage the msix Dart package [6], the obvious choice. It hooks a few entries in the pubspec.yaml file and expands it into the XML files the packaging tools need, thus the best developer experience we can find for this community. The last time I tested it specifically for MusicPod the packaging failed, so I'm willing to patch it. MusicPod is simple enough that the patches should match upstream's interest, but based on the current state of their repository it's likely they are not interested in external contributions, so we may end up carrying a fork of that package. I don't see a problem with that, but if that becomes a hindrance in the future, we can always skip that abstraction and go straight into the native way of MSIX packaging, which is essentially defining an XML file and running the right tools in the right order.
Once we clear that out, we should implement a CI job (or amend the existing one) to build the MSIX and publish it to MS Store. I implemented a similar workflow for Ubuntu Pro for WSL [7]. It's doable with GH-hosted runners.
Proposed tasks
Questions:
- Where to put the policy for the community account in MS Partner Center? It should be visible to the community such that if we need to change which members can access that account, it's clearly documented for everybody what has to be done and how.
- Are we fine with creating a MS account for the community so we can publish to MS Store? The alternative is not do it and do not publish to MS Store. We could pay for some CA to issue a code-signing certificate for the community to enhance the install UX at least.
- If we're fine with creating the account, are we also fine with doing the individual account as I suggested above (instead of the Corporate option)?
- Where should we host the released MSIX? Either if we go with publishing to MS Store plus the second alternative (or if we skip MS Store and go only with our preferred storage) we should agree upon where to host the binary. Unless we define that publishing solely to MS Store is enough. I think the answer is the GitHub release page, but let's confirm before proceeding.
References:
- About the MSIX format. https://learn.microsoft.com/en-us/windows/msix/overview
- App certification. https://learn.microsoft.com/en-us/windows/apps/publish/publish-your-app/msix/app-certification-process
- About the embedded App Installer file. https://learn.microsoft.com/en-us/windows/msix/app-installer/how-to-embed-an-appinstaller-file
- A demo for the App installer file feature. https://github.com/CarlosNihelton/hello-app-installer/
- Publish to MS Store. https://learn.microsoft.com/en-us/windows/apps/publish/
- msix package on pub.dev. https://pub.dev/packages/msix
- Example workflow that publishes an MSIX to MS Store. https://github.com/canonical/ubuntu-pro-for-wsl/blob/main/.github/workflows/publish-msix.yaml#L28
I'm using this issue to agree on a plan regarding the details behind the publication of the MusicPod MSIX. The result of it should likely be some sort of documentation plus some non-code related tasks, depending on the agreements we reach in the end. It's a very high level description of what I intend to do for this topic, but I'd like to be sure all that is welcome before starting. Otherwise, we can decide upon which parts or steps to remove from this master plan. Feel free to raise questions, disagree providing alternatives or simply propose removing stuff.
Rationale: Why packaging in the MSIX format
The current packaging solution for Windows presents hurdles to developers. Every "classic" packaging solution for Windows is niche, featuring their own description/programming languages and requiring third party tools to assemble them. The end result is usually a
.msior.exethat can be perceived from the user's perspective as just a random binary that asks for elevation of permissions to write to privileged locations such asC:\Program Filesor the Windows Registry. It becomes harder to inspire trust if the developers don't sign their package with a executable signing certificate issued by a well-known CA (our case 😅 -- no offense ), as Windows shows the binary as originated from unknown sources.Packaging MusicPod as MSIX has the following benefits:
Specification: The birds-eye view
In my opinion we can provide the best user experience starting from installation time by:
An application submitted to MS Store goes through a certification process that ends with the package being signed by the Store itself [2]. That signature means any Windows computer will consider the binary trusted and show it as a MS Store application rather than an unknown source, without the need for the user to manually trust the developers certificate. As developers we can manage that submission, download the signed package and host where we prefer (as an asset of a GitHub release page, for example). Doing so allows the users to either rely on MS Store for installing MusicPod or downloading from our page of choice. The end result is almost the same: a trusted package. It's totally possible to compile the app, create the package and submit it to MS Store automatically in CI. The downside of it is waiting for the MS Store to complete the certification (which can take from few hours to 3 business days) in order to download the signed package and update the release page to include the downloaded package as an asset. That step has to be manual.
Users installing the app from the Store get automatic updates for granted, and they are differential, meaning when a new package is published to the Store, rather than downloading the entirety of it, the Windows infra will download only the binary diffs (as you'd expect from a first party store). We can provide automatic updates even without the MS Store by leveraging the App Installer file. Specifically on Windows 11 an MSIX package can ship a
.appinstallerfile containing recipes for when and where to check for new versions of the application. On Windows 10 that feature requires the application to be installed via the.appinstallerfile, but on Windows 11 any MSIX shipping that file is automatically associated [3]. So, our MSIX can point to the latest GitHub releases page and the OS will fetch that page checking for updates with the periodicity we define in that file. I have a demo app doing exactly that [4]. The less nice aspect of this feature is that it cannot implement differential updates, but MusicPod is unlikely to grow to hundreds of megabytes, thus users should be mostly fine with downloading the new version of the package in its entirety. By submitting to the MS Store and implementing the App Installer file we give users the choice of installing from the Store or directly from us with almost feature parity and the same security guarantees.Publishing to MS Store requires creating an account in Microsoft Partner Center [5]. There are two types of accounts:
I believe we'd be fine with the individual account option, but highly recommend that as part of this initiative we put together a piece of documentation (like a wiki post) establishing the rules to get access to that account, so if in the future the bus factor hits or any unforeseeable event requires the community to take over this publication channel, we have defined clearly how to pass the credentials along. Since the individual account is tied to a Microsoft account, we'd need to create a shared account for the community which few selected people would have access to at any time. We should make sure at any time there are at least two people with access to the MS Partner Center portal for both trust/auditability as well as to mitigate the bus factor. I wish there was a cleaner way to do this, like linking a second account as the successor for a specific app, but to the best of my knowledge that's not possible. The same account works for multiple apps, so if we later decide that other apps from this community should also be published to MS Store, no new account set up is necessary.
Regarding the packaging activity itself, my plan is to leverage the msix Dart package [6], the obvious choice. It hooks a few entries in the
pubspec.yamlfile and expands it into the XML files the packaging tools need, thus the best developer experience we can find for this community. The last time I tested it specifically for MusicPod the packaging failed, so I'm willing to patch it. MusicPod is simple enough that the patches should match upstream's interest, but based on the current state of their repository it's likely they are not interested in external contributions, so we may end up carrying a fork of that package. I don't see a problem with that, but if that becomes a hindrance in the future, we can always skip that abstraction and go straight into the native way of MSIX packaging, which is essentially defining an XML file and running the right tools in the right order.Once we clear that out, we should implement a CI job (or amend the existing one) to build the MSIX and publish it to MS Store. I implemented a similar workflow for Ubuntu Pro for WSL [7]. It's doable with GH-hosted runners.
Proposed tasks
.appinstallerfile for MusicPod and include it in the MSIX packagingQuestions:
References: