Visual Build Professional (Pro, vbp) has "Success Exit Codes" where I can put in a whitelisted values...(when I define a call out to an external .exe)
When I create a call to an external .exe , how can I capture the return-code / exit-code and put it into a macro?
Basically, I'm trying to do in Visual Build Pro, what the below msbuild does.
Namely, capture the value of "ExitCode" to a property (macro in vbp language)...called MyExitErrorCode
<Target Name="ExecuteSomeEXETarget">
<Exec Command='"C:\Some.exe"' ContinueOnError='true'>
<Output TaskParameter="ExitCode" PropertyName="MyExitErrorCode"/>
</Exec>
<Message Text="The exit code is $(MyExitErrorCode)"/>
<Error Text="Error while executing Some EXE" Condition="'$(MyExitErrorCode)' > '0'" />
</Target>
You can do a "Run Program"
In the "Command" put the path to your exe.
On the "More" tab, select the "Continue building" radio button.
..
Then you can capture the macro %RUNPROGRAM_EXITCODE%
..
For example, after your "Run Program" (step), Create a "Log Message" (step), and put this in
Hello '%RUNPROGRAM_EXITCODE%' !
.......
Not sure why the Macro doesn't show up in the list of global macros.
Now that I know the magic macro name, the documentation can be found
http://www.kinook.com/VisBuildPro/Manual/index.htm?visualbuild5_x.htm
• The build status of the Run Program action will always be a value from BuildStatusEnum and not the exit code of the process. The exit code is available in the RUNPROGRAM_EXITCODE temporary macro.
http://www.kinook.com/VisBuildPro/Manual/index.htm?runprogramaction.htm
The Run Program action creates a step to launch any external application, program, batch file, or command script. Visual Build starts and monitors the application, captures any output and logs it to the Output pane (and a log file if enabled), and terminates the application if the build is stopped.
When the step completes, the following temporary macros are created or updated:
RUNPROGRAM_EXITCODE: If the Wait option is checked, the exit code of the process will be stored in this macro.
RUNPROGRAM_PROCESSID: If the Wait option is unchecked, the process ID of the launched process will be stored in this macro.
Related
I am writing an Ant script where I want to forcefully sync the client workspace from depot. Below is the code snippet that I am using, but I am not able to figure it out , how to use the flag -f in the xml. Can some please help me?
<target name="sync_head_sql" description="Sync the workspace with head sql">
<taskdef name="p4sync" classname="com.perforce.p4java.ant.tasks.SyncTask" classpathref="p4_classpath"/>
<p4sync
files="//pay_import2/pay/wup2-parent/WU_DEV_ABCD_JBOSS62_V2_594_3/data- engine/conf/..."
user="abcd"
port="xx.xx.xx.xx:1669"
client="wp-nagiosmon">
</p4sync>
</target>
The code mentioned above is able to sync the code successfully, but wants to know about the option of force sync. If i want to add in the above code, then how to do that? Where should i use the -f flag?
Thanks,
Faraz
You can add the force flag into your p4sync tag like this:
<p4sync
files="//pay_import2/pay/wup2-parent/WU_DEV_ABCD_JBOSS62_V2_594_3/data- engine/conf/..."
force="true"
user="abcd"
port="xx.xx.xx.xx:1669"
client="wp-nagiosmon">
For some specific purpose, I need to install some fonts on the instances. It comes as no surprise when I choose StartUp Task to accomplish that goal. I've configured the Service Definitions as below:
<Startup>
<Task commandLine="Fonts\InstallFonts.vbs" executionContext="elevated" taskType="simple" />
</Startup>
Nothing special here. Click and run, it failed. However, if I changed the commandLine into a cmd file including just nonsense, namely "echo test", the instance would run without ado. So there must be some issue with my scripting:
Const FONTS = &H14&
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(CreateObject("Scripting.FileSystemObject").GetAbsolutePathName("."))
Set fontFolder = objShell.Namespace(FONTS)
Set rxTTF = New RegExp
rxTTF.IgnoreCase = True
rxTTF.Pattern = "\.ttf$"
Set fso = CreateObject("Scripting.FileSystemObject")
FOR EACH FontFile IN objFolder.Items()
IF rxTTF.Test(FontFile.Path) THEN
IF NOT fso.FileExists(fontFolder.Self.Path+"\\"+FontFile.Name) THEN
FontFile.InvokeVerb("Install")
END IF
END IF
NEXT
The script should come with no error because I've tested it either locally or on Azure via RDP.
Weirdly, when I put it in the startup, the role just won't start. The instance just keeps recycling and at last says "I'm unhealthy". Even if I deprecate the vbs into just one line of code - the first line Const FONTS = &H14&, it just won't start. Even if I wrap the invocation of the vbs into a cmd file, namely to put something like "cscript /B file.vbs", it won't run either.
So I'm concluding that there must be some issue regarding the communication between the script and the Windows Azure monitor. I'm not sure but I think the monitor might take the running script as a failed task. Besides, I'm wondering if there is any timeout for the startup task, which should be the problem though, because the script can guarantee that no UI interaction block the process.
Any idea would be greatly appreciated.
I am sure you must have but just for the sake of confirmation, have you checked that the InstallFonts.vbs file is exported with the package? I mean is the "Copy To Output Directory" is set to "Copy Always/Copy if newer"?
This is pretty much possible that it is not able to locate your file.
You need to write a cmd file as a start up task. In your cmd file, you can call the vbs file using the command line tool cscript.
Azure start up can compile only command line tools.
Oh god, I finally solved the problem.
Although the compiler does quite a good job usually, it allows to use subfolder as a source of command, I mean something like "Subfolder\command.cmd", which will not work always. I've seen examples in which people put whatever we do in cmd in commandLine property, such as "copy fileA fileB" and it really works. But as for vbs, you need to be cautious. Until now I still don't know what's under the cover, but there should be some problem with the path. And the solution is definitely simple, instead of doing the subfolder work for tidiness, just leave the command file in the root folder like most people do:
<Startup>
<Task commandLine="InstallFonts.vbs" executionContext="elevated" taskType="simple" />
</Startup>
And thank you all the same, Kunal. :)
I'm facing a problem using Ant
I'd like to check for the end of a long process, without using a nasty <sleep> command.
In my Ant target, I'm launching
<exec executable="my long process" />
When I'm manually checking for the end of the process, I'm using this following command :
watch " "check ksh script" | grep "ONLINE" "
When the grep returns something, it means my process has ended (because the check ksh script outputs ONLINE)
How can I perform the same check in Ant ?
I'm trying to use something like the following (to simulate the watch command)
<exec executable="my long process" />
<waitfor maxwait="2" maxwaitunit="minute" checkevery="5" checkeveryunit="second">
// do something here to check "ONLINE"
</waitfor>
But I don't know what to put in the <waitfor>
There are ways with Ant to execute your check script and then test its output, but it cannot fit the waitfor tasks which is accepting just one condition.
You could try with scripting though.
See: http://ant.apache.org/manual/Tasks/conditions.html#scriptcondition
It should look something like that:
<scriptcondition language="javascript" value="true">
var p = java.lang.Runtime.getRuntime().exec("ksh check");
p.waitFor();
var reader = new java.io.InputStreamReader(p.getInputStream());
var out = org.apache.tools.ant.util.FileUtils.safeReadFully(reader);
self.setValue(out.contains("ONLINE"));
</scriptcondition>
How to get build definition from TFS and pass it to the external program
This is what we are doing manually:
1) Queue new build
2) Once build is completed go to the drop folder and get the exe name
3) pass this exe name to the test automation program and run it.`
I want to automate these 3 steps.
Is it possible to get the build definition programatically?
Create a custom Build Template. Use a copy of the default (or what ever you're using now) as your starting point. Look in the work flow where BuildDetail.CompilationStatus = BuildPhaseStatus.Succeeded. You will then have the opportunity to invoke another application, it would be a stub program/powershell script/any other executable process. you can pass the path of the build that you just completed by using BuildDetail.DropLocation.
Assuming that your step #1 has executed, this latest (successful!) build is reachable as the lastKnownGoodBuild of the specific build definition.With this in mind you can employ a console app that bases on the following:
using System;
using System.IO;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
namespace BuildDropLocation
{
class Program
{
static void Main()
{
TfsTeamProjectCollection teamProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://yourTFSServerUri"));
var buildService = (IBuildServer)teamProjectCollection.GetService(typeof(IBuildServer));
IBuildDefinition myBuildDefinition = buildService.GetBuildDefinition("TeamProjectName", "BuildDefinitionName");
Uri lastKnownGoodBuild = myBuildDefinition.LastGoodBuildUri;
IBuildDetail myBuildDetail = buildService.GetBuild(lastKnownGoodBuild);
string[] myExeFiles = Directory.GetFiles(myBuildDetail.DropLocation, "*.exe",SearchOption.AllDirectories);
foreach (var exeFile in myExeFiles)
{
Console.WriteLine(myExeFile);
}
}
}
}
With the above you can retrieve the path to any *.exe under the drop location of the last build of build definition BuildDefinitionName that lives in Team Project TeamProjectName.This approach allows you to fully separate your TFS-Build with the execution of your tests. You can, for example, schedule this console-app to execute every night and invoke your runner to operate on the latest successful build.In case you would like the build and the testrun to be coupled in any way, you should proceed as #TimWagaman suggests by invoking your test runner during build. This 'coupling' might include:
The test results are contained in the build log
A failure generates a Bug
Test coverage is reportable
In this case, your tests will execute with each and every build that doesn't break in the compilation phase.
<MakeDir Directories="$(TemporaryFolder)" />
<Exec Condition=" '$(IsInTeamBuild)'=='True'" Command=""$(TfsTask)" history ../ /r /noprompt /stopafter:1 /version:W > "$(TemporaryFolder)\grab-changeset.txt"" />
<Exec Condition=" '$(IsInTeamBuild)'=='True'" Command=""$(TfsTask)" properties "$(MyMSBuildStartupDirectory)\all-companies-run-after-update.js" > "$(TemporaryFolder)\grab-properties.txt"" />
We use the above to extract: build#, branch, revision#
from the generated .txt files.
I'm try to develop a cruise control step which will process database migration scripts and apply them.
I'd like to be able to get hold of a list of the modifications from the SourceControl (to see if any new database changes need to be applied).
Any ideas how I can achieve this? I know that this information is written into the log xml but I was wondering if there is an easy mechanism to get a reference to this from with an Ant builder.
I have investigated writing a custom CC Listener or Builder plugin but neither supply this in the interface.
We have "svn update" as one of the steps in ant builder, and later we use output redirected to the file (ant property also could be used):
<exec executable="svn" dir=".">
<arg line="up"/>
<redirector output="svnup.log" alwayslog="true" append="true"/>
</exec>
<property name="svnup.log" value="svnup.log"/>
this creates file named "svnup.log" in the build folder with output of "svn up" command.
I think I'm going to try to write a custom plugin implementing Publisher
#Override
public void publish(Element cruisecontrolLog) throws CruiseControlException { XMLLogHelper xmlHelper = new XMLLogHelper(cruisecontrolLog);
Set<Modification> modifications = xmlHelper.getModifications();
for (Modification modification : modifications) {
handleModification(modification);
}
}
Or another idea is to use the timestamp flag in the sscm ant task combined with the cclastbuildtimestamp property supplied to the ant builder to produce a list of files changed since last build.