Skip to content

feat(x2a): GitLab authentication and token for jobs#2419

Merged
elai-shalev merged 3 commits into
redhat-developer:mainfrom
mareklibra:FLPATH-3353.gitlab
Mar 3, 2026
Merged

feat(x2a): GitLab authentication and token for jobs#2419
elai-shalev merged 3 commits into
redhat-developer:mainfrom
mareklibra:FLPATH-3353.gitlab

Conversation

@mareklibra
Copy link
Copy Markdown
Member

@mareklibra mareklibra commented Mar 2, 2026

Fixes: FLPATH-3353

The user can be authenticated against gitlab.com.

In addition. the Create Conversion Project template can handle gitlab.com for source and target repos and passing down correct tokens.

No matter what provider is selected to authenticate the user for the app (guest, GitHub, something else), the template collects (pops-up relevant dialog) GitLab credentials to issue the correct token.

TODO:

  • adapt backend for Gitlab (in addition to the GitHub)
  • revert the PR to GitHub by default (comment out GitLab)
  • document required GitLab OAuth app scopes

@rhdh-gh-app
Copy link
Copy Markdown

rhdh-gh-app Bot commented Mar 2, 2026

Changed Packages

Package Name Package Path Changeset Bump Current Version
app workspaces/x2a/packages/app none v0.0.0
backend workspaces/x2a/packages/backend none v0.0.0
@red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-x2a workspaces/x2a/plugins/scaffolder-backend-module-x2a patch v0.1.1
@red-hat-developer-hub/backstage-plugin-x2a-common workspaces/x2a/plugins/x2a-common patch v1.0.1
@red-hat-developer-hub/backstage-plugin-x2a workspaces/x2a/plugins/x2a patch v1.0.1

@rhdh-qodo-merge
Copy link
Copy Markdown

Review Summary by Qodo

Add GitLab authentication and scaffolder integration

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add GitLab authentication provider alongside GitHub
• Integrate GitLab scaffolder backend module for job support
• Update conversion template to support GitLab repositories
• Configure GitLab OAuth and environment variables
• Add GitLab sign-in option to frontend authentication UI
Diagram
flowchart LR
  A["GitLab OAuth Config"] -->|"Auth Provider"| B["Backend Auth Module"]
  B -->|"Scaffolder Support"| C["GitLab Scaffolder Module"]
  A -->|"Frontend Integration"| D["GitLab Sign-in UI"]
  C -->|"Template Support"| E["Conversion Project Template"]
  D -->|"User Authentication"| F["GitLab.com Access"]
Loading

Grey Divider

File Changes

1. workspaces/x2a/packages/backend/src/index.ts ✨ Enhancement +3/-0

Register GitLab backend modules

• Added GitLab scaffolder backend module import
• Added GitLab authentication provider module import

workspaces/x2a/packages/backend/src/index.ts


2. workspaces/x2a/README.md 📝 Documentation +5/-0

Document GitLab authentication setup

• Added GitLab authentication setup instructions
• Documented OAuth app creation on gitlab.com
• Added environment variable exports for GitLab credentials

workspaces/x2a/README.md


3. workspaces/x2a/app-config.yaml ⚙️ Configuration changes +20/-11

Configure GitLab integration and auth

• Commented out GitHub integration configuration
• Added GitLab integration configuration example
• Added experimental redirect flow comment for cookie handling
• Updated GitLab auth provider configuration with audience
• Changed resolver from emailMatchingUserEntityProfileEmail to usernameMatchingUserEntityName

workspaces/x2a/app-config.yaml


View more (5)
4. workspaces/x2a/examples/org.yaml Miscellaneous +10/-0

Add GitLab user example

• Added new User entity for mlibra with GitLab username
• Duplicated user profile configuration for GitLab compatibility

workspaces/x2a/examples/org.yaml


5. workspaces/x2a/package.json Dependencies +2/-1

Add GitLab provider dependency resolution

• Added GitLab auth backend module provider resolution
• Pinned version 0.3.9 for GitLab provider compatibility

workspaces/x2a/package.json


6. workspaces/x2a/packages/app/src/App.tsx ✨ Enhancement +7/-1

Add GitLab sign-in provider to UI

• Imported gitlabAuthApiRef from core plugin API
• Added GitLab authentication provider to sign-in options
• Configured GitLab provider with title and message

workspaces/x2a/packages/app/src/App.tsx


7. workspaces/x2a/packages/backend/package.json Dependencies +2/-0

Add GitLab backend dependencies

• Added GitLab scaffolder backend module dependency
• Added GitLab authentication provider module dependency
• Both dependencies pinned to version 0.3.9 and 0.11.3

workspaces/x2a/packages/backend/package.json


8. workspaces/x2a/templates/conversion-project-template.yaml ✨ Enhancement +11/-6

Update template for GitLab repository support

• Updated source repository description to reference SCM instead of GitHub
• Changed allowedHosts from github.com to gitlab.com
• Updated target repository description to reference SCM
• Added commented examples for gitlab.cee.redhat.com
• Removed TODO comment about RepoBranchPicker

workspaces/x2a/templates/conversion-project-template.yaml


Grey Divider

Qodo Logo

@rhdh-qodo-merge
Copy link
Copy Markdown

rhdh-qodo-merge Bot commented Mar 2, 2026

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Git clone URL malformed 🐞 Bug ✓ Correctness
Description
With GitLab now enabled in the template, the conversion job clones using https://${TOKEN}@host/...
(token as username, no password), which is a brittle/nonstandard auth URL format and is likely to
fail for GitLab OAuth tokens.
Code

workspaces/x2a/templates/conversion-project-template.yaml[R63-69]

              #  github:
              #    - workflow
            allowedHosts:
-              - github.com
+              # This is to be updated per deployment
+              # - github.com
+              - gitlab.com
+              # - gitlab.cee.redhat.com
Evidence
The template requests user OAuth tokens into SRC_USER_OAUTH_TOKEN/TGT_USER_OAUTH_TOKEN, the
scaffolder action requires those secrets, and the backend job script injects those tokens into clone
URLs as the *username* portion only. This newly matters because the template now directs users to
GitLab hosts.

workspaces/x2a/templates/conversion-project-template.yaml[58-69]
workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts[119-128]
workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh[113-141]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The job script builds clone URLs as `https://${TOKEN}@host/...`, which sets the token as the URL username with no password. This is a brittle pattern and is likely incompatible with GitLab OAuth tokens, causing clone/push failures.

### Issue Context
The scaffolder template collects user OAuth tokens and the backend job uses them for `git clone`/`git push`. With the template now allowing GitLab hosts, this auth formatting becomes a critical path.

### Fix Focus Areas
- workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh[113-141]
- workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts[119-128]
- workspaces/x2a/templates/conversion-project-template.yaml[60-69]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Integrations left unconfigured 🐞 Bug ⛯ Reliability
Description
app-config.yaml now defines integrations: but with no configured providers, so SCM
integration-driven behavior (integrations discovery / SCM auth defaults) is likely missing unless
every deployment supplies an override.
Code

workspaces/x2a/app-config.yaml[R35-47]

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}
-    ### 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}
+#  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}
Evidence
The repo’s frontend explicitly constructs the SCM integrations API from config, but the committed
config contains only an empty integrations: key (all actual providers commented out), meaning
there are no configured SCM integrations in this repo’s default config.

workspaces/x2a/app-config.yaml[35-47]
workspaces/x2a/packages/app/src/apis.ts[16-34]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`integrations:` is present but contains no configured providers (only comments). This leaves the default config without any SCM integration entries, while the app constructs `ScmIntegrationsApi` from config.

### Issue Context
The frontend APIs are wired to create the SCM integrations API from configuration. With no integrations defined, SCM-dependent flows may not work as intended unless deployments provide overrides.

### Fix Focus Areas
- workspaces/x2a/app-config.yaml[35-47]
- workspaces/x2a/packages/app/src/apis.ts[16-34]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Template restricts SCM hosts 🐞 Bug ✓ Correctness
Description
The conversion template’s RepoUrlPicker allowedHosts now effectively only allows gitlab.com,
preventing GitHub-based conversions even though the codebase/docs indicate GitHub URLs are
supported.
Code

workspaces/x2a/templates/conversion-project-template.yaml[R63-69]

              #  github:
              #    - workflow
            allowedHosts:
-              - github.com
+              # This is to be updated per deployment
+              # - github.com
+              - gitlab.com
+              # - gitlab.cee.redhat.com
Evidence
The template UI limits repository selection to gitlab.com. Meanwhile, repo URL normalization
explicitly supports GitHub/GitLab-style URLs and backend docs still show GitHub URLs, so this UI
constraint will block an expected use case.

workspaces/x2a/templates/conversion-project-template.yaml[53-69]
workspaces/x2a/plugins/x2a-common/src/utils/normalizeRepoUrl.ts[17-55]
workspaces/x2a/plugins/x2a-backend/README.md[228-239]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The conversion template currently restricts `allowedHosts` to `gitlab.com`, blocking GitHub repository selection.

### Issue Context
The codebase and documentation show GitHub URLs as a supported/expected path, and URL normalization supports both GitHub and GitLab.

### Fix Focus Areas
- workspaces/x2a/templates/conversion-project-template.yaml[60-69]
- workspaces/x2a/templates/conversion-project-template.yaml[103-109]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. GitLab admin user mismatch 🐞 Bug ⛨ Security
Description
The example org catalog adds user:default/mlibra, but the RBAC admin allowlist doesn’t include it;
if GitLab sign-in resolves to mlibra, that user won’t have admin rights as implied by the example.
Code

workspaces/x2a/examples/org.yaml[R40-46]

+metadata:
+  name: mlibra
+spec:
+  profile:
+    displayName: Marek Libra
+    email: foo@bar.com
+  memberOf: [x2a-admin-group]
Evidence
The catalog includes both mareklibra and mlibra as User entities, but the RBAC admin users list
only names mareklibra and elai-shalev. That means mlibra will not be considered an admin user
by this config.

workspaces/x2a/examples/org.yaml[28-46]
workspaces/x2a/app-config.yaml[121-132]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
A new example user entity `mlibra` exists, but RBAC admin configuration does not include it. This can lead to unexpected permission behavior when signing in via GitLab username resolution.

### Issue Context
The repo config uses an explicit RBAC admin allowlist. Any intended admin identity must be present there.

### Fix Focus Areas
- workspaces/x2a/examples/org.yaml[28-47]
- workspaces/x2a/app-config.yaml[121-133]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread workspaces/x2a/templates/conversion-project-template.yaml Outdated
@mareklibra mareklibra force-pushed the FLPATH-3353.gitlab branch 5 times, most recently from c5c88c5 to b833e03 Compare March 3, 2026 08:36
@mareklibra mareklibra marked this pull request as ready for review March 3, 2026 08:51
@rhdh-qodo-merge
Copy link
Copy Markdown

Review Summary by Qodo

Add GitLab authentication and scaffolder backend support

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add GitLab authentication and scaffolder backend support alongside GitHub
• Implement token augmentation for GitLab OAuth2 git access requirements
• Fix typo in parameter name areTargeAndSourceRepoShared to areTargetAndSourceRepoShared
• Add userPrompt parameter support for init-phase API requests
• Improve error handling and logging in project creation workflow
• Update documentation with GitLab OAuth setup and configuration instructions
Diagram
flowchart LR
  A["Backend Setup"] -->|Add GitLab modules| B["Auth & Scaffolder"]
  C["Token Management"] -->|Augment for GitLab| D["Git Access"]
  E["Project Creation"] -->|Support userPrompt| F["Init-phase API"]
  G["Documentation"] -->|GitLab OAuth scopes| H["Setup Guide"]
  B --> I["Multi-provider Support"]
  D --> I
  F --> I
Loading

Grey Divider

File Changes

1. workspaces/x2a/packages/backend/src/index.ts ✨ Enhancement +3/-0

Add GitLab auth and scaffolder backend modules

workspaces/x2a/packages/backend/src/index.ts


2. workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.test.ts 🧪 Tests +75/-12

Fix typo and add userPrompt test case

workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.test.ts


3. workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts ✨ Enhancement +34/-13

Implement token augmentation and improve error handling

workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts


View more (17)
4. workspaces/x2a/plugins/x2a-common/src/utils/augmentRepoToken.ts ✨ Enhancement +34/-0

New utility for GitLab token augmentation

workspaces/x2a/plugins/x2a-common/src/utils/augmentRepoToken.ts


5. workspaces/x2a/plugins/x2a-common/src/utils/getAuthTokenDescriptor.ts 📝 Documentation +8/-2

Add JSDoc documentation for token descriptor

workspaces/x2a/plugins/x2a-common/src/utils/getAuthTokenDescriptor.ts


6. workspaces/x2a/plugins/x2a-common/src/utils/index.ts ✨ Enhancement +3/-0

Export new token utilities and types

workspaces/x2a/plugins/x2a-common/src/utils/index.ts


7. workspaces/x2a/plugins/x2a-common/src/utils/tokenDescriptorTypes.ts 📝 Documentation +6/-0

Add JSDoc documentation for auth types

workspaces/x2a/plugins/x2a-common/src/utils/tokenDescriptorTypes.ts


8. workspaces/x2a/plugins/x2a/src/repoAuth/index.ts ✨ Enhancement +0/-2

Remove local exports, use common package

workspaces/x2a/plugins/x2a/src/repoAuth/index.ts


9. workspaces/x2a/plugins/x2a/src/repoAuth/useRepoAuth.ts ✨ Enhancement +13/-6

Import utilities from common, apply token augmentation

workspaces/x2a/plugins/x2a/src/repoAuth/useRepoAuth.ts


10. workspaces/x2a/.changeset/large-signs-serve.md 📝 Documentation +7/-0

Document GitLab support addition

workspaces/x2a/.changeset/large-signs-serve.md


11. workspaces/x2a/README.md 📝 Documentation +20/-4

Add GitLab OAuth setup and configuration instructions

workspaces/x2a/README.md


12. workspaces/x2a/app-config.yaml ⚙️ Configuration changes +21/-11

Configure GitLab auth provider and update integrations

workspaces/x2a/app-config.yaml


13. workspaces/x2a/package.json Dependencies +2/-1

Add GitLab auth backend module resolution

workspaces/x2a/package.json


14. workspaces/x2a/packages/app/src/App.tsx ✨ Enhancement +7/-1

Add GitLab auth provider to sign-in options

workspaces/x2a/packages/app/src/App.tsx


15. workspaces/x2a/packages/backend/package.json Dependencies +2/-0

Add GitLab scaffolder and auth backend dependencies

workspaces/x2a/packages/backend/package.json


16. workspaces/x2a/plugins/x2a-common/package.json Dependencies +1/-0

Add core-plugin-api dependency for OAuth scopes

workspaces/x2a/plugins/x2a-common/package.json


17. workspaces/x2a/plugins/x2a-common/report.api.md 📝 Documentation +24/-0

Update API documentation with new exports

workspaces/x2a/plugins/x2a-common/report.api.md


18. workspaces/x2a/plugins/x2a/src/components/ModulePage/ModulePage.tsx ✨ Enhancement +5/-2

Import getAuthTokenDescriptor from common package

workspaces/x2a/plugins/x2a/src/components/ModulePage/ModulePage.tsx


19. workspaces/x2a/plugins/x2a/src/components/ModuleTable/ModuleTable.tsx ✨ Enhancement +2/-1

Import getAuthTokenDescriptor from common package

workspaces/x2a/plugins/x2a/src/components/ModuleTable/ModuleTable.tsx


20. workspaces/x2a/templates/conversion-project-template.yaml ✨ Enhancement +14/-9

Fix typo and add GitLab support to template

workspaces/x2a/templates/conversion-project-template.yaml


Grey Divider

Qodo Logo

@rhdh-qodo-merge
Copy link
Copy Markdown

rhdh-qodo-merge Bot commented Mar 3, 2026

Code Review by Qodo

🐞 Bugs (7) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Double JSON read 🐞 Bug ⛯ Reliability ⭐ New
Description
On project creation failure, the code calls response.json() twice, which will throw on the second
call because the body stream is already consumed. This masks the actual backend error and can cause
confusing failures whenever project creation returns a non-2xx response.
Code

workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts[R165-171]

          ctx.logger.error(
            `Project creation response status: ${response.status}, error: ${JSON.stringify(error)}`,
          );
-          throw new Error(error);
+
+          const errorObj = (await response.json()) as any;
+          const msg = errorObj?.message ?? JSON.stringify(errorObj);
+          throw new Error(msg);
Evidence
The error branch reads the same Response body twice; the second read will fail at runtime and the
logged/raised error becomes misleading.

workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts[162-171]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`createProjectAction` consumes the HTTP response body twice on the non-OK path (`response.json()` is called twice). The second read will throw and hide the real failure.

### Issue Context
This affects the scaffolder action `x2a:project:create` when the x2a backend returns any non-2xx response.

### Fix Focus Areas
- workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts[162-172]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Init error stringification 🐞 Bug ✧ Quality ⭐ New
Description
When the init-phase call fails, the code throws new Error(error) where error is a parsed JSON
object, producing an unhelpful message like "[object Object]". This drops structured error details
and makes failures difficult to debug.
Code

↗ workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts

Evidence
The thrown Error is constructed from a non-string object, losing the backend-provided
message/details even though they were already parsed and logged.

workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts[207-213]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The init-phase failure path throws `new Error(error)` where `error` is an object, resulting in `"[object Object]"` and losing useful context.

### Issue Context
This affects the scaffolder action after project creation when triggering `/projects/:projectId/run`.

### Fix Focus Areas
- workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts[207-213]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Git clone URL malformed 🐞 Bug ✓ Correctness
Description
With GitLab now enabled in the template, the conversion job clones using https://${TOKEN}@host/...
(token as username, no password), which is a brittle/nonstandard auth URL format and is likely to
fail for GitLab OAuth tokens.
Code

workspaces/x2a/templates/conversion-project-template.yaml[R63-69]

             #  github:
             #    - workflow
           allowedHosts:
-              - github.com
+              # This is to be updated per deployment
+              # - github.com
+              - gitlab.com
+              # - gitlab.cee.redhat.com
Evidence
The template requests user OAuth tokens into SRC_USER_OAUTH_TOKEN/TGT_USER_OAUTH_TOKEN, the
scaffolder action requires those secrets, and the backend job script injects those tokens into clone
URLs as the *username* portion only. This newly matters because the template now directs users to
GitLab hosts.

workspaces/x2a/templates/conversion-project-template.yaml[58-69]
workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts[119-128]
workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh[113-141]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The job script builds clone URLs as `https://${TOKEN}@host/...`, which sets the token as the URL username with no password. This is a brittle pattern and is likely incompatible with GitLab OAuth tokens, causing clone/push failures.
### Issue Context
The scaffolder template collects user OAuth tokens and the backend job uses them for `git clone`/`git push`. With the template now allowing GitLab hosts, this auth formatting becomes a critical path.
### Fix Focus Areas
- workspaces/x2a/plugins/x2a-backend/templates/x2a-job-script.sh[113-141]
- workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts[119-128]
- workspaces/x2a/templates/conversion-project-template.yaml[60-69]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Provider casing mismatch 🐞 Bug ✓ Correctness ⭐ New
Description
AuthTokenDescriptor documentation states provider matching is case-insensitive, but provider checks
are implemented as case-sensitive strict equality. Any mixed-case provider value (e.g., 'GitLab')
will fail auth selection and may skip required GitLab token augmentation.
Code

workspaces/x2a/plugins/x2a/src/repoAuth/useRepoAuth.ts[R64-72]

    async (tokenDescriptor: AuthTokenDescriptor): Promise<AuthToken> => {
-      let authApi = githubAuthApi;
-      if (tokenDescriptor.provider.toLocaleLowerCase('en-US') === 'gitlab') {
-        authApi = gitlabAuthApi;
+      let token;
+      if (tokenDescriptor.provider === 'github') {
+        token = await getProviderToken(githubAuthApi, tokenDescriptor);
+      } else if (tokenDescriptor.provider === 'gitlab') {
+        token = await getProviderToken(gitlabAuthApi, tokenDescriptor);
+      } else {
+        throw new Error(`Unsupported provider: ${tokenDescriptor.provider}`);
      }
Evidence
The type docs promise case-insensitive matching, but the runtime implementation compares exact
strings and throws on anything else.

workspaces/x2a/plugins/x2a-common/src/utils/tokenDescriptorTypes.ts[38-45]
workspaces/x2a/plugins/x2a/src/repoAuth/useRepoAuth.ts[64-72]
workspaces/x2a/plugins/x2a-common/src/utils/augmentRepoToken.ts[28-32]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Provider matching is documented as case-insensitive, but comparisons are case-sensitive and can throw or skip GitLab augmentation.

### Issue Context
This can surface if any caller sets provider casing differently than expected.

### Fix Focus Areas
- workspaces/x2a/plugins/x2a/src/repoAuth/useRepoAuth.ts[63-77]
- workspaces/x2a/plugins/x2a-common/src/utils/augmentRepoToken.ts[24-33]
- workspaces/x2a/plugins/x2a-common/src/utils/tokenDescriptorTypes.ts[38-45]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Integrations left unconfigured 🐞 Bug ⛯ Reliability
Description
app-config.yaml now defines integrations: but with no configured providers, so SCM
integration-driven behavior (integrations discovery / SCM auth defaults) is likely missing unless
every deployment supplies an override.
Code

workspaces/x2a/app-config.yaml[R35-47]

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}
-    ### 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}
+#  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}
Evidence
The repo’s frontend explicitly constructs the SCM integrations API from config, but the committed
config contains only an empty integrations: key (all actual providers commented out), meaning
there are no configured SCM integrations in this repo’s default config.

workspaces/x2a/app-config.yaml[35-47]
workspaces/x2a/packages/app/src/apis.ts[16-34]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`integrations:` is present but contains no configured providers (only comments). This leaves the default config without any SCM integration entries, while the app constructs `ScmIntegrationsApi` from config.
### Issue Context
The frontend APIs are wired to create the SCM integrations API from configuration. With no integrations defined, SCM-dependent flows may not work as intended unless deployments provide overrides.
### Fix Focus Areas
- workspaces/x2a/app-config.yaml[35-47]
- workspaces/x2a/packages/app/src/apis.ts[16-34]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Template restricts SCM hosts 🐞 Bug ✓ Correctness
Description
The conversion template’s RepoUrlPicker allowedHosts now effectively only allows gitlab.com,
preventing GitHub-based conversions even though the codebase/docs indicate GitHub URLs are
supported.
Code

workspaces/x2a/templates/conversion-project-template.yaml[R63-69]

             #  github:
             #    - workflow
           allowedHosts:
-              - github.com
+              # This is to be updated per deployment
+              # - github.com
+              - gitlab.com
+              # - gitlab.cee.redhat.com
Evidence
The template UI limits repository selection to gitlab.com. Meanwhile, repo URL normalization
explicitly supports GitHub/GitLab-style URLs and backend docs still show GitHub URLs, so this UI
constraint will block an expected use case.

workspaces/x2a/templates/conversion-project-template.yaml[53-69]
workspaces/x2a/plugins/x2a-common/src/utils/normalizeRepoUrl.ts[17-55]
workspaces/x2a/plugins/x2a-backend/README.md[228-239]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The conversion template currently restricts `allowedHosts` to `gitlab.com`, blocking GitHub repository selection.
### Issue Context
The codebase and documentation show GitHub URLs as a supported/expected path, and URL normalization supports both GitHub and GitLab.
### Fix Focus Areas
- workspaces/x2a/templates/conversion-project-template.yaml[60-69]
- workspaces/x2a/templates/conversion-project-template.yaml[103-109]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
7. GitLab admin user mismatch 🐞 Bug ⛨ Security
Description
The example org catalog adds user:default/mlibra, but the RBAC admin allowlist doesn’t include it;
if GitLab sign-in resolves to mlibra, that user won’t have admin rights as implied by the example.
Code

workspaces/x2a/examples/org.yaml[R40-46]

+metadata:
+  name: mlibra
+spec:
+  profile:
+    displayName: Marek Libra
+    email: foo@bar.com
+  memberOf: [x2a-admin-group]
Evidence
The catalog includes both mareklibra and mlibra as User entities, but the RBAC admin users list
only names mareklibra and elai-shalev. That means mlibra will not be considered an admin user
by this config.

workspaces/x2a/examples/org.yaml[28-46]
workspaces/x2a/app-config.yaml[121-132]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new example user entity `mlibra` exists, but RBAC admin configuration does not include it. This can lead to unexpected permission behavior when signing in via GitLab username resolution.
### Issue Context
The repo config uses an explicit RBAC admin allowlist. Any intended admin identity must be present there.
### Fix Focus Areas
- workspaces/x2a/examples/org.yaml[28-47]
- workspaces/x2a/app-config.yaml[121-133]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines 165 to +171
ctx.logger.error(
`Project creation response status: ${response.status}, error: ${JSON.stringify(error)}`,
);
throw new Error(error);

const errorObj = (await response.json()) as any;
const msg = errorObj?.message ?? JSON.stringify(errorObj);
throw new Error(msg);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Double json read 🐞 Bug ⛯ Reliability

On project creation failure, the code calls response.json() twice, which will throw on the second
call because the body stream is already consumed. This masks the actual backend error and can cause
confusing failures whenever project creation returns a non-2xx response.
Agent Prompt
### Issue description
`createProjectAction` consumes the HTTP response body twice on the non-OK path (`response.json()` is called twice). The second read will throw and hide the real failure.

### Issue Context
This affects the scaffolder action `x2a:project:create` when the x2a backend returns any non-2xx response.

### Fix Focus Areas
- workspaces/x2a/plugins/scaffolder-backend-module-x2a/src/actions/createProject.ts[162-172]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@mareklibra mareklibra force-pushed the FLPATH-3353.gitlab branch from b833e03 to 25261e2 Compare March 3, 2026 09:00
Signed-off-by: Marek Libra <marek.libra@gmail.com>
@mareklibra mareklibra force-pushed the FLPATH-3353.gitlab branch from 25261e2 to 8955e7d Compare March 3, 2026 09:36
Copy link
Copy Markdown
Contributor

@elai-shalev elai-shalev left a comment

Choose a reason for hiding this comment

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

some comments, two actual bugs IMO
Question - this PR only supports "gitlab.com"? not all enterprise gitlab instances?

Comment on lines +164 to +171
@@ -147,13 +165,17 @@ export function createProjectAction(
ctx.logger.error(
`Project creation response status: ${response.status}, error: ${JSON.stringify(error)}`,
);
throw new Error(error);

const errorObj = (await response.json()) as any;
const msg = errorObj?.message ?? JSON.stringify(errorObj);
throw new Error(msg);
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.

When the project creation response is not OK, the code calls response.json() on line 164 (assigned to error), logs it, then calls response.json() again on line 169 (assigned to errorObj).
A fetch Response body can only be consumed once — the second call will throw TypeError: body used already. This means the error message will never be extracted properly; instead, the catch block will get the "body used already" error. We should the first response.json() call or reuse the result.

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.

fixed

Comment on lines +140 to +144
targetRepoToken = augmentRepoToken(
targetRepoToken,
getAuthTokenDescriptor({
repoUrl: targetRepoUrl,
readOnly: false,
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.

When areTargetAndSourceRepoShared is true, Then line 134-135 sets targetRepoToken = sourceRepoToken (already augmented).
Then lines 140-146 call augmentRepoToken again on targetRepoToken, producing oauth2:oauth2:. I think this is a bug

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.

right, later change :-( Thanks for catching it

"@eloycoto"
],
"dependencies": {
"@backstage/core-plugin-api": "^1.10.9",
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.

should we couple the common package to the frontend-only package?
We could the import to import type { OAuthScope } and move @backstage/core-plugin-api to devDependencies to avoid pulling frontend code into the backend.

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.

The common pckg is for bth the BE and frontend. Removing this dependency completely, does not bring much benefits.

}): AuthTokenDescriptor => {
// Based on https://docs.github.com/en/enterprise-cloud[@latest](https://github.com/latest)/admin/managing-your-enterprise-account/changing-the-url-for-your-enterprise
// the GH URL should always contain github.com.
const provider = repoUrl.includes('github.com') ? 'github' : 'gitlab';
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.

gitlab.com is a very improbable provider
we should support all gitlab* enterprise providers, it's odd to "default" to gitlab.com

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.

This call is about choosing the provider, either github or gitlab, no matter if upstream or enterprise-deployed.

A custom-deployed gitlab can have a different URL, not containing the gitlab.com which this particular function is aligned with.

The standard and commonly used component for SCM URL selection (the RepoUrlPicker) does not provide the provider, just the URL (or I can not find otherwise). All suggestions I could find lead to parsing the URL :-(

To our luck (so far), we support gitlab-* and github only.
The GitHub Enterprise URL should always contain github.com (based on the documentation).
So the rest of the URLs lead to the the gitlab auth provider.

If we need to add an additional provider (like Azure), we will probably need to avoid this Backstage-standard component and reimplement it on our own.

In a follow-up, I will focus on the RH gitlab and defining steps needed towards integrating with it. The rcent understanding is that this function should not be affected.

Comment thread workspaces/x2a/README.md Outdated

3. Start the development environment with just the plugin loaded:

**GitHub OAuth**: Create a GitHub OAuth application](https://github.com/settings/developers).
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.

broken link, missing [

@mareklibra mareklibra force-pushed the FLPATH-3353.gitlab branch from 435f8b8 to b28abea Compare March 3, 2026 12:27
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Mar 3, 2026

@mareklibra
Copy link
Copy Markdown
Member Author

Question - this PR only supports "gitlab.com"? not all enterprise gitlab instances?

So far tested on gitlab.com only.
In a follow-up, I will adapt it to the RH instance.

I believe just the authentication part will be affected by that, not the plugin code itself.

@elai-shalev elai-shalev merged commit 0c598fb into redhat-developer:main Mar 3, 2026
10 checks passed
rohitratannagar pushed a commit to rohitratannagar/rhdh-plugins that referenced this pull request Mar 12, 2026
…#2419)

* feat(x2a): GitLab authentication and token for jobs

Signed-off-by: Marek Libra <marek.libra@gmail.com>

* documentation

* review

---------

Signed-off-by: Marek Libra <marek.libra@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants