Skip to content

Upgrade to Go v1.27 - #6332

Merged
chrisd8088 merged 1 commit into
git-lfs:mainfrom
chrisd8088:upgrade-go-1-27
Aug 24, 2026
Merged

chrisd8088 merged 1 commit into
git-lfs:mainfrom
chrisd8088:upgrade-go-1-27

Conversation

@chrisd8088

Copy link
Copy Markdown
Member

Go version 1.27 has been released, and because we aim to build and test Git LFS against only supported versions of Go, we upgrade our GitHub Actions CI workflows to test against Go versions 1.27 and 1.26.

After this PR is merged, we will revise the required set of jobs in our CI test suite, and also upgrade the version of Go used in the scripts and Dockerfiles in our github/build-dockers project.

Go version 1.27 has been released, and because we aim to build and test
Git LFS against only supported versions of Go, we upgrade our GitHub
Actions CI workflows to test against Go versions 1.27 and 1.26.
@chrisd8088
chrisd8088 requested a review from a team as a code owner August 24, 2026 05:08
@chrisd8088 chrisd8088 added the github_actions Pull requests that update GitHub Actions code label Aug 24, 2026
@chrisd8088
chrisd8088 merged commit 4b49bc7 into git-lfs:main Aug 24, 2026
10 checks passed
@chrisd8088
chrisd8088 deleted the upgrade-go-1-27 branch August 24, 2026 15:59
chrisd8088 added a commit that referenced this pull request Oct 22, 2026
Our integration test suite includes an "lfs-ssh-echo" test utility
program which a number of tests use to simulate the behaviour of an
actual SSH client and server.  Our tests set the GIT_SSH environment
variable with the name of the "lfs-ssh-echo" utility so that the
Git LFS client will invoke the utility when making requests to a
remote SSH server.

When the Git LFS client specifies the "git-lfs-authenticate" command
in the arguments it passes to the "lfs-ssh-echo" utility, the utility
simulates the JSON response expected from a remote server.  The JSON
the utility outputs contains an HTTP URL constructed from the other
SSH command arguments, one of which is the name of the repository
the Git LFS client has extracted from the path portion of the URL
configured for the Git remote.

Our tests typically configure SSH remotes using a full SSH URL syntax,
so the path portion of the URL begins with a leading slash character,
i.e., "ssh://<user>@<host>:<port>/<path>".  (Both Git and Git LFS also
accept SSH remotes configured using an scp(1)-style format, i.e.,
"<user>@<host>:<path>", in which case the path does not begin with
a leading slash character.)

At present, our "lfs-ssh-echo" utility expects that the repository
name it extracts from its command-line arguments always begins with
a leading slash character.  While this is sufficient for our current
set of tests, an unintended consequence is that the HTTP URL the
utility returns in its JSON response contains an extra leading slash
character in the path component.

When the Git LFS client then makes a request to this HTTP URL whose
path begins with an extra slash character, our "lfstest-gitserver"
test utility program responds with a 307 Temporary Redirect status
code and a Location header, the value of which is the same URL but
with the extra slash character removed.

This HTTP redirection is enforced by the "net/http" package of the
Go standard library.  Our "lfstest-gitserver" utility uses the
"net/http" package's ServeMux structure and methods to listen for
HTTP requests and route them to various functions, and the Go
library's implementation of this HTTP multiplexing service sanitizes
request paths by redirecting clients when necessary:

  https://pkg.go.dev/net/http#hdr-Request_sanitizing-ServeMux

In a subsequent commit, we expect to introduce new shell tests which
construct SSH URLs with URL-encoded characters in their paths.  If
the paths of these URLs also contain an extra leading slash character
when they are used in requests to the "lfstest-gitserver" utility,
the Go library's ServeMux HTTP multiplexing service will sanitize
the URL path and return the result in a Location header with a 307
status code response.

As well, with Go v1.26, which is one of the currently supported
versions of Go, the sanitized URL paths will have a second level of
URL-encoding applied.  The consequence is that each percent sign
("%") character from the original URL will be re-encoded as "%25",
which would in turn lead to repository names with two levels of
URL-encoded characters, making our tests more complicated than we
desire them to be.

This problem with Go v1.26 was resolved in v1.27 by the changes
in commit golang/go@57f9a58,
which addressed the issue reported in golang/go#79897.  Since
PR #6332, we now build our Git LFS release binaries against Go v1.27,
but we still support Go v1.26 and run a CI job with that version
of Go.  When our new shell tests were performed by that CI job,
the sanitized URLs returned by the Go library's ServeMux HTTP
multiplexing service would differ from those generated in our
other CI jobs, leading to further complexity in our test suite.

To avoid these concerns, we first revise our "lfs-ssh-echo" utility
so that it removes any leading slash character from the repository
name it derives from its command-line arguments.  As a result, the
URLs returned by the utility in response to "git-lfs-authenticate"
commands will no longer have an extra leading slash character in
their paths.

This change has several salutary effects.  First, the URLs returned
by the "lfs-ssh-echo" utility will now be accepted by the
"lfstest-gitserver" utility without causing a redirection response,
which simplifies the steps performed during our tests of the client's
SSH support.

Second, because no redirection occurs, the request URL is not
sanitized by the Go library's ServeMux HTTP multiplexing service,
so we will avoid the problem in Go v1.26 which causes sanitized URLs
to be re-encoded.  When we add tests which include URL-encoded
characters in their SSH URLs, the "lfstest-gitserver" utility will
accept those request URLs without change.  As a consequence, the
repository names that the utility derives from the URLs will not
be doubly URL-encoded by Go v1.26, thus simplifying our new tests.

Third, the repository name that the "lfs-ssh-echo" utility extracts
from its command-line arguments will now be consistent regardless
of whether it was specified with or without a leading slash
character, which varies depending on whether a test configured an
SSH remote using the URL format or the scp(1)-style format.
The "lfs-ssh-echo" utility alters its behaviour for certain tests,
based on whether the repository name matches one of a set of
specific strings.  Previously, these strings all began with
leading slash characters, which required that the corresponding
tests configure their SSH remotes using the URL format.  However,
this restriction is no longer necessary, as the tests could now
be revised to use the scp(1) format for their SSH remotes and
the "lfs-ssh-echo" utility would continue to recognize the names
of their repositories.

In addition to modifying the "lfs-ssh-echo" utility, we also take
the opportunity to fix the format of a trace log statement generated
by the "lfstest-gitserver" utility when it responds to Git LFS
Batch API requests.  At present, we use the utility's debug()
function to log the JSON of the responses to these requests, but
we pass the JSON string to the function as its second parameter,
so the function uses it as part of a format specifier in a call to
the Printf() function of the Go standard library's "log" package.

When the JSON string includes percent sign characters, as will
occur when we introduce tests which produce repository names with
URL-encoded characters, the "log" package's Printf() function will
try to interpret the percent sign characters as formatting verbs
and will insert format error messages in its output:

  https://pkg.go.dev/fmt#hdr-Format_errors

To avoid this problem and lessen the difficulty of debugging
future problems related to URL-encoded characters, we simply
alter the "lfstest-gitserver" utility so that when it logs the
JSON response to a Batch API request, it passes a plain "%s" format
specifier to the debug() function and passes the JSON string as
the sole argument to be interpolated into that format specifier.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

github_actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants