Implement SBT UpdateChecker to fetch available versions#14918
Implement SBT UpdateChecker to fetch available versions#14918AbhishekBhaskar wants to merge 24 commits intomainfrom
Conversation
…ishekbhaskar/sbt-file-fetcher
…bot/dependabot-core into abhishekbhaskar/sbt-file-fetcher
…ishekbhaskar/sbt-file-parser
…bot/dependabot-core into abhishekbhaskar/sbt-file-parser
…ot/dependabot-core into abhishekbhaskar/sbt-file-parser
…ishekbhaskar/sbt-update-checker
…ishekbhaskar/sbt-update-checker
There was a problem hiding this comment.
Pull request overview
This PR implements the SBT ecosystem’s UpdateChecker by reusing the Maven shared version/package details infrastructure, enabling Dependabot to discover available versions (including Scala cross-versioned artifacts) from Maven Central and custom SBT resolvers and to produce updated requirement data.
Changes:
- Add SBT
VersionFinderandPackageDetailsFetcherbuilt on Maven shared components to fetch and filter available versions and verify published artifacts via HEAD checks. - Add SBT
RequirementsUpdaterto update exact requirement strings while guarding against Maven-style ranges and property-based declarations. - Replace the SBT
UpdateCheckerstub with a working implementation and add fixture-backed specs.
Show a summary per file
| File | Description |
|---|---|
| sbt/lib/dependabot/sbt/update_checker.rb | Implements SBT update-checking flow (latest/security fix versions, property-awareness, updated requirements). |
| sbt/lib/dependabot/sbt/update_checker/version_finder.rb | Finds latest and lowest security-fix versions using Maven shared filtering + release verification. |
| sbt/lib/dependabot/sbt/update_checker/requirements_updater.rb | Updates requirement strings for exact versions; skips comma-based ranges; respects property-based updates. |
| sbt/lib/dependabot/sbt/package/package_details_fetcher.rb | Fetches version metadata from Maven Central + SBT resolvers + credential repos using shared Maven fetcher behavior. |
| sbt/spec/dependabot/sbt/update_checker_spec.rb | Adds end-to-end UpdateChecker behavior coverage for latest/security-fix/property handling. |
| sbt/spec/dependabot/sbt/update_checker/version_finder_spec.rb | Adds unit coverage for VersionFinder filtering and release verification. |
| sbt/spec/dependabot/sbt/update_checker/requirements_updater_spec.rb | Adds unit coverage for RequirementsUpdater behavior (exact, nil, range, property-based). |
| sbt/spec/dependabot/sbt/package/package_details_fetcher_spec.rb | Adds unit coverage for repository assembly and release listing behavior. |
| sbt/spec/fixtures/maven_metadata/guava.xml | Maven metadata fixture for version listing tests (classifier variants). |
| sbt/spec/fixtures/maven_metadata/cats_core_2.13.xml | Maven metadata fixture for Scala cross-versioned artifact tests (incl. prerelease). |
| sbt/spec/fixtures/maven_metadata/akka_actor_2.13.xml | Maven metadata fixture for prerelease-to-stable behavior tests. |
| sbt/spec/fixtures/maven_metadata/scalatest_2.13.xml | Maven metadata fixture for additional Scala cross-versioned artifact coverage. |
Copilot's findings
- Files reviewed: 12/12 changed files
- Comments generated: 3
kbukum1
left a comment
There was a problem hiding this comment.
@AbhishekBhaskar , is there a reason we are not sharing most be of filtering functions in shared version finder? I mean I am unable to think if there is any difference between maven and sbt, maybe even gradle.
kbukum1
left a comment
There was a problem hiding this comment.
Great job, really. I think everything looks good overall. Just a couple of follow-ups you can consider:
-
If you make the package fetcher shared between
mavenandsbtas a method in their version finders (e.g.def package_fetcher), you can also move the calls related to the fetcher such asreleased?and so on directly into the shared part, instead of keeping them in their related package managers. You can checkuv,pip, and so on to see how they extend the package latest version finder — it may help. -
In general, the PR is doing what it needs to do, so these follow-ups would be more on the optimization side, similar to what I mentioned above.
-
For aligning
gradlewithmavenandsbt, it would be great if we could at least have a refactoring issue opened. Then, depending on bandwidth and priorities, we can decide whether to pick it up or not. Just having the issue tracked would already be great.
What are you trying to accomplish?
Implements the
UpdateCheckerfor the SBT ecosystem. This enables Dependabot to fetch available versions from Maven Central and custom SBT resolvers, correctly resolve Scala-versioned artifacts, and prepare version data for updates. It also refactors the Maven shared version-finding infrastructure to reduce code duplication across Maven, SBT, and Gradle ecosystems.Changes:
Refactoring: Shared version-finder class hierarchy
Introduced
Dependabot::Maven::Shared::BaseVersionFinderas an intermediate abstract class betweenSharedVersionFinderand the Maven/SBTVersionFinderclasses. This separates concerns:SharedVersionFinder— Constants (pre-release qualifiers, snapshot regex, git SHA detection), version-type matching (matches_dependency_version_type?), and shared filters (filter_date_based_versions,filter_version_types). Used by all three ecosystems.BaseVersionFinder— The release-fetching pipeline (fetch_latest_release,fetch_lowest_security_fix_release) with HEAD-check verification via abstractreleased?. Used only by Maven and SBT.New files:
maven/lib/dependabot/maven/shared/base_version_finder.rb— Intermediate class with the release-fetching filter chain shared by Maven and SBTsbt/lib/dependabot/sbt/update_checker/version_finder.rb— Inherits fromBaseVersionFinder; delegates to SBTPackageDetailsFetchersbt/lib/dependabot/sbt/update_checker/requirements_updater.rb— Updates exact version strings in requirements, respects property-based dependenciessbt/lib/dependabot/sbt/package/package_details_fetcher.rb— Inherits fromSharedPackageDetailsFetcher; assembles repositories from SBT resolver declarations + credentialssbt/lib/dependabot/sbt/update_checker.rb— Full implementation replacing stub; delegates toVersionFinderfor version discoveryModified files:
maven/lib/dependabot/maven/shared/shared_version_finder.rb— Removedreleases,latest_version_details,lowest_security_fix_version_details,fetch_latest_release,fetch_lowest_security_fix_release, andreleased?(moved toBaseVersionFinder)maven/lib/dependabot/maven/update_checker/version_finder.rb— Now inherits fromBaseVersionFinderinstead ofSharedVersionFinder; removed duplicated filter-chain methodsgradle/lib/dependabot/gradle/update_checker/version_finder.rb— Removedreleased?override (no longer needed sinceSharedVersionFinderdoesn't declare it)Anything you want to highlight for special attention from reviewers?
Design decisions:
SharedVersionFinderremainsabstract!because it inherits fromPackageLatestVersionFinder(which has an abstractpackage_detailsmethod) without implementing itBaseVersionFindercallsreleased?(version)in the filter chain, which subclasses must implement — Maven/SBT delegate topackage_details_fetcher.released?(HEAD-check), while Gradle bypasses this entirely with its ownlatest_version_detailsoverrideVersionFindercontinues to inherit directly fromSharedVersionFinderbecause it uses a fundamentally different approach (no release verification, custom cooldown logic,max_byinstead offind)latest_version_details,lowest_security_fix_version_details,releases) is unchangedNot in scope (deferred):
PropertyUpdaterfor multi-dependencyvalupdatesHow will you know you've accomplished your goal?
All existing Maven, Gradle, and SBT specs pass, and the shared filter chain is defined in exactly one place (
BaseVersionFinder) rather than duplicated across ecosystemVersionFinderclasses.Checklist