I am trying to create batches to achieve Nightly build under Windows. I managed to compile in release and debug automatically produce via a script.
But now I would like to be notified if there is an error during compilation and the need to return an email if this fails. This raises the following question:
Will I return an error nmake? Or rather the batch itself if it fails?
And if so, how I can return this error in a text file or an email?
I'm running under à Windows Server 2012 and use the task scheduler to automate. And here is my batch (EDITED) :
@echo on
echo[
set rel=release
@echo ####### COMPILATION CORE (DEBUG / x86) #######
echo[
cd C:\Users\mea\Documents\Repos\corealpi\cmake\nmake
@echo ####### delete cache #######
rm -R *
@echo ####### Generation of Makefile #######
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
cmake -DCMAKE_BUILD_TYPE=Debug -G"NMake Makefiles" ../
if %errorlevel% neq 0 goto mailcmaked
@echo ####### compilation of core #######
echo[
nmake
if %errorlevel% neq 0 goto mailnmaked
pause
@echo ####### COMPILATION CORE(RELEASE / x86) #######
echo[
cd C:\Users\mea\Documents\Repos\corealpi\cmake\nmake
@echo ####### Suppression du CACHE #######
rm -R *
@echo ####### Generation of Makefile #######
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
cmake -DCMAKE_BUILD_TYPE=Release -G"NMake Makefiles" ../
if %ERRORLEVEL% neq 0 goto mailcmaker
@echo ####### Compilation of CORE #######
echo[
>"..\log\buildRel.log" nmake
if %errorlevel% neq 0 goto mailnmaker
pause
:mailcmaked
echo Error!
sendEmail -f from@mail.com -t someone@mail.com -m "cmake debug failed" -s 192.168.x.x
exit 1
:mailnmaked
echo Error!
sendEmail -f from@mail.com -t someone@mail.com -m "nmake debug failed" -s 192.168.x.x
exit 1
:mailcmaker
sendEmail -f from@mail.com -t someone@mail.com -m "cmake release failed" -s 192.168.x.x
exit 1
:mailnmaker
grep -Eo '.{0,20}error.{0,100}' ..\log\buildRel.log > ..\log\mailBuild.txt
sendEmail -f from@mail.com -u "build failed" -t someone@mail.com -m "nmake release failed" -a ..\log\mailBuild.txt -s 192.168.x.x
exit 1
EDIT
I edited my script drawing inspiration from your example and now that's working great (just for the :mailnmaker
section for the moment). I organize my ouput with the grep command.
For the mail problem, i've just install sendEmail and put it in my Windows PATH and that's working.
Thank you for your help.
Firstly, there's no native command available that'll let you send email. You can script something with Windows Scripting (VBScript or JScript) using CDO.Message
though. The least cumbersome way of incorporating the Windows Script Host into a batch script is to use a hybrid script.
You can use conditional execution to fire the send email function if cmake
or nmake
exit with a non-zero status.
Here's an example framework to get you started. Please note that this is untested and might be broken. But it should at least give you a place to start, anyway.
(Also note that I replaced rm -R *
with native Windows commands, and the output of cmake
and nmake
are redirected to %temp%\build.log
for inclusion into the email if needed. If you want the output echoed to the console as well, you will probably have to use tee -a
if you have cygwin or gnuwin32 or similar installed; or possibly incorporate this scripted imitation.)
@if (@CodeSection == @Batch) @then
@echo on
echo[
@echo ####### COMPILATION CORE (DEBUG / x86) #######
call :make Debug || exit /b %ERRORLEVEL%
@echo ####### COMPILATION CORE(RELEASE / x86) #######
call :make Release || exit /b %ERRORLEVEL%
goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
:make <Release|Debug>
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
echo[
cd /d C:\Users\mea\Documents\Repos\corealpi\cmake\nmake
@echo ####### delete cache #######
for /d %%I in (*) do rmdir /q /s "%%~I"
del /q /y *
@echo ####### Makefile #######
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
:: use conditional execution to send an email if cmake exits non-zero
>"%temp%\build.log" cmake -DCMAKE_BUILD_TYPE=%1 -G"NMake Makefiles" ../ || (
call :sendmail cmake %1 %ERRORLEVEL%
exit /b %ERRORLEVEL%
)
@echo ####### compilation of core (debug/x86) #######
echo[
:: use conditional execution to send an email if nmake exits non-zero
>"%temp%\build.log" nmake || (
call :sendmail nmake %1 %ERRORLEVEL%
exit /b %ERRORLEVEL%
)
goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
:sendmail <name> <buildtype> <errorlevel>
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
cscript /nologo /e:JScript "%~f0" "%~1" "%~2" "%~3" "%temp%\build.log"
exit /b %~3
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: end batch / begin JScript
:::::::::::::::::::::::::::::::::::::::::::::::::::::::
@end
var buildstep = WSH.Arguments(0),
buildtype = WSH.Arguments(1),
errorlevel = WSH.Arguments(2),
buildlog = WSH.Arguments(3),
oSH = WSH.CreateObject('WScript.Shell'),
fso = WSH.CreateObject('Scripting.FileSystemObject');
function SendEMail(config) {
try {
var oMsg = WSH.CreateObject("CDO.Message");
for (var i in config) oMsg[i] = config[i];
oMsg.Send();
}
catch(e) {
var profile = oSH.Environment('Process')('USERPROFILE'),
alert = fso.CreateTextFile(profile + '\\Desktop\\builderr.log', 1);
alert.WriteLine(buildstep + ' build type ' + buildtype
+ ' failed. Email failed. Everything is broken. I give up.');
alert.WriteLine(getLog(20));
alert.Close();
}
}
function getLog(lines) {
log = fso.OpenTextFile(buildlog, 1),
contents = [];
while (!log.AtEndOfStream) {
contents.push(log.ReadLine());
if (contents.length > lines) contents.shift();
}
log.Close();
return contents.join('\n');
}
SendEMail({
From: "from@example.com",
To: "to@example.com",
Subject: "Build failed",
TextBody: buildstep + " build type " + buildtype
+ " failed with error code " + errorlevel
+ '\n\nLast 20 lines of messages from ' + buildlog + ':\n\n' + getLog(20)
});