Skip to content

Commit dab8833

Browse files
sandy081joaomoreno
andauthored
Support signing related features (#994)
* fix #993 * feedback * Update src/main.ts Co-authored-by: João Moreno <[email protected]> --------- Co-authored-by: João Moreno <[email protected]>
1 parent f3c15a2 commit dab8833

File tree

3 files changed

+55
-8
lines changed

3 files changed

+55
-8
lines changed

src/main.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import program from 'commander';
22
import leven from 'leven';
3-
import { packageCommand, ls, Targets } from './package';
3+
import { packageCommand, ls, Targets, generateManifest } from './package';
44
import { publish, unpublish } from './publish';
55
import { show } from './show';
66
import { search } from './search';
@@ -197,6 +197,8 @@ module.exports = function (argv: string[]): void {
197197
)
198198
.option('--no-update-package-json', 'Do not update `package.json`. Valid only when [version] is provided.')
199199
.option('-i, --packagePath <paths...>', 'Publish the provided VSIX packages.')
200+
.option('--manifestPath <paths...>', 'Manifest files to publish alongside the VSIX packages.')
201+
.option('--signaturePath <paths...>', 'Signature files to publish alongside the VSIX packages.')
200202
.option('--sigzipPath <paths...>', 'Signature archives to publish alongside the VSIX packages.')
201203
.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.')
202204
.option(
@@ -237,6 +239,8 @@ module.exports = function (argv: string[]): void {
237239
gitTagVersion,
238240
updatePackageJson,
239241
packagePath,
242+
manifestPath,
243+
signaturePath,
240244
sigzipPath,
241245
githubBranch,
242246
gitlabBranch,
@@ -269,6 +273,8 @@ module.exports = function (argv: string[]): void {
269273
gitTagVersion,
270274
updatePackageJson,
271275
packagePath,
276+
manifestPath,
277+
signaturePath,
272278
sigzipPath,
273279
githubBranch,
274280
gitlabBranch,
@@ -298,6 +304,19 @@ module.exports = function (argv: string[]): void {
298304
.option('-f, --force', 'Skip confirmation prompt when unpublishing an extension')
299305
.action((id, { pat, azureCredential, force }) => main(unpublish({ id, pat, azureCredential, force })));
300306

307+
program
308+
.command('generate-manifest')
309+
.description('Generates the extension manifest from the provided VSIX package.')
310+
.requiredOption('-i, --packagePath <path>', 'Path to the VSIX package')
311+
.option('-o, --out <path>', 'Output the extension manifest to <path> location (defaults to <packagename>.manifest)')
312+
.action((
313+
packagePath,
314+
out
315+
) =>
316+
main(
317+
generateManifest(packagePath, out)
318+
));
319+
301320
program
302321
.command('ls-publishers')
303322
.description('Lists all known publishers')

src/package.ts

+17-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { detectYarn, getDependencies } from './npm';
2424
import * as GitHost from 'hosted-git-info';
2525
import parseSemver from 'parse-semver';
2626
import * as jsonc from 'jsonc-parser';
27-
import { generateManifest, zip } from '@vscode/vsce-sign';
27+
import * as vsceSign from '@vscode/vsce-sign';
2828

2929
const MinimatchOptions: minimatch.IOptions = { dot: true };
3030

@@ -1850,14 +1850,27 @@ export async function signPackage(packageFile: string, signTool: string): Promis
18501850
const signatureFile = path.join(packageFolder, `${packageName}.signature.p7s`);
18511851
const signatureZip = path.join(packageFolder, `${packageName}.signature.zip`);
18521852

1853-
// Generate the signature manifest file
18541853
await generateManifest(packageFile, manifestFile);
18551854

18561855
// Sign the manifest file to generate the signature file
18571856
cp.execSync(`${signTool} "${manifestFile}" "${signatureFile}"`, { stdio: 'inherit' });
18581857

1859-
// Create a signature zip file containing the manifest and signature file
1860-
return zip(manifestFile, signatureFile, signatureZip);
1858+
return createSignatureArchive(manifestFile, signatureFile, signatureZip);
1859+
}
1860+
1861+
// Generate the signature manifest file
1862+
export function generateManifest(packageFile: string, outputFile?: string): Promise<string> {
1863+
if (!outputFile) {
1864+
const packageFolder = path.dirname(packageFile);
1865+
const packageName = path.basename(packageFile, '.vsix');
1866+
outputFile = path.join(packageFolder, `${packageName}.manifest`);
1867+
}
1868+
return vsceSign.generateManifest(packageFile, outputFile);
1869+
}
1870+
1871+
// Create a signature zip file containing the manifest and signature file
1872+
export async function createSignatureArchive(manifestFile: string, signatureFile: string, outputFile?: string): Promise<string> {
1873+
return vsceSign.zip(manifestFile, signatureFile, outputFile)
18611874
}
18621875

18631876
export async function packageCommand(options: IPackageOptions = {}): Promise<any> {

src/publish.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as fs from 'fs';
22
import { promisify } from 'util';
33
import * as semver from 'semver';
44
import { ExtensionQueryFlags, PublishedExtension } from 'azure-devops-node-api/interfaces/GalleryInterfaces';
5-
import { pack, readManifest, versionBump, prepublish, signPackage } from './package';
5+
import { pack, readManifest, versionBump, prepublish, signPackage, createSignatureArchive } from './package';
66
import * as tmp from 'tmp';
77
import { IVerifyPatOptions, getPublisher } from './store';
88
import { getGalleryAPI, read, getPublishedUrl, log, getHubUrl, patchOptionsWithManifest, getAzureCredentialAccessToken } from './util';
@@ -76,6 +76,8 @@ export interface IPublishOptions {
7676
readonly skipLicense?: boolean;
7777

7878
readonly sigzipPath?: string[];
79+
readonly manifestPath?: string[];
80+
readonly signaturePath?: string[];
7981
readonly signTool?: string;
8082
}
8183

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

94+
if (options.manifestPath || options.signaturePath) {
95+
if (options.packagePath.length !== options.manifestPath?.length || options.packagePath.length !== options.signaturePath?.length) {
96+
throw new Error(`Either all packages must be signed or none of them.`);
97+
}
98+
}
99+
92100
for (let index = 0; index < options.packagePath.length; index++) {
93101
const packagePath = options.packagePath[index];
94102
const vsix = await readVSIXPackage(packagePath);
@@ -118,12 +126,19 @@ export async function publish(options: IPublishOptions = {}): Promise<any> {
118126

119127
validateMarketplaceRequirements(vsix.manifest, options);
120128

121-
let sigzipPath = options.sigzipPath?.[index];
129+
let sigzipPath: string | undefined;
130+
if (options.manifestPath?.[index] && options.signaturePath?.[index]) {
131+
sigzipPath = await createSignatureArchive(options.manifestPath[index], options.signaturePath[index]);
132+
}
133+
134+
if (!sigzipPath) {
135+
sigzipPath = options.sigzipPath?.[index];
136+
}
137+
122138
if (!sigzipPath && options.signTool) {
123139
sigzipPath = await signPackage(packagePath, options.signTool);
124140
}
125141

126-
127142
await _publish(packagePath, sigzipPath, vsix.manifest, { ...options, target });
128143
}
129144
} else {

0 commit comments

Comments
 (0)