Compare commits

...

3 Commits

Author SHA1 Message Date
Keeley Hammond
a541d511d6 test: move squirrel feed tests to api-autoupdater 2026-02-16 17:59:19 -08:00
Keeley Hammond
b7eb2cc2ac test: remove redundent feedURL test 2026-02-16 17:24:30 -08:00
Keeley Hammond
7dd84bedfa fix: code-sign binaries for notification tests 2026-02-16 17:24:30 -08:00
8 changed files with 80 additions and 60 deletions

View File

@@ -191,12 +191,18 @@ jobs:
run: |
cd src/out/Default
unzip -:o dist.zip
#- name: Import & Trust Self-Signed Codesigning Cert on MacOS
# if: ${{ inputs.target-platform == 'macos' && inputs.target-arch == 'x64' }}
# run: |
# sudo security authorizationdb write com.apple.trust-settings.admin allow
# cd src/electron
# ./script/codesign/generate-identity.sh
- name: Import & Trust Self-Signed Codesigning Cert on MacOS
if: ${{ inputs.target-platform == 'macos' }}
run: |
cd src/electron
./script/codesign/generate-identity.sh
- name: Sign Electron.app for macOS tests
if: ${{ inputs.target-platform == 'macos' }}
run: |
identity=$(src/electron/script/codesign/get-trusted-identity.sh)
if [ -n "$identity" ]; then
codesign -s "$identity" --deep --force src/out/Default/Electron.app
fi
- name: Run Electron Tests
shell: bash

View File

@@ -0,0 +1,21 @@
#!/bin/sh
# Removes the codesigning keychain created by generate-identity.sh.
# Safe to run even if generate-identity.sh was never run (each step
# is guarded).
set -eo pipefail
KEYCHAIN="electron-codesign.keychain-db"
# delete-keychain also removes it from the search list
if security list-keychains -d user | grep -q "$KEYCHAIN"; then
security delete-keychain "$KEYCHAIN"
echo "Deleted keychain: $KEYCHAIN"
else
echo "Keychain not found, nothing to delete"
fi
# Clean up working directory
rm -rf "$(dirname $0)"/.working
echo "Cleanup complete"

View File

@@ -3,6 +3,8 @@
set -eo pipefail
dir="$(dirname $0)"/.working
KEYCHAIN="electron-codesign.keychain-db"
KEYCHAIN_TEMP="$(openssl rand -hex 12)"
cleanup() {
rm -rf "$dir"
@@ -18,30 +20,16 @@ mkdir -p "$dir"
# Generate Certs
openssl req -new -newkey rsa:2048 -x509 -days 7300 -nodes -config "$(dirname $0)"/codesign.cnf -extensions extended -batch -out "$dir"/certificate.cer -keyout "$dir"/certificate.key
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "$dir"/certificate.cer
sudo security import "$dir"/certificate.key -A -k /Library/Keychains/System.keychain
# restart(reload) taskgated daemon
sudo pkill -f /usr/libexec/taskgated
# macOS 15+ blocks modifications to the system keychain via SIP/TCC,
# so we use a custom user-scoped keychain instead.
# Refs https://github.com/electron/electron/issues/48182
security create-keychain -p "$KEYCHAIN_TEMP" "$KEYCHAIN"
security set-keychain-settings -t 3600 -u "$KEYCHAIN"
security unlock-keychain -p "$KEYCHAIN_TEMP" "$KEYCHAIN"
# need once
sudo security authorizationdb write system.privilege.taskport allow
# need once
DevToolsSecurity -enable
security list-keychains -d user -s "$KEYCHAIN" $(security list-keychains -d user | tr -d '"')
security import "$dir"/certificate.cer -k "$KEYCHAIN" -T /usr/bin/codesign
security import "$dir"/certificate.key -k "$KEYCHAIN" -T /usr/bin/codesign -A
# openssl req -newkey rsa:2048 -nodes -keyout "$dir"/private.pem -x509 -days 1 -out "$dir"/certificate.pem -extensions extended -config "$(dirname $0)"/codesign.cnf
# openssl x509 -inform PEM -in "$dir"/certificate.pem -outform DER -out "$dir"/certificate.cer
# openssl x509 -pubkey -noout -in "$dir"/certificate.pem > "$dir"/public.key
# rm -f "$dir"/certificate.pem
# Import Certs
# security import "$dir"/certificate.cer -k $KEY_CHAIN
# security import "$dir"/private.pem -k $KEY_CHAIN
# security import "$dir"/public.key -k $KEY_CHAIN
# Generate Trust Settings
# TODO: Remove NPX
npm_config_yes=true npx ts-node "$(dirname $0)"/gen-trust.ts "$dir"/certificate.cer "$dir"/trust.xml
# Import Trust Settings
sudo security trust-settings-import -d "$dir/trust.xml"
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_TEMP" "$KEYCHAIN"

View File

@@ -2,7 +2,7 @@
set -e
valid_certs=$(security find-identity -p codesigning -v)
valid_certs=$(security find-identity -p codesigning)
if [[ $valid_certs == *"1)"* ]]; then
first_valid_cert=$(echo $valid_certs | sed 's/ \".*//' | sed 's/.* //')
echo $first_valid_cert

View File

@@ -56,29 +56,6 @@ ifdescribe(!process.mas)('autoUpdater module', function () {
).to.throw('Expected options object to contain a \'url\' string property in setFeedUrl call');
});
});
ifdescribe(process.platform === 'darwin' && process.arch !== 'arm64')('on Mac', function () {
it('emits an error when the application is unsigned', async () => {
const errorEvent = once(autoUpdater, 'error') as Promise<[Error]>;
autoUpdater.setFeedURL({ url: '' });
const [error] = await errorEvent;
expect(error.message).equal('Could not get code signature for running application');
});
it('does not throw if default is the serverType', () => {
// "Could not get code signature..." means the function got far enough to validate that serverType was OK.
expect(() => autoUpdater.setFeedURL({ url: '', serverType: 'default' })).to.throw('Could not get code signature for running application');
});
it('does not throw if json is the serverType', () => {
// "Could not get code signature..." means the function got far enough to validate that serverType was OK.
expect(() => autoUpdater.setFeedURL({ url: '', serverType: 'json' })).to.throw('Could not get code signature for running application');
});
it('does throw if an unknown string is the serverType', () => {
expect(() => autoUpdater.setFeedURL({ url: '', serverType: 'weow' as any })).to.throw('Expected serverType to be \'default\' or \'json\'');
});
});
});
describe('quitAndInstall', () => {

View File

@@ -153,6 +153,33 @@ ifdescribe(shouldRunCodesignTests)('autoUpdater behavior', function () {
});
});
ifit(process.arch !== 'arm64')('should fail with code signature error when serverType is default and app is unsigned', async () => {
await withTempDirectory(async (dir) => {
const appPath = await copyMacOSFixtureApp(dir);
const launchResult = await launchApp(appPath, ['', 'default']);
expect(launchResult.code).to.equal(1);
expect(launchResult.out).to.include('Could not get code signature for running application');
});
});
ifit(process.arch !== 'arm64')('should fail with code signature error when serverType is json and app is unsigned', async () => {
await withTempDirectory(async (dir) => {
const appPath = await copyMacOSFixtureApp(dir);
const launchResult = await launchApp(appPath, ['', 'json']);
expect(launchResult.code).to.equal(1);
expect(launchResult.out).to.include('Could not get code signature for running application');
});
});
ifit(process.arch !== 'arm64')('should fail with serverType error when an invalid serverType is provided', async () => {
await withTempDirectory(async (dir) => {
const appPath = await copyMacOSFixtureApp(dir);
const launchResult = await launchApp(appPath, ['', 'weow']);
expect(launchResult.code).to.equal(1);
expect(launchResult.out).to.include("Expected serverType to be 'default' or 'json'");
});
});
it('should cleanly set the feed URL when the app is signed', async () => {
await withTempDirectory(async (dir) => {
const appPath = await copyMacOSFixtureApp(dir);

View File

@@ -6,12 +6,16 @@ process.on('uncaughtException', (err) => {
const { autoUpdater } = require('electron');
const feedUrl = process.argv[1];
const serverType = process.argv[2];
console.log('Setting Feed URL');
autoUpdater.setFeedURL({
url: feedUrl
});
const opts = { url: feedUrl };
if (serverType) {
opts.serverType = serverType;
}
autoUpdater.setFeedURL(opts);
console.log('Feed URL Set:', feedUrl);

View File

@@ -7,11 +7,8 @@ import * as path from 'node:path';
const features = process._linkedBinding('electron_common_features');
const fixturesPath = path.resolve(__dirname, '..', 'fixtures');
// Re-enable codesign tests for macOS x64
// Refs https://github.com/electron/electron/issues/48182
export const shouldRunCodesignTests =
process.platform === 'darwin' &&
!(process.env.CI) &&
!process.mas &&
!features.isComponentBuild();