Run or Schedule Custom Email
This scheduled job will automatically send email notifications periodically based on a condition and email template. This is particularly useful if you want a daily summary of what has happened in Bitbucket.
You need to configure the interval and then provide a subject and an email template, as well as the email format (plain text or HTML) and a list of recipients.
List all public repositories
This example sends an email notification listing all the public repositories present in your Bitbucket Server instance.
The email format selected should be Plain text.
You can use the following code below in the Condition and Configuration section:
import com.atlassian.bitbucket.repository.Repository import com.atlassian.bitbucket.repository.RepositorySearchRequest import com.atlassian.bitbucket.repository.RepositoryService import com.atlassian.bitbucket.util.Page import com.atlassian.bitbucket.util.PageProvider import com.atlassian.bitbucket.util.PageRequest import com.atlassian.bitbucket.util.PageRequestImpl import com.atlassian.bitbucket.util.PagedIterable import com.atlassian.sal.api.component.ComponentLocator import javax.annotation.Nonnull import static com.atlassian.bitbucket.repository.RepositoryVisibility.PUBLIC def repositoryService = ComponentLocator.getComponent(RepositoryService) def publicRepositories = new PagedIterable<Repository>(new PageProvider<Repository>() { @Override Page<Repository> get(@Nonnull PageRequest pageRequest) { repositoryService.search(new RepositorySearchRequest.Builder().visibility(PUBLIC).build(), pageRequest) // <1> } }, new PageRequestImpl(0, 100)) .collect { Repository repository -> "$repository.project.key/$repository.slug" } // <2> .join("\n") config.content = publicRepositories // <3> !publicRepositories.isEmpty() // <4>
As this is a condition the email will only be sent if there are public repositories in your Bitbucket instance.
- We find all public repositories
For each public repository we build a string containing the project key and repository slug
We use the config variable in the binding to store the content for use in the template below (see additional configuration section for details)
The condition will evaluate to true if we have any private repositories and then the email will be sent
The subject template:
List of public repositories:
The body template:
These repositories are public, and you should review them:
$publicReposContent
The result should look similar to the following:
These repositories are public, and you should review them:
PROJECT_1/aPublicRepo
PROJECT_5/anotherPublicRepo
Additional Configuration in Emails
You may notice the syntax for getting content in the template is a bit clunky, as the template engine does not allow you to use the import
keyword. Rather than doing this, you can pass in a config
map to the bindings for both the subject and body templates. This is done in the Mail configuration section.
A useful example of a Mail configuration section that defines config variables for all pull requests that have been merged in the last 24 hours is:
import com.atlassian.bitbucket.nav.NavBuilder import com.atlassian.bitbucket.pull.PullRequest import com.atlassian.bitbucket.pull.PullRequestSearchRequest import com.atlassian.bitbucket.pull.PullRequestService import com.atlassian.bitbucket.pull.PullRequestState import com.atlassian.bitbucket.repository.RepositoryService import com.atlassian.bitbucket.util.Page import com.atlassian.bitbucket.util.PageProvider import com.atlassian.bitbucket.util.PageRequest import com.atlassian.bitbucket.util.PageRequestImpl import com.atlassian.bitbucket.util.PagedIterable import com.atlassian.sal.api.component.ComponentLocator import groovy.xml.MarkupBuilder import javax.annotation.Nonnull def pullRequestService = ComponentLocator.getComponent(PullRequestService) def repositoryService = ComponentLocator.getComponent(RepositoryService) def projectKey = "PROJECT_1" def repoSlug = "rep_1" def repo = repositoryService.getBySlug(projectKey, repoSlug) def yesterday = new Date().minus(1) def pullRequestSearchRequest = new PullRequestSearchRequest.Builder() .state(PullRequestState.MERGED) .closedSince(yesterday) .toRepositoryId(repo.id) .build() def mergedPullRequests = new PagedIterable<PullRequest>(new PageProvider<PullRequest>() { @Override Page<PullRequest> get(@Nonnull PageRequest pageRequest) { pullRequestService.search(pullRequestSearchRequest, pageRequest) } }, new PageRequestImpl(0, 100)) as Iterable<PullRequest> def navBuilder = ComponentLocator.getComponent(NavBuilder) def writer = new StringWriter() def builder = new MarkupBuilder(writer) builder.ul { mergedPullRequests.each { PullRequest pullRequest -> def url = navBuilder.repo(repo).pullRequest(pullRequest.id).buildAbsolute() builder.li { a(href: url, pullRequest.title) } } } config.content = writer.toString() config.numberMerged = mergedPullRequests.size()
You must change the projectKey
and repoSlug
variable above to match your own. The email format selected should be HTML.
The subject template:
$numberMerged PRs have been merged today
The body template:
The following pull requests were merged today: $content
As a result of that configuration, an email will be sent to the selected email addresses with a content similar to the following one:
Clicking on the links will take you to that pull request in Bitbucket.