Add initial support for Bitbucket Cloud scaffolding

This commit is contained in:
Mathias Åhsberg
2020-12-18 22:47:14 +00:00
parent d9eba5b715
commit 37a5244ef2
3 changed files with 43 additions and 14 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': minor
---
Add scaffolding support for Bitbucket Cloud and Server.
@@ -26,10 +26,10 @@ import { Config } from '@backstage/config';
export class BitbucketPreparer implements PreparerBase {
private readonly privateToken: string;
private readonly user: string;
private readonly username: string;
constructor(config: Config) {
this.user =
this.username =
config.getOptionalString('scaffolder.bitbucket.api.username') ?? '';
this.privateToken =
config.getOptionalString('scaffolder.bitbucket.api.token') ?? '';
@@ -50,13 +50,7 @@ export class BitbucketPreparer implements PreparerBase {
const templateId = template.metadata.name;
const repo = GitUriParser(location);
let repositoryCheckoutUrl;
// could be refactor once https://github.com/IonicaBizau/git-url-parse/pull/117 has been published
if (repo.source === 'bitbucket.org') {
repositoryCheckoutUrl = `${repo.protocol}://${repo.resource}/${repo.owner}/${repo.name}`;
} else {
repositoryCheckoutUrl = `${repo.protocol}://${repo.resource}/scm/${repo.owner}/${repo.name}`;
}
const repositoryCheckoutUrl = repo.toString('https');
const tempDir = await fs.promises.mkdtemp(
path.join(workingDirectory, templateId),
@@ -72,7 +66,7 @@ export class BitbucketPreparer implements PreparerBase {
fetchOpts: {
callbacks: {
credentials: () =>
Cred.userpassPlaintextNew(this.user, this.privateToken),
Cred.userpassPlaintextNew(this.username, this.privateToken),
},
},
}
@@ -50,7 +50,7 @@ export class BitbucketPublisher implements PublisherBase {
values: RequiredTemplateValues & Record<string, JsonValue>,
): Promise<PublisherResult> {
const [project, name] = values.storePath.split('/');
if (this.host === 'bitbucket.org') {
if (this.host === 'https://bitbucket.org') {
return this.createBitbucketCloudRepository(project, name);
}
return this.createBitbucketServerRepository(project, name);
@@ -60,9 +60,39 @@ export class BitbucketPublisher implements PublisherBase {
project: string,
name: string,
): Promise<PublisherResult> {
throw new Error(
`Failed to create ${project}/${name} on bitbucket.org which is currently not supported`,
);
let response: Response;
const buffer = Buffer.from(`${this.username}:${this.token}`, 'utf8');
const options: RequestInit = {
method: 'POST',
body: JSON.stringify({}),
headers: {
Authorization: `Basic ${buffer.toString('base64')}`,
'Content-Type': 'application/json',
},
};
try {
response = await fetch(
`https://api.bitbucket.org/2.0/repositories/${project}/${name}`,
options,
);
} catch (e) {
throw new Error(`Unable to create repository, ${e}`);
}
if (response.status === 200) {
const r = await response.json();
let remoteUrl = '';
for (const link of r.links.clone) {
if (link.name === 'https') {
remoteUrl = link.href;
}
}
// TODO use the urlReader to get the defautl branch
const catalogInfoUrl = `${r.links.html.href}/src/master/catalog-info.yaml`;
return { remoteUrl, catalogInfoUrl };
}
throw new Error(`Not a valid response code ${await response.text()}`);
}
private async createBitbucketServerRepository(