use configured git author in scaffolder actions
Co-authored-by: Himanshu Mishra <himanshu@orkohunter.net> Signed-off-by: Chase Rutherford-Jenkins <chaseajen@users.noreply.github.com>
This commit is contained in:
@@ -116,6 +116,7 @@ export const createBuiltinActions: (options: {
|
||||
integrations: ScmIntegrations;
|
||||
catalogClient: CatalogApi;
|
||||
templaters: TemplaterBuilder;
|
||||
config: Config;
|
||||
}) => TemplateAction<any>[];
|
||||
|
||||
// @public (undocumented)
|
||||
@@ -155,11 +156,13 @@ export function createLegacyActions(options: Options): TemplateAction<any>[];
|
||||
// @public (undocumented)
|
||||
export function createPublishAzureAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}): TemplateAction<any>;
|
||||
|
||||
// @public (undocumented)
|
||||
export function createPublishBitbucketAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}): TemplateAction<any>;
|
||||
|
||||
// @public
|
||||
@@ -168,6 +171,7 @@ export function createPublishFileAction(): TemplateAction<any>;
|
||||
// @public (undocumented)
|
||||
export function createPublishGithubAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}): TemplateAction<any>;
|
||||
|
||||
// @public (undocumented)
|
||||
@@ -176,6 +180,7 @@ export const createPublishGithubPullRequestAction: ({ integrations, clientFactor
|
||||
// @public (undocumented)
|
||||
export function createPublishGitlabAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}): TemplateAction<any>;
|
||||
|
||||
// @public (undocumented)
|
||||
|
||||
+9
@@ -17,6 +17,15 @@
|
||||
export interface Config {
|
||||
/** Configuration options for the scaffolder plugin */
|
||||
scaffolder?: {
|
||||
git?: {
|
||||
/**
|
||||
* The commit author info used when new components are created.
|
||||
*/
|
||||
author?: {
|
||||
name?: string;
|
||||
email?: string;
|
||||
};
|
||||
};
|
||||
github?: {
|
||||
[key: string]: string;
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import { UrlReader } from '@backstage/backend-common';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { Config } from '@backstage/config';
|
||||
import { TemplaterBuilder } from '../../stages';
|
||||
import {
|
||||
createCatalogRegisterAction,
|
||||
@@ -41,8 +42,9 @@ export const createBuiltinActions = (options: {
|
||||
integrations: ScmIntegrations;
|
||||
catalogClient: CatalogApi;
|
||||
templaters: TemplaterBuilder;
|
||||
config: Config;
|
||||
}) => {
|
||||
const { reader, integrations, templaters, catalogClient } = options;
|
||||
const { reader, integrations, templaters, catalogClient, config } = options;
|
||||
|
||||
return [
|
||||
createFetchPlainAction({
|
||||
@@ -56,18 +58,22 @@ export const createBuiltinActions = (options: {
|
||||
}),
|
||||
createPublishGithubAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishGithubPullRequestAction({
|
||||
integrations,
|
||||
}),
|
||||
createPublishGitlabAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishBitbucketAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishAzureAction({
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createDebugLogAction(),
|
||||
createCatalogRegisterAction({ catalogClient, integrations }),
|
||||
|
||||
@@ -28,17 +28,17 @@ import { PassThrough } from 'stream';
|
||||
import { initRepoAndPush } from '../../../stages/publish/helpers';
|
||||
|
||||
describe('publish:azure', () => {
|
||||
const integrations = ScmIntegrations.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {
|
||||
azure: [
|
||||
{ host: 'dev.azure.com', token: 'tokenlols' },
|
||||
{ host: 'myazurehostnotoken.com' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
);
|
||||
const action = createPublishAzureAction({ integrations });
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
azure: [
|
||||
{ host: 'dev.azure.com', token: 'tokenlols' },
|
||||
{ host: 'myazurehostnotoken.com' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
const action = createPublishAzureAction({ integrations, config });
|
||||
const mockContext = {
|
||||
input: {
|
||||
repoUrl: 'dev.azure.com?repo=repo&owner=owner&organization=org',
|
||||
@@ -187,6 +187,7 @@ describe('publish:azure', () => {
|
||||
defaultBranch: 'master',
|
||||
auth: { username: 'notempty', password: 'tokenlols' },
|
||||
logger: mockContext.logger,
|
||||
gitAuthorInfo: {},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -21,11 +21,13 @@ import { GitRepositoryCreateOptions } from 'azure-devops-node-api/interfaces/Git
|
||||
import { getPersonalAccessTokenHandler, WebApi } from 'azure-devops-node-api';
|
||||
import { getRepoSourceDirectory, parseRepoUrl } from './util';
|
||||
import { createTemplateAction } from '../../createTemplateAction';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
export function createPublishAzureAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}) {
|
||||
const { integrations } = options;
|
||||
const { integrations, config } = options;
|
||||
|
||||
return createTemplateAction<{
|
||||
repoUrl: string;
|
||||
@@ -123,6 +125,11 @@ export function createPublishAzureAction(options: {
|
||||
// so it's just the base path I think
|
||||
const repoContentsUrl = remoteUrl;
|
||||
|
||||
const gitAuthorInfo = {
|
||||
name: config.getOptionalString('scaffolder.git.author.name'),
|
||||
email: config.getOptionalString('scaffolder.git.author.email'),
|
||||
};
|
||||
|
||||
await initRepoAndPush({
|
||||
dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),
|
||||
remoteUrl,
|
||||
@@ -132,6 +139,7 @@ export function createPublishAzureAction(options: {
|
||||
password: integrationConfig.config.token,
|
||||
},
|
||||
logger: ctx.logger,
|
||||
gitAuthorInfo,
|
||||
});
|
||||
|
||||
ctx.output('remoteUrl', remoteUrl);
|
||||
|
||||
+22
-21
@@ -26,27 +26,27 @@ import { PassThrough } from 'stream';
|
||||
import { initRepoAndPush } from '../../../stages/publish/helpers';
|
||||
|
||||
describe('publish:bitbucket', () => {
|
||||
const integrations = ScmIntegrations.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {
|
||||
bitbucket: [
|
||||
{
|
||||
host: 'bitbucket.org',
|
||||
token: 'tokenlols',
|
||||
},
|
||||
{
|
||||
host: 'hosted.bitbucket.com',
|
||||
token: 'thing',
|
||||
apiBaseUrl: 'https://hosted.bitbucket.com/rest/api/1.0',
|
||||
},
|
||||
{
|
||||
host: 'notoken.bitbucket.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
);
|
||||
const action = createPublishBitbucketAction({ integrations });
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
bitbucket: [
|
||||
{
|
||||
host: 'bitbucket.org',
|
||||
token: 'tokenlols',
|
||||
},
|
||||
{
|
||||
host: 'hosted.bitbucket.com',
|
||||
token: 'thing',
|
||||
apiBaseUrl: 'https://hosted.bitbucket.com/rest/api/1.0',
|
||||
},
|
||||
{
|
||||
host: 'notoken.bitbucket.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
const action = createPublishBitbucketAction({ integrations, config });
|
||||
const mockContext = {
|
||||
input: {
|
||||
repoUrl: 'bitbucket.org?repo=repo&owner=owner',
|
||||
@@ -331,6 +331,7 @@ describe('publish:bitbucket', () => {
|
||||
defaultBranch: 'main',
|
||||
auth: { username: 'x-token-auth', password: 'tokenlols' },
|
||||
logger: mockContext.logger,
|
||||
gitAuthorInfo: {},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import fetch from 'cross-fetch';
|
||||
import { initRepoAndPush } from '../../../stages/publish/helpers';
|
||||
import { createTemplateAction } from '../../createTemplateAction';
|
||||
import { getRepoSourceDirectory, parseRepoUrl } from './util';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
const createBitbucketCloudRepository = async (opts: {
|
||||
owner: string;
|
||||
@@ -184,8 +185,9 @@ const performEnableLFS = async (opts: {
|
||||
|
||||
export function createPublishBitbucketAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}) {
|
||||
const { integrations } = options;
|
||||
const { integrations, config } = options;
|
||||
|
||||
return createTemplateAction<{
|
||||
repoUrl: string;
|
||||
@@ -284,6 +286,11 @@ export function createPublishBitbucketAction(options: {
|
||||
apiBaseUrl,
|
||||
});
|
||||
|
||||
const gitAuthorInfo = {
|
||||
name: config.getOptionalString('scaffolder.git.author.name'),
|
||||
email: config.getOptionalString('scaffolder.git.author.email'),
|
||||
};
|
||||
|
||||
await initRepoAndPush({
|
||||
dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),
|
||||
remoteUrl,
|
||||
@@ -297,6 +304,7 @@ export function createPublishBitbucketAction(options: {
|
||||
},
|
||||
defaultBranch,
|
||||
logger: ctx.logger,
|
||||
gitAuthorInfo,
|
||||
});
|
||||
|
||||
if (enableLFS && host !== 'bitbucket.org') {
|
||||
|
||||
@@ -25,17 +25,17 @@ import { initRepoAndPush } from '../../../stages/publish/helpers';
|
||||
import { when } from 'jest-when';
|
||||
|
||||
describe('publish:github', () => {
|
||||
const integrations = ScmIntegrations.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {
|
||||
github: [
|
||||
{ host: 'github.com', token: 'tokenlols' },
|
||||
{ host: 'ghe.github.com' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
);
|
||||
const action = createPublishGithubAction({ integrations });
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
github: [
|
||||
{ host: 'github.com', token: 'tokenlols' },
|
||||
{ host: 'ghe.github.com' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
const action = createPublishGithubAction({ integrations, config });
|
||||
const mockContext = {
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
@@ -178,6 +178,7 @@ describe('publish:github', () => {
|
||||
defaultBranch: 'master',
|
||||
auth: { username: 'x-access-token', password: 'tokenlols' },
|
||||
logger: mockContext.logger,
|
||||
gitAuthorInfo: {},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -207,6 +208,7 @@ describe('publish:github', () => {
|
||||
defaultBranch: 'main',
|
||||
auth: { username: 'x-access-token', password: 'tokenlols' },
|
||||
logger: mockContext.logger,
|
||||
gitAuthorInfo: {},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -25,14 +25,16 @@ import {
|
||||
} from '../../../stages/publish/helpers';
|
||||
import { getRepoSourceDirectory, parseRepoUrl } from './util';
|
||||
import { createTemplateAction } from '../../createTemplateAction';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
type Permission = 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
|
||||
type Collaborator = { access: Permission; username: string };
|
||||
|
||||
export function createPublishGithubAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}) {
|
||||
const { integrations } = options;
|
||||
const { integrations, config } = options;
|
||||
|
||||
const credentialsProviders = new Map(
|
||||
integrations.github.list().map(integration => {
|
||||
@@ -248,6 +250,11 @@ export function createPublishGithubAction(options: {
|
||||
const remoteUrl = newRepo.clone_url;
|
||||
const repoContentsUrl = `${newRepo.html_url}/blob/${defaultBranch}`;
|
||||
|
||||
const gitAuthorInfo = {
|
||||
name: config.getOptionalString('scaffolder.git.author.name'),
|
||||
email: config.getOptionalString('scaffolder.git.author.email'),
|
||||
};
|
||||
|
||||
await initRepoAndPush({
|
||||
dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),
|
||||
remoteUrl,
|
||||
@@ -257,6 +264,7 @@ export function createPublishGithubAction(options: {
|
||||
password: token,
|
||||
},
|
||||
logger: ctx.logger,
|
||||
gitAuthorInfo,
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
@@ -24,24 +24,24 @@ import { PassThrough } from 'stream';
|
||||
import { initRepoAndPush } from '../../../stages/publish/helpers';
|
||||
|
||||
describe('publish:gitlab', () => {
|
||||
const integrations = ScmIntegrations.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {
|
||||
gitlab: [
|
||||
{
|
||||
host: 'gitlab.com',
|
||||
token: 'tokenlols',
|
||||
apiBaseUrl: 'https://api.gitlab.com',
|
||||
},
|
||||
{
|
||||
host: 'hosted.gitlab.com',
|
||||
apiBaseUrl: 'https://api.hosted.gitlab.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
);
|
||||
const action = createPublishGitlabAction({ integrations });
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
gitlab: [
|
||||
{
|
||||
host: 'gitlab.com',
|
||||
token: 'tokenlols',
|
||||
apiBaseUrl: 'https://api.gitlab.com',
|
||||
},
|
||||
{
|
||||
host: 'hosted.gitlab.com',
|
||||
apiBaseUrl: 'https://api.hosted.gitlab.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
const action = createPublishGitlabAction({ integrations, config });
|
||||
const mockContext = {
|
||||
input: {
|
||||
repoUrl: 'gitlab.com?repo=repo&owner=owner',
|
||||
@@ -166,6 +166,7 @@ describe('publish:gitlab', () => {
|
||||
remoteUrl: 'http://mockurl.git',
|
||||
auth: { username: 'oauth2', password: 'tokenlols' },
|
||||
logger: mockContext.logger,
|
||||
gitAuthorInfo: {},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -20,11 +20,13 @@ import { Gitlab } from '@gitbeaker/node';
|
||||
import { initRepoAndPush } from '../../../stages/publish/helpers';
|
||||
import { getRepoSourceDirectory, parseRepoUrl } from './util';
|
||||
import { createTemplateAction } from '../../createTemplateAction';
|
||||
import { Config } from '@backstage/config';
|
||||
|
||||
export function createPublishGitlabAction(options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
config: Config;
|
||||
}) {
|
||||
const { integrations } = options;
|
||||
const { integrations, config } = options;
|
||||
|
||||
return createTemplateAction<{
|
||||
repoUrl: string;
|
||||
@@ -121,6 +123,11 @@ export function createPublishGitlabAction(options: {
|
||||
const remoteUrl = (http_url_to_repo as string).replace(/\.git$/, '');
|
||||
const repoContentsUrl = `${remoteUrl}/-/blob/master`;
|
||||
|
||||
const gitAuthorInfo = {
|
||||
name: config.getOptionalString('scaffolder.git.author.name'),
|
||||
email: config.getOptionalString('scaffolder.git.author.email'),
|
||||
};
|
||||
|
||||
await initRepoAndPush({
|
||||
dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath),
|
||||
remoteUrl: http_url_to_repo as string,
|
||||
@@ -130,6 +137,7 @@ export function createPublishGitlabAction(options: {
|
||||
password: integrationConfig.config.token,
|
||||
},
|
||||
logger: ctx.logger,
|
||||
gitAuthorInfo,
|
||||
});
|
||||
|
||||
ctx.output('remoteUrl', remoteUrl);
|
||||
|
||||
@@ -25,12 +25,14 @@ export async function initRepoAndPush({
|
||||
auth,
|
||||
logger,
|
||||
defaultBranch = 'master',
|
||||
gitAuthorInfo,
|
||||
}: {
|
||||
dir: string;
|
||||
remoteUrl: string;
|
||||
auth: { username: string; password: string };
|
||||
logger: Logger;
|
||||
defaultBranch?: string;
|
||||
gitAuthorInfo?: { name?: string; email?: string };
|
||||
}): Promise<void> {
|
||||
const git = Git.fromAuth({
|
||||
username: auth.username,
|
||||
@@ -53,11 +55,17 @@ export async function initRepoAndPush({
|
||||
await git.add({ dir, filepath });
|
||||
}
|
||||
|
||||
// use provided info if possible, otherwise use fallbacks
|
||||
const authorInfo = {
|
||||
name: gitAuthorInfo?.name ?? 'Scaffolder',
|
||||
email: gitAuthorInfo?.email ?? 'scaffolder@backstage.io',
|
||||
};
|
||||
|
||||
await git.commit({
|
||||
dir,
|
||||
message: 'Initial commit',
|
||||
author: { name: 'Scaffolder', email: 'scaffolder@backstage.io' },
|
||||
committer: { name: 'Scaffolder', email: 'scaffolder@backstage.io' },
|
||||
author: authorInfo,
|
||||
committer: authorInfo,
|
||||
});
|
||||
|
||||
await git.addRemote({
|
||||
|
||||
@@ -129,6 +129,7 @@ export async function createRouter(
|
||||
catalogClient,
|
||||
templaters,
|
||||
reader,
|
||||
config,
|
||||
}),
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user