Merge pull request #28816 from drodil/git_commit_signing
feat: allow signing git commits from scaffolder
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-bitbucket': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-gerrit': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-gitlab': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-azure': patch
|
||||
'@backstage/plugin-scaffolder-backend-module-gitea': patch
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
'@backstage/plugin-scaffolder-node': patch
|
||||
'@backstage/integration': patch
|
||||
---
|
||||
|
||||
Allow signing git commits using configured private PGP key in scaffolder
|
||||
Vendored
+35
@@ -62,6 +62,11 @@ export interface Config {
|
||||
tenantId?: string;
|
||||
personalAccessToken?: string;
|
||||
}[];
|
||||
/**
|
||||
* PGP signing key for signing commits.
|
||||
* @visibility secret
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
}>;
|
||||
|
||||
/**
|
||||
@@ -94,6 +99,11 @@ export interface Config {
|
||||
* @visibility secret
|
||||
*/
|
||||
appPassword?: string;
|
||||
/**
|
||||
* PGP signing key for signing commits.
|
||||
* @visibility secret
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
}>;
|
||||
|
||||
/** Integration configuration for Bitbucket Cloud */
|
||||
@@ -108,6 +118,11 @@ export interface Config {
|
||||
* @visibility secret
|
||||
*/
|
||||
appPassword: string;
|
||||
/**
|
||||
* PGP signing key for signing commits.
|
||||
* @visibility secret
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
}>;
|
||||
|
||||
/** Integration configuration for Bitbucket Server */
|
||||
@@ -137,6 +152,11 @@ export interface Config {
|
||||
* @visibility frontend
|
||||
*/
|
||||
apiBaseUrl?: string;
|
||||
/**
|
||||
* PGP signing key for signing commits.
|
||||
* @visibility secret
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
}>;
|
||||
|
||||
/** Integration configuration for Gerrit */
|
||||
@@ -172,6 +192,11 @@ export interface Config {
|
||||
* @visibility secret
|
||||
*/
|
||||
password?: string;
|
||||
/**
|
||||
* PGP signing key for signing commits.
|
||||
* @visibility secret
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
}>;
|
||||
|
||||
/** Integration configuration for GitHub */
|
||||
@@ -269,6 +294,11 @@ export interface Config {
|
||||
* @visibility frontend
|
||||
*/
|
||||
baseUrl?: string;
|
||||
/**
|
||||
* PGP signing key for signing commits.
|
||||
* @visibility secret
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
}>;
|
||||
|
||||
/** Integration configuration for Google Cloud Storage */
|
||||
@@ -349,6 +379,11 @@ export interface Config {
|
||||
* @visibility secret
|
||||
*/
|
||||
password?: string;
|
||||
/**
|
||||
* PGP signing key for signing commits.
|
||||
* @visibility secret
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
}>;
|
||||
/** Integration configuration for Harness Code */
|
||||
harness?: Array<{
|
||||
|
||||
@@ -201,6 +201,7 @@ export type AzureIntegrationConfig = {
|
||||
token?: string;
|
||||
credential?: AzureDevOpsCredential;
|
||||
credentials?: AzureDevOpsCredential[];
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
// @public
|
||||
@@ -237,6 +238,7 @@ export type BitbucketCloudIntegrationConfig = {
|
||||
username?: string;
|
||||
appPassword?: string;
|
||||
token?: string;
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
// @public @deprecated
|
||||
@@ -267,6 +269,7 @@ export type BitbucketIntegrationConfig = {
|
||||
token?: string;
|
||||
username?: string;
|
||||
appPassword?: string;
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
// @public
|
||||
@@ -297,6 +300,7 @@ export type BitbucketServerIntegrationConfig = {
|
||||
token?: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
// @public @deprecated
|
||||
@@ -395,6 +399,7 @@ export type GerritIntegrationConfig = {
|
||||
gitilesBaseUrl: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
// @public
|
||||
@@ -630,6 +635,7 @@ export type GiteaIntegrationConfig = {
|
||||
baseUrl?: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
// @public
|
||||
@@ -744,6 +750,7 @@ export type GitLabIntegrationConfig = {
|
||||
apiBaseUrl: string;
|
||||
token?: string;
|
||||
baseUrl: string;
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
// @public
|
||||
|
||||
@@ -57,6 +57,11 @@ export type AzureIntegrationConfig = {
|
||||
* If no credentials are specified at all, either a default credential (for Azure DevOps) or anonymous access (for Azure DevOps Server) is used.
|
||||
*/
|
||||
credentials?: AzureDevOpsCredential[];
|
||||
|
||||
/**
|
||||
* Signing key for commits
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -349,6 +354,7 @@ export function readAzureIntegrationConfig(
|
||||
return {
|
||||
host,
|
||||
credentials,
|
||||
commitSigningKey: config.getOptionalString('commitSigningKey'),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,11 @@ export type BitbucketIntegrationConfig = {
|
||||
* See https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/
|
||||
*/
|
||||
appPassword?: string;
|
||||
|
||||
/**
|
||||
* Signing key for commits
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -100,6 +105,7 @@ export function readBitbucketIntegrationConfig(
|
||||
token,
|
||||
username,
|
||||
appPassword,
|
||||
commitSigningKey: config.getOptionalString('commitSigningKey'),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,9 @@ export type BitbucketCloudIntegrationConfig = {
|
||||
* The access token to use for requests to Bitbucket Cloud (bitbucket.org).
|
||||
*/
|
||||
token?: string;
|
||||
|
||||
/** PGP private key for signing commits. */
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -74,6 +77,7 @@ export function readBitbucketCloudIntegrationConfig(
|
||||
apiBaseUrl,
|
||||
username,
|
||||
appPassword,
|
||||
commitSigningKey: config.getOptionalString('commitSigningKey'),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,11 @@ export type BitbucketServerIntegrationConfig = {
|
||||
* See https://developer.atlassian.com/server/bitbucket/how-tos/command-line-rest/#authentication
|
||||
*/
|
||||
password?: string;
|
||||
|
||||
/**
|
||||
* Signing key for commits
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -99,6 +104,7 @@ export function readBitbucketServerIntegrationConfig(
|
||||
token,
|
||||
username,
|
||||
password,
|
||||
commitSigningKey: config.getOptionalString('commitSigningKey'),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,11 @@ export type GerritIntegrationConfig = {
|
||||
* The password or http token to use for authentication.
|
||||
*/
|
||||
password?: string;
|
||||
|
||||
/**
|
||||
* The signing key to use for signing commits.
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -119,6 +124,7 @@ export function readGerritIntegrationConfig(
|
||||
gitilesBaseUrl,
|
||||
username,
|
||||
password,
|
||||
commitSigningKey: config.getOptionalString('commitSigningKey'),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,11 @@ export type GiteaIntegrationConfig = {
|
||||
* The password or http token to use for authentication.
|
||||
*/
|
||||
password?: string;
|
||||
|
||||
/**
|
||||
* Signing key to to sign commits
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -79,5 +84,6 @@ export function readGiteaConfig(config: Config): GiteaIntegrationConfig {
|
||||
baseUrl,
|
||||
username,
|
||||
password,
|
||||
commitSigningKey: config.getOptionalString('commitSigningKey'),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,6 +54,11 @@ export type GitLabIntegrationConfig = {
|
||||
* If no baseUrl is provided, it will default to `https://${host}`
|
||||
*/
|
||||
baseUrl: string;
|
||||
|
||||
/**
|
||||
* Signing key to sign commits
|
||||
*/
|
||||
commitSigningKey?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -95,7 +100,13 @@ export function readGitLabIntegrationConfig(
|
||||
);
|
||||
}
|
||||
|
||||
return { host, token, apiBaseUrl, baseUrl };
|
||||
return {
|
||||
host,
|
||||
token,
|
||||
apiBaseUrl,
|
||||
baseUrl,
|
||||
commitSigningKey: config.getOptionalString('commitSigningKey'),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,7 @@ export function createPublishAzureAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
signCommit?: boolean;
|
||||
},
|
||||
JsonObject
|
||||
>;
|
||||
|
||||
@@ -20,10 +20,10 @@ import {
|
||||
ScmIntegrationRegistry,
|
||||
} from '@backstage/integration';
|
||||
import {
|
||||
initRepoAndPush,
|
||||
getRepoSourceDirectory,
|
||||
parseRepoUrl,
|
||||
createTemplateAction,
|
||||
getRepoSourceDirectory,
|
||||
initRepoAndPush,
|
||||
parseRepoUrl,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
import { GitRepositoryCreateOptions } from 'azure-devops-node-api/interfaces/GitInterfaces';
|
||||
import {
|
||||
@@ -54,6 +54,7 @@ export function createPublishAzureAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
signCommit?: boolean;
|
||||
}>({
|
||||
id: 'publish:azure',
|
||||
examples,
|
||||
@@ -103,6 +104,11 @@ export function createPublishAzureAction(options: {
|
||||
type: 'string',
|
||||
description: 'The token to use for authorization to Azure',
|
||||
},
|
||||
signCommit: {
|
||||
title: 'Sign commit',
|
||||
type: 'boolean',
|
||||
description: 'Sign commit with configured PGP private key',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
@@ -134,6 +140,7 @@ export function createPublishAzureAction(options: {
|
||||
gitCommitMessage = 'initial commit',
|
||||
gitAuthorName,
|
||||
gitAuthorEmail,
|
||||
signCommit,
|
||||
} = ctx.input;
|
||||
|
||||
const { project, repo, host, organization } = parseRepoUrl(
|
||||
@@ -151,6 +158,7 @@ export function createPublishAzureAction(options: {
|
||||
const credentialProvider =
|
||||
DefaultAzureDevOpsCredentialsProvider.fromIntegrations(integrations);
|
||||
const credentials = await credentialProvider.getCredentials({ url: url });
|
||||
const integrationConfig = integrations.azure.byHost(host);
|
||||
|
||||
if (credentials === undefined && ctx.input.token === undefined) {
|
||||
throw new InputError(
|
||||
@@ -212,6 +220,15 @@ export function createPublishAzureAction(options: {
|
||||
password: ctx.input.token ?? credentials!.token,
|
||||
};
|
||||
|
||||
const signingKey =
|
||||
integrationConfig?.config.commitSigningKey ??
|
||||
config.getOptionalString('scaffolder.defaultCommitSigningKey');
|
||||
if (signCommit && !signingKey) {
|
||||
throw new Error(
|
||||
'Signing commits is enabled but no signing key is provided in the configuration',
|
||||
);
|
||||
}
|
||||
|
||||
const commitResult = await initRepoAndPush({
|
||||
dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),
|
||||
remoteUrl,
|
||||
@@ -222,6 +239,7 @@ export function createPublishAzureAction(options: {
|
||||
? gitCommitMessage
|
||||
: config.getOptionalString('scaffolder.defaultCommitMessage'),
|
||||
gitAuthorInfo,
|
||||
signingKey: signCommit ? signingKey : undefined,
|
||||
});
|
||||
|
||||
ctx.output('commitHash', commitResult?.commitHash);
|
||||
|
||||
@@ -39,6 +39,7 @@ export function createPublishBitbucketCloudAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
sourcePath?: string;
|
||||
token?: string;
|
||||
signCommit?: boolean;
|
||||
},
|
||||
JsonObject
|
||||
>;
|
||||
|
||||
@@ -18,8 +18,8 @@ import { InputError } from '@backstage/errors';
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import {
|
||||
createTemplateAction,
|
||||
initRepoAndPush,
|
||||
getRepoSourceDirectory,
|
||||
initRepoAndPush,
|
||||
parseRepoUrl,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
|
||||
@@ -113,6 +113,7 @@ export function createPublishBitbucketCloudAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
sourcePath?: string;
|
||||
token?: string;
|
||||
signCommit?: boolean;
|
||||
}>({
|
||||
id: 'publish:bitbucketCloud',
|
||||
examples,
|
||||
@@ -158,6 +159,11 @@ export function createPublishBitbucketCloudAction(options: {
|
||||
description:
|
||||
'The token to use for authorization to BitBucket Cloud',
|
||||
},
|
||||
signCommit: {
|
||||
title: 'Sign commit',
|
||||
type: 'boolean',
|
||||
description: 'Sign commit with configured PGP private key',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
@@ -185,6 +191,7 @@ export function createPublishBitbucketCloudAction(options: {
|
||||
defaultBranch = 'master',
|
||||
gitCommitMessage,
|
||||
repoVisibility = 'private',
|
||||
signCommit,
|
||||
} = ctx.input;
|
||||
|
||||
const { workspace, project, repo, host } = parseRepoUrl(
|
||||
@@ -256,6 +263,15 @@ export function createPublishBitbucketCloudAction(options: {
|
||||
};
|
||||
}
|
||||
|
||||
const signingKey =
|
||||
integrationConfig.config.commitSigningKey ??
|
||||
config.getOptionalString('scaffolder.defaultCommitSigningKey');
|
||||
if (signCommit && !signingKey) {
|
||||
throw new Error(
|
||||
'Signing commits is enabled but no signing key is provided in the configuration',
|
||||
);
|
||||
}
|
||||
|
||||
const commitResult = await initRepoAndPush({
|
||||
dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),
|
||||
remoteUrl,
|
||||
@@ -266,6 +282,7 @@ export function createPublishBitbucketCloudAction(options: {
|
||||
gitCommitMessage ||
|
||||
config.getOptionalString('scaffolder.defaultCommitMessage'),
|
||||
gitAuthorInfo,
|
||||
signingKey: signCommit ? signingKey : undefined,
|
||||
});
|
||||
|
||||
ctx.output('commitHash', commitResult?.commitHash);
|
||||
|
||||
@@ -29,6 +29,7 @@ export function createPublishBitbucketServerAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
signCommit?: boolean;
|
||||
},
|
||||
JsonObject
|
||||
>;
|
||||
|
||||
@@ -21,8 +21,8 @@ import {
|
||||
} from '@backstage/integration';
|
||||
import {
|
||||
createTemplateAction,
|
||||
initRepoAndPush,
|
||||
getRepoSourceDirectory,
|
||||
initRepoAndPush,
|
||||
parseRepoUrl,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
|
||||
@@ -137,6 +137,7 @@ export function createPublishBitbucketServerAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
signCommit?: boolean;
|
||||
}>({
|
||||
id: 'publish:bitbucketServer',
|
||||
description:
|
||||
@@ -197,6 +198,11 @@ export function createPublishBitbucketServerAction(options: {
|
||||
type: 'string',
|
||||
description: `Sets the author email for the commit.`,
|
||||
},
|
||||
signCommit: {
|
||||
title: 'Sign commit',
|
||||
type: 'boolean',
|
||||
description: 'Sign commit with configured PGP private key',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
@@ -227,6 +233,7 @@ export function createPublishBitbucketServerAction(options: {
|
||||
gitCommitMessage = 'initial commit',
|
||||
gitAuthorName,
|
||||
gitAuthorEmail,
|
||||
signCommit,
|
||||
} = ctx.input;
|
||||
|
||||
const { project, repo, host } = parseRepoUrl(repoUrl, integrations);
|
||||
@@ -279,6 +286,15 @@ export function createPublishBitbucketServerAction(options: {
|
||||
: config.getOptionalString('scaffolder.defaultAuthor.email'),
|
||||
};
|
||||
|
||||
const signingKey =
|
||||
integrationConfig.config.commitSigningKey ??
|
||||
config.getOptionalString('scaffolder.defaultCommitSigningKey');
|
||||
if (signCommit && !signingKey) {
|
||||
throw new Error(
|
||||
'Signing commits is enabled but no signing key is provided in the configuration',
|
||||
);
|
||||
}
|
||||
|
||||
const auth = authConfig.token
|
||||
? {
|
||||
token: token!,
|
||||
@@ -298,6 +314,7 @@ export function createPublishBitbucketServerAction(options: {
|
||||
? gitCommitMessage
|
||||
: config.getOptionalString('scaffolder.defaultCommitMessage'),
|
||||
gitAuthorInfo,
|
||||
signingKey: signCommit ? signingKey : undefined,
|
||||
});
|
||||
|
||||
if (enableLFS) {
|
||||
|
||||
@@ -44,6 +44,7 @@ export function createPublishBitbucketAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
signCommit?: boolean;
|
||||
},
|
||||
JsonObject
|
||||
>;
|
||||
|
||||
@@ -21,8 +21,8 @@ import {
|
||||
} from '@backstage/integration';
|
||||
import {
|
||||
createTemplateAction,
|
||||
initRepoAndPush,
|
||||
getRepoSourceDirectory,
|
||||
initRepoAndPush,
|
||||
parseRepoUrl,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
import { Config } from '@backstage/config';
|
||||
@@ -220,6 +220,7 @@ export function createPublishBitbucketAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
signCommit?: boolean;
|
||||
}>({
|
||||
id: 'publish:bitbucket',
|
||||
description:
|
||||
@@ -280,6 +281,11 @@ export function createPublishBitbucketAction(options: {
|
||||
type: 'string',
|
||||
description: `Sets the default author email for the commit.`,
|
||||
},
|
||||
signCommit: {
|
||||
title: 'Sign commit',
|
||||
type: 'boolean',
|
||||
description: 'Sign commit with configured PGP private key',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
@@ -313,6 +319,7 @@ export function createPublishBitbucketAction(options: {
|
||||
gitCommitMessage = 'initial commit',
|
||||
gitAuthorName,
|
||||
gitAuthorEmail,
|
||||
signCommit,
|
||||
} = ctx.input;
|
||||
|
||||
const { workspace, project, repo, host } = parseRepoUrl(
|
||||
@@ -380,6 +387,14 @@ export function createPublishBitbucketAction(options: {
|
||||
? gitAuthorEmail
|
||||
: config.getOptionalString('scaffolder.defaultAuthor.email'),
|
||||
};
|
||||
const signingKey =
|
||||
integrationConfig.config.commitSigningKey ??
|
||||
config.getOptionalString('scaffolder.defaultCommitSigningKey');
|
||||
if (signCommit && !signingKey) {
|
||||
throw new Error(
|
||||
'Signing commits is enabled but no signing key is provided in the configuration',
|
||||
);
|
||||
}
|
||||
|
||||
let auth;
|
||||
|
||||
@@ -409,6 +424,7 @@ export function createPublishBitbucketAction(options: {
|
||||
? gitCommitMessage
|
||||
: config.getOptionalString('scaffolder.defaultCommitMessage'),
|
||||
gitAuthorInfo,
|
||||
signingKey: signCommit ? signingKey : undefined,
|
||||
});
|
||||
|
||||
if (enableLFS && host !== 'bitbucket.org') {
|
||||
|
||||
@@ -22,6 +22,7 @@ export function createPublishGerritAction(options: {
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
sourcePath?: string;
|
||||
signCommit?: boolean;
|
||||
},
|
||||
JsonObject
|
||||
>;
|
||||
@@ -38,6 +39,7 @@ export function createPublishGerritReviewAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
signCommit?: boolean;
|
||||
},
|
||||
JsonObject
|
||||
>;
|
||||
|
||||
@@ -24,8 +24,8 @@ import {
|
||||
} from '@backstage/integration';
|
||||
import {
|
||||
createTemplateAction,
|
||||
initRepoAndPush,
|
||||
getRepoSourceDirectory,
|
||||
initRepoAndPush,
|
||||
parseRepoUrl,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
import { examples } from './gerrit.examples';
|
||||
@@ -99,6 +99,7 @@ export function createPublishGerritAction(options: {
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
sourcePath?: string;
|
||||
signCommit?: boolean;
|
||||
}>({
|
||||
id: 'publish:gerrit',
|
||||
supportsDryRun: true,
|
||||
@@ -143,6 +144,11 @@ export function createPublishGerritAction(options: {
|
||||
type: 'string',
|
||||
description: `Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.`,
|
||||
},
|
||||
signCommit: {
|
||||
title: 'Sign commit',
|
||||
type: 'boolean',
|
||||
description: 'Sign commit with configured PGP private key',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
@@ -172,6 +178,7 @@ export function createPublishGerritAction(options: {
|
||||
gitAuthorEmail,
|
||||
gitCommitMessage = 'initial commit',
|
||||
sourcePath,
|
||||
signCommit,
|
||||
} = ctx.input;
|
||||
const { repo, host, owner, workspace } = parseRepoUrl(
|
||||
repoUrl,
|
||||
@@ -233,6 +240,15 @@ export function createPublishGerritAction(options: {
|
||||
email: gitEmail,
|
||||
};
|
||||
|
||||
const signingKey =
|
||||
integrationConfig.config.commitSigningKey ??
|
||||
config.getOptionalString('scaffolder.defaultCommitSigningKey');
|
||||
if (signCommit && !signingKey) {
|
||||
throw new Error(
|
||||
'Signing commits is enabled but no signing key is provided in the configuration',
|
||||
);
|
||||
}
|
||||
|
||||
const commitResult = await initRepoAndPush({
|
||||
dir: getRepoSourceDirectory(ctx.workspacePath, sourcePath),
|
||||
remoteUrl,
|
||||
@@ -241,6 +257,7 @@ export function createPublishGerritAction(options: {
|
||||
logger: ctx.logger,
|
||||
commitMessage: generateCommitMessage(config, gitCommitMessage),
|
||||
gitAuthorInfo,
|
||||
signingKey: signCommit ? signingKey : undefined,
|
||||
});
|
||||
|
||||
ctx.output('remoteUrl', remoteUrl);
|
||||
|
||||
@@ -19,8 +19,8 @@ import { InputError } from '@backstage/errors';
|
||||
import { Config } from '@backstage/config';
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import {
|
||||
createTemplateAction,
|
||||
commitAndPushRepo,
|
||||
createTemplateAction,
|
||||
getRepoSourceDirectory,
|
||||
parseRepoUrl,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
@@ -48,6 +48,7 @@ export function createPublishGerritReviewAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
signCommit?: boolean;
|
||||
}>({
|
||||
id: 'publish:gerrit:review',
|
||||
description: 'Creates a new Gerrit review.',
|
||||
@@ -88,6 +89,11 @@ export function createPublishGerritReviewAction(options: {
|
||||
type: 'string',
|
||||
description: `Sets the default author email for the commit.`,
|
||||
},
|
||||
signCommit: {
|
||||
title: 'Sign commit',
|
||||
type: 'boolean',
|
||||
description: 'Sign commit with configured PGP private key',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
@@ -112,6 +118,7 @@ export function createPublishGerritReviewAction(options: {
|
||||
gitAuthorName,
|
||||
gitAuthorEmail,
|
||||
gitCommitMessage,
|
||||
signCommit,
|
||||
} = ctx.input;
|
||||
const { host, repo } = parseRepoUrl(repoUrl, integrations);
|
||||
|
||||
@@ -139,6 +146,14 @@ export function createPublishGerritReviewAction(options: {
|
||||
? gitAuthorEmail
|
||||
: config.getOptionalString('scaffolder.defaultAuthor.email'),
|
||||
};
|
||||
const signingKey =
|
||||
integrationConfig.config.commitSigningKey ??
|
||||
config.getOptionalString('scaffolder.defaultCommitSigningKey');
|
||||
if (signCommit && !signingKey) {
|
||||
throw new Error(
|
||||
'Signing commits is enabled but no signing key is provided in the configuration',
|
||||
);
|
||||
}
|
||||
const changeId = generateGerritChangeId();
|
||||
const commitMessage = `${gitCommitMessage}\n\nChange-Id: ${changeId}`;
|
||||
|
||||
@@ -150,6 +165,7 @@ export function createPublishGerritReviewAction(options: {
|
||||
gitAuthorInfo,
|
||||
branch,
|
||||
remoteRef: `refs/for/${branch}`,
|
||||
signingKey: signCommit ? signingKey : undefined,
|
||||
});
|
||||
|
||||
const repoContentsUrl = `${integrationConfig.config.gitilesBaseUrl}/${repo}/+/refs/heads/${branch}`;
|
||||
|
||||
@@ -23,6 +23,7 @@ export function createPublishGiteaAction(options: {
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
sourcePath?: string;
|
||||
signCommit?: boolean;
|
||||
},
|
||||
JsonObject
|
||||
>;
|
||||
|
||||
@@ -219,6 +219,7 @@ export function createPublishGiteaAction(options: {
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
sourcePath?: string;
|
||||
signCommit?: boolean;
|
||||
}>({
|
||||
id: 'publish:gitea',
|
||||
description:
|
||||
@@ -268,6 +269,11 @@ export function createPublishGiteaAction(options: {
|
||||
type: 'string',
|
||||
description: `Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the repository.`,
|
||||
},
|
||||
signCommit: {
|
||||
title: 'Sign commit',
|
||||
type: 'boolean',
|
||||
description: 'Sign commit with configured PGP private key',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
@@ -298,6 +304,7 @@ export function createPublishGiteaAction(options: {
|
||||
gitAuthorEmail,
|
||||
gitCommitMessage = 'initial commit',
|
||||
sourcePath,
|
||||
signCommit,
|
||||
} = ctx.input;
|
||||
|
||||
const { repo, host, owner } = parseRepoUrl(repoUrl, integrations);
|
||||
@@ -338,6 +345,16 @@ export function createPublishGiteaAction(options: {
|
||||
? gitAuthorEmail
|
||||
: config.getOptionalString('scaffolder.defaultAuthor.email'),
|
||||
};
|
||||
|
||||
const signingKey =
|
||||
integrationConfig.config.commitSigningKey ??
|
||||
config.getOptionalString('scaffolder.defaultCommitSigningKey');
|
||||
if (signCommit && !signingKey) {
|
||||
throw new Error(
|
||||
'Signing commits is enabled but no signing key is provided in the configuration',
|
||||
);
|
||||
}
|
||||
|
||||
// The owner to be used should be either the org name or user authenticated with the gitea server
|
||||
const remoteUrl = `${integrationConfig.config.baseUrl}/${owner}/${repo}.git`;
|
||||
const commitResult = await initRepoAndPush({
|
||||
|
||||
@@ -144,6 +144,7 @@ export function createPublishGitlabAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
signCommit?: boolean;
|
||||
setUserAsOwner?: boolean;
|
||||
topics?: string[];
|
||||
settings?: {
|
||||
|
||||
@@ -75,6 +75,7 @@ describe('publish:gitlab', () => {
|
||||
host: 'gitlab.com',
|
||||
token: 'tokenlols',
|
||||
apiBaseUrl: 'https://api.gitlab.com',
|
||||
commitSigningKey: 'test-signing-key',
|
||||
},
|
||||
{
|
||||
host: 'hosted.gitlab.com',
|
||||
@@ -470,6 +471,31 @@ describe('publish:gitlab', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should call initRepoAndPush with the signing key', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
...mockContext,
|
||||
input: { ...mockContext.input, signCommit: true },
|
||||
});
|
||||
|
||||
expect(initRepoAndPush).toHaveBeenCalledWith({
|
||||
dir: mockContext.workspacePath,
|
||||
defaultBranch: 'master',
|
||||
remoteUrl: 'http://mockurl.git',
|
||||
auth: { username: 'oauth2', password: 'tokenlols' },
|
||||
logger: mockContext.logger,
|
||||
commitMessage: 'initial commit',
|
||||
gitAuthorInfo: {},
|
||||
signingKey: 'test-signing-key',
|
||||
});
|
||||
});
|
||||
|
||||
it('should not call initRepoAndPush when sourcePath is false', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
import { Gitlab, VariableType } from '@gitbeaker/rest';
|
||||
import {
|
||||
initRepoAndPush,
|
||||
createTemplateAction,
|
||||
getRepoSourceDirectory,
|
||||
initRepoAndPush,
|
||||
parseRepoUrl,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
import { Gitlab, VariableType } from '@gitbeaker/rest';
|
||||
import { Config } from '@backstage/config';
|
||||
import { examples } from './gitlab.examples';
|
||||
|
||||
@@ -49,6 +49,7 @@ export function createPublishGitlabAction(options: {
|
||||
gitCommitMessage?: string;
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
signCommit?: boolean;
|
||||
setUserAsOwner?: boolean;
|
||||
/** @deprecated in favour of settings.topics field */
|
||||
topics?: string[];
|
||||
@@ -122,6 +123,11 @@ export function createPublishGitlabAction(options: {
|
||||
type: 'string',
|
||||
description: `Sets the default author email for the commit.`,
|
||||
},
|
||||
signCommit: {
|
||||
title: 'Sign commit',
|
||||
type: 'boolean',
|
||||
description: 'Sign commit with configured PGP private key',
|
||||
},
|
||||
sourcePath: {
|
||||
title: 'Source Path',
|
||||
description:
|
||||
@@ -349,6 +355,7 @@ export function createPublishGitlabAction(options: {
|
||||
branches = [],
|
||||
projectVariables = [],
|
||||
skipExisting = false,
|
||||
signCommit,
|
||||
} = ctx.input;
|
||||
const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);
|
||||
|
||||
@@ -452,6 +459,15 @@ export function createPublishGitlabAction(options: {
|
||||
? gitAuthorEmail
|
||||
: config.getOptionalString('scaffolder.defaultAuthor.email'),
|
||||
};
|
||||
const signingKey =
|
||||
integrationConfig.config.commitSigningKey ??
|
||||
config.getOptionalString('scaffolder.defaultCommitSigningKey');
|
||||
if (signCommit && !signingKey) {
|
||||
throw new Error(
|
||||
'Signing commits is enabled but no signing key is provided in the configuration',
|
||||
);
|
||||
}
|
||||
|
||||
const shouldSkipPublish =
|
||||
typeof ctx.input.sourcePath === 'boolean' && !ctx.input.sourcePath;
|
||||
if (!shouldSkipPublish) {
|
||||
@@ -474,6 +490,7 @@ export function createPublishGitlabAction(options: {
|
||||
? gitCommitMessage
|
||||
: config.getOptionalString('scaffolder.defaultCommitMessage'),
|
||||
gitAuthorInfo,
|
||||
signingKey: signCommit ? signingKey : undefined,
|
||||
});
|
||||
|
||||
if (branches) {
|
||||
|
||||
+5
@@ -27,6 +27,11 @@ export interface Config {
|
||||
email?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Default PGP signing key for signing commits.
|
||||
* @visibility secret
|
||||
*/
|
||||
defaultCommitSigningKey?: string;
|
||||
/**
|
||||
* The commit message used when new components are created.
|
||||
*/
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"@backstage/integration": "workspace:^",
|
||||
"@backstage/plugin-scaffolder-common": "workspace:^",
|
||||
"@backstage/types": "workspace:^",
|
||||
"@isomorphic-git/pgp-plugin": "^0.0.7",
|
||||
"concat-stream": "^2.0.0",
|
||||
"fs-extra": "^11.2.0",
|
||||
"globby": "^11.0.0",
|
||||
|
||||
@@ -106,6 +106,7 @@ export function commitAndPushBranch(options: {
|
||||
branch?: string;
|
||||
remoteRef?: string;
|
||||
remote?: string;
|
||||
signingKey?: string;
|
||||
}): Promise<{
|
||||
commitHash: string;
|
||||
}>;
|
||||
@@ -129,6 +130,7 @@ export function commitAndPushRepo(input: {
|
||||
};
|
||||
branch?: string;
|
||||
remoteRef?: string;
|
||||
signingKey?: string;
|
||||
}): Promise<{
|
||||
commitHash: string;
|
||||
}>;
|
||||
@@ -242,6 +244,7 @@ export function initRepoAndPush(input: {
|
||||
name?: string;
|
||||
email?: string;
|
||||
};
|
||||
signingKey?: string;
|
||||
}): Promise<{
|
||||
commitHash: string;
|
||||
}>;
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
|
||||
import { Git } from '../scm';
|
||||
import {
|
||||
commitAndPushRepo,
|
||||
initRepoAndPush,
|
||||
commitAndPushBranch,
|
||||
addFiles,
|
||||
createBranch,
|
||||
cloneRepo,
|
||||
commitAndPushBranch,
|
||||
commitAndPushRepo,
|
||||
createBranch,
|
||||
initRepoAndPush,
|
||||
} from './gitHelpers';
|
||||
import { mockServices } from '@backstage/backend-test-utils';
|
||||
import { loggerToWinstonLogger } from './loggerToWinstonLogger';
|
||||
@@ -224,6 +224,32 @@ describe('commitAndPushRepo', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('creates commit with signing key', async () => {
|
||||
await commitAndPushRepo({
|
||||
dir: '/test/repo/dir/',
|
||||
auth: {
|
||||
username: 'test-user',
|
||||
password: 'test-password',
|
||||
},
|
||||
logger: loggerToWinstonLogger(mockServices.logger.mock()),
|
||||
commitMessage: 'commit message',
|
||||
signingKey: 'test-signing-key',
|
||||
});
|
||||
expect(mockedGit.commit).toHaveBeenCalledWith({
|
||||
dir: '/test/repo/dir/',
|
||||
message: 'commit message',
|
||||
author: {
|
||||
name: 'Scaffolder',
|
||||
email: 'scaffolder@backstage.io',
|
||||
},
|
||||
committer: {
|
||||
name: 'Scaffolder',
|
||||
email: 'scaffolder@backstage.io',
|
||||
},
|
||||
signingKey: 'test-signing-key',
|
||||
});
|
||||
});
|
||||
|
||||
it('pushes to the remote', () => {
|
||||
expect(mockedGit.push).toHaveBeenCalledWith({
|
||||
dir: '/test/repo/dir/',
|
||||
|
||||
@@ -31,6 +31,7 @@ export async function initRepoAndPush(input: {
|
||||
defaultBranch?: string;
|
||||
commitMessage?: string;
|
||||
gitAuthorInfo?: { name?: string; email?: string };
|
||||
signingKey?: string;
|
||||
}): Promise<{ commitHash: string }> {
|
||||
const {
|
||||
dir,
|
||||
@@ -40,6 +41,7 @@ export async function initRepoAndPush(input: {
|
||||
defaultBranch = 'master',
|
||||
commitMessage = 'Initial commit',
|
||||
gitAuthorInfo,
|
||||
signingKey,
|
||||
} = input;
|
||||
const git = Git.fromAuth({
|
||||
...auth,
|
||||
@@ -64,6 +66,7 @@ export async function initRepoAndPush(input: {
|
||||
message: commitMessage,
|
||||
author: authorInfo,
|
||||
committer: authorInfo,
|
||||
signingKey,
|
||||
});
|
||||
|
||||
await git.push({
|
||||
@@ -89,6 +92,7 @@ export async function commitAndPushRepo(input: {
|
||||
gitAuthorInfo?: { name?: string; email?: string };
|
||||
branch?: string;
|
||||
remoteRef?: string;
|
||||
signingKey?: string;
|
||||
}): Promise<{ commitHash: string }> {
|
||||
const {
|
||||
dir,
|
||||
@@ -98,6 +102,7 @@ export async function commitAndPushRepo(input: {
|
||||
gitAuthorInfo,
|
||||
branch = 'master',
|
||||
remoteRef,
|
||||
signingKey,
|
||||
} = input;
|
||||
|
||||
const git = Git.fromAuth({
|
||||
@@ -120,6 +125,7 @@ export async function commitAndPushRepo(input: {
|
||||
message: commitMessage,
|
||||
author: authorInfo,
|
||||
committer: authorInfo,
|
||||
signingKey,
|
||||
});
|
||||
|
||||
await git.push({
|
||||
@@ -213,6 +219,7 @@ export async function commitAndPushBranch(options: {
|
||||
branch?: string;
|
||||
remoteRef?: string;
|
||||
remote?: string;
|
||||
signingKey?: string;
|
||||
}): Promise<{ commitHash: string }> {
|
||||
const {
|
||||
dir,
|
||||
@@ -223,6 +230,7 @@ export async function commitAndPushBranch(options: {
|
||||
branch = 'master',
|
||||
remoteRef,
|
||||
remote = 'origin',
|
||||
signingKey,
|
||||
} = options;
|
||||
const git = Git.fromAuth({
|
||||
...auth,
|
||||
@@ -240,6 +248,7 @@ export async function commitAndPushBranch(options: {
|
||||
message: commitMessage,
|
||||
author: authorInfo,
|
||||
committer: authorInfo,
|
||||
signingKey,
|
||||
});
|
||||
|
||||
await git.push({
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
jest.mock('isomorphic-git');
|
||||
jest.mock('isomorphic-git/http/node');
|
||||
jest.mock('fs-extra');
|
||||
jest.mock('@isomorphic-git/pgp-plugin', () => ({
|
||||
...jest.requireActual('@isomorphic-git/pgp-plugin'),
|
||||
pgp: {
|
||||
sign: jest.fn().mockResolvedValue({ signature: 'sign' }),
|
||||
},
|
||||
}));
|
||||
|
||||
import * as isomorphic from 'isomorphic-git';
|
||||
import { Git } from './git';
|
||||
@@ -140,8 +146,9 @@ describe('Git', () => {
|
||||
name: 'comitter',
|
||||
email: 'test@backstage.io',
|
||||
};
|
||||
const signingKey = 'test-signing-key';
|
||||
|
||||
await git.commit({ dir, message, author, committer });
|
||||
await git.commit({ dir, message, author, committer, signingKey });
|
||||
|
||||
expect(isomorphic.commit).toHaveBeenCalledWith({
|
||||
fs,
|
||||
@@ -149,6 +156,8 @@ describe('Git', () => {
|
||||
message,
|
||||
author,
|
||||
committer,
|
||||
signingKey,
|
||||
onSign: expect.any(Function),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,14 +15,16 @@
|
||||
*/
|
||||
|
||||
import git, {
|
||||
ProgressCallback,
|
||||
MergeResult,
|
||||
ReadCommitResult,
|
||||
AuthCallback,
|
||||
MergeResult,
|
||||
ProgressCallback,
|
||||
ReadCommitResult,
|
||||
} from 'isomorphic-git';
|
||||
import http from 'isomorphic-git/http/node';
|
||||
import fs from 'fs-extra';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
// @ts-ignore
|
||||
import { pgp } from '@isomorphic-git/pgp-plugin';
|
||||
|
||||
function isAuthCallbackOptions(
|
||||
options: StaticAuthOptions | AuthCallbackOptions,
|
||||
@@ -137,12 +139,21 @@ export class Git {
|
||||
message: string;
|
||||
author: { name: string; email: string };
|
||||
committer: { name: string; email: string };
|
||||
signingKey?: string;
|
||||
}): Promise<string> {
|
||||
const { dir, message, author, committer } = options;
|
||||
const { dir, message, author, committer, signingKey } = options;
|
||||
this.config.logger?.info(
|
||||
`Committing file to repo {dir=${dir},message=${message}}`,
|
||||
);
|
||||
return git.commit({ fs, dir, message, author, committer });
|
||||
return git.commit({
|
||||
fs,
|
||||
dir,
|
||||
message,
|
||||
author,
|
||||
committer,
|
||||
signingKey,
|
||||
onSign: signingKey ? pgp.sign : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
/** https://isomorphic-git.org/docs/en/clone */
|
||||
@@ -241,8 +252,9 @@ export class Git {
|
||||
ours?: string;
|
||||
author: { name: string; email: string };
|
||||
committer: { name: string; email: string };
|
||||
signingKey?: string;
|
||||
}): Promise<MergeResult> {
|
||||
const { dir, theirs, ours, author, committer } = options;
|
||||
const { dir, theirs, ours, author, committer, signingKey } = options;
|
||||
this.config.logger?.info(
|
||||
`Merging branch '${theirs}' into '${ours}' for repository {dir=${dir}}`,
|
||||
);
|
||||
@@ -255,6 +267,8 @@ export class Git {
|
||||
theirs,
|
||||
author,
|
||||
committer,
|
||||
signingKey,
|
||||
onSign: signingKey ? pgp.sign : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -7794,6 +7794,7 @@ __metadata:
|
||||
"@backstage/integration": "workspace:^"
|
||||
"@backstage/plugin-scaffolder-common": "workspace:^"
|
||||
"@backstage/types": "workspace:^"
|
||||
"@isomorphic-git/pgp-plugin": ^0.0.7
|
||||
concat-stream: ^2.0.0
|
||||
fs-extra: ^11.2.0
|
||||
globby: ^11.0.0
|
||||
@@ -10933,6 +10934,59 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@isomorphic-git/pgp-plugin@npm:^0.0.7":
|
||||
version: 0.0.7
|
||||
resolution: "@isomorphic-git/pgp-plugin@npm:0.0.7"
|
||||
dependencies:
|
||||
"@isomorphic-pgp/sign-and-verify": ^0.0.10
|
||||
"@isomorphic-pgp/util": ^0.0.6
|
||||
checksum: 5361b4e58933f87747607b4bcfdf7ce2e4d75f591d5839ecd313fba55196020ee0e867c307fbfa2cd0aa85442942a5efca40653dfac0acabe8043e80f1dbebc1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@isomorphic-pgp/parser@npm:^0.0.3":
|
||||
version: 0.0.3
|
||||
resolution: "@isomorphic-pgp/parser@npm:0.0.3"
|
||||
dependencies:
|
||||
array-buffer-to-hex: ^1.0.0
|
||||
base64-js: ^1.3.0
|
||||
bn.js: ^4.11.8
|
||||
clz-buffer: ^1.0.0
|
||||
concat-buffers: ^1.0.0
|
||||
crc: ^3.8.0
|
||||
isomorphic-textencoder: ^1.0.1
|
||||
select-case: ^1.0.0
|
||||
checksum: 3ddfb1d39e7a9c0da98940c95bf2a9b7a59819a1ee0a4839fcbf3152c386aa974a16854043e6cd5f987db2f9475b480c10f3ef5686f0da1495675cb399cdd22f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@isomorphic-pgp/sign-and-verify@npm:^0.0.10":
|
||||
version: 0.0.10
|
||||
resolution: "@isomorphic-pgp/sign-and-verify@npm:0.0.10"
|
||||
dependencies:
|
||||
"@isomorphic-pgp/parser": ^0.0.3
|
||||
"@isomorphic-pgp/util": ^0.0.6
|
||||
"@wmhilton/crypto-hash": ^1.0.2
|
||||
array-buffer-to-hex: ^1.0.0
|
||||
isomorphic-textencoder: ^1.0.1
|
||||
jsbn: ^1.1.0
|
||||
sha.js: ^2.4.11
|
||||
checksum: 3d43408abdb0d53c4514797ef47ec1d8f634e4a6b4a80f0df9ac826b9ba51df1a9cedcb26f7ddbee4594827de9676d7cda57549d321ea87bc95facfaa7127146
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@isomorphic-pgp/util@npm:^0.0.6":
|
||||
version: 0.0.6
|
||||
resolution: "@isomorphic-pgp/util@npm:0.0.6"
|
||||
dependencies:
|
||||
"@isomorphic-pgp/parser": ^0.0.3
|
||||
array-buffer-to-hex: ^1.0.0
|
||||
concat-buffers: ^1.0.0
|
||||
sha.js: ^2.4.11
|
||||
checksum: 721a15ddb4597f90b7b897b2d18a5819e86988ac44510f9aee9dc6a7823a62c3f1ba5b12eb35792c803b3b1c6d4af924ae0bc31123f21fbc6f5a8e8e7962a412
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@istanbuljs/load-nyc-config@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "@istanbuljs/load-nyc-config@npm:1.0.0"
|
||||
@@ -21814,6 +21868,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@wmhilton/crypto-hash@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "@wmhilton/crypto-hash@npm:1.0.2"
|
||||
checksum: 99c7e46856d75dbd828922ed8088dcd85ac405d58976f785e3d3062e3e4044b11073ef43a6c74976d42abd2c320820993afcd6a1d41db22f19bf7a9fe5557140
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@xmldom/is-dom-node@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@xmldom/is-dom-node@npm:1.0.1"
|
||||
@@ -23063,6 +23124,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"array-buffer-to-hex@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "array-buffer-to-hex@npm:1.0.0"
|
||||
checksum: 8de16fbb42fc79c839e5579e3e7dbf9a36dfa52cfcb4c0576a0e9cc6eeb5bf3f066b671858a292c97fcf9bd117c6eebc121085325e836dfb62b2737babd29264
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"array-differ@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "array-differ@npm:3.0.0"
|
||||
@@ -23989,7 +24057,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.9":
|
||||
"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.8, bn.js@npm:^4.11.9":
|
||||
version: 4.12.0
|
||||
resolution: "bn.js@npm:4.12.0"
|
||||
checksum: 39afb4f15f4ea537b55eaf1446c896af28ac948fdcf47171961475724d1bb65118cca49fa6e3d67706e4790955ec0e74de584e45c8f1ef89f46c812bee5b5a12
|
||||
@@ -24314,7 +24382,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"buffer@npm:^5.5.0, buffer@npm:^5.7.1":
|
||||
"buffer@npm:^5.1.0, buffer@npm:^5.5.0, buffer@npm:^5.7.1":
|
||||
version: 5.7.1
|
||||
resolution: "buffer@npm:5.7.1"
|
||||
dependencies:
|
||||
@@ -25153,6 +25221,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"clz-buffer@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "clz-buffer@npm:1.0.0"
|
||||
checksum: 00a177ec2e7732e2c6393e3825de5f9d4a530d77fefb1797cdf1782a3d72407c43941e0c30d4511dd6c0536ed0652cf17d356ce8408e4c3234e80e1d5c88e980
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cmd-extension@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "cmd-extension@npm:1.0.2"
|
||||
@@ -25541,6 +25616,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"concat-buffers@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "concat-buffers@npm:1.0.0"
|
||||
checksum: 5b1d0215687a1ab27d9181d9a5036664e0f86f7da5bda5a9e446962572736e5c345eb3ca40b7d276198efad703754f8870fd216e70a36990d231b0b27c5fe9d7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"concat-map@npm:0.0.1":
|
||||
version: 0.0.1
|
||||
resolution: "concat-map@npm:0.0.1"
|
||||
@@ -25942,6 +26024,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"crc@npm:^3.8.0":
|
||||
version: 3.8.0
|
||||
resolution: "crc@npm:3.8.0"
|
||||
dependencies:
|
||||
buffer: ^5.1.0
|
||||
checksum: dabbc4eba223b206068b92ca82bb471d583eb6be2384a87f5c3712730cfd6ba4b13a45e8ba3ef62174d5a781a2c5ac5c20bf36cf37bba73926899bd0aa19186f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"create-ecdh@npm:^4.0.4":
|
||||
version: 4.0.4
|
||||
resolution: "create-ecdh@npm:4.0.4"
|
||||
@@ -29389,6 +29480,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-text-encoding@npm:^1.0.0":
|
||||
version: 1.0.6
|
||||
resolution: "fast-text-encoding@npm:1.0.6"
|
||||
checksum: 9d58f694314b3283e785bf61954902536da228607ad246905e30256f9ab8331f780ac987e7222c9f5eafd04168d07e12b8054c85cedb76a2c05af0e82387a903
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-uri@npm:^3.0.1":
|
||||
version: 3.0.1
|
||||
resolution: "fast-uri@npm:3.0.1"
|
||||
@@ -33010,6 +33108,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"isomorphic-textencoder@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "isomorphic-textencoder@npm:1.0.1"
|
||||
dependencies:
|
||||
fast-text-encoding: ^1.0.0
|
||||
checksum: 9bd0c04bff7b1dc9e410d2f9a2705ca4cc288872929d88fbb7758f06b5147de8dbaea5f95ce6cf4d314f064643f3d42d69a07bbb68df0261e81153d2d56f77f3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"isomorphic-timers-promises@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "isomorphic-timers-promises@npm:1.0.1"
|
||||
@@ -33807,7 +33914,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jsbn@npm:1.1.0":
|
||||
"jsbn@npm:1.1.0, jsbn@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "jsbn@npm:1.1.0"
|
||||
checksum: 944f924f2bd67ad533b3850eee47603eed0f6ae425fd1ee8c760f477e8c34a05f144c1bd4f5a5dd1963141dc79a2c55f89ccc5ab77d039e7077f3ad196b64965
|
||||
@@ -43006,6 +43113,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"select-case@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "select-case@npm:1.0.0"
|
||||
checksum: 19cf1c8fd16ae4b811dea9fc4a11860dc764b9f7d2e6f7c8910814d91617e0d0d508ce2186aa9f99a3708834caf261e963769fed3a313552e1dae3d28d64042a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"select-hose@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "select-hose@npm:2.0.0"
|
||||
|
||||
Reference in New Issue
Block a user