feat(bitbucket): ensure apiBaseUrl, replace hardcoded cases
Ensure presence of apiBaseUrl for bitbucket integrations for both cases Bitbucket Cloud and Bitbucket Server by setting the default for Bitbucket Server at the integration config, too. Replace hardcoded uses of the default apiBaseUrl with the use of the integration config's value. Signed-off-by: Patrick Jungermann <Patrick.Jungermann@gmail.com>
This commit is contained in:
@@ -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.`,
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -32,6 +32,7 @@ const createBitbucketCloudRepository = async (opts: {
|
||||
description?: string;
|
||||
repoVisibility: 'private' | 'public';
|
||||
authorization: string;
|
||||
apiBaseUrl: string;
|
||||
}) => {
|
||||
const {
|
||||
workspace,
|
||||
@@ -40,6 +41,7 @@ const createBitbucketCloudRepository = async (opts: {
|
||||
description,
|
||||
repoVisibility,
|
||||
authorization,
|
||||
apiBaseUrl,
|
||||
} = opts;
|
||||
|
||||
const options: RequestInit = {
|
||||
@@ -59,7 +61,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) {
|
||||
@@ -88,16 +90,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,
|
||||
@@ -121,8 +121,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}`);
|
||||
}
|
||||
@@ -306,7 +305,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,
|
||||
);
|
||||
|
||||
@@ -319,7 +322,6 @@ export function createPublishBitbucketAction(options: {
|
||||
|
||||
const { remoteUrl, repoContentsUrl } = await createMethod({
|
||||
authorization,
|
||||
host,
|
||||
workspace: workspace || '',
|
||||
project,
|
||||
repo,
|
||||
|
||||
Reference in New Issue
Block a user