Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions workspaces/x2a/.changeset/two-taxis-lose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@red-hat-developer-hub/backstage-plugin-x2a-common': patch
'@red-hat-developer-hub/backstage-plugin-x2a': patch
'@red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-x2a': patch
---

Add Bitbucket repository support.
46 changes: 46 additions & 0 deletions workspaces/x2a/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ See the [backend plugin README](./plugins/x2a-backend/README.md) for detailed co
- **`auth:`**
- Configure authentication providers for sign-in and SCM access (GitHub, GitLab). See [Backstage auth docs](https://backstage.io/docs/auth/).
- Based on your options of auth-providers, mind updating the `conversion-project-template.yaml` for source and target repository URLs.
- **`integrations:`**
- Configure SCM integrations for custom-domain hosts (e.g. self-hosted GitHub Enterprise, GitLab, or Bitbucket). The plugin reads the `integrations:` section to detect which SCM provider owns a given repository URL. Only the `host` field is required for this purpose; access tokens in `integrations:` entries are **not** needed by the x2a plugin (authentication is handled via OAuth through the `auth:` providers above). See the [SCM Provider Detection](#scm-provider-detection) section below.
- **`x2a:`** - Provide LLM credentials, Ansible Automation Platform connection details, and Kubernetes resource limits. See [x2a-convertor technical details](https://github.com/x2ansible/x2a-convertor?tab=readme-ov-file#technical-details).

3. Start the development environment with just the plugin loaded:
Expand All @@ -46,6 +48,16 @@ See the [backend plugin README](./plugins/x2a-backend/README.md) for detailed co

**GitLab OAuth:** When [creating a GitLab OAuth application](https://gitlab.com/-/user_settings/applications), request scopes per [official documentation](https://backstage.io/docs/auth/gitlab/provider/).

Cloud-based **Bitbucket.org OAuth:** When creating a Bitbucket OAuth consumer via `https://bitbucket.org/[YOUR_WORKSPACE]/workspace/settings/api`, request scopes per [official documentation](https://backstage.io/docs/auth/bitbucket/provider/), which include:
- `account:read`
- `workspace membership:read`

In addition, request the following scopes required by the Backstage Bitbucket scaffolder module for repository and pull-request operations:
- `project:read`
- `snippet:write`
- `issue:write`
- `pullrequest:write`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this, but without project:read didn't work

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, updating


```sh
export AUTH_GITHUB_CLIENT_ID=.... # Optional if "guest" user is not enough
export AUTH_GITHUB_CLIENT_SECRET=... # Optional if "guest" user is not enough
Expand All @@ -54,6 +66,10 @@ See the [backend plugin README](./plugins/x2a-backend/README.md) for detailed co
export AUTH_GITLAB_CLIENT_ID=...
export AUTH_GITLAB_CLIENT_SECRET=...

# For Bitbucket:
export AUTH_BITBUCKET_CLIENT_ID=... # Bitbucket "key"
export AUTH_BITBUCKET_CLIENT_SECRET=...... # Bitbucket "secret"

yarn dev
```

Expand All @@ -70,6 +86,36 @@ See the [backend plugin README](./plugins/x2a-backend/README.md) for detailed co
yarn start
```

## SCM Provider Detection

The plugin needs to know which SCM provider (GitHub, GitLab, or Bitbucket) a repository URL belongs to so it can use the correct OAuth scopes, token formats, and web UI URL patterns.

### How detection works

1. **Config-based detection (recommended for custom domains):** The plugin reads the Backstage `integrations:` config section and builds a hostname-to-provider mapping. Any host listed under `integrations.github`, `integrations.gitlab`, or `integrations.bitbucketCloud` is automatically associated with the corresponding provider.

2. **URL heuristic fallback:** When no matching host is found in the config, the plugin falls back to simple URL matching: URLs containing `github.com` resolve to GitHub, `bitbucket.org` to Bitbucket, and everything else defaults to GitLab.

### Configuration

To enable detection for SCM hosts on custom domains, add them to the `integrations:` section of `app-config.yaml`. Only the `host` field is required — access tokens are **not** needed for provider detection (the x2a plugin authenticates via OAuth through the `auth:` providers, not through integration tokens).

```yaml
integrations:
github:
- host: github.com
- host: github.mycompany.com # GitHub Enterprise on a custom domain
apiBaseUrl: https://github.mycompany.com/api/v3
gitlab:
- host: gitlab.com
- host: gitlab.internal.io # Self-hosted GitLab
apiBaseUrl: https://gitlab.internal.io/api/v4
bitbucketCloud:
- host: bitbucket.org
```

Without this configuration, only the well-known cloud hosts (`github.com`, `bitbucket.org`) are detected by URL; all other hosts fall back to GitLab behavior.

## Adding New API Endpoints

To add a new API endpoint, follow these steps:
Expand Down
42 changes: 27 additions & 15 deletions workspaces/x2a/app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,6 @@ backend:
connection: ':memory:'
# workingDirectory: /tmp # Use this to configure a working directory for the scaffolder, defaults to the OS temp-dir

integrations:
# So far no need for integrations
# github:
# - host: github.com
# # This is a Personal Access Token or PAT from GitHub. You can find out how to generate this token, and more information
# # about setting up the GitHub integration here: https://backstage.io/docs/integrations/github/locations#configuration
# token: ${GITHUB_TOKEN}
# gitlab:
# - host: gitlab.cee.redhat.com
# token: ${GITLAB_TOKEN}
### Example for how to add your GitHub Enterprise instance using the API:
# - host: ghe.example.net
# apiBaseUrl: https://ghe.example.net/api/v3
# token: ${GHE_TOKEN}

proxy:
### Example for how to add a proxy endpoint for the frontend.
### A typical reason to do this is to handle HTTPS and CORS for internal services.
Expand All @@ -70,6 +55,22 @@ techdocs:
# when the popup and main window have different cookie contexts
#enableExperimentalRedirectFlow: true

integrations:
# Needed for SCM provider detection in the x2a plugin
# See https://backstage.io/docs/integrations/github/locations#configuration
# The tokens are not needed for provider detection, only the hostnames.
# To access a SCM (pull, push), the plugin authenticates via OAuth through the auth: providers, not through integration tokens.
github:
- host: github.com
#- host: github.mycompany.com # GitHub Enterprise on a custom domain
# apiBaseUrl: https://github.mycompany.com/api/v3
gitlab:
- host: gitlab.com
#- host: gitlab.internal.io # Self-hosted GitLab
# apiBaseUrl: https://gitlab.internal.io/api/v4
bitbucketCloud:
- host: bitbucket.org

auth:
# see https://backstage.io/docs/auth/ to learn about auth providers
environment: development
Expand All @@ -92,6 +93,17 @@ auth:
signIn:
resolvers:
- resolver: usernameMatchingUserEntityName
bitbucket:
# Follow https://backstage.io/docs/auth/bitbucket/provider/
development:
clientId: ${AUTH_BITBUCKET_CLIENT_ID:-}
clientSecret: ${AUTH_BITBUCKET_CLIENT_SECRET:-}
signIn:
resolvers:
# The usernameMatchingUserEntityName resolver is not working for Bitbucket.
# Cannot make the bitbucket to provide user's email.
# See the org.yaml file for an example of how to use the usernameMatchingUserEntityAnnotation resolver.
- resolver: usernameMatchingUserEntityAnnotation

scaffolder: {}
# see https://backstage.io/docs/features/software-templates/configuration for software template options
Expand Down
4 changes: 4 additions & 0 deletions workspaces/x2a/examples/org.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ spec:
apiVersion: backstage.io/v1alpha1
kind: User
metadata:
annotations:
# example for Bitbucket usernameMatchingUserEntityAnnotation resolver
# the Bitbucket adds "-admin" to my username (based on role)
bitbucket.org/username: mareklibra-admin
name: mareklibra
spec:
profile:
Expand Down
12 changes: 11 additions & 1 deletion workspaces/x2a/packages/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ import {
X2APage,
x2aPluginTranslations,
} from '@red-hat-developer-hub/backstage-plugin-x2a';
import { githubAuthApiRef, gitlabAuthApiRef } from '@backstage/core-plugin-api';
import {
bitbucketAuthApiRef,
githubAuthApiRef,
gitlabAuthApiRef,
} from '@backstage/core-plugin-api';

const app = createApp({
apis,
Expand Down Expand Up @@ -96,6 +100,12 @@ const app = createApp({
message: 'Sign in using GitLab',
apiRef: gitlabAuthApiRef,
},
{
id: 'bitbucket-auth-provider',
title: 'Bitbucket',
message: 'Sign in using Bitbucket',
apiRef: bitbucketAuthApiRef,
},
]}
/>
),
Expand Down
2 changes: 2 additions & 0 deletions workspaces/x2a/packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@backstage/config": "^1.3.6",
"@backstage/plugin-app-backend": "^0.5.8",
"@backstage/plugin-auth-backend": "^0.25.6",
"@backstage/plugin-auth-backend-module-bitbucket-provider": "^0.3.12",
"@backstage/plugin-auth-backend-module-github-provider": "^0.3.9",
"@backstage/plugin-auth-backend-module-gitlab-provider": "^0.3.9",
"@backstage/plugin-auth-backend-module-guest-provider": "^0.2.14",
Expand All @@ -40,6 +41,7 @@
"@backstage/plugin-permission-node": "^0.10.6",
"@backstage/plugin-proxy-backend": "^0.6.8",
"@backstage/plugin-scaffolder-backend": "^3.0.1",
"@backstage/plugin-scaffolder-backend-module-bitbucket": "^0.3.19",
"@backstage/plugin-scaffolder-backend-module-github": "^0.9.2",
"@backstage/plugin-scaffolder-backend-module-gitlab": "^0.11.3",
"@backstage/plugin-scaffolder-backend-module-notifications": "^0.1.16",
Expand Down
3 changes: 3 additions & 0 deletions workspaces/x2a/packages/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ backend.add(import('@backstage/plugin-proxy-backend'));
backend.add(import('@backstage/plugin-scaffolder-backend'));
backend.add(import('@backstage/plugin-scaffolder-backend-module-github'));
backend.add(import('@backstage/plugin-scaffolder-backend-module-gitlab'));
backend.add(import('@backstage/plugin-scaffolder-backend-module-bitbucket'));

backend.add(
import('@backstage/plugin-scaffolder-backend-module-notifications'),
);
Expand All @@ -38,6 +40,7 @@ backend.add(import('@backstage/plugin-auth-backend'));
backend.add(import('@backstage/plugin-auth-backend-module-guest-provider'));
backend.add(import('@backstage/plugin-auth-backend-module-github-provider'));
backend.add(import('@backstage/plugin-auth-backend-module-gitlab-provider'));
backend.add(import('@backstage/plugin-auth-backend-module-bitbucket-provider'));

// See https://backstage.io/docs/auth/guest/provider

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
},
"dependencies": {
"@backstage/backend-plugin-api": "1.4.2",
"@backstage/config": "^1.3.6",
"@backstage/plugin-scaffolder-node": "^0.11.0",
"@red-hat-developer-hub/backstage-plugin-x2a-common": "workspace:*"
},
Expand Down
Loading
Loading