feat: notify owner about failed autobuild (#13891)

This commit is contained in:
Marcin Tojek
2024-07-16 10:48:17 +02:00
committed by GitHub
parent 36454aa81b
commit a5e4bf38fe
8 changed files with 204 additions and 25 deletions
@@ -1687,7 +1687,7 @@ func TestNotifications(t *testing.T) {
require.Contains(t, notifEnq.sent[0].targets, workspace.OrganizationID)
require.Contains(t, notifEnq.sent[0].targets, user.ID)
if tc.deletionReason == database.BuildReasonInitiator {
require.Equal(t, notifEnq.sent[0].labels["initiatedBy"], initiator.Username)
require.Equal(t, initiator.Username, notifEnq.sent[0].labels["initiator"])
}
} else {
require.Len(t, notifEnq.sent, 0)
@@ -1695,6 +1695,117 @@ func TestNotifications(t *testing.T) {
})
}
})
t.Run("Workspace build failed", func(t *testing.T) {
t.Parallel()
tests := []struct {
name string
buildReason database.BuildReason
shouldNotify bool
}{
{
name: "initiated by owner",
buildReason: database.BuildReasonInitiator,
shouldNotify: false,
},
{
name: "initiated by autostart",
buildReason: database.BuildReasonAutostart,
shouldNotify: true,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
ctx := context.Background()
notifEnq := &fakeNotificationEnqueuer{}
// Otherwise `(*Server).FailJob` fails with:
// audit log - get build {"error": "sql: no rows in result set"}
ignoreLogErrors := true
srv, db, ps, pd := setup(t, ignoreLogErrors, &overrides{
notificationEnqueuer: notifEnq,
})
user := dbgen.User(t, db, database.User{})
initiator := user
template := dbgen.Template(t, db, database.Template{
Name: "template",
Provisioner: database.ProvisionerTypeEcho,
OrganizationID: pd.OrganizationID,
})
template, err := db.GetTemplateByID(ctx, template.ID)
require.NoError(t, err)
file := dbgen.File(t, db, database.File{CreatedBy: user.ID})
workspace := dbgen.Workspace(t, db, database.Workspace{
TemplateID: template.ID,
OwnerID: user.ID,
OrganizationID: pd.OrganizationID,
})
version := dbgen.TemplateVersion(t, db, database.TemplateVersion{
OrganizationID: pd.OrganizationID,
TemplateID: uuid.NullUUID{
UUID: template.ID,
Valid: true,
},
JobID: uuid.New(),
})
build := dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
WorkspaceID: workspace.ID,
TemplateVersionID: version.ID,
InitiatorID: initiator.ID,
Transition: database.WorkspaceTransitionDelete,
Reason: tc.buildReason,
})
job := dbgen.ProvisionerJob(t, db, ps, database.ProvisionerJob{
FileID: file.ID,
Type: database.ProvisionerJobTypeWorkspaceBuild,
Input: must(json.Marshal(provisionerdserver.WorkspaceProvisionJob{
WorkspaceBuildID: build.ID,
})),
OrganizationID: pd.OrganizationID,
})
_, err = db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{
OrganizationID: pd.OrganizationID,
WorkerID: uuid.NullUUID{
UUID: pd.ID,
Valid: true,
},
Types: []database.ProvisionerType{database.ProvisionerTypeEcho},
})
require.NoError(t, err)
_, err = srv.FailJob(ctx, &proto.FailedJob{
JobId: job.ID.String(),
Type: &proto.FailedJob_WorkspaceBuild_{
WorkspaceBuild: &proto.FailedJob_WorkspaceBuild{
State: []byte{},
},
},
})
require.NoError(t, err)
if tc.shouldNotify {
// Validate that the notification was sent and contained the expected values.
require.Len(t, notifEnq.sent, 1)
require.Equal(t, notifEnq.sent[0].userID, user.ID)
require.Contains(t, notifEnq.sent[0].targets, template.ID)
require.Contains(t, notifEnq.sent[0].targets, workspace.ID)
require.Contains(t, notifEnq.sent[0].targets, workspace.OrganizationID)
require.Contains(t, notifEnq.sent[0].targets, user.ID)
require.Equal(t, "autobuild", notifEnq.sent[0].labels["initiator"])
require.Equal(t, string(tc.buildReason), notifEnq.sent[0].labels["reason"])
} else {
require.Len(t, notifEnq.sent, 0)
}
})
}
})
}
type overrides struct {