diff --git a/Gruntfile.js b/Gruntfile.js index 48d0db6e5b0..136ec6d3ce8 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -217,6 +217,11 @@ module.exports = function(grunt) { // empty on purpose }, }, + 'zip-mac-folder': { + [targetName]: { + dropPath: dropPath, + }, + }, }); }); @@ -437,10 +442,46 @@ module.exports = function(grunt) { ); }); + grunt.registerMultiTask('zip-mac-folder', function() { + grunt.task.requires('drop:' + this.target); + grunt.task.requires('configure-electron-builder:' + this.target); + grunt.task.requires('electron-builder-pack:' + this.target); + + // We found that the mac update fails unless we produce the + // zip file ourselves; electron-builder requires a zip file, but + // the zip file it produces leads to 'couldn't find pkzip signatures' + // during the eventual update. + + if (process.platform !== 'darwin') { + grunt.log.writeln(`task not required for this platform (${process.platform})`); + return true; + } + + const { dropPath } = this.data; + const packedPath = `${dropPath}/packed`; + + const taskDoneCallback = this.async(); + + grunt.util.spawn( + { + cmd: 'node', + args: ['pipeline/scripts/zip-mac-folder.js', packedPath], + }, + (error, result, code) => { + if (error) { + grunt.fail.fatal(`zipping mac folder exited with error code ${code}:\n\n${result.stdout}`, code); + } + + taskDoneCallback(); + }, + ); + }); + grunt.registerMultiTask('unified-release-drop', function() { grunt.task.run(`drop:${this.target}`); grunt.task.run(`configure-electron-builder:${this.target}`); grunt.task.run(`electron-builder-pack:${this.target}`); + grunt.task.run(`zip-mac-folder:${this.target}`); }); grunt.registerTask('package-report', function() { diff --git a/package.json b/package.json index a9061834d2e..5ee51da7d41 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "test:e2e:docker:run": "docker run -t accessibility-insights-web-e2e", "test:e2e:docker": "npm-run-all --serial test:e2e:docker:build \"test:e2e:docker:run {@}\" --", "test:unified": "cross-env --max-old-space-size=16384 jest --projects src/tests/electron --runInBand", - "update:electron-checksum": "node ./pipeline/scripts/update-electron-checksum.js", "watch": "npm-run-all --parallel --race --print-label watch:scss watch:grunt watch:test watch:webpack-dev-browser watch:webpack-unified", "watch:build:all": "npm-run-all --parallel --race --print-label watch:scss watch:grunt watch:webpack-dev-browser watch:webpack-unified", "watch:build:web": "npm-run-all --parallel --race --print-label watch:scss watch:grunt watch:webpack-dev-browser", @@ -127,6 +126,7 @@ "webpack-node-externals": "^1.7.2" }, "dependencies": { + "7zip-bin": "^5.0.3", "applicationinsights-js": "^1.0.21", "axe-core": "3.3.2", "axios": "^0.19.2", diff --git a/pipeline/scripts/update-electron-checksum.js b/pipeline/scripts/update-latest-yml.js similarity index 66% rename from pipeline/scripts/update-electron-checksum.js rename to pipeline/scripts/update-latest-yml.js index 861a86e2c35..0a3a9cee38d 100644 --- a/pipeline/scripts/update-electron-checksum.js +++ b/pipeline/scripts/update-latest-yml.js @@ -6,9 +6,10 @@ const YAML = require('js-yaml'); const path = require('path'); const parentDir = process.argv[2]; +const platform = process.argv[3]; // should be 'mac', 'linux', or 'windows' const getLatestYAMLPath = parentDir => { - const platformModifier = process.platform == 'darwin' ? '-mac' : process.platform == 'linux' ? '-linux' : ''; + const platformModifier = platform === 'windows' ? '' : `-${platform}`; const latestPath = path.join(parentDir, `latest${platformModifier}.yml`); return latestPath; }; @@ -42,11 +43,29 @@ const writeLatestYAML = (latestPath, latestContent) => { fs.writeFileSync(latestPath, rawLatestContent); }; -const updateElectronChecksum = async () => { +// On mac we add the zip file ourselves & thus need +// to update the latest-mac.yml files entry +const updateFileList = latestContent => { + if (platform === 'mac') { + const files = fs.readdirSync(parentDir); + const zipFile = files.find(f => path.extname(f) === '.zip'); + latestContent.files.push({ + url: path.basename(zipFile), + sha512: 'WILL BE OVERWRITTEN', + size: fs.statSync(path.resolve(parentDir, zipFile)).size, + }); + } +}; + +const updateLatestYaml = async () => { const latestPath = getLatestYAMLPath(parentDir); const latestContent = readLatestYAML(latestPath); + updateFileList(latestContent); await updateAllSha512s(latestContent); writeLatestYAML(latestPath, latestContent); }; -updateElectronChecksum(); +updateLatestYaml().catch(err => { + console.error(err); + process.exit(1); +}); diff --git a/pipeline/scripts/zip-mac-folder.js b/pipeline/scripts/zip-mac-folder.js new file mode 100644 index 00000000000..65842bb9ae9 --- /dev/null +++ b/pipeline/scripts/zip-mac-folder.js @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +/* + The macOS electron-builder update process requires a zip file + (electron-builder #4230), but the zip file produced by + electron-builder is corrupted (electron-builder #3534). + We use 7z to create the zip file ourselves. +*/ + +const child_process = require('child_process'); +const fs = require('fs'); +const path = require('path'); +const sevenBin = require('7zip-bin'); + +const parentDir = process.argv[2]; +const files = fs.readdirSync(parentDir); +const existingDmg = files.find(f => path.extname(f) === '.dmg'); +const appName = path.basename(existingDmg, path.extname(existingDmg)); + +console.log(`existingDmg: ${existingDmg}`); +console.log(`appName: ${appName}`); +console.log(`path to 7z: ${sevenBin.path7za}`); + +child_process.execSync(`${sevenBin.path7za} a "${appName}.zip" -r mac`, { + cwd: parentDir, + stdio: 'inherit', +}); diff --git a/pipeline/unified/channel/sign-release-package-linux.yaml b/pipeline/unified/channel/sign-release-package-linux.yaml index 72928708db5..1aa4a2d53cf 100644 --- a/pipeline/unified/channel/sign-release-package-linux.yaml +++ b/pipeline/unified/channel/sign-release-package-linux.yaml @@ -59,8 +59,8 @@ jobs: Accessibility_Insights_for_Android*.* TargetFolder: '$(System.DefaultWorkingDirectory)/signing-in-progress/${{ parameters.signedArtifactName }}' - - script: yarn update:electron-checksum signing-in-progress/${{ parameters.signedArtifactName }} - displayName: update electron checksum after signing + - script: node ./pipeline/scripts/update-latest-yml.js signing-in-progress/${{ parameters.signedArtifactName }} linux + displayName: update electron-builder latest yaml after signing - template: ../publish-packed-build-output.yaml parameters: diff --git a/pipeline/unified/channel/sign-release-package-mac.yaml b/pipeline/unified/channel/sign-release-package-mac.yaml index 80d8e6f6fd6..3659823e918 100644 --- a/pipeline/unified/channel/sign-release-package-mac.yaml +++ b/pipeline/unified/channel/sign-release-package-mac.yaml @@ -13,6 +13,7 @@ jobs: signedArtifactName: ${{ parameters.signedArtifactName }} vmImage: macOS-10.14 filePattern: '*.dmg, *.zip' + platform: mac inlineSignParams: | [ { diff --git a/pipeline/unified/channel/sign-release-package-windows.yaml b/pipeline/unified/channel/sign-release-package-windows.yaml index 78301ed5d63..0a39889e9c5 100644 --- a/pipeline/unified/channel/sign-release-package-windows.yaml +++ b/pipeline/unified/channel/sign-release-package-windows.yaml @@ -13,6 +13,7 @@ jobs: signedArtifactName: ${{ parameters.signedArtifactName }} vmImage: windows-latest filePattern: '*.exe, *.dll' + platform: windows inlineSignParams: | [ { diff --git a/pipeline/unified/channel/sign-release-package.yaml b/pipeline/unified/channel/sign-release-package.yaml index 2bad5e4856f..073453f813c 100644 --- a/pipeline/unified/channel/sign-release-package.yaml +++ b/pipeline/unified/channel/sign-release-package.yaml @@ -7,6 +7,7 @@ parameters: unsignedPipelineResource: null unsignedArtifactName: null signedArtifactName: null + platform: null jobs: - job: ${{ parameters.signedArtifactName }} @@ -34,8 +35,8 @@ jobs: signConfigType: inlineSignParams inlineOperation: ${{ parameters.inlineSignParams }} - - script: yarn update:electron-checksum signing-in-progress/${{ parameters.signedArtifactName }} - displayName: update electron checksum after signing + - script: node ./pipeline/scripts/update-latest-yml.js signing-in-progress/${{ parameters.signedArtifactName }} ${{ parameters.platform }} + displayName: update electron-builder latest.yml after signing - template: ../publish-packed-build-output.yaml parameters: diff --git a/src/electron/electron-builder/electron-builder.template.yaml b/src/electron/electron-builder/electron-builder.template.yaml index fa240471a01..b13a7d4b3df 100644 --- a/src/electron/electron-builder/electron-builder.template.yaml +++ b/src/electron/electron-builder/electron-builder.template.yaml @@ -26,7 +26,7 @@ linux: mac: artifactName: ${productName}.${ext} icon: TARGET_SPECIFIC - target: [dmg, zip] # zip is required because of electron-userland/electron-builder#2199 + target: dmg # we also need zip (electron-userland/electron-builder#2199) & add it in grunt identity: null win: diff --git a/yarn.lock b/yarn.lock index 97e1aab75b6..ab6f1aced28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"7zip-bin@~5.0.3": +"7zip-bin@^5.0.3", "7zip-bin@~5.0.3": version "5.0.3" resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-5.0.3.tgz#bc5b5532ecafd923a61f2fb097e3b108c0106a3f" integrity sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA==