Skip to content

added renovate endpoint and dashboard endpoint#1833

Open
5byuri wants to merge 4 commits intomainfrom
renovate-bot-feature
Open

added renovate endpoint and dashboard endpoint#1833
5byuri wants to merge 4 commits intomainfrom
renovate-bot-feature

Conversation

@5byuri
Copy link
Copy Markdown
Member

@5byuri 5byuri commented Mar 31, 2026

already tried this out, will do copilot code review now
most testing was done already here 5byuri/renovate-poc#2

TODO:

  • fix failing tests
  • mocks
  • test backend with new repository, generating pull requests
  • review copilot suggestions

Copilot AI review requested due to automatic review settings March 31, 2026 10:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new Renovate-facing API endpoint that returns a recommended fixed version for a dependency, backed by a new repository/service lookup on stored dependency-vulnerability data.

Changes:

  • Expose GET /api/v1/renovate/recommendation/ handled by DependencyVulnController.GetRecommendation.
  • Introduce a dtos.Recommendation response DTO for external integrations.
  • Add repository/service plumbing to fetch a recent direct_dependency_fixed_version by package name.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
shared/common_interfaces.go Extends DependencyVulnRepository with a new recommendation lookup method.
router/apiv1_router.go Registers the new Renovate recommendation endpoint under /api/v1.
dtos/recommendation_dto.go Adds the JSON response DTO for recommended version.
database/repositories/dependency_vuln_repository.go Implements DB query to fetch the latest direct-dependency fixed version by package name.
controllers/dependency_vuln_controller.go Adds the HTTP handler and PURL version extraction helper.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +504 to +511
currentValue := ctx.QueryParam("packageValue")
if currentValue == "" {
currentValue = ctx.QueryParam("currentValue")
}
if currentValue == "" {
return echo.NewHTTPError(400, "missing packageValue or currentValue")
}

Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

currentValue is parsed/validated but never used afterwards; this will not compile in Go due to an unused local variable. Either use currentValue (e.g., to decide whether a recommendation should be returned) or remove the variable and its required-query-param validation.

Suggested change
currentValue := ctx.QueryParam("packageValue")
if currentValue == "" {
currentValue = ctx.QueryParam("currentValue")
}
if currentValue == "" {
return echo.NewHTTPError(400, "missing packageValue or currentValue")
}

Copilot uses AI. Check for mistakes.
Comment on lines +549 to +557
err := repository.GetDB(ctx, tx).
WithContext(ctx).
Table("dependency_vulns").
Where("direct_dependency_fixed_version IS NOT NULL AND direct_dependency_fixed_version != ''").
Where("EXISTS (SELECT 1 FROM jsonb_array_elements(vulnerability_path) AS purl WHERE purl::text LIKE '%/' || ? || '@%')", packageName, packageName).
Select("direct_dependency_fixed_version").
Order("last_detected DESC").
Limit(1).
Scan(&directDependencyFixedVersion).Error
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

This query expands vulnerability_path with jsonb_array_elements(...) and uses a LIKE predicate, which will force a scan over dependency_vulns and is unlikely to use indexes. Since this endpoint can be called frequently (Renovate), consider a more index-friendly approach (e.g., store extracted package names in a dedicated column/table, or use a JSONB/GiN indexable predicate) to avoid performance degradation as the table grows.

Copilot uses AI. Check for mistakes.
Comment on lines 229 to 234
GetHintsInOrganizationForVuln(ctx context.Context, tx DB, orgID uuid.UUID, pURL string, cveID string) (dtos.DependencyVulnHints, error)
GetAllByAssetIDAndState(ctx context.Context, tx DB, assetID uuid.UUID, state dtos.VulnState, durationSinceStateChange time.Duration) ([]models.DependencyVuln, error)
GetDependencyVulnsByOtherAssetVersions(ctx context.Context, tx DB, assetVersionName string, assetID uuid.UUID) ([]models.DependencyVuln, error)
GetAllVulnsByArtifact(ctx context.Context, tx DB, artifact models.Artifact) ([]models.DependencyVuln, error)
GetAllVulnsForTagsAndDefaultBranchInAsset(ctx context.Context, tx DB, assetID uuid.UUID, excludedStates []dtos.VulnState) ([]models.DependencyVuln, error)
// regardless of path. Used for applying status changes to all instances of a CVE+component combination.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

Adding a new method to DependencyVulnRepository requires regenerating/updating any mocks (e.g., the mockery-generated mocks.DependencyVulnRepository) so tests compile. Please ensure mock generation is rerun and committed as part of this change.

Copilot uses AI. Check for mistakes.
Comment on lines +495 to +523
func (controller DependencyVulnController) GetRecommendation(ctx echo.Context) error {
packageName := ctx.QueryParam("packageName")
if packageName == "" {
packageName = ctx.QueryParam("depName")
}
if packageName == "" {
return echo.NewHTTPError(400, "missing packageName or depName")
}

currentValue := ctx.QueryParam("packageValue")
if currentValue == "" {
currentValue = ctx.QueryParam("currentValue")
}
if currentValue == "" {
return echo.NewHTTPError(400, "missing packageValue or currentValue")
}

recommendedVersion, err := controller.dependencyVulnService.GetDirectDependencyFixedVersionByPackageName(ctx.Request().Context(), packageName)
if err != nil {
return echo.NewHTTPError(500, "could not get recommendation").WithInternal(err)
}
if recommendedVersion == nil || *recommendedVersion == "" {
return ctx.JSON(200, dtos.Recommendation{RecommendedVersion: ""})
}

version := extractVersionFromPURL(*recommendedVersion)

return ctx.JSON(200, dtos.Recommendation{RecommendedVersion: version})
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

New behavior added via GetRecommendation (Renovate integration endpoint) currently has no tests. There are existing controller tests in the repo (e.g., for CreateEvent), so please add coverage for the expected query-param handling and response shape (including the "no recommendation" case).

Copilot uses AI. Check for mistakes.
Comment on lines +546 to +556
func (repository *dependencyVulnRepository) GetDirectDependencyFixedVersionByPackageName(ctx context.Context, tx *gorm.DB, packageName string) (*string, error) {
var directDependencyFixedVersion *string

err := repository.GetDB(ctx, tx).
WithContext(ctx).
Table("dependency_vulns").
Where("direct_dependency_fixed_version IS NOT NULL AND direct_dependency_fixed_version != ''").
Where("EXISTS (SELECT 1 FROM jsonb_array_elements(vulnerability_path) AS purl WHERE purl::text LIKE '%/' || ? || '@%')", packageName, packageName).
Select("direct_dependency_fixed_version").
Order("last_detected DESC").
Limit(1).
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

This repository method looks up a recommendation across the entire dependency_vulns table and is not scoped to an org/project/asset. If this data is tenant-specific, this can leak information across tenants (especially since the router exposes it publicly). Consider scoping the query (e.g., by asset/org) or ensuring the returned recommendation is derived from non-tenant-specific data.

Copilot uses AI. Check for mistakes.
WithContext(ctx).
Table("dependency_vulns").
Where("direct_dependency_fixed_version IS NOT NULL AND direct_dependency_fixed_version != ''").
Where("EXISTS (SELECT 1 FROM jsonb_array_elements(vulnerability_path) AS purl WHERE purl::text LIKE '%/' || ? || '@%')", packageName, packageName).
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

LIKE treats % and _ in the parameter as wildcards. If packageName can contain these characters (e.g., underscores are common), this query can match unintended packages and return incorrect recommendations. Consider using an exact-match approach (e.g., strpos(...) > 0 on extracted text) or escaping wildcards in the parameter.

Suggested change
Where("EXISTS (SELECT 1 FROM jsonb_array_elements(vulnerability_path) AS purl WHERE purl::text LIKE '%/' || ? || '@%')", packageName, packageName).
Where("EXISTS (SELECT 1 FROM jsonb_array_elements(vulnerability_path) AS purl WHERE strpos(purl::text, '/' || ? || '@') > 0)", packageName).

Copilot uses AI. Check for mistakes.
@5byuri 5byuri force-pushed the renovate-bot-feature branch from dbc071f to 1830499 Compare April 1, 2026 11:23
@5byuri 5byuri changed the title added renovate endpoint added renovate endpoint and dashboard endpoint Apr 1, 2026
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