app/appengine: automate the hiding of old release branches

Also, because this is the first CL in this package to add tests, add a
helper to return the right template filename depending on the
environment (go test vs prod) so tests don't panic in init.

Fixes golang/go#34097
Updates golang/go#34116

Change-Id: I4b3e83c2417611cfbdc32e27941dbb90687eb509
Reviewed-on: https://go-review.googlesource.com/c/build/+/194643
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
This commit is contained in:
Brad Fitzpatrick 2019-09-11 16:50:06 +00:00
Родитель 8805279864
Коммит 9c46470faf
8 изменённых файлов: 78 добавлений и 29 удалений

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

@ -8,6 +8,8 @@ import (
"context"
"encoding/gob"
"net/http"
"sort"
"strings"
"google.golang.org/appengine"
)
@ -196,19 +198,19 @@ var goPackages = []*Package{
},
}
// hiddenBranches specifies branches that
// should not be displayed on the build dashboard.
// This also prevents the builder infrastructure
// from testing sub-repos against these branches.
var hiddenBranches = map[string]bool{
"release-branch.go1.4": true,
"release-branch.go1.5": true,
"release-branch.go1.6": true,
"release-branch.go1.7": true,
"release-branch.go1.8": true,
"release-branch.go1.9": true,
"release-branch.go1.10": true,
"release-branch.go1.10-security": true,
"release-branch.go1.11-security": true,
"release-branch.go1.11": true,
// supportedReleaseBranches returns a slice containing the most recent two non-security release branches
// contained in branches.
func supportedReleaseBranches(branches []string) (supported []string) {
for _, b := range branches {
if !strings.HasPrefix(b, "release-branch.go1.") ||
len(b) != len("release-branch.go1.nn") { // assumes nn in range [10, 99]
continue
}
supported = append(supported, b)
}
sort.Strings(supported)
if len(supported) > 2 {
supported = supported[len(supported)-2:]
}
return supported
}

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

@ -0,0 +1,39 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"reflect"
"testing"
)
func TestSupportedReleaseBranches(t *testing.T) {
tests := []struct {
in, want []string
}{
{
in: []string{"master", "release-branch.go1.12", "release-branch.go1.5", "release-branch.go1.14"},
want: []string{"release-branch.go1.12", "release-branch.go1.14"},
},
{
in: []string{"master", "release-branch.go1.12", "release-branch.go1.5", "release-branch.go1.14", "release-branch.go1.15-security", "release-branch.go1.15"},
want: []string{"release-branch.go1.14", "release-branch.go1.15"},
},
{
in: []string{"master", "release-branch.go1.12", "release-branch.go1.5"},
want: []string{"release-branch.go1.12"},
},
{
in: []string{"master", "release-branch.go1.12-security"},
want: nil,
},
}
for _, tt := range tests {
got := supportedReleaseBranches(tt.in)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("supportedReleaseBranches(%q) = %q; want %q", tt.in, got, tt.want)
}
}
}

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

@ -123,7 +123,7 @@ func firstMatch(c context.Context, q *datastore.Query, v interface{}) error {
var (
notifyLater = delay.Func("notify", notify)
notifyTmpl = template.Must(template.New("notify.txt").
Funcs(template.FuncMap(tmplFuncs)).ParseFiles("app/appengine/notify.txt"))
Funcs(template.FuncMap(tmplFuncs)).ParseFiles(templateFile("notify.txt")))
)
// notify tries to update the CL for the given Commit with a failure message.
@ -272,7 +272,7 @@ var (
sendPerfMailTmpl = template.Must(
template.New("perf_notify.txt").
Funcs(template.FuncMap(tmplFuncs)).
ParseFiles("app/appengine/perf_notify.txt"),
ParseFiles(templateFile("perf_notify.txt")),
)
)

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

@ -215,7 +215,7 @@ type uiPerfConfigElem struct {
}
var perfChangesTemplate = template.Must(
template.New("perf_changes.html").Funcs(tmplFuncs).ParseFiles("app/appengine/perf_changes.html"),
template.New("perf_changes.html").Funcs(tmplFuncs).ParseFiles(templateFile("perf_changes.html")),
)
type perfChangesData struct {

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

@ -209,5 +209,5 @@ func (l uiPerfDetailMetrics) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
func (l uiPerfDetailMetrics) Less(i, j int) bool { return l[i].Name < l[j].Name }
var uiPerfDetailTemplate = template.Must(
template.New("perf_detail.html").Funcs(tmplFuncs).ParseFiles("app/appengine/perf_detail.html"),
template.New("perf_detail.html").Funcs(tmplFuncs).ParseFiles(templateFile("perf_detail.html")),
)

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

@ -238,7 +238,7 @@ func perfGraphHandler(w http.ResponseWriter, r *http.Request) {
}
var perfGraphTemplate = template.Must(
template.New("perf_graph.html").ParseFiles("app/appengine/perf_graph.html"),
template.New("perf_graph.html").ParseFiles(templateFile("perf_graph.html")),
)
type perfGraphData struct {

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

@ -157,7 +157,7 @@ func perfLearnHandler(w http.ResponseWriter, r *http.Request) {
}
var perfLearnTemplate = template.Must(
template.New("perf_learn.html").Funcs(tmplFuncs).ParseFiles("app/appengine/perf_learn.html"),
template.New("perf_learn.html").Funcs(tmplFuncs).ParseFiles(templateFile("perf_learn.html")),
)
type perfLearnData struct {

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

@ -14,6 +14,8 @@ import (
"fmt"
"html/template"
"net/http"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
@ -110,13 +112,7 @@ func uiHandler(w http.ResponseWriter, r *http.Request) {
return
}
tagState = []*TagState{s}
for _, b := range branches {
if !strings.HasPrefix(b, "release-branch.") {
continue
}
if hiddenBranches[b] {
continue
}
for _, b := range supportedReleaseBranches(branches) {
s, err := GetTagState(c, "release", b)
if err == datastore.ErrNoSuchEntity {
continue
@ -582,7 +578,7 @@ func (td *uiTemplateData) populateBuildingURLs(ctx context.Context) {
}
var uiTemplate = template.Must(
template.New("ui.html").Funcs(tmplFuncs).ParseFiles("app/appengine/ui.html"),
template.New("ui.html").Funcs(tmplFuncs).ParseFiles(templateFile("ui.html")),
)
var tmplFuncs = template.FuncMap{
@ -706,3 +702,15 @@ func tail(n int, s string) string {
}
return strings.Join(lines[len(lines)-n:], "\n")
}
// templateFile returns the path to the provided HTML template file,
// conditionally prepending a relative path depending on the
// environment.
func templateFile(base string) string {
// In tests the current directory is ".", but in prod it's up
// two levels. So just look to see if it's in . first.
if _, err := os.Stat(base); err == nil {
return base
}
return filepath.Join("app/appengine", base)
}