Execute npm with ant - npm

I want to automate the build of an application with frontend and backend. To do this I want to use maven with ant for platform independent copy and cli tasks. With some cli's like docker ... this works. But this does not work for cli's provided by npm or npm itself.
<exec executable="docker">
<arg line="version"/>
</exec>
<!--Works-->
<exec executable="C:\Program Files\nodejs\npm.cmd">
<arg line="version"/>
</exec>
<!--Doesn't work-->
<exec executable="npm">
<arg line="version"/>
</exec>
As seen in the second example, the script works if I specify the full path to the npm.cmd. But this should work at least on windows and unix. So specifying the full path is not an option.
Is there any way to run npm and its modules from ant?
Late edit:
The real problem was, that the windows node installer also placed a file named npm into the bin folder which is a bash script meant for cygwin. The npm bin folder was added to the 'global' PATH env var and the windows cmd did pick up the correct binary because it uses the PATHEXT env var to determine what is executable and what not. The ant exec plugin does not use PATHEXT and just executes the first file named npm which fails. The Solution was to rename the plain npm file in the path. This way ant sees the npm.cmd file first and everything runs smoothly.

I know this is old, but this is what I have, for others in the future. Works in our mac, unix, and windows boxes.
<macrodef name="exec-node">
<attribute name="module" description="The name of the NodeJS module to execute" />
<attribute name="failonerror" default="true" description="Fail if the exit code is not 0" />
<attribute name="dir" description="Directory to execute task" />
<element name="args" implicit="yes" description="Argument to pass to the exec task" />
<sequential>
<exec executable="cmd.exe" dir="#{dir}" failonerror="#{failonerror}" osfamily="winnt">
<arg line="/c #{module}" />
<args />
</exec>
<exec executable="#{module}" dir="#{dir}" failonerror="#{failonerror}" osfamily="unix" logError="true">
<args />
</exec>
</sequential>
</macrodef>
Then things like this can work
<exec-node dir="${node.project.dir}" module="npm" failonerror="true" >
<arg value="run" />
<arg value="lint" />
</exec-node>
You can of course hardcode module as npm, or default it, but I use this with npm and npx.

From what I can gather, its not possible to call npm directly through the antrun plugin.
I did manage to get it tu run by calling cmd (on windows) with the /c argument.
Example:
<exec executable="cmd">
<arg line="/c npm run babel -- src/main/webapp/js/es6/ --presets babel-preset-es2015 --out-dir src/main/webapp/js/"/>
</exec>

This works for me on Windows:
<exec executable="npm.cmd">
<arg value="version"/>
</exec>

If you like to use npm you should take a look at the frontend-maven-plugin.

Related

dotnet publish -o ./dist does not set $OutDir or $OutPath in msbuild

I Have a file move event which I want to trigger after a publish
<Target Name="CopyEmailTemplates" AfterTargets="AfterPublish">
<ItemGroup>
<TemplatesFolder Include="Views\EmailTemplates\*.cshtml" />
</ItemGroup>
<Copy SourceFiles="#(TemplatesFolder)" DestinationFolder="$(OutDir)Views\EmailTemplates\" />
</Target>
I've confirmed that the command does not return the publish directory with this target:
<Target Name="OutputTest" AfterTargets="AfterPublish">
<Exec Command="echo OutPath: $(OutputPath)" />
<Exec Command="echo OutDir: $(OutDir)" />
</Target>
Expected:
OutDir is set to dist/
Actual behavior:
OutDir is set to bin/Release/netcoreapp2.0/
I am using: .NET Command Line Tools (2.1.4) on osx.10.12-x64
Publish is a two-step process. The project is built using normal build settings and then published to $(PublishDir). Use this property wherever you need to know the path of the publish output.
Self answering in hopes to prevent future headaches for people.
The dotnet publish -o ./dist command will set the $(PublishDir) variable in msbuild.
dotnet build -o ./dist does however set $(OutDir)
To be more explicit with our build I now use the msbuild command
dotnet publish -o ./dist -c Release
Becomes:
dotnet msbuild /t:publish /p:PublishDir=dist/ /p:Configuration=Release

MSBuild and Webpack

I am developing an Angular2 application in VS2015 and have a webpack bundling and minification environment set up for the same.
This is my webpack.conf.js
switch (process.env.NODE_ENV) {
case 'prod':
case 'production':
module.exports = require('./config/webpack.prod');
break;
case 'test':
case 'testing':
//module.exports = require('./config/webpack.test');
break;
case 'dev':
case 'development':
default:
module.exports = require('./config/webpack.dev');
}
I have also installed a webpack task runner which invokes this with the following commands
cmd /c SET NODE_ENV=development&& webpack -d --color
and
cmd /c SET NODE_ENV=production&& webpack -p --color
The setup seems to work fine. However, I want to integrate this with my TFS builds CI. The webpack command should fire after the project is built and report a build failure incase the webpack build fails. I have tried to incorporate the following code in my .csproj file
<Target Name="AfterBuild">
<Exec Condition="$(Configuration) == 'Debug'" Command="cmd /c SET NODE_ENV=production&& webpack -p --color">
</Exec>
</Target>
It failed with an error 9009
After that I tried, starting the command up from the node_modules folder where webpack was installed
<Target Name="AfterBuild">
<Exec Condition="$(Configuration) == 'Debug'" Command="./node_modules/.bin cmd /c SET NODE_ENV=production&& webpack -p --color">
</Exec>
</Target>
still in vain. Even if I get this to work, I am not sure if it would cause the VS build to fail if it encounters an error in webpack.
How do I go ahead with this?
Put different scripts in package.json for development and production mode. Then on 'AfterBuild' event of visual studio, call those scripts on different configurations.
Add following two scripts, 'buildDev' and 'buildProd' in package.json:
"scripts": {
"buildDev": "SET NODE_ENV=development && webpack -d --color",
"buildProd": "SET NODE_ENV=production && webpack -p --color",
}
In AfterBuild events of visual studio add these two conditional commands:
<Target Name="AfterBuild">
<Exec Condition="$(Configuration) == 'Debug'" Command="npm run buildDev" />
<Exec Condition="$(Configuration) == 'Release'" Command="npm run buildProd" />
</Target>
And finally webpack.conf.js like this:
switch (process.env.NODE_ENV.trim()) {
case 'prod':
case 'production':
module.exports = require('./config/webpack.prod');
break;
case 'dev':
case 'development':
default:
module.exports = require('./config/webpack.dev');
break;
}
Important Note: Make sure to use trim() function with process.env.NODE_ENV as cmd will treat the blank space in the command "SET NODE_ENV=development && webpack -d --color as character and append it in NODE_ENV variable. So when we are setting it as 'development', it actually gets set as (development + whitespace).
For TFS CI build, you can refer to these steps to achieve your requirement.
Add npm step
Add Command Line step
Note: There is –bail argument, which is required otherwise the step/task will be succeed even though webpack command throws exception.
Also, you can add variable in build definition (variable tab)

Open ssh tunnel in Ant in and keep it open (but continue on to other tasks)

I tried opening an ssh tunnel in ant, but it appears to close immediately and requires a task to run under it. How can I open a tunnel on a port and keep it open but not hang up the rest of the tasks while it sits open?
I tried:
<target name="tunnel">
<sshsession host="${ssh.host}" username="${username}" keyfile="${keyfile}" localtunnels="${port}:localhost:${port}">
<sequential />
</sshsession>
</target>
Found the answer. You can't use sshsession but instead have to use exec.
<exec spawn="true" executable="ssh">
<arg value="-t" />
<arg value="-t" />
<arg value="-L" />
<arg value="4003:localhost:4003" />
<arg value="username#server" />
</exec>
Note: The double -t is not an error. You need two of those or it won't work
This starts it in the background. To shut it down, you need to find the pid, which you can do with a grep: ps aux | grep 4003 | grep -v grep | awl '{print $2}' and then kill it

how to exec command in new prompt using ant

I am trying to run a command in ant to start the selenium server but it opens up in the same command prompt, is there anyway i can open it up in a new prompt?
<project>
<target name="startGRID">
<exec dir="." executable="cmd">
<arg value="/c"/>
<arg value="java -jar selenium-server-standalone-2.43.1.jar -role hub"/>
</exec>
</target>
</project>
To see a separate command prompt in which your server is run, use the dos start command, which does exactly that:
<exec dir="." executable="cmd">
<arg value="/c"/>
<arg value="start"/>
<arg value="java -jar selenium-server-standalone-2.43.1.jar -role hub"/>
</exec>
The only issue I find with that is that, when the server is terminated, the new command prompt window will remain open. This can be worked around by wrapping the java command in a batch script, let's call it start-selenium.bat, with an exit statement at the end:
java -jar selenium-server-standalone-2.43.1.jar -role hub
exit
then the Ant task becomes:
<exec dir="." executable="cmd">
<arg value="/c"/>
<arg value="start"/>
<arg value="start-selenium.bat"/>
</exec>

Exec Task in MSBuild for execution of command on remote machine

I am using following command to install a service via MSBuild file. This works great
<Exec Command= 'c:\test\myService.Appservices.exe install' ContinueOnError='false' />
But the above command install the service on local machine. I want to install the service on a remote machine. How can I specify the machine name using this command?
As per Mike Vine's comment, MSBuild doesn't include tools for remote execution. You could however use something like psexec. e.g.
<Exec Command='psexec -accepteula -s \\RemoteServer "C:\Path To EXE on Remote Machine\my.EXE"' IgnoreExitCode="false" ContinueOnError="false" Timeout="600000" >
<Output TaskParameter="ExitCode" PropertyName="exitCode1"/>
</Exec>