Skip to content

Commit 59c99ab

Browse files
dmitshurgopherbot
authored andcommitted
internal/task: add release announcement email templates and test data
This CL contains just the templates and test data for review convenience. The next CL in the stack holds the implementation. The email templates have a MIME-style header with a Subject key, which is used to determine the email subject, and the rest is the email body in Markdown format. While the announcement emails have been generated from templates for a while, there was variation in minor formatting and wording over the years. These templates are converted to Markdown and attempt to not to deviate from the average past announcements too much while correcting minor inconsistencies. Making larger changes can be considered later. It should be easier now that this task is driven by templates without outsourcing the responsibility of HTML formatting and editing to the human senders. For golang/go#47405. Fixes golang/go#47404. Change-Id: Ie04d94b35ce1b5d111eeb1b0b076c034ba3f4dcb Reviewed-on: https://go-review.googlesource.com/c/build/+/412754 Auto-Submit: Dmitri Shuralyov <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Dmitri Shuralyov <[email protected]> Reviewed-by: Heschi Kreinick <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
1 parent d6ffeea commit 59c99ab

16 files changed

+596
-0
lines changed

internal/task/announce.go

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package task
6+
7+
import (
8+
"embed"
9+
"fmt"
10+
"strings"
11+
"text/template"
12+
13+
"golang.org/x/build/maintner/maintnerd/maintapi/version"
14+
)
15+
16+
type ReleaseAnnouncement struct {
17+
// Version is the Go version that has been released.
18+
//
19+
// The version string must use the same format as Go tags. For example:
20+
// • "go1.17.2" for a minor Go release
21+
// • "go1.18" for a major Go release
22+
// • "go1.18beta1" or "go1.18rc1" for a pre-release
23+
Version string
24+
// SecondaryVersion is an older Go version that was also released.
25+
// This only applies to minor releases. For example, "go1.16.10".
26+
SecondaryVersion string
27+
28+
// Security is a list of descriptions, one for each distinct
29+
// security fix included in this release, in Markdown format.
30+
//
31+
// The empty list means there are no security fixes included.
32+
//
33+
// This field applies only to minor releases; it is an error
34+
// to try to use it another release type.
35+
Security []string
36+
37+
// Names is an optional list of release coordinator names to
38+
// include in the sign-off message.
39+
Names []string
40+
}
41+
42+
type mailContent struct {
43+
Subject string
44+
BodyHTML string
45+
BodyText string
46+
}
47+
48+
// announcementMail generates the announcement email for release r.
49+
func announcementMail(r ReleaseAnnouncement) (mailContent, error) {
50+
// Pick a template name for this type of release.
51+
var name string
52+
if i := strings.Index(r.Version, "beta"); i != -1 { // A beta release.
53+
name = "announce-beta.md"
54+
} else if i := strings.Index(r.Version, "rc"); i != -1 { // Release Candidate.
55+
name = "announce-rc.md"
56+
} else if strings.Count(r.Version, ".") == 1 { // Major release like "go1.X".
57+
name = "announce-major.md"
58+
} else if strings.Count(r.Version, ".") == 2 { // Minor release like "go1.X.Y".
59+
name = "announce-minor.md"
60+
} else {
61+
return mailContent{}, fmt.Errorf("unknown version format: %q", r.Version)
62+
}
63+
64+
if len(r.Security) > 0 && name != "announce-minor.md" {
65+
// The Security field isn't supported in templates other than minor,
66+
// so report an error instead of silently dropping it.
67+
//
68+
// Note: Maybe in the future we'd want to consider support for including sentences like
69+
// "This beta release includes the same security fixes as in Go X.Y.Z and Go A.B.C.",
70+
// but we'll have a better idea after these initial templates get more practical use.
71+
return mailContent{}, fmt.Errorf("email template %q doesn't support the Security field; this field can only be used in minor releases", name)
72+
}
73+
74+
// TODO(go.dev/issue/47405): Render the announcement template.
75+
// Get the email subject.
76+
// Render the email body.
77+
return mailContent{}, fmt.Errorf("not implemented yet")
78+
}
79+
80+
// announceTmpl holds templates for Go release announcement emails.
81+
//
82+
// Each email template starts with a MIME-style header with a Subject key,
83+
// and the rest of it is Markdown for the email body.
84+
var announceTmpl = template.Must(template.New("").Funcs(template.FuncMap{
85+
"join": func(s []string) string {
86+
switch len(s) {
87+
case 0:
88+
return ""
89+
case 1:
90+
return s[0]
91+
case 2:
92+
return s[0] + " and " + s[1]
93+
default:
94+
return strings.Join(s[:len(s)-1], ", ") + ", and " + s[len(s)-1]
95+
}
96+
},
97+
"indent": func(s string) string { return "\t" + strings.ReplaceAll(s, "\n", "\n\t") },
98+
99+
// subjectPrefix returns the email subject prefix for release r, if any.
100+
"subjectPrefix": func(r ReleaseAnnouncement) string {
101+
switch {
102+
case len(r.Security) > 0:
103+
// Include a security prefix as documented at https://go.dev/security#receiving-security-updates:
104+
//
105+
// > The best way to receive security announcements is to subscribe to the golang-announce mailing list.
106+
// > Any messages pertaining to a security issue will be prefixed with [security].
107+
//
108+
return "[security]"
109+
default:
110+
return ""
111+
}
112+
},
113+
114+
// short and helpers below manipulate valid Go version strings
115+
// for the current needs of the announcement templates.
116+
"short": func(v string) string { return strings.TrimPrefix(v, "go") },
117+
// major extracts the major part of a valid Go version.
118+
// For example, major("go1.18.4") == "1.18".
119+
"major": func(v string) (string, error) {
120+
x, ok := version.Go1PointX(v)
121+
if !ok {
122+
return "", fmt.Errorf("internal error: version.Go1PointX(%q) is not ok", v)
123+
}
124+
return fmt.Sprintf("1.%d", x), nil
125+
},
126+
// build extracts the pre-release build number of a valid Go version.
127+
// For example, build("go1.19beta2") == "2".
128+
"build": func(v string) (string, error) {
129+
if i := strings.Index(v, "beta"); i != -1 {
130+
return v[i+len("beta"):], nil
131+
} else if i := strings.Index(v, "rc"); i != -1 {
132+
return v[i+len("rc"):], nil
133+
}
134+
return "", fmt.Errorf("internal error: unhandled pre-release Go version %q", v)
135+
},
136+
}).ParseFS(tmplDir, "template/announce-*.md"))
137+
138+
//go:embed template
139+
var tmplDir embed.FS

internal/task/announce_test.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package task
6+
7+
import (
8+
"os"
9+
"path/filepath"
10+
"testing"
11+
12+
"github.com/google/go-cmp/cmp"
13+
)
14+
15+
func TestAnnouncementMail(t *testing.T) {
16+
tests := [...]struct {
17+
name string
18+
in ReleaseAnnouncement
19+
wantSubject string
20+
}{
21+
{
22+
name: "minor",
23+
in: ReleaseAnnouncement{
24+
Version: "go1.18.1",
25+
SecondaryVersion: "go1.17.9",
26+
Names: []string{"Alice", "Bob", "Charlie"},
27+
},
28+
wantSubject: "Go 1.18.1 and Go 1.17.9 are released",
29+
},
30+
{
31+
name: "minor-with-security",
32+
in: ReleaseAnnouncement{
33+
Version: "go1.18.1",
34+
SecondaryVersion: "go1.17.9",
35+
Security: []string{
36+
`encoding/pem: fix stack overflow in Decode
37+
38+
A large (more than 5 MB) PEM input can cause a stack overflow in Decode, leading the program to crash.
39+
40+
Thanks to Juho Nurminen of Mattermost who reported the error.
41+
42+
This is CVE-2022-24675 and https://go.dev/issue/51853.`,
43+
`crypto/elliptic: tolerate all oversized scalars in generic P-256
44+
45+
A crafted scalar input longer than 32 bytes can cause P256().ScalarMult or P256().ScalarBaseMult to panic. Indirect uses through crypto/ecdsa and crypto/tls are unaffected. amd64, arm64, ppc64le, and s390x are unaffected.
46+
47+
This was discovered thanks to a Project Wycheproof test vector.
48+
49+
This is CVE-2022-28327 and https://go.dev/issue/52075.`,
50+
`crypto/x509: non-compliant certificates can cause a panic in Verify on macOS in Go 1.18
51+
52+
Verifying certificate chains containing certificates which are not compliant with RFC 5280 causes Certificate.Verify to panic on macOS.
53+
54+
These chains can be delivered through TLS and can cause a crypto/tls or net/http client to crash.
55+
56+
Thanks to Tailscale for doing weird things and finding this.
57+
58+
This is CVE-2022-27536 and https://go.dev/issue/51759.`,
59+
},
60+
},
61+
wantSubject: "[security] Go 1.18.1 and Go 1.17.9 are released",
62+
},
63+
{
64+
name: "beta",
65+
in: ReleaseAnnouncement{
66+
Version: "go1.19beta5",
67+
},
68+
wantSubject: "Go 1.19 Beta 5 is released",
69+
},
70+
{
71+
name: "rc",
72+
in: ReleaseAnnouncement{
73+
Version: "go1.19rc6",
74+
},
75+
wantSubject: "Go 1.19 Release Candidate 6 is released",
76+
},
77+
{
78+
name: "major",
79+
in: ReleaseAnnouncement{
80+
Version: "go1.19",
81+
},
82+
wantSubject: "Go 1.19 is released",
83+
},
84+
}
85+
for _, tc := range tests {
86+
t.Run(tc.name, func(t *testing.T) {
87+
m, err := announcementMail(tc.in)
88+
if err != nil {
89+
t.Skip("announcementMail is not implemented yet") // TODO(go.dev/issue/47405): Implement.
90+
t.Fatal("announcementMail returned non-nil error:", err)
91+
}
92+
if *updateFlag {
93+
writeTestdataFile(t, "announce-"+tc.name+".html", []byte(m.BodyHTML))
94+
writeTestdataFile(t, "announce-"+tc.name+".txt", []byte(m.BodyText))
95+
return
96+
}
97+
if diff := cmp.Diff(tc.wantSubject, m.Subject); diff != "" {
98+
t.Errorf("subject mismatch (-want +got):\n%s", diff)
99+
}
100+
if diff := cmp.Diff(testdataFile(t, "announce-"+tc.name+".html"), m.BodyHTML); diff != "" {
101+
t.Errorf("body HTML mismatch (-want +got):\n%s", diff)
102+
}
103+
if diff := cmp.Diff(testdataFile(t, "announce-"+tc.name+".txt"), m.BodyText); diff != "" {
104+
t.Errorf("body text mismatch (-want +got):\n%s", diff)
105+
}
106+
if t.Failed() {
107+
t.Log("\n\n(if the new output is intentional, use -update flag to update goldens)")
108+
}
109+
})
110+
}
111+
}
112+
113+
// testdataFile reads the named file in the testdata directory.
114+
func testdataFile(t *testing.T, name string) string {
115+
t.Helper()
116+
b, err := os.ReadFile(filepath.Join("testdata", name))
117+
if err != nil {
118+
t.Fatal(err)
119+
}
120+
return string(b)
121+
}
122+
123+
// writeTestdataFile writes the named file in the testdata directory.
124+
func writeTestdataFile(t *testing.T, name string, data []byte) {
125+
t.Helper()
126+
err := os.WriteFile(filepath.Join("testdata", name), data, 0644)
127+
if err != nil {
128+
t.Fatal(err)
129+
}
130+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Subject: Go {{.Version|major}} Beta {{.Version|build}} is released
2+
3+
Hello gophers,
4+
5+
We have just released {{.Version}}, a beta version of Go {{.Version|major}}.
6+
It is cut from the master branch at the revision tagged {{.Version}}.
7+
8+
Please try your production load tests and unit tests with the new version.
9+
Your help testing these pre-release versions is invaluable.
10+
11+
Report any problems using the issue tracker:
12+
https://go.dev/issue/new
13+
14+
If you have Go installed already, an easy way to try {{.Version}}
15+
is by using the go command:
16+
$ go install golang.org/dl/{{.Version}}@latest
17+
$ {{.Version}} download
18+
19+
You can download binary and source distributions from the usual place:
20+
https://go.dev/dl/#{{.Version}}
21+
22+
To find out what has changed in Go {{.Version|major}}, read the draft release notes:
23+
https://tip.golang.org/doc/go{{.Version|major}}
24+
25+
Cheers,
26+
{{with .Names}}{{join .}} for the{{else}}The{{end}} Go team
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Subject: Go {{short .Version}} is released
2+
3+
Hello gophers,
4+
5+
We have just released Go {{short .Version}}.
6+
7+
To find out what has changed in Go {{short .Version}}, read the release notes:
8+
https://go.dev/doc/{{.Version}}
9+
10+
You can download binary and source distributions from our download page:
11+
https://go.dev/dl/#{{.Version}}
12+
13+
If you have Go installed already, an easy way to try {{.Version}}
14+
is by using the go command:
15+
$ go install golang.org/dl/{{.Version}}@latest
16+
$ {{.Version}} download
17+
18+
To compile from source using a Git clone, update to the release with
19+
`git checkout {{.Version}}` and build as usual.
20+
21+
Thanks to everyone who contributed to the release!
22+
23+
Cheers,
24+
{{with .Names}}{{join .}} for the{{else}}The{{end}} Go team
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Subject: {{subjectPrefix .}}
2+
Go {{short .Version}} and Go {{short .SecondaryVersion}} are released
3+
4+
Hello gophers,
5+
6+
We have just released Go versions {{short .Version}} and {{short .SecondaryVersion}}, minor point releases.
7+
8+
{{with .Security}}These minor releases include {{len .}} security fixes following the [security policy](https://go.dev/security):
9+
{{range .}}
10+
-{{indent .}}
11+
{{end}}
12+
{{end -}}
13+
14+
View the release notes for more information:
15+
https://go.dev/doc/devel/release#{{.Version}}
16+
17+
You can download binary and source distributions from the Go website:
18+
https://go.dev/dl/
19+
20+
To compile from source using a Git clone, update to the release with
21+
`git checkout {{.Version}}` and build as usual.
22+
23+
Thanks to everyone who contributed to the releases.
24+
25+
Cheers,
26+
{{with .Names}}{{join .}} for the{{else}}The{{end}} Go team

internal/task/template/announce-rc.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Subject: Go {{.Version|major}} Release Candidate {{.Version|build}} is released
2+
3+
Hello gophers,
4+
5+
We have just released {{.Version}}, a release candidate version of Go {{.Version|major}}.
6+
It is cut from release-branch.go{{.Version|major}} at the revision tagged {{.Version}}.
7+
8+
Please try your production load tests and unit tests with the new version.
9+
Your help testing these pre-release versions is invaluable.
10+
11+
Report any problems using the issue tracker:
12+
https://go.dev/issue/new
13+
14+
If you have Go installed already, an easy way to try {{.Version}}
15+
is by using the go command:
16+
$ go install golang.org/dl/{{.Version}}@latest
17+
$ {{.Version}} download
18+
19+
You can download binary and source distributions from the usual place:
20+
https://go.dev/dl/#{{.Version}}
21+
22+
To find out what has changed in Go {{.Version|major}}, read the draft release notes:
23+
https://tip.golang.org/doc/go{{.Version|major}}
24+
25+
Cheers,
26+
{{with .Names}}{{join .}} for the{{else}}The{{end}} Go team
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<p>Hello gophers,</p>
2+
<p>We have just released go1.19beta5, a beta version of Go 1.19.<br>
3+
It is cut from the master branch at the revision tagged go1.19beta5.</p>
4+
<p>Please try your production load tests and unit tests with the new version.<br>
5+
Your help testing these pre-release versions is invaluable.</p>
6+
<p>Report any problems using the issue tracker:<br>
7+
<a href="https://go.dev/issue/new">https://go.dev/issue/new</a></p>
8+
<p>If you have Go installed already, an easy way to try go1.19beta5<br>
9+
is by using the go command:<br>
10+
$ go install golang.org/dl/go1.19beta5@latest<br>
11+
$ go1.19beta5 download</p>
12+
<p>You can download binary and source distributions from the usual place:<br>
13+
<a href="https://go.dev/dl/#go1.19beta5">https://go.dev/dl/#go1.19beta5</a></p>
14+
<p>To find out what has changed in Go 1.19, read the draft release notes:<br>
15+
<a href="https://tip.golang.org/doc/go1.19">https://tip.golang.org/doc/go1.19</a></p>
16+
<p>Cheers,<br>
17+
The Go team</p>

0 commit comments

Comments
 (0)