By default, a user can push more content to a pull request even after it has been approved, yet the approvals remain. This can make a mockery of your defined approval process. This listener will remove any approvals when new content is pushed to an existing pull request, if the condition matches. Using the conditions, you could apply this only when the pull request contains some sensitive code, or for less trusted developers.

The default behaviour in Bitbucket is that approvers will NOT be automatically notified in the event of a changed Pull Request. In this scenario, we recommend creating an entirely new listener that listens for the PullRequestParticipantUnapprovedEvent and for example sends an email to all Reviewers that had already approved the Pull Request. The following code shows a simple way to send an email after an approval has been removed:

import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.bitbucket.nav.NavBuilder
import com.onresolve.scriptrunner.canned.ConfiguredObjectMapper
import com.onresolve.scriptrunner.canned.bitbucket.events.BitbucketEventListenerExecutionContext
import com.onresolve.scriptrunner.canned.bitbucket.events.email.StashSendCustomEmailListener
import com.onresolve.scriptrunner.canned.bitbucket.events.model.StashSendCustomEmailListenerCommand
import com.onresolve.scriptrunner.mail.EmailFormat
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl

def pullRequest = event.pullRequest
def navBuilder = ComponentLocator.getComponent(NavBuilder)
def pullRequestUrl = navBuilder.repo(pullRequest.toRef.repository).pullRequest(pullRequest.id).buildAbsolute()

def objectMapper = ScriptRunnerImpl.scriptRunner.getBean(ConfiguredObjectMapper).get()

def subjectTemplate = "Your approval of the Pull Request $pullRequest.title has been removed"
def emailTemplate = "Your approval of the pull request <a href=\"$pullRequestUrl\">$pullRequest.title</a> has been removed," +
    "as the contents of the branch $pullRequest.fromRef.id have been changed"

def params = [
    "FIELD_EMAIL_SUBJECT_TEMPLATE": subjectTemplate.toString(),
    "FIELD_EMAIL_TEMPLATE"        : emailTemplate.toString(),
    "FIELD_TO_ADDRESSES"          : event.participant.user.emailAddress, // <1>
    "FIELD_CC_ADDRESSES"          : null,
    "FIELD_EMAIL_FORMAT"          : EmailFormat.HTML.name(), // <2>
]

def command = objectMapper.convertValue(params, StashSendCustomEmailListenerCommand)
def executionContext = new BitbucketEventListenerExecutionContext(event: event)

ScriptRunnerImpl.scriptRunner.createBean(StashSendCustomEmailListener).execute(command, executionContext) // <3>

Line 23: Only sends an email to the pull request participant for which the approval has been removed.

Line 25: If you want to send an email with plain text content, change the emailTemplate variable and enter EmailFormat.TEXT.name() instead of EmailFormat.HTML.name().

Line 31: Uses the internal ScriptRunner script to send an email.