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>
diff --git a/app/appengine/dash.go b/app/appengine/dash.go
index d4dd42d..1250188 100644
--- a/app/appengine/dash.go
+++ b/app/appengine/dash.go
@@ -8,6 +8,8 @@
"context"
"encoding/gob"
"net/http"
+ "sort"
+ "strings"
"google.golang.org/appengine"
)
@@ -196,19 +198,19 @@
},
}
-// 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
}
diff --git a/app/appengine/dash_test.go b/app/appengine/dash_test.go
new file mode 100644
index 0000000..18a8515
--- /dev/null
+++ b/app/appengine/dash_test.go
@@ -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)
+ }
+ }
+}
diff --git a/app/appengine/notify.go b/app/appengine/notify.go
index 6c0b9fb..47b5adc 100644
--- a/app/appengine/notify.go
+++ b/app/appengine/notify.go
@@ -123,7 +123,7 @@
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 @@
sendPerfMailTmpl = template.Must(
template.New("perf_notify.txt").
Funcs(template.FuncMap(tmplFuncs)).
- ParseFiles("app/appengine/perf_notify.txt"),
+ ParseFiles(templateFile("perf_notify.txt")),
)
)
diff --git a/app/appengine/perf_changes.go b/app/appengine/perf_changes.go
index ec276ee..2602af5 100644
--- a/app/appengine/perf_changes.go
+++ b/app/appengine/perf_changes.go
@@ -215,7 +215,7 @@
}
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 {
diff --git a/app/appengine/perf_detail.go b/app/appengine/perf_detail.go
index 2ff7a96..0a91d1c 100644
--- a/app/appengine/perf_detail.go
+++ b/app/appengine/perf_detail.go
@@ -209,5 +209,5 @@
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")),
)
diff --git a/app/appengine/perf_graph.go b/app/appengine/perf_graph.go
index 319a22a..92f580c 100644
--- a/app/appengine/perf_graph.go
+++ b/app/appengine/perf_graph.go
@@ -238,7 +238,7 @@
}
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 {
diff --git a/app/appengine/perf_learn.go b/app/appengine/perf_learn.go
index 156f014..eef4da6 100644
--- a/app/appengine/perf_learn.go
+++ b/app/appengine/perf_learn.go
@@ -157,7 +157,7 @@
}
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 {
diff --git a/app/appengine/ui.go b/app/appengine/ui.go
index d273393..8f86be6 100644
--- a/app/appengine/ui.go
+++ b/app/appengine/ui.go
@@ -14,6 +14,8 @@
"fmt"
"html/template"
"net/http"
+ "os"
+ "path/filepath"
"sort"
"strconv"
"strings"
@@ -110,13 +112,7 @@
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 @@
}
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 @@
}
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)
+}