webfactory / ssh-agent

GitHub Action to setup `ssh-agent` with a private key
MIT License
1.23k stars 256 forks source link

Go compatibility #82

Closed iamnoah closed 3 years ago

iamnoah commented 3 years ago

I struggled to get Go private modules working and wanted to share my workaround in case it's helpful or the changes can be incorporated. Basically the default .gitconfig generated when using commented keys doesn't seem to work with go get and related commands.

The tl;dr is I need the config to go from this:

[url "git@d5ec..:my-org/my-repo.git"]
    insteadOf = https://github.com/my-org/my-repo.git
        ...

to

[url "ssh://git@d5ec.../my-org/my-repo"]
    insteadOf = https://github.com/my-org/my-repo
    ...

The key differences being:

The reason for this seems to be that go interacts with git by specifying the origin as https://github.com/my-org/my-repo, which works, but won't match the longer (arguably more correct) URL you've put in the config. e.g., internally go is doing git remote add origin -- https://github.com/my-org/my-repo without a trailing slash or .git.

I'm currently working around this with this sed script:

          sed -i.bak -re '
          s|(insteadOf.*https://.*)\.git$|\1|g
          s|\[url "(git@[^:]*]?):(.*?)\.git"\]$|[url "ssh://\1/\2"]|g' ~/.gitconfig

NOTE: For anyone else trying to get this working, you will also need GOPRIVATE=github.com/my-org/* as an environment variable.

mpdude commented 3 years ago

Thank you for raising this issue! First, let me say that I have no experience with go at all.

I have tried to find some documentation on how go finds and loads private modules and I came across this https://golang.org/ref/mod#vcs-find:

If the module path has a VCS qualifier (one of .bzr, .fossil, .git, .hg, .svn) at the end of a path component, the go command will use everything up to that path qualifier as the repository URL. For example, for the module example.com/foo.git/bar, the go command downloads the repository at example.com/foo.git using git, expecting to find the module in the bar subdirectory. The go command will guess the protocol to use based on the protocols supported by the version control tool.

Also, a bit further down, it says:

repo-url is the repository's URL. If the URL does not include a scheme (either because the module path has a VCS qualifier or because the tag lacks a scheme), the go command will try each protocol supported by the version control system. For example, with Git, the go command will try https:// then git+ssh://. Insecure protocols (like http:// and git://) may only be used if the module path is matched by the GOINSECURE environment variable.

This makes me wonder if you could specify your module slightly different, including the .git extension, to make it work without the extra configuration?

iamnoah commented 3 years ago

I honestly am not entirely sure what that is referring to, but including the scheme is not valid in go.mod. I can't go get ssh://.. without getting go get: malformed module path

There are some hardcoded assumptions in the go tooling about the github.com namespace that cause it to default to git over https. I could be wrong and there is an easier workaround, but the only solution I have seen is to use insteadOf gitconfig to rewrite the URL.

mpdude commented 3 years ago

https://github.com/webfactory/ssh-agent/blob/5f066a372ec13036ab7cb9a8adf18c936f8d2043/index.js#L53-L68

Doesn't that generate the insteadOf = config value without a trailing .git as you suggested?

iamnoah commented 3 years ago

@mpdude my apologies, I seem to have been running against v0.5.0. The URL format in v0.5.3 seems to resolve everything for me without modifications. Thanks!