Skip to content

Conversation

jurre
Copy link
Member

@jurre jurre commented Jul 30, 2025

What are you trying to accomplish?

In order for customers to leverage go proxy servers and/or to configure environment variables used by go to determine how to resolve dependencies, we'll now do two things:

  • If a go.env file is present at the root of the repository, we'll pull it in and tell the Go toolchain to use it.
  • If a credential for a goproxy_server is passed in, and no go.env exists, we export the URLs from the credentials as GOPROXY, allowing the toolchain to use it. By default we also append direct so that direct access to dependencies is still possible.

This should give customers all the flexibility they need to configure how go mod accesses dependencies for their projects, with nice defaults.

Anything you want to highlight for special attention from reviewers?

The approach I've taken here is to export these values at the file fetching step, from here on the toolchain should use them.

Since every job runs in its own container, once the job finished the environment is wiped when done.

How will you know you've accomplished your goal?

Tests and manual verification

Checklist

  • I have run the complete test suite to ensure all tests and linters pass.
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request, including the problem it addresses, how it fixes the problem, and any relevant details about the implementation.
  • I have ensured that the code is well-documented and easy to understand.

@jurre jurre requested a review from a team as a code owner July 30, 2025 14:31
@github-actions github-actions bot added the L: go:modules Golang modules label Jul 30, 2025
@jurre jurre force-pushed the jurre/go-proxy-support branch from fffd129 to 5b8ebd6 Compare July 30, 2025 15:15
jakecoffman
jakecoffman previously approved these changes Jul 30, 2025
Copy link
Member

@jakecoffman jakecoffman left a comment

Choose a reason for hiding this comment

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

👍 LGTM, just optional nitpicks

Comment on lines 64 to 69
if go_env
T.must(go_env)
File.write(T.must(go_env).name, T.must(go_env).content)
go_env_path = Pathname.new(T.must(go_env).name).realpath.to_s
ENV["GOENV"] = go_env_path
end
Copy link
Member

Choose a reason for hiding this comment

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

In theory you could always set GOENV to the repo without checking the file exists. The Go CLI will not error if it doesn't find a go.env there. Tried it locally seems to be ok with it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm I think I prefer safeguarding since it's cheap, just in case the behavior ever changes

kbukum1
kbukum1 previously approved these changes Jul 30, 2025
Copy link
Contributor

@kbukum1 kbukum1 left a comment

Choose a reason for hiding this comment

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

LGTM

@jurre
Copy link
Member Author

jurre commented Jul 31, 2025

This actually needs a bit more work, there are some places where we're explicitly passing in a GOPRIVATE environment variable based on what's passed in from job payload, and I think we need to unset these if they are set via the go.env file

@jurre jurre force-pushed the jurre/go-proxy-support branch 4 times, most recently from adb6f9c to a308639 Compare August 6, 2025 08:00
@jurre jurre force-pushed the jurre/go-proxy-support branch from a308639 to 4e5520e Compare August 20, 2025 09:55
def set_goproxy_variable
return if go_env&.content&.include?("GOPROXY")

goproxy_credentials = credentials.select { |cred| cred["type"] == "goproxy_server" }
Copy link
Member

Choose a reason for hiding this comment

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

where do these goproxy_server credentials come from? In the go tests I see git_source credentials being used.

Copy link
Member Author

Choose a reason for hiding this comment

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

They would come in just like other credentials

@alhss
Copy link
Contributor

alhss commented Aug 22, 2025

goprivate testing

I tested your branch against a test repo containing a vitess dependency using two different go.env configurations to validate the environment variable handling works as expected. I built a Docker image from this branch and ran the tests against this custom image to ensure the go.env functionality was properly integrated.

When I set GOPRIVATE="*" in the go.env file, Dependabot behaved exactly as intended - it bypassed the Go package manager proxy and fetched directly from the GitHub source repository. This direct fetching naturally excluded the problematic incompatible versions that were causing issues in the original vitess problem.
When I set GOPRIVATE="" to force proxy usage, Dependabot encountered the same error we've been seeing in the opaque repo when attempting to fetch vitess versions from the Go package manager. This consistent error behavior across both test environments confirms that your go.env implementation is correctly parsing the environment variables and routing dependency requests according to the specified GOPRIVATE settings.

@alhss
Copy link
Contributor

alhss commented Aug 25, 2025

GOPROXY testing

I successfully created a GO private registry through Jfrog. And used it as proxy here
When I set GOPRIVATE="" , all Go modules were successfully routed through the private registry as expected. However, when is set to GOPRIVATE="*" or specific patterns(github.com) or not present at all, Go bypassed the configured proxy entirely and fetched directly from upstream sources like GitHub.
I'm not sure if that's the intended behavior, When a goprivate is not present, the goproxy is completely bypassed. What do you think? @jurre

@jurre
Copy link
Member Author

jurre commented Aug 26, 2025

Go bypassed the configured proxy entirely and fetched directly from upstream sources like GitHub.

Hmm, yeah I think that is problematic because we inject GOPRIVATE=* outside of users' control, I think we might need to avoid setting automatically it if a registry is configured, and only set it if explicitly configured via go.env?

@alhss
Copy link
Contributor

alhss commented Aug 26, 2025

Go bypassed the configured proxy entirely and fetched directly from upstream sources like GitHub.

Hmm, yeah I think that is problematic because we inject GOPRIVATE=* outside of users' control, I think we might need to avoid setting automatically it if a registry is configured, and only set it if explicitly configured via go.env?

@jurre i think the best solution here is probably Only inject GOPRIVATE when GOPROXY is not present, and do nothing when goproxy is present. that reduces complexity on customers about always setting goprivate

@jurre
Copy link
Member Author

jurre commented Aug 26, 2025

@jurre i think the best solution here is probably Only inject GOPRIVATE when GOPROXY is not present, and do nothing when goproxy is present. that reduces complexity on customers about always setting goprivate

I think that's right, let me run through the logic and think about potential edge cases for a bit tomorrow though

@jurre jurre force-pushed the jurre/go-proxy-support branch 2 times, most recently from 16a37c9 to c19a2da Compare August 27, 2025 12:29
@jurre jurre force-pushed the jurre/go-proxy-support branch from c19a2da to fdd8331 Compare August 28, 2025 11:22
In order for customers to leverage go proxy servers and/or to configure
environment variables used by go to determine how to resolve
dependencies, we'll now do two things:

- If a `go.env` file is present at the root of the repository, we'll
  pull it in and tell the Go toolchain to use it.
- If a credential for a goproxy_server is passed in, and no `go.env`
  exists, we export the URLs from the credentials as `GOPROXY`, allowing
  the toolchain to use it. By default we also append `direct` so that
  direct access to dependencies is still possible.

This should give customers all the flexibility they need to configure
how go mod accesses dependencies for their projects, with nice defaults.

The approach I've taken here is to export these values at the file
fetching step, from here on the toolchain should use them.

Since every job runs in its own container, once the job finished the
environment is wiped when done.
jurre and others added 2 commits August 28, 2025 13:22
This makes it easier to configure things correctly once, since the local
variables would otherwise override what is configured via go.env
@jurre jurre force-pushed the jurre/go-proxy-support branch from fdd8331 to d6101c6 Compare August 28, 2025 11:22
By default dependabot will set `GOPRIVATE=*`, which will cause none of
the dependencies to go through the proxy that was configured.

When `go.env` configures this value it is still respected.

Co-authored-by: alhss <[email protected]>
@jurre jurre force-pushed the jurre/go-proxy-support branch from d6101c6 to ae9c361 Compare August 28, 2025 11:24
@jurre
Copy link
Member Author

jurre commented Aug 28, 2025

Seeing a failure in CI now that seems not related to the changes here and I can reproduce on main, but taking a look at it nonetheless

@alhss
Copy link
Contributor

alhss commented Aug 28, 2025

Seeing a failure in CI now that seems not related to the changes here and I can reproduce on main, but taking a look at it nonetheless

It was a flaky test

@alhss alhss merged commit 637b597 into main Aug 29, 2025
81 checks passed
@alhss alhss deleted the jurre/go-proxy-support branch August 29, 2025 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
L: go:modules Golang modules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants