diff --git a/package-lock.json b/package-lock.json index b5c7a21f..70279176 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "@azure/identity": "^4.1.0", + "@vscode/vsce-sign": "^2.0.0", "azure-devops-node-api": "^12.5.0", "chalk": "^2.4.2", "cheerio": "^1.0.0-rc.9", @@ -597,6 +598,131 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, + "node_modules/@vscode/vsce-sign": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.3.tgz", + "integrity": "sha512-NYktTVXYIjJ41CTfImuWLYSw2UoZwYYFk7VcVYTjTZnD7NnuaM3DizaFZfuRG5YMRT/oZa1t1d4bwzrBALR3VQ==", + "hasInstallScript": true, + "optionalDependencies": { + "@vscode/vsce-sign-alpine-arm64": "2.0.1", + "@vscode/vsce-sign-alpine-x64": "2.0.1", + "@vscode/vsce-sign-darwin-arm64": "2.0.1", + "@vscode/vsce-sign-darwin-x64": "2.0.1", + "@vscode/vsce-sign-linux-arm": "2.0.1", + "@vscode/vsce-sign-linux-arm64": "2.0.1", + "@vscode/vsce-sign-linux-x64": "2.0.1", + "@vscode/vsce-sign-win32-arm64": "2.0.1", + "@vscode/vsce-sign-win32-x64": "2.0.1" + } + }, + "node_modules/@vscode/vsce-sign-alpine-arm64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.1.tgz", + "integrity": "sha512-HM2BHzyRKoUHVaaVmLFYcKlnMOcUAfU99oA1yAWX46D6iLZ8rWJYy2IOKTSMOXtVoc5d2hQdZR4+BCV5By4Flg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "alpine" + ] + }, + "node_modules/@vscode/vsce-sign-alpine-x64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.1.tgz", + "integrity": "sha512-GNh4dNmqwQqEDP2ngUgdu5ZYkJZAHomTppMI0v9sveFoZdML5iWuNGemvCEyInUpSb6Xjxc78ejeMoDay22wBw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "alpine" + ] + }, + "node_modules/@vscode/vsce-sign-darwin-arm64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.1.tgz", + "integrity": "sha512-iFnCbC8RBUyT0ZKEmop5yi7/NxP5G2gIW/giJHYDYppkhfyAR5STxlpf8Vx9hqIS0jPbeldNSn5a5BGMKtGXug==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@vscode/vsce-sign-darwin-x64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.1.tgz", + "integrity": "sha512-Dpv3PRpOzfDpji9JGVxe+hHyh41evyquMeXYykkTdcB3u3bZMoAgYoBlEOGnu87xb4s2J5DTj/J590yN0+dI0A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@vscode/vsce-sign-linux-arm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.1.tgz", + "integrity": "sha512-iltMQuS8K63aIabVrPBB8P2L37XkSwUqPTFLYlH6Bw+UpWJTFFvFFCKlmbxWrq1j8WkG+68Fm437ZfAkRW/rjQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-linux-arm64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.1.tgz", + "integrity": "sha512-SL6MeobrArp5SKPeUYVr5chp7a42L83vYAzLvD+oQM8fQ8DrZWYpNIyVkxGgsppZRyAt0UU2/5ShPxuNKfnZOA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-linux-x64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.1.tgz", + "integrity": "sha512-6N6dkZoJX/WKezZ3efCKVKjnbx+TlnUtNUkepyUUhCa3dGjGDqUkeakE2Kz266Bsp0Mm/68zS9HLKVOEv9vn0A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-win32-arm64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.1.tgz", + "integrity": "sha512-t4uYPpQummrmKaDw5Ka6QMEQ+We/Uo6xDEytFjN2jZ3jNOno3Mi7yWlTLg3VDAteHNGA7eBbMZ89Habl6xn8bg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@vscode/vsce-sign-win32-x64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.1.tgz", + "integrity": "sha512-ofY1iXoXaNlM3zDt5jw7v59NMh0y2GvKrP4A74aUDJjaXaDd6n/hLaOpDLk4a+MjX6HWiEBr5yNqHGKYa+t2jg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/acorn": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", @@ -3891,6 +4017,76 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, + "@vscode/vsce-sign": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.3.tgz", + "integrity": "sha512-NYktTVXYIjJ41CTfImuWLYSw2UoZwYYFk7VcVYTjTZnD7NnuaM3DizaFZfuRG5YMRT/oZa1t1d4bwzrBALR3VQ==", + "requires": { + "@vscode/vsce-sign-alpine-arm64": "2.0.1", + "@vscode/vsce-sign-alpine-x64": "2.0.1", + "@vscode/vsce-sign-darwin-arm64": "2.0.1", + "@vscode/vsce-sign-darwin-x64": "2.0.1", + "@vscode/vsce-sign-linux-arm": "2.0.1", + "@vscode/vsce-sign-linux-arm64": "2.0.1", + "@vscode/vsce-sign-linux-x64": "2.0.1", + "@vscode/vsce-sign-win32-arm64": "2.0.1", + "@vscode/vsce-sign-win32-x64": "2.0.1" + } + }, + "@vscode/vsce-sign-alpine-arm64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.1.tgz", + "integrity": "sha512-HM2BHzyRKoUHVaaVmLFYcKlnMOcUAfU99oA1yAWX46D6iLZ8rWJYy2IOKTSMOXtVoc5d2hQdZR4+BCV5By4Flg==", + "optional": true + }, + "@vscode/vsce-sign-alpine-x64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.1.tgz", + "integrity": "sha512-GNh4dNmqwQqEDP2ngUgdu5ZYkJZAHomTppMI0v9sveFoZdML5iWuNGemvCEyInUpSb6Xjxc78ejeMoDay22wBw==", + "optional": true + }, + "@vscode/vsce-sign-darwin-arm64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.1.tgz", + "integrity": "sha512-iFnCbC8RBUyT0ZKEmop5yi7/NxP5G2gIW/giJHYDYppkhfyAR5STxlpf8Vx9hqIS0jPbeldNSn5a5BGMKtGXug==", + "optional": true + }, + "@vscode/vsce-sign-darwin-x64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.1.tgz", + "integrity": "sha512-Dpv3PRpOzfDpji9JGVxe+hHyh41evyquMeXYykkTdcB3u3bZMoAgYoBlEOGnu87xb4s2J5DTj/J590yN0+dI0A==", + "optional": true + }, + "@vscode/vsce-sign-linux-arm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.1.tgz", + "integrity": "sha512-iltMQuS8K63aIabVrPBB8P2L37XkSwUqPTFLYlH6Bw+UpWJTFFvFFCKlmbxWrq1j8WkG+68Fm437ZfAkRW/rjQ==", + "optional": true + }, + "@vscode/vsce-sign-linux-arm64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.1.tgz", + "integrity": "sha512-SL6MeobrArp5SKPeUYVr5chp7a42L83vYAzLvD+oQM8fQ8DrZWYpNIyVkxGgsppZRyAt0UU2/5ShPxuNKfnZOA==", + "optional": true + }, + "@vscode/vsce-sign-linux-x64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.1.tgz", + "integrity": "sha512-6N6dkZoJX/WKezZ3efCKVKjnbx+TlnUtNUkepyUUhCa3dGjGDqUkeakE2Kz266Bsp0Mm/68zS9HLKVOEv9vn0A==", + "optional": true + }, + "@vscode/vsce-sign-win32-arm64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.1.tgz", + "integrity": "sha512-t4uYPpQummrmKaDw5Ka6QMEQ+We/Uo6xDEytFjN2jZ3jNOno3Mi7yWlTLg3VDAteHNGA7eBbMZ89Habl6xn8bg==", + "optional": true + }, + "@vscode/vsce-sign-win32-x64": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.1.tgz", + "integrity": "sha512-ofY1iXoXaNlM3zDt5jw7v59NMh0y2GvKrP4A74aUDJjaXaDd6n/hLaOpDLk4a+MjX6HWiEBr5yNqHGKYa+t2jg==", + "optional": true + }, "acorn": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", diff --git a/package.json b/package.json index b6454611..d992984f 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ }, "dependencies": { "@azure/identity": "^4.1.0", + "@vscode/vsce-sign": "^2.0.0", "azure-devops-node-api": "^12.5.0", "chalk": "^2.4.2", "cheerio": "^1.0.0-rc.9", diff --git a/src/main.ts b/src/main.ts index ad1cc62c..e11843f3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -117,6 +117,7 @@ module.exports = function (argv: string[]): void { .option('--allow-star-activation', 'Allow using * in activation events') .option('--allow-missing-repository', 'Allow missing a repository URL in package.json') .option('--skip-license', 'Allow packaging without license file') + .option('--sign-tool', 'Path to the VSIX signing tool. Will be invoked with two arguments: `SIGNTOOL `.') .action( ( version, @@ -143,6 +144,7 @@ module.exports = function (argv: string[]): void { allowStarActivation, allowMissingRepository, skipLicense, + signTool, } ) => main( @@ -170,6 +172,7 @@ module.exports = function (argv: string[]): void { allowStarActivation, allowMissingRepository, skipLicense, + signTool, }) ) ); @@ -195,6 +198,7 @@ module.exports = function (argv: string[]): void { .option('--no-update-package-json', 'Do not update `package.json`. Valid only when [version] is provided.') .option('-i, --packagePath ', 'Publish the provided VSIX packages.') .option('--sigzipPath ', 'Signature archives to publish alongside the VSIX packages.') + .option('--sign-tool', 'Path to the VSIX signing tool. Will be invoked with two arguments: `SIGNTOOL `. This will be ignored if --sigzipPath is provided.') .option( '--githubBranch ', 'The GitHub branch used to infer relative links in README.md. Can be overridden by --baseContentUrl and --baseImagesUrl.' @@ -249,6 +253,7 @@ module.exports = function (argv: string[]): void { allowMissingRepository, skipDuplicate, skipLicense, + signTool, } ) => main( @@ -280,6 +285,7 @@ module.exports = function (argv: string[]): void { allowMissingRepository, skipDuplicate, skipLicense, + signTool }) ) ); diff --git a/src/package.ts b/src/package.ts index 4e5b2efa..e09866bc 100644 --- a/src/package.ts +++ b/src/package.ts @@ -24,6 +24,7 @@ import { detectYarn, getDependencies } from './npm'; import * as GitHost from 'hosted-git-info'; import parseSemver from 'parse-semver'; import * as jsonc from 'jsonc-parser'; +import { generateManifest, zip } from '@vscode/vsce-sign'; const MinimatchOptions: minimatch.IOptions = { dot: true }; @@ -151,6 +152,8 @@ export interface IPackageOptions { readonly allowStarActivation?: boolean; readonly allowMissingRepository?: boolean; readonly skipLicense?: boolean; + + readonly signTool?: string; } export interface IProcessor { @@ -1840,6 +1843,23 @@ export async function pack(options: IPackageOptions = {}): Promise { + const packageFolder = path.dirname(packageFile); + const packageName = path.basename(packageFile, '.vsix'); + const manifestFile = path.join(packageFolder, `${packageName}.signature.manifest`); + const signatureFile = path.join(packageFolder, `${packageName}.signature.p7s`); + const signatureZip = path.join(packageFolder, `${packageName}.signature.zip`); + + // Generate the signature manifest file + await generateManifest(packageFile, manifestFile); + + // Sign the manifest file to generate the signature file + cp.spawnSync(signScript, [manifestFile, signatureFile], { stdio: 'inherit' }); + + // Create a signature zip file containing the manifest and signature file + return zip(manifestFile, signatureFile, signatureZip); +} + export async function packageCommand(options: IPackageOptions = {}): Promise { const cwd = options.cwd || process.cwd(); const manifest = await readManifest(cwd); @@ -1849,6 +1869,11 @@ export async function packageCommand(options: IPackageOptions = {}): Promise { @@ -117,7 +118,13 @@ export async function publish(options: IPublishOptions = {}): Promise { validateMarketplaceRequirements(vsix.manifest, options); - await _publish(packagePath, options.sigzipPath?.[index], vsix.manifest, { ...options, target }); + let sigzipPath = options.sigzipPath?.[index]; + if (!sigzipPath && options.signTool) { + sigzipPath = await signPackage(packagePath, options.signTool); + } + + + await _publish(packagePath, sigzipPath, vsix.manifest, { ...options, target }); } } else { const cwd = options.cwd || process.cwd(); @@ -134,12 +141,14 @@ export async function publish(options: IPublishOptions = {}): Promise { for (const target of options.targets) { const packagePath = await tmpName(); const packageResult = await pack({ ...options, target, packagePath }); - await _publish(packagePath, undefined, packageResult.manifest, { ...options, target }); + const sigzipPath = options.signTool ? await signPackage(packagePath, options.signTool) : undefined; + await _publish(packagePath, sigzipPath, packageResult.manifest, { ...options, target }); } } else { const packagePath = await tmpName(); const packageResult = await pack({ ...options, packagePath }); - await _publish(packagePath, undefined, packageResult.manifest, options); + const sigzipPath = options.signTool ? await signPackage(packagePath, options.signTool) : undefined; + await _publish(packagePath, sigzipPath, packageResult.manifest, options); } } }