Cancel Build if Task Runner Explorer Task Fails

南笙酒味 提交于 2019-12-03 05:54:42
davidmdem

You are correct in that this seems to be a Task Runner issue. The task runner does not communicate with MSBuild to stop a build if a BeforeBuild task fails.

To get around this, you can run your Gulp task via the project's pre-build event instead of via the Task Runner bindings.

Set the pre-build event

For class libraries, you can access Build Events by right-clicking your project and selecting Properties -> Compile -> Build Events....

For web projects, they are located at Properties -> Build Events.

Here is the command I used to call the Gulp task in pre-build event, which will prevent the MSBuild from running if it exits with a failure:

gulp -b $(ProjectDir) --gulpfile $(ProjectDir)gulpfile.js my-task

This command calls Gulp passing absolute paths for working directory and gulpfile.js.

Notes:

  • I found all kinds of context and working directory issues trying to use a more straight up command like gulp my-task.
  • $(ProjectDir) is one of the Macros for Build Commands.
  • It is assumed that Gulp is installed globally: npm install -g gulp. See jonas.ninja's answer for how to build this install into the command (or for an alternative that does not require the global dependency).

I have build fail for jshint with gulp working (well enough for me, maybe sufficient for others.) I imagine it may be extended to include all the tasks in Task Runner.

Here is what I used/did...

As per this page, I added/edited this in my project.json, which hooks into the prebuild event...

  "scripts": {
    "prebuild": [ "gulp default" ]
  }

As per this page, I included the following for my jshint task...

// =============================
// jsHint - error detection
// =============================
gulp.task("jshint", function () {
    var jshGlobals = [
        '$',
        'jQuery',
        'window',
        'document',
        'Element',
        'Node',
        'console'
    ];

    gulp.src([paths.jsFiles, norefs])
        .pipe(jshint({
            predef: jshGlobals,
            undef: true,
            eqnull: true
        }))
        .pipe(jshint.reporter('jshint-stylish'))
        .pipe(jshint.reporter('fail'))
});

The latter two lines being the most significant. You will need to npm install jshint-stylish if you don't already have it.

Alternatively, for jshint-stylish, you can let VS handle it for you. Add the line for jshint-stylish as indicated below to your package.json...

{
  "name": "ASP.NET",
  "version": "0.0.0",
  "devDependencies": {
    "es6-promise": "~3.1.2",
    "gulp": "^3.8.11",
    "del": "^2.2.0",
    "jshint": "~2.9.1",
    "jshint-stylish": "~2.1.0",
    "gulp-jshint": "~2.0.0",
    "gulp-flatten": "~0.2.0",
    "gulp-rename": "~1.2.2",
    "gulp-cssmin": "0.1.7",
    "gulp-uglify": "1.2.0",
    "gulp-postcss": "~6.1.0",
    "autoprefixer": "~6.3.3"
  }
}

Which gives me this when there is an error (in addition to the failed build) which is sufficient for me to dig further if/as necessary...

As opposed to the more detailed error info I get when running the same task via command line or Task Runner...

I imagine this solution can be improved but figured I would share as I hadn't seen a whole lot about it elsewhere.

Cheers.

I implemented davidmdem's solution above and it was great... on my system. I had gulp installed globally, but one of my coworkers did not, so the pre-build event would fail. Running gulp from Task Runner Explorer uses the project-level gulp installation, but running gulp from the pre-build script uses the global gulp installation.

To prevent the situation where a new developer doesn't have gulp installed, I expanded davidmdem's pre-build script to the following: (gulp --version || npm install -g gulp@3.9.0) & gulp -b $(ProjectDir) --gulpfile $(ProjectDir)gulpfile.js my-task

This command installs gulp (version 3.9.0 to match the project-level gulp installation) only if it is not already installed. Now gulp is not something that you have to think about before you can build the project!


(Update:)

An alternative (in my opinion: better) solution to this problem is to use npm as an intermediary. Continuing and modifying from the example above, I have a gulp task my-task that is being called from the command line. This removed the global gulp dependency and still properly stops msbuild if gulp fails.

Pre-build event:

npm run build

package.json:

"scripts": {
  "build": "gulp min"
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!