1MSIX Package
2============
3
4Firefox MSIX packages are full participants in the "modern" Windows
5app packaging system.  They are distributed, installed, updated,
6repaired, and uninstalled entirely using that system.  This gives
7administrators lots of deployment options, and also grants complete
8control over when and how application updates are rolled out
9(Firefox's built-in updater is always fully disabled in MSIX
10packages).  This stands in contrast to Firefox MSI packages, which
11mostly work against the Windows Installer framework rather than with
12it, and therefore are missing a lot of important functionality; for
13example, tools that install MSI packages generally cannot uninstall
14Firefox [#]_.  This means the MSIX package may well be the better
15option for deploying to Windows 10 and up.
16
17In automation
18-------------
19
20The ``repackage-msix`` and ``repackage-shippable-l10n-msix`` tasks
21repackage the ZIP packages produced by signed build tasks into MSIX
22packages. The ``shippable-l10n`` variants depend on Linux64 builds and
23localization tasks to produce signed langpacks, which are incorporated
24into the MSIX package as distribution extensions. (This is the same
25approach taken by ``snap`` and ``flatpak`` Linux packages.)
26
27The ``repackage-signing-msix`` and
28``repackage-signing-shippable-l10n-msix`` tasks sign the MSIX packages
29produced by the repackage tasks.
30
31Signing in automation
32~~~~~~~~~~~~~~~~~~~~~
33
34MSIX packages are signed by the same certificates that sign binaries for
35other jobs. In practice, this means that try builds are signed with the
36```Mozilla Fake CA``
37certificate `MozFakeCA_2017-10-13.cer <https://raw.githubusercontent.com/mozilla-releng/OpenCloudConfig/3493a608bf700b68a54ff2fd506f33373bb87a04/userdata/Configuration/Mozilla%20Maintenance%20Service/MozFakeCA_2017-10-13.cer>`__.
38In order to install try builds locally, you must trust this certificate.
39**For your own security, it's best to do this in Windows Sandbox or a
40Virtual Machine**. To do so run the following in an elevated
41(administrator) Powershell:
42
43::
44
45    $ Import-Certificate -FilePath "MozFakeCA_2017-10-13.cer" -Cert Cert:\LocalMachine\Root\
46    ...
47    Thumbprint                                Subject
48    ----------                                -------
49    FA056CEBEFF3B1D0500A1FB37C2BD2F9CE4FB5D8  CN=Mozilla Fake CA
50
51The ``shippable-l10n`` MSIX variants incorporate signed langpacks. These
52in turn are signed with the same certificate. Firefox knows about this
53certificate but does not trust it by default. To trust it, set the
54hidden Gecko boolean preference
55
56::
57
58    xpinstall.signatures.dev-root=true
59
60Sadly, it's not possible to set preferences via a ``distribution.ini``
61early enough to impact loading the signed langpacks (see `Bug
621721764 <https://bugzilla.mozilla.org/show_bug.cgi?id=1721764>`__), and
63once the signed langpacks fail to load once, they will not be reloaded
64(see `Bug
651721763 <https://bugzilla.mozilla.org/show_bug.cgi?id=1721763>`__). This
66make testing the first-run experience challenging. What can be done is
67to install the MSIX package (perhaps using
68``Add-AppxPackage -Path ...``) and determine the profile directory
69(using ``about:support``). Uninstall the MSIX package (perhaps using
70``Get-AppxPackage | Where -Property Name -like "Mozilla.*" | Remove-AppxPackage``).
71Delete the contents of the profile directory entirely, but add a file
72``user.js`` containing:
73
74::
75
76    user_pref("xpinstall.signatures.dev-root", true);
77    user_pref("extensions.logging.enabled", true);
78
79Reinstall the MSIX package and the signed langpacks should now be loaded
80(slowly!) and available after first startup.
81
82Local developer builds
83----------------------
84
85``mach repackage msix`` lets you repackage a Firefox package (or
86directory) into an MSIX/App Package. The main complication is that an
87App Package contains channel-specific paths and assets, and therefore
88needs to be branding-aware, much as an Android package needs to be
89branding-aware.
90
91Usage
92~~~~~
93
94The tool is designed to repackage ZIP archives produced in automation.
95Start looking for official builds at locations like:
96
97==========    ==========================================================================================================================
98Channel       URL
99==========    ==========================================================================================================================
100Release       https://archive.mozilla.org/pub/firefox/candidates/88.0.1-candidates/build1/win64/en-US/firefox-88.0.1.zip
101Beta          https://archive.mozilla.org/pub/firefox/candidates/89.0b15-candidates/build1/win64/en-US/firefox-89.0b15.zip
102Devedition    https://archive.mozilla.org/pub/devedition/candidates/89.0b15-candidates/build1/win64/en-US/firefox-89.0b15.zip
103Nightly       https://archive.mozilla.org/pub/firefox/nightly/2021/05/2021-05-21-09-57-54-mozilla-central/firefox-90.0a1.en-US.win64.zip
104==========    ==========================================================================================================================
105
106Repackage using commands like:
107
108::
109
110    $ ./mach repackage msix \
111      --input firefox-88.0.1.zip \
112      --channel=official \
113      --arch=x86_64 \
114      --verbose
115
116Or package a local developer build directly with ``mach repackage msix``:
117
118::
119
120    $ ./mach repackage msix
121
122This command will do its best to guess your channel and other necessary
123information. You can override these with options like ``--channel``
124(see the ``--help`` text for all supported options).
125
126Paths to tools can be set via environment variables. In order, searched
127first to searched last:
128
1291. the tool name, like ``MAKEAPPX`` or ``SIGNTOOL``
1302. searching on ``PATH``
1313. searching under ``WINDOWSSDKDIR``
1324. searching under ``C:/Program Files (x86)/Windows Kits/10``
133
134If you are cross compiling from Linux or macOS you will need a
135compiled version of `Mozilla's fork of Microsoft's msix-packaging
136<https://github.com/mozilla/msix-packaging/tree/johnmcpms/signing>`__
137tools.
138
139Linux users can obtain a prebuilt version with:
140
141::
142
143    $ ./mach artifact toolchain --from-build linux64-msix-packaging
144
145After `bug 1743036 <https://bugzilla.mozilla.org/show_bug.cgi?id=1743036>`__
146is fixed, macOS and Windows users will have a similar option.
147
148Signing locally
149~~~~~~~~~~~~~~~
150
151The repackaged MSIX files produced are not signed by default. In
152automation, Mozilla's signing service signs the repackaged MSIX files.
153For local testing, you can sign them with a self-signed certificate by
154adding ``--sign`` to ``mach repackage msix``, or with commands like:
155
156::
157
158    $ ./mach repackage sign-msix --input test.msix --verbose
159
160Or sign them yourself following `Microsoft's self-signed certificate
161instructions <https://docs.microsoft.com/en-us/windows/msix/package/create-certificate-package-signing#create-a-self-signed-certificate>`__.
162
163Signing Certificates
164^^^^^^^^^^^^^^^^^^^^
165
166Mach will create the necessary signing keys and certificates for you
167and re-use them for subsequent signings. Before your locally signed
168builds can be installed you will need to install the correct
169certificate to the Windows Root Store. This can be done with a command
170like:
171
172::
173
174    $ powershell -c 'Import-Certificate -FilePath mycert.cer -Cert Cert:\LocalMachine\Root\'
175
176The exact command to run will be shown if you run ``./mach repackage``
177with ``--verbose``.
178
179You _may_ choose to sign in a different manner, with a key and certificate
180you create yourself, but Windows requires that the Subject of the certificate
181match the Publisher found in the MSIX's AppxManifest.xml. If you choose
182to go this route, ensure that you pass ``--publisher`` to
183``./mach repackage msix`` to set that correctly.
184
185For developers
186~~~~~~~~~~~~~~
187
188Updating the MSIX template
189^^^^^^^^^^^^^^^^^^^^^^^^^^
190
191MSIX is an "open format" in one sense: the MSIX container format is
192specified at https://github.com/Microsoft/msix-packaging. It is
193categorically *not* an open format in another sense: many of the
194contained files are proprietary binary formats (``.reg`` -- registry
195hive files) or undocumented (``.pri`` files -- resource index files).
196
197Generally the MSIX packaging code tries to avoid requiring such files
198that can't be built from sources. Where they are truly required, it
199tries to use a single such file independent of branding and other
200configuration, checked into the source tree.
201
202resources.pri
203'''''''''''''
204
205Generate a new ``resources.pri`` file on a Windows machine using
206``makepri.exe`` from the Windows SDK, like:
207
208::
209
210    $ makepri.exe new \
211        -IndexName firefox \
212        -ConfigXml browser/installer/windows/msix/priconfig.xml \
213        -ProjectRoot browser/branding/official/msix \
214        -OutputFile browser/installer/windows/msix/resources.pri \
215        -Overwrite
216
217The choice of channel (i.e.,
218``browser/branding/{official,aurora,beta,nightly,unofficial}``) should
219not matter.
220
221.. [#] The MSI has to be limited in this way because of the difficulty
222       of migrating existing installations into MSI and adding support
223       for it to Firefox's update pipeline. MSIX does not have these
224       constraints, because the partially virtualized file system that
225       these kinds of apps run in makes install migration impossible
226       and unnecessary.
227