cmd/releasebot: split the release log into multiple posts if necessary

This change splits the release log into parts that are equal to or
smaller than the maximum GitHub comment character limit. It attempts
to break the parts up by the last new line found per part.

Fixes golang/go#45998

Change-Id: Ica35ceff961e7c02a1e37fc1f928705c32007853
Reviewed-on: https://go-review.googlesource.com/c/build/+/318070
Trust: Carlos Amedee <carlos@golang.org>
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Carlos Amedee 2021-05-07 14:47:00 -04:00
Родитель 58cc22bdea
Коммит 6a8a81f6d1
3 изменённых файлов: 107 добавлений и 4 удалений

Просмотреть файл

@ -235,9 +235,11 @@ func (w *Work) removeOkayAfterBeta1() {
}
}
const githubCommentCharacterLimit = 65536 // discovered in golang.org/issue/45998
func postGithubComment(number int, body string) error {
if dryRun {
return errors.New("attemted write operation in dry-run mode")
return errors.New("attempted write operation in dry-run mode")
}
_, _, err := githubClient.Issues.CreateComment(context.TODO(), projectOwner, projectRepo, number, &github.IssueComment{
Body: &body,

Просмотреть файл

@ -567,9 +567,16 @@ func (w *Work) postSummary() {
if dryRun || w.Security {
return
}
err := postGithubComment(w.ReleaseIssue, body)
if err != nil {
fmt.Printf("error posting update comment: %v\n", err)
// Ensure that the entire body can be posted to the issue by splitting it into multiple
// GitHub comments if necesary.
// golang.org/issue/45998
bodyParts := splitLogMessage(body, githubCommentCharacterLimit)
for _, b := range bodyParts {
err := postGithubComment(w.ReleaseIssue, b)
if err != nil {
fmt.Printf("error posting update comment: %v\n", err)
}
}
}
@ -946,3 +953,25 @@ func match(query, goVer string) bool {
panic(fmt.Errorf("match: query %q is not supported", query))
}
}
// splitLogMessage splits a string into n number of strings of maximum size maxStrLen.
// It naively attempts to split the string along the bounderies of new line characters in order
// to make each individual string as readable as possible.
func splitLogMessage(s string, maxStrLen int) []string {
sl := []string{}
for len(s) > maxStrLen {
end := strings.LastIndex(s[:maxStrLen], "\n")
if end == -1 {
end = maxStrLen
}
sl = append(sl, s[:end])
if string(s[end]) == "\n" {
s = s[end+1:]
} else {
s = s[end:]
}
}
sl = append(sl, s)
return sl
}

Просмотреть файл

@ -90,3 +90,75 @@ func TestAllQueriesSupported(t *testing.T) {
})
}
}
func TestSplitLogMessage(t *testing.T) {
testCases := []struct {
desc string
str string
maxLen int
want []string
}{
{
desc: "string matches max size",
str: "the quicks",
maxLen: 10,
want: []string{"the quicks"},
},
{
desc: "string greater than max size",
str: "the quick brown fox",
maxLen: 10,
want: []string{"the quick ", "brown fox"},
},
{
desc: "string smaller than max size",
str: "the quick",
maxLen: 20,
want: []string{"the quick"},
},
{
desc: "string matches max size with return",
str: "the quick\n",
maxLen: 10,
want: []string{"the quick\n"},
},
{
desc: "string greater than max size with return",
str: "the quick\n brown fox",
maxLen: 10,
want: []string{"the quick", " brown fox"},
},
{
desc: "string smaller than max size with return",
str: "the \nquick",
maxLen: 20,
want: []string{"the \nquick"},
},
{
desc: "string is multiples of max size",
str: "000000000011111111112222222222",
maxLen: 10,
want: []string{"0000000000", "1111111111", "2222222222"},
},
{
desc: "string is multiples of max size with return",
str: "000000000\n111111111\n222222222\n",
maxLen: 10,
want: []string{"000000000", "111111111", "222222222\n"},
},
{
desc: "string is multiples of max size with extra return",
str: "000000000\n111111111\n222222222\n\n",
maxLen: 10,
want: []string{"000000000", "111111111", "222222222", "\n"},
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
got := splitLogMessage(tc.str, tc.maxLen)
if !cmp.Equal(tc.want, got) {
t.Errorf("splitStringToSlice(%q, %d) =\ngot \t %#v\nwant \t %#v", tc.str, tc.maxLen, got, tc.want)
}
})
}
}