Sending mail from msbuild
Any decent build system must be able to call out for help or just send happy little progress messages. On other OSs than windows it’s typically as easy as piping something via sendmail. Here, not so easy.
Luckily, it’s not incredibly hard. I wrote myself a little msbuild task that does the job. Here goes:
using System.Globalization;
using System.Linq;
using System.Net.Mail;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Jesper.MsbuildTasks
{
public class SendMail: Task
{
[Required]
public ITaskItem[] To { get; set; }
public ITaskItem[] Contents { get; set; }
public string Subject { get; set; }
[Required]
public string Host { get; set; }
public string Port { get; set; }
public string From { get; set; }
private StringBuilder CreateContents()
{
var result = new StringBuilder();
result.AppendLine("[[Sent from fxCop]]");
if (Contents != null)
{
foreach (var content in Contents)
{
result.AppendLine(content.ItemSpec);
}
}
Log.LogMessage(MessageImportance.Low, "Message contents: {0}", result);
return result;
}
public override bool Execute()
{
var client = new SmtpClient(Host, ActualPort) {DeliveryMethod = SmtpDeliveryMethod.Network};
Log.LogMessage(MessageImportance.Normal, "Sending via {0}:{1}", Host, ActualPort);
try
{
client.Send(CreateMessage());
return true;
}
catch (Exception e)
{
Log.LogErrorFromException(e);
return false;
}
}
protected int ActualPort
{
get
{
int port;
return int.TryParse(Port, NumberStyles.Integer, CultureInfo.InvariantCulture, out port) ? port : 25;
}
}
private MailMessage CreateMessage()
{
var result = new MailMessage {From = new MailAddress(From), Body = CreateContents().ToString(), Subject = ActualSubject};
foreach (var r in To.Select(recipient => new MailAddress(recipient.ItemSpec)))
{
Log.LogMessage(MessageImportance.Normal, "Sending to {0}", r);
result.To.Add(r);
}
return result;
}
protected string ActualSubject
{
get { return Subject ?? "Sent from fxcop"; }
}
}
}
Using it in a script might look something like:
<Target Name="foo">
<SendMail
To="jesper@somewhere.else;jayone@elsewhere.net"
From="jesper@buildmachine.home"
Host="smtphost.home"
Contents="@(SomeDataToSend)"/>
</Target>
Once I had that written and tested, I decided to check if either the tigris community tasks or the microsoft extension pack included something similar.
Yes they do. Both of them. However, it was a nice exercise in writing msbuild tasks and a reminder to first check what is available out there
–Jesper
[...] admins life when writing custom msbuild tasks can no longer be avoided. I myself is no stranger to writing my own tasks. However, when it’s time to tidy up all those pesky ‘Command [...]