Skip to content
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

Update Windows configuration to remove AppX ambiguity #3239

Merged
merged 5 commits into from
Aug 8, 2024

Conversation

mokagio
Copy link
Contributor

@mokagio mokagio commented Jul 25, 2024

What this does

In hindsight, it sounds pretty simple... This fix removes the appx node from the default configuration, electron-builder.json, so that CI generates only one set of appx files. The appx are then generated using a dedicated configuration. More on that later.

If you check the logs for the v2.22.1 build, you'll notice that two pairs of appx are being built. First as part of the npx electron-builder --win call which uses electron-builder.json...:

image

...then from the npx electron-builder --win --config=electron-builder-appx.json call:

image

You'll also notice that the first appx are code signed while the last are not. This sent me down a bit of a rabbit hole, more on that later, too.

So, it turns out that the code signing was not strictly broken, it just so happened that I downloaded the wrong appx artifacts from the release... 🤦‍♂️ That's an error only on my part, as our process checklist clearly states to download the ones with win-store in the name.

About code signing AppX

The short story is: We don't need to code sign AppX if we want to upload them to the Microsoft Partner Center. Upon uploading, Microsoft signs them for us. See also https://www.electron.build/configuration/appx#appx-package-code-signing.

Things got confusing when in the migration between CircleCI and Buildkite I made use of the certificate with publisher CN="Automattic, Inc.", O="Automattic, Inc.", S=California, C=US where before we were using CN=E2E5A157-746D-4B04-9116-ABE5CB928306.

So, even though I was able to code sign the appx with the new certificates (despite code siging being unnecessary, which I only learned afterwards) Microsoft rejected them because of the mismatch between the expected publisher.

About using two configurations

The reason for this setup is that, as far as I able to find, the configuration required to generate a code signed exe via the nsis target will conflict the appx configuration.

You can see the various experiments I went through to try and make both configurations play well together in #3235.

In practice, "certificateSubjectName": "Automattic, Inc." is required to sign the exe — which we need for it to run without looking dodgy, given it is distributed outside the store – but if that setting is present and so are the appx settings, there will be a failure, e.g. https://buildkite.com/automattic/simplenote-electron/builds/176#0190e45b-0298-4168-b47c-6e2aef7caec3, similar to what is reported in electron-userland/electron-builder#6698

As a personal note, I wish I'd been smarter and dig into why we had two configurations sooner. Also worth noting that WordPress Desktop also uses this approach, and I knew it, too, use electron-builder. The fact that two projects use the same odd configuration setup would have pointed more clearly to the config incompatibility.

"Proof" that it works

Here's a screenshot of the Partner Center where the appx packages from the latest build in this branch have passed validation:

image

And here is a screenshot of my Windows VM where the exe from the same build passes the Edge safety check etc.

image

image

Where to go from here

Things I'd like to look into:

  • Convert the config to YML so we can have comments and document why the setup exists close to where the setup is used. (In the meantime, I added a little note about code signing in the make task output)
  • Look into the crash on the electron-builder side, as well as the configuration hierarchy that results in the clash. Maybe there is a reason, but I don't see why we cannot set code sining settings at the nsis level so that only the exe will code sign, instead of having certificateSubjectName in the win root and resulting in it code signing the appx, too
  • If we really have to stick with the two config approach, then we should generated the ad hoc config at runtime with a script that
    1. Reads electron-builder.json
    2. Strips the unrelated settings
    3. Injects the appropriate appx settings

@mokagio
Copy link
Contributor Author

mokagio commented Jul 25, 2024

@codebykat @roundhill I wanted to add additional details on the implementation in the PR description but I run out of time today.

Here's a ping to have a look and maybe test the exe on your end. I'll put the finishing touches tomorrow.

@codebykat
Copy link
Member

Oh, nice. I haven't tested this, but I'm looking at that transparent icon setting and wondering about these reported issues: #3057 and #3157

Possibly we want the icon to be not transparent? 🤔

@roundhill roundhill marked this pull request as ready for review July 25, 2024 16:34
@roundhill roundhill marked this pull request as draft July 25, 2024 16:34
@roundhill
Copy link
Contributor

The .x64 exe worked great for me on Windows 10. I tried installing the .appx but it said there was a code sign error, which I assume is because that has to be done on the Partner Center Portal?

@mokagio
Copy link
Contributor Author

mokagio commented Jul 25, 2024

I tried installing the .appx but it said there was a code sign error, which I assume is because that has to be done on the Partner Center Portal?

Correct @roundhill . The AppX are explicitly not signed by CI and we the Partner Center do that for us.

@mokagio mokagio changed the title Update Windows configuration to successfully upload to Microsoft Partner Center Update Windows configuration to remove AppX ambiguity Jul 26, 2024
@mokagio mokagio marked this pull request as ready for review July 26, 2024 05:05
@mokagio mokagio requested review from codebykat, roundhill and a team July 26, 2024 05:05
@npx electron-builder --win -p $(PUBLISH)
ifeq ($(IS_WINDOWS),true)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to remove the platform check under the assumption these will mostly run in CI.

I'm not aware of any requirement for building Windows on a non Windows machine either.

This way, the script is simpler to understand.

Makefile Outdated
Comment on lines 147 to 146
@echo Packaging .appx as well...
@echo "Packaging appx with dedicated configuration to work around code signing conflicts..."
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A tiny attempt of help future readers understand the need for the dedicated config

Comment on lines -33 to -34
"afterSign": "./after_sign_hook.js",
"afterAllArtifactBuild": "./after_sign_hook.js"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notice that these were the same script. If you look into it, the only thing it does is notarizing for macOS. I decided to remove it to keep the config as small as possible.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To check my understanding of this file: it's fine to remove the calls to the after_sign_hook.js script because they only do macOS notarization and this file only deals with the Windows AppX build, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makefile Outdated Show resolved Hide resolved
},
{
"target": "appx",
"arch": ["ia32", "x64"]
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mokagio I was about to suggest adding some comments to mention that the .appx is instead generated with a custom config via make package-win32 so it's properly code-signed, + link to this PR's description for the breadcrumbs…

…but then I just realized this is a .json file, which doesn't accept comments 😢

That being said, it seems that electron-builder supports configuration files in YAML (or js) format. So WDYT of migrating the project to a electron-builder.yml file instead of .json in a future PR, so we can start adding such comments to it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, 100% agree. I thought I had written it somewhere as a TODO myself, but I couldn't find a reference to share here.

Every time I see a JSON used for config these days my first instinct is to ask if we can make it into a YAML. Being able to comment and use anchors and aliases makes the config work simpler.

Co-authored-by: Olivier Halligon <[email protected]>
@mokagio mokagio merged commit 98dfd5c into release/2.22.2 Aug 8, 2024
7 checks passed
@mokagio mokagio deleted the mokagio/fix-windows-code-signing branch August 8, 2024 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants