diff --git a/build/azure-pipelines/win32/codesign.js b/build/azure-pipelines/win32/codesign.js new file mode 100644 index 00000000000..81b261beff8 --- /dev/null +++ b/build/azure-pipelines/win32/codesign.js @@ -0,0 +1,73 @@ +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +const zx_1 = require("zx"); +const arch = process.env['VSCODE_ARCH']; +const esrpCliDLLPath = process.env['EsrpCliDllPath']; +const codeSigningFolderPath = process.env['CodeSigningFolderPath']; +function printBanner(title) { + console.log('#'.repeat(65)); + console.log(`# ${title.padEnd(61)} #`); + console.log('#'.repeat(65)); +} +function sign(type, glob) { + return (0, zx_1.$) `node build/azure-pipelines/common/sign ${esrpCliDLLPath} ${type} ${codeSigningFolderPath} '${glob}'`; +} +async function main() { + (0, zx_1.usePwsh)(); + const codesignTasks = [ + { + banner: 'Codesign executables and shared libraries', + processPromise: sign('sign-windows', '*.dll,*.exe,*.node') + }, + { + banner: 'Codesign Powershell scripts', + processPromise: sign('sign-windows-appx', '*.ps1') + } + ]; + if (process.env['VSCODE_QUALITY'] === 'insider') { + codesignTasks.push({ + banner: 'Codesign context menu appx package', + processPromise: sign('sign-windows-appx', '*.appx') + }); + } + // Wait for processes to finish and stream their output + for (const { banner, processPromise } of codesignTasks) { + printBanner(banner); + await processPromise.pipe(process.stdout); + } + await (0, zx_1.$) `New-Item -ItemType Directory -Path .build/win32-${arch} -Force`; + // Package client + if (process.env['BUILT_CLIENT']) { + // Product version + const version = await (0, zx_1.$) `node -p "require('../VSCode-win32-${arch}/resources/app/package.json').version"`; + printBanner('Package client'); + const clientArchivePath = `.build/win32-${arch}/VSCode-win32-${arch}-${version}.zip`; + await (0, zx_1.$) `7z.exe a -tzip ${clientArchivePath} ../VSCode-win32-${arch}/* "-xr!CodeSignSummary*.md"`.pipe(process.stdout); + await (0, zx_1.$) `7z.exe l ${clientArchivePath}`.pipe(process.stdout); + } + // Package server + if (process.env['BUILT_SERVER']) { + printBanner('Package server'); + const serverArchivePath = `.build/win32-${arch}/vscode-server-win32-${arch}.zip`; + await (0, zx_1.$) `7z.exe a -tzip ${serverArchivePath} ../vscode-server-win32-${arch}`.pipe(process.stdout); + await (0, zx_1.$) `7z.exe l ${serverArchivePath}`.pipe(process.stdout); + } + // Package server (web) + if (process.env['BUILT_WEB']) { + printBanner('Package server (web)'); + const webArchivePath = `.build/win32-${arch}/vscode-server-win32-${arch}-web.zip`; + await (0, zx_1.$) `7z.exe a -tzip ${webArchivePath} ../vscode-server-win32-${arch}-web`.pipe(process.stdout); + await (0, zx_1.$) `7z.exe l ${webArchivePath}`.pipe(process.stdout); + } + // Sign setup + if (process.env['BUILT_CLIENT']) { + printBanner('Sign setup packages (system, user)'); + await (0, zx_1.$) `npm exec -- npm-run-all -lp "gulp vscode-win32-${arch}-system-setup -- --sign" "gulp vscode-win32-${arch}-user-setup -- --sign"`.pipe(process.stdout); + } +} +main(); +//# sourceMappingURL=codesign.js.map \ No newline at end of file diff --git a/build/azure-pipelines/win32/codesign.ts b/build/azure-pipelines/win32/codesign.ts new file mode 100644 index 00000000000..b735355643f --- /dev/null +++ b/build/azure-pipelines/win32/codesign.ts @@ -0,0 +1,90 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { $, ProcessPromise, usePwsh } from 'zx'; + +const arch = process.env['VSCODE_ARCH']; +const esrpCliDLLPath = process.env['EsrpCliDllPath']; +const codeSigningFolderPath = process.env['CodeSigningFolderPath']; + +type CodeSignTask = { + readonly banner: string; + readonly processPromise: ProcessPromise; +}; + +function printBanner(title: string) { + console.log('#'.repeat(65)); + console.log(`# ${title.padEnd(61)} #`); + console.log('#'.repeat(65)); +} + +function sign(type: 'sign-windows' | 'sign-windows-appx', glob: string): ProcessPromise { + return $`node build/azure-pipelines/common/sign ${esrpCliDLLPath} ${type} ${codeSigningFolderPath} '${glob}'`; +} + +async function main() { + usePwsh(); + + const codesignTasks: CodeSignTask[] = [ + { + banner: 'Codesign executables and shared libraries', + processPromise: sign('sign-windows', '*.dll,*.exe,*.node') + }, + { + banner: 'Codesign Powershell scripts', + processPromise: sign('sign-windows-appx', '*.ps1') + } + ]; + + if (process.env['VSCODE_QUALITY'] === 'insider') { + codesignTasks.push({ + banner: 'Codesign context menu appx package', + processPromise: sign('sign-windows-appx', '*.appx') + }); + } + + // Wait for processes to finish and stream their output + for (const { banner, processPromise } of codesignTasks) { + printBanner(banner); + await processPromise.pipe(process.stdout); + } + + await $`New-Item -ItemType Directory -Path .build/win32-${arch} -Force`; + + // Package client + if (process.env['BUILT_CLIENT']) { + // Product version + const version = await $`node -p "require('../VSCode-win32-${arch}/resources/app/package.json').version"`; + + printBanner('Package client'); + const clientArchivePath = `.build/win32-${arch}/VSCode-win32-${arch}-${version}.zip`; + await $`7z.exe a -tzip ${clientArchivePath} ../VSCode-win32-${arch}/* "-xr!CodeSignSummary*.md"`.pipe(process.stdout); + await $`7z.exe l ${clientArchivePath}`.pipe(process.stdout); + } + + // Package server + if (process.env['BUILT_SERVER']) { + printBanner('Package server'); + const serverArchivePath = `.build/win32-${arch}/vscode-server-win32-${arch}.zip`; + await $`7z.exe a -tzip ${serverArchivePath} ../vscode-server-win32-${arch}`.pipe(process.stdout); + await $`7z.exe l ${serverArchivePath}`.pipe(process.stdout); + } + + // Package server (web) + if (process.env['BUILT_WEB']) { + printBanner('Package server (web)'); + const webArchivePath = `.build/win32-${arch}/vscode-server-win32-${arch}-web.zip`; + await $`7z.exe a -tzip ${webArchivePath} ../vscode-server-win32-${arch}-web`.pipe(process.stdout); + await $`7z.exe l ${webArchivePath}`.pipe(process.stdout); + } + + // Sign setup + if (process.env['BUILT_CLIENT']) { + printBanner('Sign setup packages (system, user)'); + await $`npm exec -- npm-run-all -lp "gulp vscode-win32-${arch}-system-setup -- --sign" "gulp vscode-win32-${arch}-user-setup -- --sign"`.pipe(process.stdout); + } +} + +main(); diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 5fb2522ce79..e561d8e09b1 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -177,18 +177,6 @@ steps: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Build server (web) - - ${{ if or(eq(parameters.VSCODE_RUN_ELECTRON_TESTS, true), eq(parameters.VSCODE_RUN_BROWSER_TESTS, true), eq(parameters.VSCODE_RUN_REMOTE_TESTS, true)) }}: - - template: product-build-win32-test.yml@self - parameters: - VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} - VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} - VSCODE_RUN_ELECTRON_TESTS: ${{ parameters.VSCODE_RUN_ELECTRON_TESTS }} - VSCODE_RUN_BROWSER_TESTS: ${{ parameters.VSCODE_RUN_BROWSER_TESTS }} - VSCODE_RUN_REMOTE_TESTS: ${{ parameters.VSCODE_RUN_REMOTE_TESTS }} - VSCODE_TEST_ARTIFACT_NAME: ${{ parameters.VSCODE_TEST_ARTIFACT_NAME }} - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - PUBLISH_TASK_NAME: 1ES.PublishPipelineArtifact@1 - - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - task: DownloadPipelineArtifact@2 @@ -233,87 +221,59 @@ steps: echo "##vso[task.setvariable variable=EsrpCliDllPath]$Version\net6.0\esrpcli.dll" displayName: Find ESRP CLI - - powershell: node build\azure-pipelines\common\sign $env:EsrpCliDllPath sign-windows $(CodeSigningFolderPath) '*.dll,*.exe,*.node' + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { npx deemon --detach --wait -- npx zx build/azure-pipelines/win32/codesign.js } env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) - displayName: Codesign executables and shared libraries + displayName: ✍️ Codesign - - powershell: node build\azure-pipelines\common\sign $env:EsrpCliDllPath sign-windows-appx $(CodeSigningFolderPath) '*.ps1' - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - displayName: Codesign Powershell scripts - - - ${{ if eq(parameters.VSCODE_QUALITY, 'insider') }}: - - powershell: node build\azure-pipelines\common\sign $env:EsrpCliDllPath sign-windows-appx $(CodeSigningFolderPath) '*.appx' - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - displayName: Codesign context menu appx package + - ${{ if or(eq(parameters.VSCODE_RUN_ELECTRON_TESTS, true), eq(parameters.VSCODE_RUN_BROWSER_TESTS, true), eq(parameters.VSCODE_RUN_REMOTE_TESTS, true)) }}: + - template: product-build-win32-test.yml@self + parameters: + VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} + VSCODE_ARCH: ${{ parameters.VSCODE_ARCH }} + VSCODE_RUN_ELECTRON_TESTS: ${{ parameters.VSCODE_RUN_ELECTRON_TESTS }} + VSCODE_RUN_BROWSER_TESTS: ${{ parameters.VSCODE_RUN_BROWSER_TESTS }} + VSCODE_RUN_REMOTE_TESTS: ${{ parameters.VSCODE_RUN_REMOTE_TESTS }} + VSCODE_TEST_ARTIFACT_NAME: ${{ parameters.VSCODE_TEST_ARTIFACT_NAME }} + ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: + PUBLISH_TASK_NAME: 1ES.PublishPipelineArtifact@1 + - ${{ if ne(parameters.VSCODE_CIBUILD, true) }}: - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" + exec { npx deemon --attach -- npx zx build/azure-pipelines/win32/codesign.js } + condition: succeededOrFailed() + displayName: "✍️ Post-job: Codesign" + + - powershell: | + $ErrorActionPreference = "Stop" + $PackageJson = Get-Content -Raw -Path ..\VSCode-win32-$(VSCODE_ARCH)\resources\app\package.json | ConvertFrom-Json $Version = $PackageJson.version - echo "##vso[task.setvariable variable=VSCODE_VERSION]$Version" - condition: succeededOrFailed() - displayName: Get product version - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $ArchivePath = ".build\win32-$(VSCODE_ARCH)\VSCode-win32-$(VSCODE_ARCH)-$(VSCODE_VERSION).zip" - New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force - exec { 7z.exe a -tzip $ArchivePath ..\VSCode-win32-$(VSCODE_ARCH)\* "-xr!CodeSignSummary*.md" } - echo "##vso[task.setvariable variable=CLIENT_PATH]$ArchivePath" + $ClientArchivePath = ".build\win32-$(VSCODE_ARCH)\VSCode-win32-$(VSCODE_ARCH)-$Version.zip" + $ServerArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH).zip" + $WebArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH)-web.zip" - echo "Listing archive contents" - 7z.exe l $ArchivePath - condition: and(succeededOrFailed(), eq(variables['BUILT_CLIENT'], 'true')) - displayName: Package client - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH).zip" - New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force - exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH) } - echo "##vso[task.setvariable variable=SERVER_PATH]$ArchivePath" - - echo "Listing archive contents" - 7z.exe l $ArchivePath - condition: and(succeededOrFailed(), eq(variables['BUILT_SERVER'], 'true')) - displayName: Package server - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $ArchivePath = ".build\win32-$(VSCODE_ARCH)\vscode-server-win32-$(VSCODE_ARCH)-web.zip" - New-Item -ItemType Directory -Path .build\win32-$(VSCODE_ARCH) -Force - exec { 7z.exe a -tzip $ArchivePath ..\vscode-server-win32-$(VSCODE_ARCH)-web } - echo "##vso[task.setvariable variable=WEB_PATH]$ArchivePath" - - echo "Listing archive contents" - 7z.exe l $ArchivePath - condition: and(succeededOrFailed(), eq(variables['BUILT_WEB'], 'true')) - displayName: Package server (web) - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { npm exec -- npm-run-all -lp "gulp vscode-win32-$(VSCODE_ARCH)-system-setup -- --sign" "gulp vscode-win32-$(VSCODE_ARCH)-user-setup -- --sign" } - - $SystemSetupPath = ".build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup-$(VSCODE_ARCH)-$(VSCODE_VERSION).exe" - $UserSetupPath = ".build\win32-$(VSCODE_ARCH)\user-setup\VSCodeUserSetup-$(VSCODE_ARCH)-$(VSCODE_VERSION).exe" + $SystemSetupPath = ".build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup-$(VSCODE_ARCH)-$Version.exe" + $UserSetupPath = ".build\win32-$(VSCODE_ARCH)\user-setup\VSCodeUserSetup-$(VSCODE_ARCH)-$Version.exe" mv .build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup.exe $SystemSetupPath mv .build\win32-$(VSCODE_ARCH)\user-setup\VSCodeSetup.exe $UserSetupPath + echo "##vso[task.setvariable variable=CLIENT_PATH]$ClientArchivePath" + echo "##vso[task.setvariable variable=SERVER_PATH]$ServerArchivePath" + echo "##vso[task.setvariable variable=WEB_PATH]$WebArchivePath" + echo "##vso[task.setvariable variable=SYSTEM_SETUP_PATH]$SystemSetupPath" echo "##vso[task.setvariable variable=USER_SETUP_PATH]$UserSetupPath" - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - displayName: Build setup packages (system, user) + condition: succeededOrFailed() + displayName: Move setup packages - powershell: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_" condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')) diff --git a/build/package-lock.json b/build/package-lock.json index 199fc9de140..4d18fff30af 100644 --- a/build/package-lock.json +++ b/build/package-lock.json @@ -60,7 +60,8 @@ "tree-sitter": "^0.22.4", "vscode-universal-bundler": "^0.1.3", "workerpool": "^6.4.0", - "yauzl": "^2.10.0" + "yauzl": "^2.10.0", + "zx": "8.5.0" }, "optionalDependencies": { "tree-sitter-typescript": "^0.23.2", @@ -4661,6 +4662,19 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zx": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/zx/-/zx-8.5.0.tgz", + "integrity": "sha512-XS5/oKOQxKNfG2sVO6TQQjZF5RqWGE5QGSUOCZZVTnvYr3RDBTdbX3IFmV9CrnycCAQWcY0hAD3DDUa4RJE4+w==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "zx": "build/cli.js" + }, + "engines": { + "node": ">= 12.17.0" + } } } } diff --git a/build/package.json b/build/package.json index 73d4f42e843..cebae7e286d 100644 --- a/build/package.json +++ b/build/package.json @@ -54,7 +54,8 @@ "tree-sitter": "^0.22.4", "vscode-universal-bundler": "^0.1.3", "workerpool": "^6.4.0", - "yauzl": "^2.10.0" + "yauzl": "^2.10.0", + "zx": "8.5.0" }, "type": "commonjs", "scripts": {