Search code examples
visual-studio-cordovapost-build-eventtaco

BeforeBuild and AfterBuild events in Visual Studio Tools for Cordova 2015 Update 5


I am trying to use pre and post build in my Visual Studio 2015 (TACO) project. As outlined in PreBuildEvent and PostBuildEvent on Visual Studio 2015 Tools for Apache Cordova I have added <Target> elements to my .jsproj file so that it now ends as shown:

  <Import Project="_apacheCordovaProjectSourceItems.Targets" Condition="Exists('_apacheCordovaProjectSourceItems.Targets')" />
  <Target Name="BeforeBuild">
    <Exec Command="if $(ConfigurationName) == Release (echo ** Before Build **)" />  
    <Exec Command="attrib -R &quot;$(ProjectDir)\platforms\*.*&quot; /S" IgnoreExitCode="true" />
  </Target>
  <Target Name="AfterBuild">
    <Exec Command="if $(ConfigurationName) == Release (echo ** After Build **)" />  
    <Exec Command="if $(ConfigurationName) == Release (xcopy &quot;$(TargetDir)*.*&quot; &quot;$(SolutionDir)..\..\Binaries\$(PlatformName)\*.*&quot; /Y /S /E /F /I)" />
  </Target>
</Project>

My problem is that both the BeforeBuild and AfterBuild events fire at the beginning of the build

1>------ Build started: Project: MyProject, Configuration: Release Android ------
1>  ** Before Build **
1>  ** After Build **
1>  D:\Workspaces\Products\MyProduct\Projects\Main\Sources\Apps\MyProject\bin\Android\Release\android-release-unsigned.apk -> D:\Workspaces\Products\MyProduct\Projects\Binaries\Android\android-release-unsigned.apk
1>  D:\Workspaces\Products\MyProduct\Projects\Main\Sources\Apps\MyProject\bin\Android\Release\manifest-merger-release-report.txt -> D:\Workspaces\Products\MyProduct\Projects\Binaries\Android\manifest-merger-release-report.txt
1>  2 File(s) copied
1>  Your environment has been set up for using Node.js 0.12.2 (ia32) and npm.
1>   ... [Rest of output omitted] ...

Can anybody shed some light on why this is, or how I can get the post build event to run after the build has completed?


Solution

  • After banging my head against a wall for a while I gave up on the Visual Studio AfterBuild event and used a hook for the Cordova after_build one. It fires a bit earlier in the whole build process, but was good enough for my requirements. I'll post the gist of what it entails in case others need to do a similar thing.

    1. Find the config.xml in Solution Explorer, right click on it and select View Code
    2. In the config.xml add a <hook> section as follows

      <platform name="android">
          <hook type="after_build" src="scripts/afterbuild-copy-to-drop.js" />
      </platform>
      

      Here I am hooking into the after_build event for an Android build only.

    3. Now create a scripts folder at the root of the project, ie the same level as the plugins and www folders.

    4. Create a JavaScript file in here with a name that matches the src attribute in the hook definition, ie 'afterbuild-copy-to-drop.js'.
    5. In this script file write the required code. Here is mine

      module.exports = function (ctx) {
          console.log('Executing custom "' + ctx.hook + '" hook for ' + ctx.opts.platforms);
      
          var path = ctx.requireCordovaModule('path'),
              shell = ctx.requireCordovaModule('shelljs');
      
          // make sure we are in a release build
          var isRelease = (ctx.cmdLine.indexOf('--configuration Release') >= 0);
      
          var solutionRoot = path.join(ctx.opts.projectRoot, '../..');
          var dropRoot = path.join(solutionRoot, '../../Binaries/Release/Apps');
      
          if (isRelease){
              if (ctx.opts.platforms == 'android') {
      
                  var platformRoot = path.join(ctx.opts.projectRoot, 'platforms/android');
                  var apkFileLocation = path.join(platformRoot, 'build/outputs/apk/android-release.apk');
      
                  dropRoot = path.join(dropRoot, 'Android');
                  var dropApkFileLocation = path.join(dropRoot, 'my-app.apk');
      
                  console.log('------ Making directory \'' + dropRoot + '\'');
                  shell.mkdir('-p', dropRoot);
      
                  console.log('------ Copying \'' + apkFileLocation + '\' to ' + dropApkFileLocation + '\'');
                  shell.cp('-f', apkFileLocation, dropApkFileLocation);
              }
          }
      
          console.log('Finished executing "' + ctx.hook + '" hook for ' + ctx.opts.platforms);
      };
      

    Further information on hooks can be found at https://cordova.apache.org/docs/en/dev/guide/appdev/hooks/