From 957feece3be205fe5e30722b4d2eb42501f69857 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 7 Jun 2024 15:48:17 +0200 Subject: [PATCH 1/3] fix #993 --- src/main.ts | 21 ++++++++++++++++++++- src/package.ts | 16 ++++++++++++---- src/publish.ts | 21 ++++++++++++++++++--- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/main.ts b/src/main.ts index dfb8a240..b4fd5912 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,6 @@ import program from 'commander'; import leven from 'leven'; -import { packageCommand, ls, Targets } from './package'; +import { packageCommand, ls, Targets, generateManifest } from './package'; import { publish, unpublish } from './publish'; import { show } from './show'; import { search } from './search'; @@ -197,6 +197,8 @@ 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('--manifestPath ', 'Manifest files to publish alongside the VSIX packages.') + .option('--signaturePath ', 'Signature files to publish alongside the 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( @@ -237,6 +239,8 @@ module.exports = function (argv: string[]): void { gitTagVersion, updatePackageJson, packagePath, + manifestPath, + signaturePath, sigzipPath, githubBranch, gitlabBranch, @@ -269,6 +273,8 @@ module.exports = function (argv: string[]): void { gitTagVersion, updatePackageJson, packagePath, + manifestPath, + signaturePath, sigzipPath, githubBranch, gitlabBranch, @@ -298,6 +304,19 @@ module.exports = function (argv: string[]): void { .option('-f, --force', 'Skip confirmation prompt when unpublishing an extension') .action((id, { pat, azureCredential, force }) => main(unpublish({ id, pat, azureCredential, force }))); + program + .command('generate-manifest') + .description('Generates the extension manifest from the provided VSIX package.') + .requiredOption('-i, --packagePath ', 'Path to the VSIX package') + .option('-o, --out ', 'Output the extension manifest to location (defaults to .signature.manifest)') + .action(( + packagePath, + out + ) => + main( + generateManifest(packagePath, out) + )); + program .command('ls-publishers') .description('Lists all known publishers') diff --git a/src/package.ts b/src/package.ts index 2d487252..06bd6927 100644 --- a/src/package.ts +++ b/src/package.ts @@ -24,7 +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'; +import * as vsceSign from '@vscode/vsce-sign'; const MinimatchOptions: minimatch.IOptions = { dot: true }; @@ -1850,14 +1850,22 @@ export async function signPackage(packageFile: string, signTool: string): Promis 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.execSync(`${signTool} "${manifestFile}" "${signatureFile}"`, { stdio: 'inherit' }); - // Create a signature zip file containing the manifest and signature file - return zip(manifestFile, signatureFile, signatureZip); + return createSignatureArchive(manifestFile, signatureFile, signatureZip); +} + +// Generate the signature manifest file +export function generateManifest(packageFile: string, outputFile?: string): Promise { + return vsceSign.generateManifest(packageFile, outputFile); +} + +// Create a signature zip file containing the manifest and signature file +export async function createSignatureArchive(manifestFile: string, signatureFile: string, outputFile?: string): Promise { + return vsceSign.zip(manifestFile, signatureFile, outputFile) } export async function packageCommand(options: IPackageOptions = {}): Promise { diff --git a/src/publish.ts b/src/publish.ts index de7429dc..0e172d21 100644 --- a/src/publish.ts +++ b/src/publish.ts @@ -2,7 +2,7 @@ import * as fs from 'fs'; import { promisify } from 'util'; import * as semver from 'semver'; import { ExtensionQueryFlags, PublishedExtension } from 'azure-devops-node-api/interfaces/GalleryInterfaces'; -import { pack, readManifest, versionBump, prepublish, signPackage } from './package'; +import { pack, readManifest, versionBump, prepublish, signPackage, createSignatureArchive } from './package'; import * as tmp from 'tmp'; import { IVerifyPatOptions, getPublisher } from './store'; import { getGalleryAPI, read, getPublishedUrl, log, getHubUrl, patchOptionsWithManifest, getAzureCredentialAccessToken } from './util'; @@ -76,6 +76,8 @@ export interface IPublishOptions { readonly skipLicense?: boolean; readonly sigzipPath?: string[]; + readonly manifestPath?: string[]; + readonly signaturePath?: string[]; readonly signTool?: string; } @@ -89,6 +91,12 @@ export async function publish(options: IPublishOptions = {}): Promise { ); } + if (options.manifestPath || options.signaturePath) { + if (options.packagePath.length !== options.manifestPath?.length || options.packagePath.length !== options.signaturePath?.length) { + throw new Error(`Either all packages must be signed or none of them.`); + } + } + for (let index = 0; index < options.packagePath.length; index++) { const packagePath = options.packagePath[index]; const vsix = await readVSIXPackage(packagePath); @@ -118,12 +126,19 @@ export async function publish(options: IPublishOptions = {}): Promise { validateMarketplaceRequirements(vsix.manifest, options); - let sigzipPath = options.sigzipPath?.[index]; + let sigzipPath: string | undefined; + if (options.manifestPath?.[index] && options.signaturePath?.[index]) { + sigzipPath = await createSignatureArchive(options.manifestPath[index], options.signaturePath[index]) + } + + if (!sigzipPath) { + sigzipPath = options.sigzipPath?.[index]; + } + if (!sigzipPath && options.signTool) { sigzipPath = await signPackage(packagePath, options.signTool); } - await _publish(packagePath, sigzipPath, vsix.manifest, { ...options, target }); } } else { From abaeb8a4315e662f67f972d950bb29ad9b228cc4 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 7 Jun 2024 17:12:11 +0200 Subject: [PATCH 2/3] feedback --- src/main.ts | 2 +- src/package.ts | 5 +++++ src/publish.ts | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main.ts b/src/main.ts index b4fd5912..80bc052a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -308,7 +308,7 @@ module.exports = function (argv: string[]): void { .command('generate-manifest') .description('Generates the extension manifest from the provided VSIX package.') .requiredOption('-i, --packagePath ', 'Path to the VSIX package') - .option('-o, --out ', 'Output the extension manifest to location (defaults to .signature.manifest)') + .option('-o, --out ', 'Output the extension manifest to location ((defaults to .manifest)') .action(( packagePath, out diff --git a/src/package.ts b/src/package.ts index 06bd6927..867e9697 100644 --- a/src/package.ts +++ b/src/package.ts @@ -1860,6 +1860,11 @@ export async function signPackage(packageFile: string, signTool: string): Promis // Generate the signature manifest file export function generateManifest(packageFile: string, outputFile?: string): Promise { + if (!outputFile) { + const packageFolder = path.dirname(packageFile); + const packageName = path.basename(packageFile, '.vsix'); + outputFile = path.join(packageFolder, `${packageName}.manifest`); + } return vsceSign.generateManifest(packageFile, outputFile); } diff --git a/src/publish.ts b/src/publish.ts index 0e172d21..2d07b61d 100644 --- a/src/publish.ts +++ b/src/publish.ts @@ -128,7 +128,7 @@ export async function publish(options: IPublishOptions = {}): Promise { let sigzipPath: string | undefined; if (options.manifestPath?.[index] && options.signaturePath?.[index]) { - sigzipPath = await createSignatureArchive(options.manifestPath[index], options.signaturePath[index]) + sigzipPath = await createSignatureArchive(options.manifestPath[index], options.signaturePath[index]); } if (!sigzipPath) { From d99dd55f0623224b1df1b0d5d005c51ae997c583 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 7 Jun 2024 17:15:17 +0200 Subject: [PATCH 3/3] Update src/main.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: João Moreno --- src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 80bc052a..5f0c0d91 100644 --- a/src/main.ts +++ b/src/main.ts @@ -308,7 +308,7 @@ module.exports = function (argv: string[]): void { .command('generate-manifest') .description('Generates the extension manifest from the provided VSIX package.') .requiredOption('-i, --packagePath ', 'Path to the VSIX package') - .option('-o, --out ', 'Output the extension manifest to location ((defaults to .manifest)') + .option('-o, --out ', 'Output the extension manifest to location (defaults to .manifest)') .action(( packagePath, out