Skip to content

feat: golang module support pseudo version#8293

Open
olblak wants to merge 1 commit intoupdatecli:mainfrom
olblak:feat/golang/support_pseudoversion
Open

feat: golang module support pseudo version#8293
olblak wants to merge 1 commit intoupdatecli:mainfrom
olblak:feat/golang/support_pseudoversion

Conversation

@olblak
Copy link
Copy Markdown
Member

@olblak olblak commented Apr 3, 2026

Support pseudo version such as github.com/shurcooL/githubv4 v0.0.0-20230215024106-420ad0987b9b for golang module

Test

To test this pull request, you can run the following commands:

pkg/plugins/resources/go/module/
go test

Additional Information

Checklist

  • I have updated the documentation via pull request in website repository.

Tradeoff

Potential improvement

Signed-off-by: Olblak <me@olblak.com>
@olblak olblak added enhancement New feature or request go Pull requests that update Go code labels Apr 3, 2026
@olblak olblak requested a review from Copilot April 3, 2026 17:43
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

This PR extends the Go module resource to better handle modules that don’t publish tagged versions by falling back to Go proxy pseudo-versions (via @latest) when using “latest”-style filters, and updates the condition check to query specific versions via the Go proxy .info endpoint.

Changes:

  • Refactors proxy version retrieval into helper functions and trims/normalizes list responses.
  • Adds @latest JSON parsing to support pseudo-version fallback when no versions are published.
  • Updates Condition to check for a specific version using @v/<version>.info instead of scanning the full version list.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 10 comments.

File Description
pkg/plugins/resources/go/module/version.go Adds proxy helpers and @latest fallback logic to return pseudo-versions when no tagged versions exist.
pkg/plugins/resources/go/module/condition.go Switches condition checks to use the proxy .info endpoint per version and aligns GOPROXY resolution logic.

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

Comment on lines +144 to +148
req, err := http.NewRequestWithContext(ctx, "GET", URL, nil)
if err != nil {
logrus.Errorf("something went wrong while getting go module api data %q\n", err)
return "", err
}
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

getLatestVersionFromProxy uses http.NewRequestWithContext with a variable URL but doesn't include the gosec suppression used elsewhere in this file. With golangci-lint enabling gosec, this is likely to raise G107 and fail CI unless the URL is validated/whitelisted or an explicit suppression with justification is added (as done in getVersionsFromProxy).

Copilot uses AI. Check for mistakes.
Comment on lines +199 to +203
req, err := http.NewRequestWithContext(ctx, "GET", URL, nil)
if err != nil {
logrus.Errorf("something went wrong while getting go module api data %q\n", err)
return "", err
}
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

getVersionInfoFromProxy also builds a request with a variable URL and is missing the gosec G107 suppression / validation approach used above. Please either validate the proxy URL input (Spec.Proxy / GOPROXY) before use or add an explicit, justified suppression so golangci-lint doesn't fail.

Copilot uses AI. Check for mistakes.
return "", nil, fmt.Errorf("GO module %q not found on proxy %q", g.Spec.Module, GOPROXY)
}

// getVersionInfoFromProxy returns all versions of a Golang module from a proxy
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

The doc comment above getVersionsFromProxy is incorrect (it says "getVersionInfoFromProxy returns..."). This makes the helper harder to discover/understand; please update the comment to match the actual function name and behavior.

Suggested change
// getVersionInfoFromProxy returns all versions of a Golang module from a proxy
// getVersionsFromProxy returns all versions of a Golang module from a proxy

Copilot uses AI. Check for mistakes.

data, err := io.ReadAll(res.Body)
if err != nil {
logrus.Errorf("something went wrong while getting npm api data%q\n", err)
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

This error log refers to the "npm api" in a Go module proxy codepath. Please fix the message to reference the Go module/proxy request to avoid confusion when debugging.

Suggested change
logrus.Errorf("something went wrong while getting npm api data%q\n", err)
logrus.Errorf("something went wrong while reading go module proxy response %q\n", err)

Copilot uses AI. Check for mistakes.

data, err := io.ReadAll(res.Body)
if err != nil {
logrus.Errorf("something went wrong while getting npm api data%q\n", err)
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

This error log refers to the "npm api" in a Go module proxy codepath. Please fix the message to reference the Go module/proxy request to avoid confusion when debugging.

Suggested change
logrus.Errorf("something went wrong while getting npm api data%q\n", err)
logrus.Errorf("something went wrong while reading go module proxy response data %q\n", err)

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +106
body, err := httputil.DumpResponse(res, false)
logrus.Errorf("something went wrong while getting golang module data %q\n", err)
logrus.Debugf("skipping proxy %q due to %q\n", proxy, err)
logrus.Debugf("\n%v\n", string(body))
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

When res.StatusCode >= 400, the code logs err from httputil.DumpResponse, not the actual HTTP failure context (status code/status). This can emit misleading "something went wrong" errors even when the dump succeeds (err=nil). Consider logging res.Status/res.StatusCode and only logging the dump error if it occurs.

Suggested change
body, err := httputil.DumpResponse(res, false)
logrus.Errorf("something went wrong while getting golang module data %q\n", err)
logrus.Debugf("skipping proxy %q due to %q\n", proxy, err)
logrus.Debugf("\n%v\n", string(body))
logrus.Errorf("something went wrong while getting golang module data: proxy %q returned HTTP %d (%s)\n", proxy, res.StatusCode, res.Status)
logrus.Debugf("skipping proxy %q due to HTTP %d (%s)\n", proxy, res.StatusCode, res.Status)
body, err := httputil.DumpResponse(res, false)
if err != nil {
logrus.Debugf("failed to dump proxy response for %q: %q\n", proxy, err)
} else {
logrus.Debugf("\n%v\n", string(body))
}

Copilot uses AI. Check for mistakes.
Comment on lines +42 to 56
if proxyVersions == nil && isLatestVersionFilter(g.versionFilter) {
pseudoVersion, err := getLatestVersionFromProxy(ctx, g.webClient, proxy, g.Spec.Module)
if err != nil {
logrus.Debugf("skipping proxy %q due to %q\n", proxy, err)
continue
}

data, err := io.ReadAll(res.Body)
if err != nil {
logrus.Errorf("something went wrong while getting npm api data%q\n", err)
return "", []string{}, err
if pseudoVersion != "" {
versions = append(versions, pseudoVersion)
}

logrus.Debugf("no version published for module %q on proxy %q, fallback to pseudo version %q\n", g.Spec.Module, proxy, pseudoVersion)

return pseudoVersion, versions, nil
}
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

The pseudo-version fallback behavior (empty @v/list => use @latest when the filter is effectively "latest") is new and currently untested. Please add unit/integration coverage that exercises this path (ideally with a mocked HTTPClient) to prevent regressions and flaky behavior changes in version selection.

Copilot uses AI. Check for mistakes.
Comment on lines +172 to +178
type JSONData struct {
Version string `json:"Version"`
Time string `json:"Time"`
}

jsonData := JSONData{}
err = json.Unmarshal(data, &jsonData)
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

JSONData duplicates the same Version/Time shape defined again later (Info). Consider reusing a single struct type for both JSON decodes to reduce duplication and the risk of the two drifting over time.

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +36
for _, proxy := range strings.Split(GOPROXY, ",") {
if !isSupportedGoProxy(proxy) {
continue
}
version, err := getVersionInfoFromProxy(ctx, g.webClient, proxy, g.Spec.Module, versionToCheck)
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

When iterating over strings.Split(GOPROXY, ","), entries may include leading/trailing whitespace (e.g., from env var formatting). Consider strings.TrimSpace(proxy) before isSupportedGoProxy / URL building to avoid generating invalid proxy URLs like "https:// proxy.golang.org".

Copilot uses AI. Check for mistakes.
Comment on lines 32 to 36
for _, proxy := range strings.Split(GOPROXY, ",") {
if !isSupportedGoProxy(proxy) {
continue
}

Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

Like Condition, this loop splits GOPROXY on commas but doesn't trim whitespace for each entry. Trimming each proxy before validation and URL construction would make GOPROXY parsing more robust (e.g., handling "direct, proxy.golang.org").

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request go Pull requests that update Go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants