summaryrefslogtreecommitdiffstats
path: root/groovy/sendmail.groovy
blob: 73a25e57ec23e8083d84742434710a9bed63210f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
 * Copyright 2011 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import com.gitblit.GitBlit
import com.gitblit.Keys
import com.gitblit.models.RepositoryModel
import com.gitblit.models.TeamModel
import com.gitblit.models.UserModel
import com.gitblit.utils.JGitUtils
import java.text.SimpleDateFormat
import org.eclipse.jgit.lib.Repository
import org.eclipse.jgit.lib.Config
import org.eclipse.jgit.revwalk.RevCommit
import org.eclipse.jgit.transport.ReceiveCommand
import org.eclipse.jgit.transport.ReceiveCommand.Result
import org.slf4j.Logger

/**
 * Sample Gitblit Post-Receive Hook: sendmail
 *
 * The Post-Receive hook is executed AFTER the pushed commits have been applied
 * to the Git repository.  This is the appropriate point to trigger an
 * integration build or to send a notification.
 * 
 * This script is only executed when pushing to *Gitblit*, not to other Git
 * tooling you may be using.
 * 
 * If this script is specified in *groovy.postReceiveScripts* of gitblit.properties
 * or web.xml then it will be executed by any repository when it receives a
 * push.  If you choose to share your script then you may have to consider
 * tailoring control-flow based on repository access restrictions.
 *
 * Scripts may also be specified per-repository in the repository settings page.
 * Shared scripts will be excluded from this list of available scripts.
 * 
 * This script is dynamically reloaded and it is executed within it's own
 * exception handler so it will not crash another script nor crash Gitblit.
 *
 * If you want this hook script to fail and abort all subsequent scripts in the
 * chain, "return false" at the appropriate failure points.
 * 
 * Bound Variables:
 *  gitblit		Gitblit Server	 		com.gitblit.GitBlit
 *  repository	Gitblit Repository		com.gitblit.models.RepositoryModel
 *  user		Gitblit User			com.gitblit.models.UserModel
 *  commands	JGit commands 			Collection<org.eclipse.jgit.transport.ReceiveCommand>
 *	url			Base url for Gitblit	String
 *  logger		Logger instance			org.slf4j.Logger
 *  
 */

// Indicate we have started the script
logger.info("sendmail hook triggered by ${user.username} for ${repository.name}")

/*
 * Primitive email notification.
 * This requires the mail settings to be properly configured in Gitblit.
 */

Repository r = gitblit.getRepository(repository.name)

// reuse existing repository config settings, if available
Config config = r.getConfig()
def mailinglist = config.getString('hooks', null, 'mailinglist')
def emailprefix = config.getString('hooks', null, 'emailprefix')

// set default values
def toAddresses = []
if (emailprefix == null)
emailprefix = '[Gitblit]'

if (mailinglist != null) {
	def addrs = mailinglist.split(/(,|\s)/)
	toAddresses.addAll(addrs)
}

// add all mailing lists defined in gitblit.properties or web.xml
toAddresses.addAll(gitblit.getStrings(Keys.mail.mailingLists))

// add all team mailing lists
def teams = gitblit.getRepositoryTeams(repository)
for (team in teams) {
	TeamModel model = gitblit.getTeamModel(team)
	if (model.mailingLists) {
		toAddresses.addAll(model.mailingLists)
	}
}

// add all mailing lists for the repository
toAddresses.addAll(repository.mailingLists)

// define the summary and commit urls
def repo = repository.name.replace('/', gitblit.getString(Keys.web.forwardSlashCharacter, '/'))
def summaryUrl
def commitUrl
if (gitblit.getBoolean(Keys.web.mountParameters, true)) {	
	summaryUrl = url + "/summary/$repo"
	commitUrl = url + "/commit/$repo/"
} else {
	summaryUrl = url + "/summary?r=$repo"
	commitUrl = url + "/commit?r=$repo&h="
}

// construct a simple text summary of the changes contained in the push
def branchBreak = '>---------------------------------------------------------------\n'
def commitBreak = '\n\n ----\n'
def commitCount = 0
def changes = ''
SimpleDateFormat df = new SimpleDateFormat(gitblit.getString(Keys.web.datetimestampLongFormat, 'EEEE, MMMM d, yyyy h:mm a z'))
def table = { "\n ${JGitUtils.getDisplayName(it.authorIdent)}\n ${df.format(JGitUtils.getCommitDate(it))}\n\n $it.shortMessage\n\n $commitUrl$it.id.name" }
for (command in commands) {
	def ref = command.refName
	def refType = 'branch'
	if (ref.startsWith('refs/heads/')) {
		ref  = command.refName.substring('refs/heads/'.length())
	} else if (ref.startsWith('refs/tags/')) {
		ref  = command.refName.substring('refs/tags/'.length())
		refType = 'tag'
	}
		
	switch (command.type) {
		case ReceiveCommand.Type.CREATE:
			def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
			commitCount += commits.size()
			// new branch
			changes += "\n$branchBreak new $refType $ref created ($commits.size commits)\n$branchBreak"
			changes += commits.collect(table).join(commitBreak)
			changes += '\n'
			break
		case ReceiveCommand.Type.UPDATE:
			def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
			commitCount += commits.size()
			// fast-forward branch commits table
			changes += "\n$branchBreak $ref $refType updated ($commits.size commits)\n$branchBreak"
			changes += commits.collect(table).join(commitBreak)
			changes += '\n'
			break
		case ReceiveCommand.Type.UPDATE_NONFASTFORWARD:
			def commits = JGitUtils.getRevLog(r, command.oldId.name, command.newId.name).reverse()
			commitCount += commits.size()
			// non-fast-forward branch commits table
			changes += "\n$branchBreak $ref $refType updated [NON fast-forward] ($commits.size commits)\n$branchBreak"
			changes += commits.collect(table).join(commitBreak)
			changes += '\n'
			break
		case ReceiveCommand.Type.DELETE:
			// deleted branch/tag
			changes += "\n$branchBreak $ref $refType deleted\n$branchBreak"
			break
		default:
			break
	}
}
// close the repository reference
r.close()

// tell Gitblit to send the message (Gitblit filters duplicate addresses)
gitblit.sendMail("$emailprefix $user.username pushed $commitCount commits => $repository.name", "$summaryUrl\n$changes", toAddresses)