diff --git a/CHANGELOG.md b/CHANGELOG.md index f1d5ba2a2..339a669e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `wa_user_created` PostHog event fired on successful user sign-up. [#933](https://github.com/sourcebot-dev/sourcebot/pull/933) - Added `wa_askgh_login_wall_prompted` PostHog event fired when an unauthenticated user attempts to ask a question on Ask GitHub. [#933](https://github.com/sourcebot-dev/sourcebot/pull/933) - Added Bitbucket Server (Data Center) OAuth 2.0 SSO identity provider support (`provider: "bitbucket-server"`). [#934](https://github.com/sourcebot-dev/sourcebot/pull/934) +- Added Bitbucket Server (Data Center) sync all repositories support. [#927](https://github.com/sourcebot-dev/sourcebot/pull/927) ### Changed - Hide version upgrade toast for askgithub deployment (`EXPERIMENT_ASK_GH_ENABLED`). [#931](https://github.com/sourcebot-dev/sourcebot/pull/931) diff --git a/docs/docs/connections/bitbucket-data-center.mdx b/docs/docs/connections/bitbucket-data-center.mdx index 1d6979196..69e415d48 100644 --- a/docs/docs/connections/bitbucket-data-center.mdx +++ b/docs/docs/connections/bitbucket-data-center.mdx @@ -39,6 +39,18 @@ If you're not familiar with Sourcebot [connections](/docs/connections/overview), } ``` + + Requires a `token` to be set in order to access private repositories. + ```json + { + "type": "bitbucket", + "deploymentType": "server", + "url": "https://mybitbucketdeployment.com", + // Index all repos visible to the provided token + "all": true + } + ``` + ```json { diff --git a/docs/snippets/schemas/v3/bitbucket.schema.mdx b/docs/snippets/schemas/v3/bitbucket.schema.mdx index 66531ef77..14eb53018 100644 --- a/docs/snippets/schemas/v3/bitbucket.schema.mdx +++ b/docs/snippets/schemas/v3/bitbucket.schema.mdx @@ -67,6 +67,11 @@ "default": "cloud", "description": "The type of Bitbucket deployment" }, + "all": { + "type": "boolean", + "default": false, + "description": "Sync all repositories visible to the provided `token` (if any) in the Bitbucket Server instance. This option is ignored if `deploymentType` is `cloud`." + }, "workspaces": { "type": "array", "items": { diff --git a/docs/snippets/schemas/v3/connection.schema.mdx b/docs/snippets/schemas/v3/connection.schema.mdx index ef8a33138..1cd003387 100644 --- a/docs/snippets/schemas/v3/connection.schema.mdx +++ b/docs/snippets/schemas/v3/connection.schema.mdx @@ -744,6 +744,11 @@ "default": "cloud", "description": "The type of Bitbucket deployment" }, + "all": { + "type": "boolean", + "default": false, + "description": "Sync all repositories visible to the provided `token` (if any) in the Bitbucket Server instance. This option is ignored if `deploymentType` is `cloud`." + }, "workspaces": { "type": "array", "items": { diff --git a/docs/snippets/schemas/v3/index.schema.mdx b/docs/snippets/schemas/v3/index.schema.mdx index 4c65b7477..e6d4e02c5 100644 --- a/docs/snippets/schemas/v3/index.schema.mdx +++ b/docs/snippets/schemas/v3/index.schema.mdx @@ -1159,6 +1159,11 @@ "default": "cloud", "description": "The type of Bitbucket deployment" }, + "all": { + "type": "boolean", + "default": false, + "description": "Sync all repositories visible to the provided `token` (if any) in the Bitbucket Server instance. This option is ignored if `deploymentType` is `cloud`." + }, "workspaces": { "type": "array", "items": { diff --git a/packages/backend/src/bitbucket.ts b/packages/backend/src/bitbucket.ts index fd4c03ed3..b2797679c 100644 --- a/packages/backend/src/bitbucket.ts +++ b/packages/backend/src/bitbucket.ts @@ -76,6 +76,18 @@ export const getBitbucketReposFromConfig = async (config: BitbucketConnectionCon let allRepos: BitbucketRepository[] = []; let allWarnings: string[] = []; + if (config.all === true) { + if (client.deploymentType === BITBUCKET_SERVER) { + const { repos, warnings } = await serverGetAllRepos(client); + allRepos = allRepos.concat(repos); + allWarnings = allWarnings.concat(warnings); + } else { + const warning = `Ignoring option all:true in config: not supported for Bitbucket Cloud`; + logger.warn(warning); + allWarnings = allWarnings.concat(warning); + } + } + if (config.workspaces) { const { repos, warnings } = await client.getReposForWorkspace(client, config.workspaces); allRepos = allRepos.concat(repos); @@ -554,6 +566,26 @@ async function serverGetRepos(client: BitbucketClient, repoList: string[]): Prom }; } +async function serverGetAllRepos(client: BitbucketClient): Promise<{repos: ServerRepository[], warnings: string[]}> { + logger.debug(`Fetching all repos from Bitbucket Server...`); + const path = `/rest/api/1.0/repos` as ServerGetRequestPath; + const { durationMs, data } = await measure(async () => { + const fetchFn = () => getPaginatedServer(path, async (url, start) => { + const response = await client.apiClient.GET(url, { + params: { query: { start } } + }); + const { data, error } = response; + if (error) { + throw new Error(`Failed to fetch all repos: ${JSON.stringify(error)}`); + } + return data; + }); + return fetchWithRetry(fetchFn, `all repos`, logger); + }); + logger.debug(`Found ${data.length} total repos in ${durationMs}ms.`); + return { repos: data, warnings: [] }; +} + export function serverShouldExcludeRepo(repo: BitbucketRepository, config: BitbucketConnectionConfig): boolean { const serverRepo = repo as ServerRepository; diff --git a/packages/schemas/src/v3/bitbucket.schema.ts b/packages/schemas/src/v3/bitbucket.schema.ts index ce6c20581..9b5285d3e 100644 --- a/packages/schemas/src/v3/bitbucket.schema.ts +++ b/packages/schemas/src/v3/bitbucket.schema.ts @@ -66,6 +66,11 @@ const schema = { "default": "cloud", "description": "The type of Bitbucket deployment" }, + "all": { + "type": "boolean", + "default": false, + "description": "Sync all repositories visible to the provided `token` (if any) in the Bitbucket Server instance. This option is ignored if `deploymentType` is `cloud`." + }, "workspaces": { "type": "array", "items": { diff --git a/packages/schemas/src/v3/bitbucket.type.ts b/packages/schemas/src/v3/bitbucket.type.ts index a83063049..98a45c195 100644 --- a/packages/schemas/src/v3/bitbucket.type.ts +++ b/packages/schemas/src/v3/bitbucket.type.ts @@ -37,6 +37,10 @@ export interface BitbucketConnectionConfig { * The type of Bitbucket deployment */ deploymentType?: "cloud" | "server"; + /** + * Sync all repositories visible to the provided `token` (if any) in the Bitbucket Server instance. This option is ignored if `deploymentType` is `cloud`. + */ + all?: boolean; /** * List of workspaces to sync. Ignored if deploymentType is server. */ diff --git a/packages/schemas/src/v3/connection.schema.ts b/packages/schemas/src/v3/connection.schema.ts index ae4cffc2a..3de7d248e 100644 --- a/packages/schemas/src/v3/connection.schema.ts +++ b/packages/schemas/src/v3/connection.schema.ts @@ -743,6 +743,11 @@ const schema = { "default": "cloud", "description": "The type of Bitbucket deployment" }, + "all": { + "type": "boolean", + "default": false, + "description": "Sync all repositories visible to the provided `token` (if any) in the Bitbucket Server instance. This option is ignored if `deploymentType` is `cloud`." + }, "workspaces": { "type": "array", "items": { diff --git a/packages/schemas/src/v3/connection.type.ts b/packages/schemas/src/v3/connection.type.ts index f20e20498..0db5b176e 100644 --- a/packages/schemas/src/v3/connection.type.ts +++ b/packages/schemas/src/v3/connection.type.ts @@ -288,6 +288,10 @@ export interface BitbucketConnectionConfig { * The type of Bitbucket deployment */ deploymentType?: "cloud" | "server"; + /** + * Sync all repositories visible to the provided `token` (if any) in the Bitbucket Server instance. This option is ignored if `deploymentType` is `cloud`. + */ + all?: boolean; /** * List of workspaces to sync. Ignored if deploymentType is server. */ diff --git a/packages/schemas/src/v3/index.schema.ts b/packages/schemas/src/v3/index.schema.ts index 0c823a600..6b09080a7 100644 --- a/packages/schemas/src/v3/index.schema.ts +++ b/packages/schemas/src/v3/index.schema.ts @@ -1158,6 +1158,11 @@ const schema = { "default": "cloud", "description": "The type of Bitbucket deployment" }, + "all": { + "type": "boolean", + "default": false, + "description": "Sync all repositories visible to the provided `token` (if any) in the Bitbucket Server instance. This option is ignored if `deploymentType` is `cloud`." + }, "workspaces": { "type": "array", "items": { diff --git a/packages/schemas/src/v3/index.type.ts b/packages/schemas/src/v3/index.type.ts index ba064cd57..8878a2c96 100644 --- a/packages/schemas/src/v3/index.type.ts +++ b/packages/schemas/src/v3/index.type.ts @@ -488,6 +488,10 @@ export interface BitbucketConnectionConfig { * The type of Bitbucket deployment */ deploymentType?: "cloud" | "server"; + /** + * Sync all repositories visible to the provided `token` (if any) in the Bitbucket Server instance. This option is ignored if `deploymentType` is `cloud`. + */ + all?: boolean; /** * List of workspaces to sync. Ignored if deploymentType is server. */ diff --git a/schemas/v3/bitbucket.json b/schemas/v3/bitbucket.json index d6f57b5dc..5295b4b67 100644 --- a/schemas/v3/bitbucket.json +++ b/schemas/v3/bitbucket.json @@ -35,6 +35,11 @@ "default": "cloud", "description": "The type of Bitbucket deployment" }, + "all": { + "type": "boolean", + "default": false, + "description": "Sync all repositories visible to the provided `token` (if any) in the Bitbucket Server instance. This option is ignored if `deploymentType` is `cloud`." + }, "workspaces": { "type": "array", "items": {