From af2676ce8f036f8989181c1f049464d1253887a9 Mon Sep 17 00:00:00 2001 From: Johannes Faltermeier Date: Tue, 21 Jan 2025 08:53:08 +0100 Subject: [PATCH 1/4] Test MacOSX signing staging service #431 * update to staging URLs --- Jenkinsfile | 2 +- applications/electron/scripts/sign.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8b29c2db5..ec5e33e2b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -489,7 +489,7 @@ def signInstaller(String ext, String os) { // https://wiki.eclipse.org/IT_Infrastructure_Doc#Web_service if (os == 'mac') { - url = 'https://cbi.eclipse.org/macos/codesign/sign' + url = 'https://cbi-staging.eclipse.org/macos/codesign/sign' } else if (os == 'windows') { url = 'https://cbi.eclipse.org/authenticode/sign' } else { diff --git a/applications/electron/scripts/sign.sh b/applications/electron/scripts/sign.sh index c69083318..12c0cb405 100755 --- a/applications/electron/scripts/sign.sh +++ b/applications/electron/scripts/sign.sh @@ -24,7 +24,7 @@ REMOTE_NAME=${INPUT##*/} # sign over ssh # https://wiki.eclipse.org/IT_Infrastructure_Doc#Web_service -ssh -q genie.theia@projects-storage.eclipse.org curl -f -o "\"signed-${REMOTE_NAME}\"" -F file=@"\"${REMOTE_NAME}\"" -F entitlements=@entitlements.plist https://cbi.eclipse.org/macos/codesign/sign +ssh -q genie.theia@projects-storage.eclipse.org curl -f -o "\"signed-${REMOTE_NAME}\"" -F file=@"\"${REMOTE_NAME}\"" -F entitlements=@entitlements.plist https://cbi-staging.eclipse.org/macos/codesign/sign # copy signed file back from server scp -T -p genie.theia@projects-storage.eclipse.org:"\"./signed-${REMOTE_NAME}\"" "${INPUT}" From a4e0e406d19d08a854b4ec7cf7e50d4f73622d8c Mon Sep 17 00:00:00 2001 From: Johannes Faltermeier Date: Tue, 21 Jan 2025 08:55:06 +0100 Subject: [PATCH 2/4] REVERT: Enable release dry for verification builds --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ec5e33e2b..2ab956577 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -32,8 +32,8 @@ pipeline { // installers. It can sometimes be necessary to run these steps, e.g. // when troubleshooting. Set the variable below to 'true' to do so. // We will still stop short of publishing anything. - THEIA_IDE_JENKINS_RELEASE_DRYRUN = 'false' - // THEIA_IDE_JENKINS_RELEASE_DRYRUN = 'true' + // THEIA_IDE_JENKINS_RELEASE_DRYRUN = 'false' + THEIA_IDE_JENKINS_RELEASE_DRYRUN = 'true' msvs_version = '2019' GYP_MSVS_VERSION = '2019' From 0aca7c2b0802488107323cbd4c3c8e0e9258b34d Mon Sep 17 00:00:00 2001 From: Johannes Faltermeier Date: Tue, 21 Jan 2025 11:55:59 +0100 Subject: [PATCH 3/4] Only send single Zip to Mac Signin Service #431 --- applications/electron/package.json | 2 + applications/electron/scripts/after-pack.js | 83 ++++++++++++++------- 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/applications/electron/package.json b/applications/electron/package.json index c5bf4dcaf..56ed79c40 100644 --- a/applications/electron/package.json +++ b/applications/electron/package.json @@ -126,6 +126,7 @@ "@wdio/mocha-framework": "^6.8.0", "@wdio/spec-reporter": "^6.8.1", "app-builder-lib": "24.13.2", + "archiver": "^5.0.0", "chai": "^4.3.10", "concurrently": "^3.5.0", "electron": "30.1.2", @@ -133,6 +134,7 @@ "electron-chromedriver": "^28.2.8", "electron-mocha": "^12.3.0", "electron-osx-sign": "^0.6.0", + "extract-zip": "^2.0.0", "js-yaml": "^3.12.0", "mocha": "^8.2.1", "rimraf": "^2.7.1", diff --git a/applications/electron/scripts/after-pack.js b/applications/electron/scripts/after-pack.js index 1b09706a9..8668f8630 100755 --- a/applications/electron/scripts/after-pack.js +++ b/applications/electron/scripts/after-pack.js @@ -5,7 +5,8 @@ const path = require('path'); const util = require('util'); const child_process = require('child_process'); const rimraf = require('rimraf'); -const sign_util = require('electron-osx-sign/util'); +const archiver = require('archiver'); +const extract = require('extract-zip'); const asyncRimraf = util.promisify(rimraf); const DELETE_PATHS = [ @@ -39,6 +40,25 @@ const signFile = file => { } }; +async function zipDirectory(source, out) { + const archive = archiver('zip', { zlib: { level: 9 } }); + const stream = fs.createWriteStream(out); + + return new Promise((resolve, reject) => { + archive + .directory(source, false) + .on('error', err => reject(err)) + .pipe(stream); + + stream.on('close', () => resolve()); + archive.finalize(); + }); +} + +async function unzipFile(zipPath, destination) { + return extract(zipPath, { dir: destination }); +} + exports.default = async function (context) { await afterPackHook(context); const running_ci = process.env.THEIA_IDE_JENKINS_CI === 'true'; @@ -65,31 +85,44 @@ exports.default = async function (context) { return; } - // Use app-builder-lib to find all binaries to sign, at this level it will include the final .app - let childPaths = await sign_util.walkAsync(context.appOutDir); - - // Sign deepest first - // From https://github.com/electron-userland/electron-builder/blob/master/packages/app-builder-lib/electron-osx-sign/sign.js#L120 - childPaths = childPaths.sort((a, b) => { - const aDepth = a.split(path.sep).length; - const bDepth = b.split(path.sep).length; - return bDepth - aDepth; - }); - - // Sign binaries - childPaths.forEach(file => signFile(file, context.appOutDir)); + // Create a zip of the contents at context.appOutDir + const zipPath = path.resolve(context.appOutDir, '..', 'app-to-be-signed.zip'); + // const signedZipPath = path.resolve(context.appOutDir, '..', 'signed-app-to-be-signed.zip'); + console.log(`Creating zip of ${context.appOutDir} at ${zipPath}...`); + await zipDirectory(context.appOutDir, zipPath); - // Notarize app - child_process.spawnSync(notarizeCommand, [ - path.basename(appPath), - context.packager.appInfo.info._configuration.appId - ], { - cwd: path.dirname(appPath), - maxBuffer: 1024 * 10000, - env: process.env, - stdio: 'inherit', - encoding: 'utf-8' - }); + try { + // Send the zip file to the signing service + console.log('Sending zip file to signing service via sign.sh...'); + signFile(zipPath); + + console.log(`Expecting signed zip at ${zipPath}...`); + + // Replace the contents of context.appOutDir with the signed result + console.log(`Unzipping signed contents from ${zipPath} to ${context.appOutDir}...`); + await asyncRimraf(context.appOutDir); // Clean the output directory + await unzipFile(zipPath, context.appOutDir); + + // Notarize app + console.log('Proceeding with notarization...'); + child_process.spawnSync(notarizeCommand, [ + path.basename(appPath), + context.packager.appInfo.info._configuration.appId + ], { + cwd: path.dirname(appPath), + maxBuffer: 1024 * 10000, + env: process.env, + stdio: 'inherit', + encoding: 'utf-8' + }); + + console.log('Signing and notarization complete.'); + } finally { + // Clean up intermediate zip files + console.log('Cleaning up intermediate files...'); + await asyncRimraf(zipPath); + console.log('...cleanup done'); + } }; // taken and modified from: https://github.com/gergof/electron-builder-sandbox-fix/blob/a2251d7d8f22be807d2142da0cf768c78d4cfb0a/lib/index.js From e5dc6f14c6e16b4e29fca1f60a7e5ca2ba08cd76 Mon Sep 17 00:00:00 2001 From: Johannes Faltermeier Date: Tue, 21 Jan 2025 16:55:51 +0100 Subject: [PATCH 4/4] REVERT: Temporarily archive DMG and MAC Zip --- Jenkinsfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Jenkinsfile b/Jenkinsfile index 2ab956577..256fe9bb3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -293,6 +293,7 @@ spec: // Cleanup sh "rm -rf \"${extractedFolder}\" \"${mountPoint}\"" } + archiveArtifacts artifacts: "${distFolder}/*.dmg, ${distFolder}/*.zip", allowEmptyArchive: false stash includes: "${toStash}", name: 'mac3' } }