cmd/gorelease: sort packages returned by packages.Load.

packages.Load makes no guarantee about the order in which packages are
returned. Previously, we assumed that when an explicit list of
packages are passed in (no patterns), packages are returned in the
same order. packages.Load uses 'go list -deps' internally, which
prints packages in depth-first post-order.

Fixes golang/go#37756

Change-Id: I1999815e778cd2a28145027c9dba19bed51c25f2
Reviewed-on: https://go-review.googlesource.com/c/exp/+/224118
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/cmd/gorelease/gorelease.go b/cmd/gorelease/gorelease.go
index 7c898a5..7480116 100644
--- a/cmd/gorelease/gorelease.go
+++ b/cmd/gorelease/gorelease.go
@@ -870,6 +870,13 @@
 		}
 	}
 
+	// Sort the returned packages by path.
+	// packages.Load makes no guarantee about the order of returned packages.
+	// It uses 'go list -deps', which prints packages in depth-first post-order.
+	sort.Slice(pkgs, func(i, j int) bool {
+		return pkgs[i].PkgPath < pkgs[j].PkgPath
+	})
+
 	// Trim modRoot from file paths in errors.
 	prefix := modRoot + string(os.PathSeparator)
 	for _, pkg := range pkgs {
diff --git a/cmd/gorelease/testdata/mod/example.com_issue37756_v1.0.0.txt b/cmd/gorelease/testdata/mod/example.com_issue37756_v1.0.0.txt
new file mode 100644
index 0000000..b576df8
--- /dev/null
+++ b/cmd/gorelease/testdata/mod/example.com_issue37756_v1.0.0.txt
@@ -0,0 +1,18 @@
+-- go.mod --
+module example.com/issue37756
+
+go 1.14
+-- a/a.go --
+package a
+
+import _ "example.com/issue37756/b"
+
+func A1() {}
+-- b/b.go --
+package b
+
+func B1() {}
+-- c/c.go --
+package c
+
+func C1() {}
diff --git a/cmd/gorelease/testdata/mod/example.com_issue37756_v1.1.0.txt b/cmd/gorelease/testdata/mod/example.com_issue37756_v1.1.0.txt
new file mode 100644
index 0000000..e35bc51
--- /dev/null
+++ b/cmd/gorelease/testdata/mod/example.com_issue37756_v1.1.0.txt
@@ -0,0 +1,21 @@
+-- go.mod --
+module example.com/issue37756
+
+go 1.14
+-- a/a.go --
+package a
+
+import _ "example.com/issue37756/c"
+
+func A1() {}
+func A2() {}
+-- b/b.go --
+package b
+
+func B1() {}
+func B2() {}
+-- c/c.go --
+package c
+
+func C1() {}
+func C2() {}
diff --git a/cmd/gorelease/testdata/regress/README.txt b/cmd/gorelease/testdata/regress/README.txt
new file mode 100644
index 0000000..ee55a78
--- /dev/null
+++ b/cmd/gorelease/testdata/regress/README.txt
@@ -0,0 +1 @@
+This directory contains unrelated tests, used to verify issues are fixed.
\ No newline at end of file
diff --git a/cmd/gorelease/testdata/regress/issue37756.test b/cmd/gorelease/testdata/regress/issue37756.test
new file mode 100644
index 0000000..0a9093c
--- /dev/null
+++ b/cmd/gorelease/testdata/regress/issue37756.test
@@ -0,0 +1,22 @@
+# Verifies golang.org/issue/37756.
+# Packages should be compared in lexical order by package path.
+mod=example.com/issue37756
+version=v1.1.0
+base=v1.0.0
+-- want --
+example.com/issue37756/a
+------------------------
+Compatible changes:
+- A2: added
+
+example.com/issue37756/b
+------------------------
+Compatible changes:
+- B2: added
+
+example.com/issue37756/c
+------------------------
+Compatible changes:
+- C2: added
+
+Suggested version: v1.1.0