mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: notify owner about failed autobuild (#13891)
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user