Skip to content

Conversation

@slachiewicz
Copy link
Member

Problem

The getTopLevelProject() method in AbstractDeployMojo incorrectly treats all SCM URLs as pointing to the same site, causing it to return the wrong top-level project when a project hierarchy uses different SCM URLs.

For example, consider two projects:

  • Child project: scm:git:[email protected]:codehaus-plexus/plexus-sec-dispatcher.git/
  • Parent project: scm:git:https://github.com/codehaus-plexus/plexus-pom.git/

These clearly point to different repositories, but the method incorrectly identifies them as the same site because SCM URLs are opaque URIs. When parsed as URIs, they only expose the scheme ("scm"), while host and port are both null, making all SCM URLs appear identical.

Solution

This PR fixes the issue by:

  1. Adding maven-scm-api dependency to properly parse SCM URLs using ScmUrlUtils.getProviderSpecificPart()

  2. Creating an extractComparableUrl() helper method that:

    • Detects SCM URLs (starting with scm:)
    • Extracts the provider-specific part (e.g., scm:git:https://github.com/user/repo.githttps://github.com/user/repo.git)
    • Handles SCP-like Git syntax (e.g., [email protected]:user/repo.git) by converting it to a comparable format (ssh://github.com/user/repo.git)
    • Returns the original URL unchanged for non-SCM URLs
  3. Updating getTopLevelProject() to use the extracted comparable URLs for site comparison

Example

Before this fix:

// These would incorrectly be considered the same site:
String url1 = "scm:git:[email protected]:codehaus-plexus/plexus-sec-dispatcher.git/";
String url2 = "scm:git:https://github.com/codehaus-plexus/plexus-pom.git/";
// Both parsed as scheme="scm", host=null, port=-1

After this fix:

// These are correctly recognized as different sites:
extractComparableUrl(url1) → "ssh://github.com/codehaus-plexus/plexus-sec-dispatcher.git/"
extractComparableUrl(url2) → "https://github.com/codehaus-plexus/plexus-pom.git/"
// Now properly compared using their actual repository URLs

Testing

Added comprehensive unit tests in AbstractDeployMojoTest covering:

  • Different SCM repositories with SCP syntax (correctly identified as different sites)
  • Same SCM repositories (correctly identified as the same site)
  • Different HTTPS SCM repositories with different domains (correctly identified as different sites)
  • Non-SCM URLs (existing behavior preserved)

All tests pass (9 total, including 4 new tests).

Security

  • No security vulnerabilities in the new maven-scm-api dependency (version 2.1.0)
  • CodeQL analysis shows no security issues introduced

Backward Compatibility

Fully maintained - non-SCM URLs continue to work exactly as before.

Fixes #1159

@slachiewicz slachiewicz added the bug Something isn't working label Oct 19, 2025
Copilot AI and others added 3 commits October 19, 2025 17:46
- Changed extractComparableUrl from private to package-private for testing
- Added scheme normalization for SVN URLs (https -> http) to enable proper comparison
- Added comprehensive test for SVN URLs with different schemes and subpaths
- Test verifies that SVN URLs with http vs https are recognized as same site

Co-authored-by: slachiewicz <[email protected]>
@slachiewicz slachiewicz force-pushed the copilot/fix-gettoplevelproject-bug branch from 1bff0e2 to dbbb8f9 Compare October 19, 2025 15:46
@slachiewicz slachiewicz requested a review from kwin October 19, 2025 16:08
@kwin
Copy link
Member

kwin commented Nov 7, 2025

Can't we rather fix #227? This change is obviously created by AI and doesn't properly leverage existing methods like ScmUrlUtils.isValid(...)

@slachiewicz
Copy link
Member Author

Yes, sure we can fix - this was just an attempt to look In for a solution from a different direction .

@slachiewicz slachiewicz closed this Nov 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[MSITE-1033] AbstractDeployMojo.getTopLevelProject(Project) returns wrong project for SCM URLs

2 participants