Structure of winget source repositories

winget 1.0 introduced a new REST API for custom repositories. The API and a reference implementation are provided by Microsoft at github.com/microsoft/winget-cli-restsource/. The reference implementation uses C# and allows self-hosting on Azure. Hosted offerings are also becoming available, such as https://winget.pro.

Before winget 1.0, the structure of winget repositories looked roughly as follows:

  1. The remote repository should have a source.msix file. You may refer to the example at the default repository: https://winget.azureedge.net/cache/source.msix

  2. One can find details about MSIX itself on the Microsoft Docs website.

  3. Actually the source.msix is a zip package with contents structured in a pre-defined fashion (just rename it to source.zip and unpack):

    • Assets/
    • Public/
    • AppxBlockMap.xml
    • AppxManifest.xml
    • AppcSignature.p7x
    • [Content_Typex.xml]
  4. The main data file seems to be Public/index.db. It is an SQLite database containing information derived from Community Repo Manifests. It has a quite simple structure to understand.

  5. Another concern is the MSIX should be signed by the developer. One should change Windows settings in order winget to accept packages signed by third parties. See below for details.

  6. Note that winget doesn't accept an HTTP repository, it requires only the HTTPS one with a trusted certificate.

  7. The most interesting tables in index.db are manifest and pathparts. The first matches application's name, version, etc. to pathparts, and the latter points to the manifest YAML-file.

    For example: https://winget.azureedge.net/cache/manifests/RubyInstallerTeam/Ruby/e70d-2.7.2.yaml (a cache of github/winget-pkgs/manifests/RubyInstallerTeam/Ruby/2.7.2.yaml).

  8. winget uses this cached manifest for application installation.

  9. In order winget could add the third-party source repository (when the source.msix signed by third-party certificate) one should allow installing sideload apps.

Windows Settings

  1. Summarizing the above the overall sequence seems to be the following:

    • Download the source.msix from the winget's default repo: https://winget.azureedge.net/cache/source.msix
    • Unpack it as a ZIP-package or using the MSIX Packaging Tool to get the index.db file from Public directory.
    • Edit this SQLite DB (I've used the DB Browser for SQLite for that) leaving only your application (tables ids, monikers, names, versions).
    • Set the path to YAML-manifest in pathparts table (one record per each path element). E.g. for /manifests/MyCompany/MyProduct/1.0.0.yaml the table should be like: pathparts table example
    • Edit the manifest table by adding the record that unites all related records.
    • Save the edited index.db, overwrite it in source.msix using the MSIX Packaging Tool, sign the MSIX with your own code-signing certificate.
    • Upload both the manifest (see Manifest Specification for details about manifest itself) and source.msix to your server (e.g. to myserver.net/repo/source.msix and myserver.net/repo/manifests/MyCompany/MyProduct/1.0.0.yaml).
    • Use:
    winget source add myrepo https://myserver.net/repo
    winget install MyProduct
    

You can deploy a private REST source to Azure using the reference implementation.

It is also possible to create your own implementation referencing the Swagger API.