Skip to content

Commit

Permalink
Support signing related features (#994)
Browse files Browse the repository at this point in the history
* fix #993

* feedback

* Update src/main.ts

Co-authored-by: João Moreno <joao.moreno@microsoft.com>

---------

Co-authored-by: João Moreno <joao.moreno@microsoft.com>
  • Loading branch information
sandy081 and joaomoreno authored Jun 7, 2024
1 parent f3c15a2 commit dab8833
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
21 changes: 20 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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 <paths...>', 'Publish the provided VSIX packages.')
.option('--manifestPath <paths...>', 'Manifest files to publish alongside the VSIX packages.')
.option('--signaturePath <paths...>', 'Signature files to publish alongside the VSIX packages.')
.option('--sigzipPath <paths...>', 'Signature archives to publish alongside the VSIX packages.')
.option('--sign-tool <path>', 'Path to the VSIX signing tool. Will be invoked with two arguments: `SIGNTOOL <path/to/extension.signature.manifest> <path/to/extension.signature.p7s>`. This will be ignored if --sigzipPath is provided.')
.option(
Expand Down Expand Up @@ -237,6 +239,8 @@ module.exports = function (argv: string[]): void {
gitTagVersion,
updatePackageJson,
packagePath,
manifestPath,
signaturePath,
sigzipPath,
githubBranch,
gitlabBranch,
Expand Down Expand Up @@ -269,6 +273,8 @@ module.exports = function (argv: string[]): void {
gitTagVersion,
updatePackageJson,
packagePath,
manifestPath,
signaturePath,
sigzipPath,
githubBranch,
gitlabBranch,
Expand Down Expand Up @@ -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>', 'Path to the VSIX package')
.option('-o, --out <path>', 'Output the extension manifest to <path> location (defaults to <packagename>.manifest)')
.action((
packagePath,
out
) =>
main(
generateManifest(packagePath, out)
));

program
.command('ls-publishers')
.description('Lists all known publishers')
Expand Down
21 changes: 17 additions & 4 deletions src/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };

Expand Down Expand Up @@ -1850,14 +1850,27 @@ 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<string> {
if (!outputFile) {
const packageFolder = path.dirname(packageFile);
const packageName = path.basename(packageFile, '.vsix');
outputFile = path.join(packageFolder, `${packageName}.manifest`);
}
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<string> {
return vsceSign.zip(manifestFile, signatureFile, outputFile)
}

export async function packageCommand(options: IPackageOptions = {}): Promise<any> {
Expand Down
21 changes: 18 additions & 3 deletions src/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -76,6 +76,8 @@ export interface IPublishOptions {
readonly skipLicense?: boolean;

readonly sigzipPath?: string[];
readonly manifestPath?: string[];
readonly signaturePath?: string[];
readonly signTool?: string;
}

Expand All @@ -89,6 +91,12 @@ export async function publish(options: IPublishOptions = {}): Promise<any> {
);
}

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);
Expand Down Expand Up @@ -118,12 +126,19 @@ export async function publish(options: IPublishOptions = {}): Promise<any> {

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 {
Expand Down

0 comments on commit dab8833

Please sign in to comment.