Merge pull request #4315 from n2ygk/scaffolder_repo_visibility
Add repoVisibility for other-than-GitHub repos
This commit is contained in:
+12
@@ -19,9 +19,17 @@ export interface Config {
|
||||
scaffolder?: {
|
||||
github?: {
|
||||
[key: string]: string;
|
||||
/**
|
||||
* The visibility to set on created repositories.
|
||||
*/
|
||||
visiblity?: 'public' | 'internal' | 'private';
|
||||
};
|
||||
gitlab?: {
|
||||
api: { [key: string]: string };
|
||||
/**
|
||||
* The visibility to set on created repositories.
|
||||
*/
|
||||
visiblity?: 'public' | 'internal' | 'private';
|
||||
};
|
||||
azure?: {
|
||||
baseUrl: string;
|
||||
@@ -29,6 +37,10 @@ export interface Config {
|
||||
};
|
||||
bitbucket?: {
|
||||
api: { [key: string]: string };
|
||||
/**
|
||||
* The visibility to set on created repositories.
|
||||
*/
|
||||
visiblity?: 'public' | 'private';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,11 +63,14 @@ describe('Bitbucket Publisher', () => {
|
||||
),
|
||||
);
|
||||
|
||||
const publisher = await BitbucketPublisher.fromConfig({
|
||||
host: 'bitbucket.org',
|
||||
username: 'fake-user',
|
||||
appPassword: 'fake-token',
|
||||
});
|
||||
const publisher = await BitbucketPublisher.fromConfig(
|
||||
{
|
||||
host: 'bitbucket.org',
|
||||
username: 'fake-user',
|
||||
appPassword: 'fake-token',
|
||||
},
|
||||
{ repoVisibility: 'private' },
|
||||
);
|
||||
|
||||
const result = await publisher.publish({
|
||||
values: {
|
||||
@@ -122,10 +125,13 @@ describe('Bitbucket Publisher', () => {
|
||||
),
|
||||
);
|
||||
|
||||
const publisher = await BitbucketPublisher.fromConfig({
|
||||
host: 'bitbucket.mycompany.com',
|
||||
token: 'fake-token',
|
||||
});
|
||||
const publisher = await BitbucketPublisher.fromConfig(
|
||||
{
|
||||
host: 'bitbucket.mycompany.com',
|
||||
token: 'fake-token',
|
||||
},
|
||||
{ repoVisibility: 'private' },
|
||||
);
|
||||
|
||||
const result = await publisher.publish({
|
||||
values: {
|
||||
|
||||
@@ -21,17 +21,23 @@ import { BitbucketIntegrationConfig } from '@backstage/integration';
|
||||
import parseGitUrl from 'git-url-parse';
|
||||
import path from 'path';
|
||||
|
||||
export type RepoVisibilityOptions = 'private' | 'public';
|
||||
|
||||
// TODO(blam): We should probably start to use a bitbucket client here that we can change
|
||||
// the baseURL to point at on-prem or public bitbucket versions like we do for
|
||||
// github and ghe. There's to much logic and not enough types here for us to say that this way is better than using
|
||||
// a supported bitbucket client if one exists.
|
||||
export class BitbucketPublisher implements PublisherBase {
|
||||
static async fromConfig(config: BitbucketIntegrationConfig) {
|
||||
static async fromConfig(
|
||||
config: BitbucketIntegrationConfig,
|
||||
{ repoVisibility }: { repoVisibility: RepoVisibilityOptions },
|
||||
) {
|
||||
return new BitbucketPublisher({
|
||||
host: config.host,
|
||||
token: config.token,
|
||||
appPassword: config.appPassword,
|
||||
username: config.username,
|
||||
repoVisibility,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -41,6 +47,7 @@ export class BitbucketPublisher implements PublisherBase {
|
||||
token?: string;
|
||||
appPassword?: string;
|
||||
username?: string;
|
||||
repoVisibility: RepoVisibilityOptions;
|
||||
},
|
||||
) {}
|
||||
|
||||
@@ -101,6 +108,7 @@ export class BitbucketPublisher implements PublisherBase {
|
||||
body: JSON.stringify({
|
||||
scm: 'git',
|
||||
description: description,
|
||||
is_private: this.config.repoVisibility === 'private',
|
||||
}),
|
||||
headers: {
|
||||
Authorization: `Basic ${buffer.toString('base64')}`,
|
||||
@@ -144,6 +152,7 @@ export class BitbucketPublisher implements PublisherBase {
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
description: description,
|
||||
is_private: this.config.repoVisibility === 'private',
|
||||
}),
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.config.token}`,
|
||||
|
||||
@@ -54,11 +54,14 @@ describe('GitLab Publisher', () => {
|
||||
|
||||
describe('publish: createRemoteInGitLab', () => {
|
||||
it('should use gitbeaker to create a repo in a namespace if the namespace property is set', async () => {
|
||||
const publisher = await GitlabPublisher.fromConfig({
|
||||
host: 'gitlab.com',
|
||||
token: 'fake-token',
|
||||
baseUrl: 'https://gitlab.hosted.com',
|
||||
});
|
||||
const publisher = await GitlabPublisher.fromConfig(
|
||||
{
|
||||
host: 'gitlab.com',
|
||||
token: 'fake-token',
|
||||
baseUrl: 'https://gitlab.hosted.com',
|
||||
},
|
||||
{ repoVisibility: 'public' },
|
||||
);
|
||||
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 42,
|
||||
@@ -88,6 +91,7 @@ describe('GitLab Publisher', () => {
|
||||
expect(mockGitlabClient.Projects.create).toHaveBeenCalledWith({
|
||||
namespace_id: 42,
|
||||
name: 'test',
|
||||
visibility: 'public',
|
||||
});
|
||||
expect(initRepoAndPush).toHaveBeenCalledWith({
|
||||
dir: resultPath,
|
||||
@@ -98,10 +102,13 @@ describe('GitLab Publisher', () => {
|
||||
});
|
||||
|
||||
it('should use gitbeaker to create a repo in the authed user if the namespace property is not set', async () => {
|
||||
const publisher = await GitlabPublisher.fromConfig({
|
||||
host: 'gitlab.com',
|
||||
token: 'fake-token',
|
||||
});
|
||||
const publisher = await GitlabPublisher.fromConfig(
|
||||
{
|
||||
host: 'gitlab.com',
|
||||
token: 'fake-token',
|
||||
},
|
||||
{ repoVisibility: 'public' },
|
||||
);
|
||||
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({});
|
||||
mockGitlabClient.Users.current.mockResolvedValue({
|
||||
@@ -128,6 +135,7 @@ describe('GitLab Publisher', () => {
|
||||
expect(mockGitlabClient.Projects.create).toHaveBeenCalledWith({
|
||||
namespace_id: 21,
|
||||
name: 'test',
|
||||
visibility: 'public',
|
||||
});
|
||||
expect(initRepoAndPush).toHaveBeenCalledWith({
|
||||
dir: resultPath,
|
||||
|
||||
@@ -22,18 +22,31 @@ import parseGitUrl from 'git-url-parse';
|
||||
import path from 'path';
|
||||
import { GitLabIntegrationConfig } from '@backstage/integration';
|
||||
|
||||
export type RepoVisibilityOptions = 'private' | 'internal' | 'public';
|
||||
|
||||
export class GitlabPublisher implements PublisherBase {
|
||||
static async fromConfig(config: GitLabIntegrationConfig) {
|
||||
static async fromConfig(
|
||||
config: GitLabIntegrationConfig,
|
||||
{ repoVisibility }: { repoVisibility: RepoVisibilityOptions },
|
||||
) {
|
||||
if (!config.token) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const client = new Gitlab({ host: config.baseUrl, token: config.token });
|
||||
return new GitlabPublisher({ token: config.token, client });
|
||||
return new GitlabPublisher({
|
||||
token: config.token,
|
||||
client,
|
||||
repoVisibility,
|
||||
});
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly config: { token: string; client: GitlabClient },
|
||||
private readonly config: {
|
||||
token: string;
|
||||
client: GitlabClient;
|
||||
repoVisibility: RepoVisibilityOptions;
|
||||
},
|
||||
) {}
|
||||
|
||||
async publish({
|
||||
@@ -85,6 +98,7 @@ export class GitlabPublisher implements PublisherBase {
|
||||
const project = (await this.config.client.Projects.create({
|
||||
namespace_id: targetNamespace,
|
||||
name: name,
|
||||
visibility: this.config.repoVisibility,
|
||||
})) as { http_url_to_repo: string };
|
||||
|
||||
return project?.http_url_to_repo;
|
||||
|
||||
@@ -16,10 +16,19 @@
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import { PublisherBase, PublisherBuilder } from './types';
|
||||
import { GithubPublisher, RepoVisibilityOptions } from './github';
|
||||
import { GitlabPublisher } from './gitlab';
|
||||
import {
|
||||
GithubPublisher,
|
||||
RepoVisibilityOptions as GithubRepoVisibilityOptions,
|
||||
} from './github';
|
||||
import {
|
||||
GitlabPublisher,
|
||||
RepoVisibilityOptions as GitlabRepoVisibilityOptions,
|
||||
} from './gitlab';
|
||||
import { AzurePublisher } from './azure';
|
||||
import { BitbucketPublisher } from './bitbucket';
|
||||
import {
|
||||
BitbucketPublisher,
|
||||
RepoVisibilityOptions as BitbucketRepoVisibilityOptions,
|
||||
} from './bitbucket';
|
||||
import { Logger } from 'winston';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
|
||||
@@ -74,7 +83,7 @@ export class Publishers implements PublisherBuilder {
|
||||
for (const integration of scm.github.list()) {
|
||||
const repoVisibility = (config.getOptionalString(
|
||||
'scaffolder.github.visibility',
|
||||
) ?? 'public') as RepoVisibilityOptions;
|
||||
) ?? 'public') as GithubRepoVisibilityOptions;
|
||||
|
||||
const publisher = await GithubPublisher.fromConfig(integration.config, {
|
||||
repoVisibility,
|
||||
@@ -98,7 +107,13 @@ export class Publishers implements PublisherBuilder {
|
||||
}
|
||||
|
||||
for (const integration of scm.gitlab.list()) {
|
||||
const publisher = await GitlabPublisher.fromConfig(integration.config);
|
||||
const repoVisibility = (config.getOptionalString(
|
||||
'scaffolder.gitlab.visibility',
|
||||
) ?? 'public') as GitlabRepoVisibilityOptions;
|
||||
|
||||
const publisher = await GitlabPublisher.fromConfig(integration.config, {
|
||||
repoVisibility,
|
||||
});
|
||||
|
||||
if (publisher) {
|
||||
publishers.register(integration.config.host, publisher);
|
||||
@@ -107,16 +122,28 @@ export class Publishers implements PublisherBuilder {
|
||||
|
||||
publishers.register(
|
||||
integration.config.host,
|
||||
await GitlabPublisher.fromConfig({
|
||||
token: config.getOptionalString('scaffolder.gitlab.token') ?? '',
|
||||
host: integration.config.host,
|
||||
}),
|
||||
await GitlabPublisher.fromConfig(
|
||||
{
|
||||
token: config.getOptionalString('scaffolder.gitlab.token') ?? '',
|
||||
host: integration.config.host,
|
||||
},
|
||||
{ repoVisibility },
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (const integration of scm.bitbucket.list()) {
|
||||
const publisher = await BitbucketPublisher.fromConfig(integration.config);
|
||||
const repoVisibility = (config.getOptionalString(
|
||||
'scaffolder.bitbucket.visibility',
|
||||
) ?? 'public') as BitbucketRepoVisibilityOptions;
|
||||
|
||||
const publisher = await BitbucketPublisher.fromConfig(
|
||||
integration.config,
|
||||
{
|
||||
repoVisibility,
|
||||
},
|
||||
);
|
||||
|
||||
if (publisher) {
|
||||
publishers.register(integration.config.host, publisher);
|
||||
@@ -125,15 +152,19 @@ export class Publishers implements PublisherBuilder {
|
||||
|
||||
publishers.register(
|
||||
integration.config.host,
|
||||
await BitbucketPublisher.fromConfig({
|
||||
token: config.getOptionalString('scaffolder.bitbucket.token') ?? '',
|
||||
username:
|
||||
config.getOptionalString('scaffolder.bitbucket.username') ?? '',
|
||||
appPassword:
|
||||
config.getOptionalString('scaffolder.bitbucket.appPassword') ??
|
||||
'',
|
||||
host: integration.config.host,
|
||||
}),
|
||||
await BitbucketPublisher.fromConfig(
|
||||
{
|
||||
token:
|
||||
config.getOptionalString('scaffolder.bitbucket.token') ?? '',
|
||||
username:
|
||||
config.getOptionalString('scaffolder.bitbucket.username') ?? '',
|
||||
appPassword:
|
||||
config.getOptionalString('scaffolder.bitbucket.appPassword') ??
|
||||
'',
|
||||
host: integration.config.host,
|
||||
},
|
||||
{ repoVisibility },
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user