[autoroll] Include server URL in notification messages

Bug: 922239
Change-Id: I6fe216214fa4048f1c7213cc57f0d44b88f56188
Reviewed-on: https://skia-review.googlesource.com/c/184380
Reviewed-by: Ravi Mistry <rmistry@google.com>
Commit-Queue: Eric Boren <borenet@google.com>
diff --git a/autoroll/go/notifier/notifier.go b/autoroll/go/notifier/notifier.go
index 6a55acf..b71edd9 100644
--- a/autoroll/go/notifier/notifier.go
+++ b/autoroll/go/notifier/notifier.go
@@ -32,6 +32,8 @@
 
 	subjectLastNFailed = "The last {{.N}} {{.ChildName}} into {{.ParentName}} rolls have failed"
 	bodyLastNFailed    = "The roll is failing consistently. Time to investigate. The most recent roll attempt is here: {{.IssueURL}}"
+
+	footer = "\n\nThe AutoRoll server is located here: {{.ServerURL}}"
 )
 
 var (
@@ -55,6 +57,8 @@
 
 	subjectTmplLastNFailed = template.Must(template.New("subjectLastNFailed").Parse(subjectLastNFailed))
 	bodyTmplLastNFailed    = template.Must(template.New("bodyLastNFailed").Parse(bodyLastNFailed))
+
+	footerTmpl = template.Must(template.New("footer").Parse(footer))
 )
 
 // tmplVars is a struct which contains information used to fill
@@ -67,6 +71,7 @@
 	Message        string
 	N              int
 	ParentName     string
+	ServerURL      string
 	Strategy       string
 	ThrottledUntil string
 	User           string
@@ -79,15 +84,17 @@
 	emailer    *email.GMail
 	n          *notifier.Router
 	parentName string
+	serverURL  string
 }
 
 // Return an AutoRollNotifier instance.
-func New(ctx context.Context, childName, parentName string, emailer *email.GMail, configs []*notifier.Config) (*AutoRollNotifier, error) {
+func New(ctx context.Context, childName, parentName, serverURL string, emailer *email.GMail, configs []*notifier.Config) (*AutoRollNotifier, error) {
 	n := &AutoRollNotifier{
 		childName:  childName,
 		emailer:    emailer,
 		n:          notifier.NewRouter(emailer),
 		parentName: parentName,
+		serverURL:  serverURL,
 	}
 	if err := n.ReloadConfigs(ctx, configs); err != nil {
 		return nil, err
@@ -114,6 +121,7 @@
 func (a *AutoRollNotifier) send(ctx context.Context, vars *tmplVars, subjectTmpl, bodyTmpl *template.Template, severity notifier.Severity) {
 	vars.ChildName = a.childName
 	vars.ParentName = a.parentName
+	vars.ServerURL = a.serverURL
 	var subjectBytes bytes.Buffer
 	if err := subjectTmpl.Execute(&subjectBytes, vars); err != nil {
 		sklog.Errorf("Failed to send notification; failed to execute subject template: %s", err)
@@ -124,6 +132,10 @@
 		sklog.Errorf("Failed to send notification; failed to execute body template: %s", err)
 		return
 	}
+	if err := footerTmpl.Execute(&bodyBytes, vars); err != nil {
+		sklog.Errorf("Failed to send notification; failed to execute footer template: %s", err)
+		return
+	}
 	if err := a.n.Send(ctx, &notifier.Message{
 		Subject:  subjectBytes.String(),
 		Body:     bodyBytes.String(),
diff --git a/autoroll/go/notifier/notifier_test.go b/autoroll/go/notifier/notifier_test.go
index 0c766e5..11c0076 100644
--- a/autoroll/go/notifier/notifier_test.go
+++ b/autoroll/go/notifier/notifier_test.go
@@ -32,27 +32,28 @@
 	testutils.SmallTest(t)
 
 	ctx := context.Background()
-	n, err := New(ctx, "childRepo", "parentRepo", nil, nil)
+	n, err := New(ctx, "childRepo", "parentRepo", "https://autoroll.skia.org/r/test-roller", nil, nil)
 	assert.NoError(t, err)
 	t1 := &testNotifier{}
 	n.Router().Add(t1, notifier.FILTER_DEBUG, "")
 
+	footer := "\n\nThe AutoRoll server is located here: https://autoroll.skia.org/r/test-roller"
 	n.SendIssueUpdate(ctx, "123", "https://codereview/123", "uploaded a CL!")
 	assert.Equal(t, 1, len(t1.msgs))
 	assert.Equal(t, "The childRepo into parentRepo AutoRoller has uploaded issue 123", t1.msgs[0].subject)
-	assert.Equal(t, "uploaded a CL!", t1.msgs[0].m.Body)
+	assert.Equal(t, "uploaded a CL!"+footer, t1.msgs[0].m.Body)
 	assert.Equal(t, notifier.SEVERITY_INFO, t1.msgs[0].m.Severity)
 
 	n.SendModeChange(ctx, "test@skia.org", "STOPPED", "<b>Staaahhp!</b>")
 	assert.Equal(t, 2, len(t1.msgs))
 	assert.Equal(t, "The childRepo into parentRepo AutoRoller mode was changed", t1.msgs[1].subject)
-	assert.Equal(t, "test@skia.org changed the mode to \"STOPPED\" with message: &lt;b&gt;Staaahhp!&lt;/b&gt;", t1.msgs[1].m.Body)
+	assert.Equal(t, "test@skia.org changed the mode to \"STOPPED\" with message: &lt;b&gt;Staaahhp!&lt;/b&gt;"+footer, t1.msgs[1].m.Body)
 	assert.Equal(t, notifier.SEVERITY_WARNING, t1.msgs[1].m.Severity)
 
 	now := time.Now().Round(time.Millisecond)
 	n.SendSafetyThrottled(ctx, now)
 	assert.Equal(t, 3, len(t1.msgs))
 	assert.Equal(t, "The childRepo into parentRepo AutoRoller is throttled", t1.msgs[2].subject)
-	assert.Equal(t, fmt.Sprintf("The roller is throttled because it attempted to upload too many CLs in too short a time.  The roller will unthrottle at %s.", now.Format(time.RFC1123)), t1.msgs[2].m.Body)
+	assert.Equal(t, fmt.Sprintf("The roller is throttled because it attempted to upload too many CLs in too short a time.  The roller will unthrottle at %s."+footer, now.Format(time.RFC1123)), t1.msgs[2].m.Body)
 	assert.Equal(t, notifier.SEVERITY_ERROR, t1.msgs[2].m.Severity)
 }
diff --git a/autoroll/go/roller/autoroller.go b/autoroll/go/roller/autoroller.go
index 14f6754..b1d277e 100644
--- a/autoroll/go/roller/autoroller.go
+++ b/autoroll/go/roller/autoroller.go
@@ -172,7 +172,7 @@
 	}
 	sklog.Info("Creating notifier")
 	configCopies := replaceSheriffPlaceholder(ctx, c.Notifiers, emails)
-	n, err := arb_notifier.New(ctx, c.ChildName, c.ParentName, emailer, configCopies)
+	n, err := arb_notifier.New(ctx, c.ChildName, c.ParentName, serverURL, emailer, configCopies)
 	if err != nil {
 		return nil, err
 	}
diff --git a/autoroll/go/roller/config.go b/autoroll/go/roller/config.go
index d0c0b57..d49ec18 100644
--- a/autoroll/go/roller/config.go
+++ b/autoroll/go/roller/config.go
@@ -286,7 +286,7 @@
 	}
 
 	// Verify that the notifier configs are valid.
-	_, err := arb_notifier.New(context.Background(), "fake", "fake", nil, c.Notifiers)
+	_, err := arb_notifier.New(context.Background(), "fake", "fake", "fake", nil, c.Notifiers)
 	return err
 }
 
diff --git a/autoroll/go/state_machine/state_machine_test.go b/autoroll/go/state_machine/state_machine_test.go
index 3b78f6a..53d859d 100644
--- a/autoroll/go/state_machine/state_machine_test.go
+++ b/autoroll/go/state_machine/state_machine_test.go
@@ -317,7 +317,7 @@
 	ctx := context.Background()
 	gcsClient := gcs.NewMemoryGCSClient("test-bucket")
 	rollerImpl := NewTestAutoRollerImpl(t, ctx, gcsClient)
-	n, err := notifier.New(ctx, "fake", "fake", nil, nil)
+	n, err := notifier.New(ctx, "fake", "fake", "fake", nil, nil)
 	assert.NoError(t, err)
 	sm, err := New(ctx, rollerImpl, n, gcsClient, "test-roller")
 	assert.NoError(t, err)
@@ -640,7 +640,7 @@
 	defer cleanup()
 
 	check := func() {
-		n, err := notifier.New(ctx, "fake", "fake", nil, nil)
+		n, err := notifier.New(ctx, "fake", "fake", "fake", nil, nil)
 		assert.NoError(t, err)
 		sm2, err := New(ctx, r, n, gcsClient, gcsPrefix)
 		assert.NoError(t, err)