Skip to content

fix: open existing workspace when factory URL contains a /tree/<branc…#1608

Open
olexii4 wants to merge 3 commits into
mainfrom
CRW-10950
Open

fix: open existing workspace when factory URL contains a /tree/<branc…#1608
olexii4 wants to merge 3 commits into
mainfrom
CRW-10950

Conversation

@olexii4

@olexii4 olexii4 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Fixes duplicate workspace creation when a factory URL contains a GitHub /tree/<branch> path and "Create New" is disabled.

Root Cause

getSameRepoWorkspaces() in CheckExistingWorkspaces determines whether an existing workspace was created from the same repository by testing two conditions:

workspace.source === factoryParams.sourceUrl && revision === factoryParams.revision

When a workspace is created from https://github.com/org/repo/tree/my-branch:

  • workspace.source is stored as the full URL including /tree/my-branch.
  • The devfile project is created with checkoutFrom.revision = 'my-branch' (extracted by getProjectFromLocation.ts which splits on /tree/).

When the user returns with the same URL and "Create New" unchecked:

  • factoryParams.sourceUrl correctly equals workspace.source — the full URL including /tree/my-branch.
  • factoryParams.revision is undefined because getRevision() only reads the explicit ?revision= query parameter, never the /tree/<branch> path segment.

The revision mismatch ('my-branch' !== undefined) makes every existing workspace fail the filter, so getSameRepoWorkspaces() returns an empty list and a duplicate is created.

URLs without an explicit branch are unaffected because both workspace.checkoutFrom.revision and factoryParams.revision are undefined in that case.

Fix

Extended getRevision() in buildFactoryParams.ts to also extract the branch name from the factory URL's /tree/<branch> path segment when no explicit ?revision= query parameter is present:

 function getRevision(searchParams: URLSearchParams): string | undefined {
-  return searchParams.get(REVISION_ATTR) || undefined;
+  const revisionParam = searchParams.get(REVISION_ATTR) || undefined;
+  if (revisionParam) {
+    return revisionParam;
+  }
+  const factoryUrl = getFactoryUrl(searchParams);
+  if (factoryUrl) {
+    try {
+      const url = new URL(factoryUrl);
+      const parts = url.pathname.split('/tree/');
+      if (parts.length > 1 && parts[1]) {
+        return parts[1];
+      }
+    } catch { /* not a valid URL */ }
+  }
+  return undefined;
 }

The explicit ?revision= query parameter still takes precedence.

What issues does this PR fix or reference?

fixes https://redhat.atlassian.net/browse/CRW-10950

Is it tested? How?

  1. Deploy Dev Spaces with the dashboard image built from this PR.
  2. Go to the User Dashboard and confirm Create New is enabled (default).
  3. In Create Workspace, paste a GitHub URL that includes a branch path, e.g.:
    https://github.com/<org>/<repo>/tree/<branch>
    Create the workspace and wait for it to reach Running.
  4. Return to Create Workspace.
  5. Disable Create New.
  6. Paste the same GitHub URL (same branch) and open the workspace.

Expected: the existing workspace is opened — no duplicate is created.

Before this fix: a new workspace would be created because the branch embedded in the
/tree/<branch> path was not matched against the existing workspace's revision, so
getSameRepoWorkspaces() always returned an empty list.

Release Notes

Docs PR

…h> path (CRW-10950)

When a workspace is created from a GitHub URL with an explicit branch
(e.g. https://github.com/org/repo/tree/my-branch), getSameRepoWorkspaces()
compares workspace.source against factoryParams.sourceUrl (both equal —
the full URL including /tree/my-branch) AND workspace checkoutFrom.revision
('my-branch') against factoryParams.revision.

factoryParams.revision was only populated from the ?revision= query
parameter, never from the /tree/<branch> URL path segment. The revision
mismatch ('my-branch' !== undefined) caused getSameRepoWorkspaces() to
return no matches, so a duplicate workspace was created even when
"Create New" was disabled.

Fix: extend getRevision() in buildFactoryParams.ts to also extract the
branch name from the factory URL's /tree/<branch> path when no explicit
?revision= parameter is present. The explicit query parameter still takes
precedence.

Assisted-by: Claude Sonnet 4.6
Signed-off-by: Oleksii Orel <oorel@redhat.com>
@che-bot

che-bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Click here to review and test in web IDE: Contribute

@tolusha

tolusha commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Hi! I'm che-ai-assistant — I help with your pull requests.

Available commands:

  • /che-ai-assistant generate-che-doc — Generate a documentation PR based on this PR's changes
  • /che-ai-assistant ok-pr-review — Run a comprehensive PR review (summary, code review, deep review, impact analysis)
  • /che-ai-assistant help — Show this help message

@github-actions

Copy link
Copy Markdown

Docker image build succeeded: quay.io/eclipse/che-dashboard:pr-1608 (linux/amd64, linux/arm64, linux/s390x)

kubectl patch command
kubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/dashboard/deployment", "value": {containers: [{image: "quay.io/eclipse/che-dashboard:pr-1608", name: che-dashboard}]}}]"

@olexii4

olexii4 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

/che-ai-assistant ok-pr-review

Review is complete. Please check the review comments below.

@tolusha tolusha left a comment

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.

Comprehensive PR Review - All Stages Complete

APPROVED - This is an excellent fix with clear root cause analysis, minimal and well-scoped changes, and comprehensive test coverage.

Review Summary

Standard Review: ✅ Approve
Deep Review: ✅ Design is Sound
Impact Review: ✅ No Concerns

Highlights

  • Exemplary PR description - Thorough root cause analysis with concrete examples of the workspace matching failure
  • Correct abstraction layer - Fix placed in getRevision() where it belongs, maintaining separation of concerns
  • Follows existing patterns - Uses the same split('/tree/') approach as getProjectFromLocation.ts for consistency
  • Strong test coverage - 4 unit tests covering all scenarios (no param, query param, /tree/ path, precedence) plus integration test
  • Zero operational impact - Pure correctness improvement with no new dependencies, no config changes, no API surface changes

Optional Suggestions

The review identified a few optional improvements that would strengthen the test suite and documentation:

  1. Test for branch names with slashes - Consider adding a test for feature/branch-name patterns (common Git convention, used in this very project)
  2. Test for trailing-slash edge case - Document the behavior for malformed URLs like /tree/ (correctly returns undefined)
  3. Document the shared pattern - Add a cross-reference comment noting that both getRevision() and getProjectFromLocation.ts use split('/tree/'), so both need updating if this pattern changes

These are suggestions for future work, not blockers.

System-Level Analysis

  • Observability: No new logging/metrics needed (synchronous parsing function)
  • Failure handling: Correct - try/catch returns undefined on parse failure, which is the right fallback
  • Resource cleanup: N/A - no resources opened
  • Security: No concerns - read-only URL parsing, no injection vectors
  • Performance: Negligible - executes once during factory param construction

Verdict: Ready to merge. The fix correctly solves the duplicate workspace issue with no operational risk.

🤖 Automated review by che-ai-assistant powered by Claude Sonnet 4.5

@openshift-ci

openshift-ci Bot commented Jun 18, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: olexii4, tolusha

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

- Add cross-reference comment in getRevision() pointing to
  getProjectFromLocation.ts which uses the same split('/tree/')
  pattern, so future changes to support other Git hosts update
  both locations.

- Add two tests documenting edge-case behaviour already handled
  by the code:
  * branch names containing slashes (feature/CRW-10950)
  * /tree/ with no branch name (empty string → undefined)

Assisted-by: Claude Sonnet 4.6
Signed-off-by: Oleksii Orel <oorel@redhat.com>
@openshift-ci openshift-ci Bot removed the lgtm label Jun 18, 2026
@openshift-ci

openshift-ci Bot commented Jun 18, 2026

Copy link
Copy Markdown

New changes are detected. LGTM label has been removed.

split('/tree/') cannot distinguish a branch name containing slashes
(feature/my-branch) from a branch + subdirectory path (main/src/file.ts).
GitHub resolves this ambiguity server-side. The test pins the known
behaviour and notes the tradeoff so future maintainers understand why
the full remainder is returned.

Assisted-by: Claude Sonnet 4.6
Signed-off-by: Oleksii Orel <oorel@redhat.com>
@github-actions

Copy link
Copy Markdown

Docker image build succeeded: quay.io/eclipse/che-dashboard:pr-1608 (linux/amd64, linux/arm64, linux/s390x)

kubectl patch command
kubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/dashboard/deployment", "value": {containers: [{image: "quay.io/eclipse/che-dashboard:pr-1608", name: che-dashboard}]}}]"

1 similar comment
@github-actions

Copy link
Copy Markdown

Docker image build succeeded: quay.io/eclipse/che-dashboard:pr-1608 (linux/amd64, linux/arm64, linux/s390x)

kubectl patch command
kubectl patch -n eclipse-che "checluster/eclipse-che" --type=json -p="[{"op": "replace", "path": "/spec/components/dashboard/deployment", "value": {containers: [{image: "quay.io/eclipse/che-dashboard:pr-1608", name: che-dashboard}]}}]"

@openshift-ci

openshift-ci Bot commented Jun 18, 2026

Copy link
Copy Markdown

@olexii4: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/v19-dashboard-happy-path 564117a link true /test v19-dashboard-happy-path

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@olexii4

olexii4 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

/retest

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.

3 participants