Merge pull request #9782 from Bonial-International-GmbH/PJ_bitbucket_default-apiBaseUrl

feat(bitbucket): ensure apiBaseUrl, replace hardcoded cases
This commit is contained in:
Patrik Oldsberg
2022-03-02 17:35:12 +01:00
committed by GitHub
7 changed files with 33 additions and 39 deletions
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/integration': minor
'@backstage/backend-common': patch
'@backstage/plugin-scaffolder-backend': patch
---
ensure `apiBaseUrl` being set for Bitbucket integrations, replace hardcoded defaults
@@ -270,22 +270,6 @@ describe('BitbucketUrlReader', () => {
expect(response.etag).toBe('12ab34cd56ef');
});
it('should throw error when apiBaseUrl is missing', () => {
expect(() => {
/* eslint-disable no-new */
new BitbucketUrlReader(
new BitbucketIntegration(
readBitbucketIntegrationConfig(
new ConfigReader({
host: 'bitbucket.mycompany.net',
}),
),
),
{ treeResponseFactory },
);
}).toThrowError('must configure an explicit apiBaseUrl');
});
});
describe('search hosted', () => {
@@ -62,14 +62,9 @@ export class BitbucketUrlReader implements UrlReader {
private readonly integration: BitbucketIntegration,
private readonly deps: { treeResponseFactory: ReadTreeResponseFactory },
) {
const { host, apiBaseUrl, token, username, appPassword } =
integration.config;
const { host, token, username, appPassword } = integration.config;
if (!apiBaseUrl) {
throw new Error(
`Bitbucket integration for '${host}' must configure an explicit apiBaseUrl`,
);
} else if (!token && username && !appPassword) {
if (!token && username && !appPassword) {
throw new Error(
`Bitbucket integration for '${host}' has configured a username but is missing a required appPassword.`,
);
+1 -1
View File
@@ -88,7 +88,7 @@ export class BitbucketIntegration implements ScmIntegration {
// @public
export type BitbucketIntegrationConfig = {
host: string;
apiBaseUrl?: string;
apiBaseUrl: string;
token?: string;
username?: string;
appPassword?: string;
+5 -5
View File
@@ -36,12 +36,10 @@ export type BitbucketIntegrationConfig = {
* The base URL of the API of this provider, e.g. "https://api.bitbucket.org/2.0",
* with no trailing slash.
*
* May be omitted specifically for Bitbucket Cloud; then it will be deduced.
*
* The API will always be preferred if both its base URL and a token are
* present.
* Values omitted at the optional property at the app-config will be deduced
* from the "host" value.
*/
apiBaseUrl?: string;
apiBaseUrl: string;
/**
* The authorization token to use for requests to a Bitbucket Server provider.
@@ -90,6 +88,8 @@ export function readBitbucketIntegrationConfig(
apiBaseUrl = trimEnd(apiBaseUrl, '/');
} else if (host === BITBUCKET_HOST) {
apiBaseUrl = BITBUCKET_API_BASE_URL;
} else {
apiBaseUrl = `https://${host}/rest/api/1.0`;
}
return {
+8 -2
View File
@@ -24,7 +24,10 @@ import {
describe('basicIntegrations', () => {
describe('byUrl', () => {
it('handles hosts without a port', () => {
const integration = new BitbucketIntegration({ host: 'host.com' });
const integration = new BitbucketIntegration({
host: 'host.com',
apiBaseUrl: 'a',
});
const integrations = basicIntegrations<BitbucketIntegration>(
[integration],
i => i.config.host,
@@ -33,7 +36,10 @@ describe('basicIntegrations', () => {
expect(integrations.byUrl('https://host.com:8080/a')).toBeUndefined();
});
it('handles hosts with a port', () => {
const integration = new BitbucketIntegration({ host: 'host.com:8080' });
const integration = new BitbucketIntegration({
host: 'host.com:8080',
apiBaseUrl: 'a',
});
const integrations = basicIntegrations<BitbucketIntegration>(
[integration],
i => i.config.host,
@@ -33,6 +33,7 @@ const createBitbucketCloudRepository = async (opts: {
repoVisibility: 'private' | 'public';
mainBranch: string;
authorization: string;
apiBaseUrl: string;
}) => {
const {
workspace,
@@ -42,6 +43,7 @@ const createBitbucketCloudRepository = async (opts: {
repoVisibility,
mainBranch,
authorization,
apiBaseUrl,
} = opts;
const options: RequestInit = {
@@ -61,7 +63,7 @@ const createBitbucketCloudRepository = async (opts: {
let response: Response;
try {
response = await fetch(
`https://api.bitbucket.org/2.0/repositories/${workspace}/${repo}`,
`${apiBaseUrl}/repositories/${workspace}/${repo}`,
options,
);
} catch (e) {
@@ -91,16 +93,14 @@ const createBitbucketCloudRepository = async (opts: {
};
const createBitbucketServerRepository = async (opts: {
host: string;
project: string;
repo: string;
description?: string;
repoVisibility: 'private' | 'public';
authorization: string;
apiBaseUrl?: string;
apiBaseUrl: string;
}) => {
const {
host,
project,
repo,
description,
@@ -124,8 +124,7 @@ const createBitbucketServerRepository = async (opts: {
};
try {
const baseUrl = apiBaseUrl ? apiBaseUrl : `https://${host}/rest/api/1.0`;
response = await fetch(`${baseUrl}/projects/${project}/repos`, options);
response = await fetch(`${apiBaseUrl}/projects/${project}/repos`, options);
} catch (e) {
throw new Error(`Unable to create repository, ${e}`);
}
@@ -314,7 +313,11 @@ export function createPublishBitbucketAction(options: {
const authorization = getAuthorizationHeader(
ctx.input.token
? { host: integrationConfig.config.host, token: ctx.input.token }
? {
host: integrationConfig.config.host,
apiBaseUrl: integrationConfig.config.apiBaseUrl,
token: ctx.input.token,
}
: integrationConfig.config,
);
@@ -327,7 +330,6 @@ export function createPublishBitbucketAction(options: {
const { remoteUrl, repoContentsUrl } = await createMethod({
authorization,
host,
workspace: workspace || '',
project,
repo,