diff --git a/plugin/notify/email/email.go b/plugin/notify/email/email.go index f113101f5..666c6d251 100644 --- a/plugin/notify/email/email.go +++ b/plugin/notify/email/email.go @@ -12,9 +12,10 @@ import ( ) const ( - NotifyAlways = "always" // always send email notification - NotifyNever = "never" // never send email notifications - NotifyAuthor = "author" // only send email notifications to the author + NotifyAlways = "always" // always send email notification + NotifyNever = "never" // never send email notifications + NotifyAuthor = "author" // only send email notifications to the author + NotifyAfterChange = "change" // only if the previous commit has a different status NotifyTrue = "true" // alias for NotifyTrue NotifyFalse = "false" // alias for NotifyFalse @@ -70,6 +71,11 @@ func (e *Email) sendFailure(context *model.Request) error { switch e.Failure { case NotifyFalse, NotifyNever, NotifyOff: return nil + // if the last commit in this branch was a different status, notify + case NotifyAfterChange: + if context.Prior.Status == context.Commit.Status { + return nil + } // if configured to email the author, replace // the recipiends with the commit author email. case NotifyBlame, NotifyAuthor: @@ -103,6 +109,11 @@ func (e *Email) sendSuccess(context *model.Request) error { switch e.Success { case NotifyFalse, NotifyNever, NotifyOff: return nil + // if the last commit in this branch was a different status, notify + case NotifyAfterChange: + if context.Prior.Status == context.Commit.Status { + return nil + } // if configured to email the author, replace // the recipiends with the commit author email. case NotifyBlame, NotifyAuthor: diff --git a/server/datastore/commit.go b/server/datastore/commit.go index 9f94d955b..802125efa 100644 --- a/server/datastore/commit.go +++ b/server/datastore/commit.go @@ -31,6 +31,10 @@ type Commitstore interface { // from the datastore accessible to the specified user. GetCommitListActivity(user *model.User) ([]*model.CommitRepo, error) + // GetCommitPrior retrieves the latest commit + // from the datastore for the specified repository and branch. + GetCommitPrior(commit *model.Commit) (*model.Commit, error) + // PostCommit saves a commit in the datastore. PostCommit(commit *model.Commit) error @@ -82,6 +86,12 @@ func GetCommitListActivity(c context.Context, user *model.User) ([]*model.Commit return FromContext(c).GetCommitListActivity(user) } +// GetCommitPrior retrieves the latest commit +// from the datastore for the specified repository and branch. +func GetCommitPrior(c context.Context, commit *model.Commit) (*model.Commit, error) { + return FromContext(c).GetCommitPrior(commit) +} + // PostCommit saves a commit in the datastore. func PostCommit(c context.Context, commit *model.Commit) error { return FromContext(c).PostCommit(commit) diff --git a/server/datastore/database/commit.go b/server/datastore/database/commit.go index ac743e69a..a34c2662d 100644 --- a/server/datastore/database/commit.go +++ b/server/datastore/database/commit.go @@ -64,6 +64,14 @@ func (db *Commitstore) GetCommitListActivity(user *model.User) ([]*model.CommitR return commits, err } +// GetCommitPrior retrieves the latest commit +// from the datastore for the specified repository and branch. +func (db *Commitstore) GetCommitPrior(oldCommit *model.Commit) (*model.Commit, error) { + var commit = new(model.Commit) + var err = meddler.QueryRow(db, commit, rebind(commitPriorQuery), oldCommit.RepoID, oldCommit.Branch, oldCommit.ID) + return commit, err +} + // PostCommit saves a commit in the datastore. func (db *Commitstore) PostCommit(commit *model.Commit) error { if commit.Created == 0 { @@ -170,6 +178,17 @@ ORDER BY commit_id DESC LIMIT 1 ` +// SQL query to retrieve the prior Commit (by commit_created) in the same branch and repo as the specified Commit. +const commitPriorQuery = ` +SELECT * +FROM commits +WHERE repo_id = ? + AND commit_branch = ? + AND commit_id < ? +ORDER BY commit_id DESC +LIMIT 1 +` + // SQL statement to cancel all running Commits. const commitKillStmt = ` UPDATE commits SET commit_status = 'Killed' diff --git a/server/worker/docker/docker.go b/server/worker/docker/docker.go index bff55e2a6..8bbd622ff 100644 --- a/server/worker/docker/docker.go +++ b/server/worker/docker/docker.go @@ -120,6 +120,8 @@ func (d *Docker) Do(c context.Context, r *worker.Work) { Depth: git.GitDepth(script.Git), } + priorCommit, _ := datastore.GetCommitPrior(c, r.Commit) + // send all "started" notifications if script.Notifications == nil { script.Notifications = ¬ify.Notification{} @@ -129,6 +131,7 @@ func (d *Docker) Do(c context.Context, r *worker.Work) { Repo: r.Repo, Commit: r.Commit, Host: r.Host, + Prior: priorCommit, }) // create an instance of the Docker builder @@ -168,11 +171,14 @@ func (d *Docker) Do(c context.Context, r *worker.Work) { // notify all listeners that the build is finished commitc.Publish(r) + priorCommit, _ = datastore.GetCommitPrior(c, r.Commit) + // send all "finished" notifications script.Notifications.Send(&model.Request{ User: r.User, Repo: r.Repo, Commit: r.Commit, Host: r.Host, + Prior: priorCommit, }) } diff --git a/shared/model/request.go b/shared/model/request.go index 0bf752513..594cbeb2f 100644 --- a/shared/model/request.go +++ b/shared/model/request.go @@ -5,4 +5,5 @@ type Request struct { User *User `json:"-"` Repo *Repo `json:"repo"` Commit *Commit `json:"commit"` + Prior *Commit `json:"prior_commit"` }