]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/vcs: prevent Git signatures from breaking commit time parsing
authorAndre Marianiello <andremarianiello@users.noreply.github.com>
Tue, 14 Dec 2021 22:50:28 +0000 (22:50 +0000)
committerBryan Mills <bcmills@google.com>
Thu, 16 Dec 2021 22:39:00 +0000 (22:39 +0000)
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 <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/go/internal/vcs/vcs.go
src/cmd/go/testdata/script/version_buildvcs_git_gpg.txt [new file with mode: 0644]

index 313dc62b780e6c9f39981ba416bd0d7077ebfa01..36404533c51c97a8910dc43962dc73e64e8e6ab0 100644 (file)
@@ -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 (file)
index 0000000..6d429c5
--- /dev/null
@@ -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()
+}