From: Andre Marianiello Date: Tue, 14 Dec 2021 22:50:28 +0000 (+0000) Subject: cmd/go/internal/vcs: prevent Git signatures from breaking commit time parsing X-Git-Tag: go1.18beta2~218 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b1a53ece68d46e4fb59c74d2bc529060861f5dbf;p=gostls13.git cmd/go/internal/vcs: prevent Git signatures from breaking commit time parsing When a user has showSignature=true set in their Git config and the commit in question has a signature, the git-show command will output information about that signature. When this happens, the logic that tries to parsing a timestamp from the git-show output chokes on this signature information and the build stamping fails. This change prevents commit signature information from being displayed even if showSignature=true, preventing this issue. Change-Id: I98d0a6fdd1e90dd1b91e0394713b6eb286a69d1a GitHub-Last-Rev: 610706e23e33a037b9abede2ba0a926c0f336814 GitHub-Pull-Request: golang/go#49790 Reviewed-on: https://go-review.googlesource.com/c/go/+/367034 Trust: Cherry Mui Reviewed-by: Bryan Mills Run-TryBot: Bryan Mills TryBot-Result: Gopher Robot --- diff --git a/src/cmd/go/internal/vcs/vcs.go b/src/cmd/go/internal/vcs/vcs.go index 313dc62b78..36404533c5 100644 --- a/src/cmd/go/internal/vcs/vcs.go +++ b/src/cmd/go/internal/vcs/vcs.go @@ -309,7 +309,7 @@ func gitStatus(vcsGit *Cmd, rootDir string) (Status, error) { // uncommitted files and skip tagging revision / committime. var rev string var commitTime time.Time - out, err = vcsGit.runOutputVerboseOnly(rootDir, "show -s --format=%H:%ct") + out, err = vcsGit.runOutputVerboseOnly(rootDir, "show -s --no-show-signature --format=%H:%ct") if err != nil && !uncommitted { return Status{}, err } else if err == nil { diff --git a/src/cmd/go/testdata/script/version_buildvcs_git_gpg.txt b/src/cmd/go/testdata/script/version_buildvcs_git_gpg.txt new file mode 100644 index 0000000000..6d429c5a52 --- /dev/null +++ b/src/cmd/go/testdata/script/version_buildvcs_git_gpg.txt @@ -0,0 +1,105 @@ +# This test checks that VCS information is stamped into Go binaries even when +# the current commit is signed and the use has configured git to display commit +# signatures. + +[!exec:git] skip +[!exec:gpg] skip +[short] skip +env GOBIN=$GOPATH/bin +env GNUPGHOME=$WORK/.gpupg +mkdir $GNUPGHOME +chmod 0700 $GNUPGHOME + +# Create GPG key +exec gpg --batch --passphrase '' --quick-generate-key gopher@golang.org +exec gpg --list-secret-keys --with-colons gopher@golang.org +cp stdout keyinfo.txt +go run extract_key_id.go keyinfo.txt +cp stdout keyid.txt + +# Initialize repo +cd repo/ +exec git init +exec git config user.email gopher@golang.org +exec git config user.name 'J.R. Gopher' +exec git config --add log.showSignature true +go run ../configure_signing_key.go ../keyid.txt + +# Create signed commit +cd a +exec git add -A +exec git commit -m 'initial commit' --gpg-sign +exec git log + +# Verify commit signature does not interfere with versioning +go install +go version -m $GOBIN/a +stdout '^\tbuild\tgitrevision\t' +stdout '^\tbuild\tgitcommittime\t' +stdout '^\tbuild\tgituncommitted\tfalse$' + +-- repo/README -- +Far out in the uncharted backwaters of the unfashionable end of the western +spiral arm of the Galaxy lies a small, unregarded yellow sun. +-- repo/a/go.mod -- +module example.com/a + +go 1.18 +-- repo/a/a.go -- +package main + +func main() {} + +-- extract_key_id.go -- +package main + +import "fmt" +import "io/ioutil" +import "os" +import "strings" + +func main() { + err := run(os.Args[1]) + if err != nil { + panic(err) + } +} + +func run(keyInfoFilePath string) error { + contents, err := ioutil.ReadFile(keyInfoFilePath) + if err != nil { + return err + } + lines := strings.Split(string(contents), "\n") + for _, line := range lines { + fields := strings.Split(line, ":") + if fields[0] == "sec" { + fmt.Print(fields[4]) + return nil + } + } + return fmt.Errorf("key ID not found in: %s", keyInfoFilePath) +} + +-- configure_signing_key.go -- +package main + +import "io/ioutil" +import "os" +import "os/exec" + +func main() { + err := run(os.Args[1]) + if err != nil { + panic(err) + } +} + +func run(keyIdFilePath string) error { + keyId, err := ioutil.ReadFile(keyIdFilePath) + if err != nil { + return err + } + gitCmd := exec.Command("git", "config", "user.signingKey", string(keyId)) + return gitCmd.Run() +}