Подтвердить что ты не робот

Выполнить сборку, только если есть изменения в src

История:

У нас есть команда тестировщиков, работающих над автоматизацией сквозных тестов с использованием транспортира для нашего внутреннего приложения AngularJS. Вот задача, которую они обычно выполняют для локального тестирования:

grunt.registerTask('e2e:local', [
    'build:prod',
    'connect:test',
    'protractor:local'
]);

Он запускает задачу "build", запускает веб-сервер и запускает тесты e2e против локальной сборки.

Задача build:prod определяется как:

grunt.registerTask(
    'build:prod', [
        'clean',
        'copy:all',
        'copy:assets',
        'wiredep',
        'ngtemplates',
        'useminPrepare',
        'concat',
        'ngAnnotate',
        'autoprefixer',
        'uglify',
        'cssmin',
        'copy:cssfix',
        'usemin',
        'copy:html',
        'bowercopy',
        'template:setProdVersion'
    ]
);

Здесь у нас есть много подзадач (его определенно можно было бы улучшить, но теперь это выглядит так).

Проблема:

В настоящее время для завершения сборки требуется около 25 секунд. И каждый раз, когда человек запускает сквозные тесты, выполняется задача сборки.

Вопрос:

Как запустить задачу build:prod только в том случае, если в каталоге src есть изменения?


Обратите внимание, что здесь требуется сделать его прозрачным для тестеров, которые запускают тесты. Я не хочу, чтобы они помнили, когда им нужно выполнить сборку, а когда нет.

Другими словами, процесс должен быть автоматизирован. Цель состоит в том, чтобы автоматически определить, нужна ли сборка или нет.

Обратите внимание, что в идеале я хотел бы оставить задачу сборки как есть, так что, если она вызывается непосредственно через grunt build:prod, она будет перестраиваться независимо от datestamp предыдущей сборки.


Мысли и попытки:

  • существует тесно связанный grunt-newer пакет, но, поскольку у нас есть довольно сложная сборка, с задачей clean в начале, Я не уверен, как применить его в моем случае

  • о чем я также думал, внутри задачи e2e:local вручную проверять временные метки файлов внутри dist и src и, на основании этого, решить, требуется ли build:prod для вызова. Я думаю, что это то, что grunt-newer делает внутренне

  • мы начали использовать jit-grunt, что помогло улучшить производительность

4b9b3361

Ответ 1

Вот идея, если вы используете git:

Как насчет использования чего-то вроде grunt-gitinfo и использования последнего фиксации в HEAD в качестве базы?

Идея такова:

  • Вы создаете новую задачу grunt, которая проверяет последний хеш фиксации
  • Вы сохранили этот хеш фиксации в файле, который добавлен в gitignore (и не находится в папке clean, как правило, может быть в корне репо)
  • Прежде чем сохранять файл, он проверит значение уже в нем (стандартный node fs модуль может легко читать/писать)
  • Если хэш не соответствует, запустите задачу build:prod, а затем сохраните новый хеш фиксации
  • Строка тестеров будет напрямую зависеть от вашей новой задачи вместо build:prod

Другая опция (все еще используется git):

Вы можете использовать что-то вроде grunt-githooks и создать крюк git, который запускается после нажатия и вызывает git build:prod, то вы можете удалить его из зависимостей задания grunt, которые тестируют тестеры.

У вас может быть другой код для проверки githook и его установки при необходимости, что может быть одноразовым дополнительным шагом для тестеров или, возможно, испечь в задаче grunt, которую они вызывают.

Ответ 2

Я удивлен, что никто еще не упомянул grunt-contrib-watch (он находится в gruntjs.com, и я подумал, что это довольно широко известно!). Из github: "Запускайте предопределенные задачи, когда наблюдаемые шаблоны файлов добавляются, изменяются или удаляются". - heres образец файла grunt, который будет запускать ваши задачи в любое время, когда любые .js файлы будут изменены в src/или в test/, или если файл Grunt будет изменен.

var filesToWatch = ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'];
grunt.initConfig({
    watch: {
        files: filesToWatch,
        tasks: ['build:prod',
                'connect:test',
                'protractor:local']
    }
});
grunt.loadNpmTasks('grunt-contrib-watch');

У вас есть ваши разработчики, открывающие терминал и запускающие grunt watch, прежде чем они начнут изменять файлы, и каждый раз, когда эти файлы будут изменены, задачи будут автоматически запущены (больше не возвращаться к терминалу для запуска grunt build:prod каждый раз).

Это отличный пакет, и я предлагаю вам проверить его. - github - npmjs.org p >

npm install grunt-contrib-watch --save-dev

Ответ 3

Не ответ, который вы ищете с помощью grunt, но это будет легко с gulp.

var fs = require('fs');
var gulpif = require('gulp-if');

var sourceChanged = fs.statSync('build/directory').mtime > fs.statSync('source/directory').mtime;

gulp.task('build:prod', function() {
  if (!sourceChanged) {
    return false;
  } 
  return gulp.src('./src/*.js')
    .pipe(.... build ....)
    .pipe(gulp.dest('./dist/'));
});

Ответ 4

Вот как мы выполнили некоторую работу Git HEAD sha для нашей сборки. Мы используем его для определения того, какая версия в настоящее время развернута в нашей производственной среде, но я вполне уверен, что вы могли бы переработать ее, чтобы вернуть логическое значение и запустить сборку, если это правда.

Gruntfile.js

function getHeadSha() {
  var curr, match, next = 'HEAD';
  var repoDir = process.env.GIT_REPO_DIR || path.join(__dirname, '..');
  try {
    do {
      curr  = grunt.file.read(path.join(repoDir, '.git', next)).trim();
      match = curr.match(/^ref: (.+)$/);
      next  = match && match[1];
    } while (next);
  } catch(ex) {
    curr = 'not-found';
  }

  return curr;
}

grunt.initConfig({
  replace: {
    applicationVersion: {
      src:  '<%= config.dist %>/index.html',
      overwrite: true,
      replacements: [{
        from: '{{APPLICATION_VERSION}}',
        to:   getHeadSha
      }]
    }
  }
});

grunt.registerTask('build', {
  'replace:applicationVersion',
  /** other tasks **/
});

grunt.registerTask('e2e:local', {
  'check_if_we_should_build',
  /** other tasks **/
});

index.html

<html data-version="{{APPLICATION_VERSION}}">
  <!-- -->
</html>

Также существует пакет git -info, который упростит весь этот процесс, и мы перейдем к этому.

редактировать; Я просто заметил, что @meligy уже указал вам в направлении git -info. кредит, в котором должен быть предоставлен кредит.

Ответ 5

Я не уверен, что это было полезно или не так, но мы сделали это в нашем проекте, используя GULP framework. Мы записали наблюдателя в gulp, который постоянно проверяет изменение источника и запускает быструю функцию для создания проекта. Его тестовый вариант для проталкивателя.

gulp.task('dome', function () {


    gulp.src(["maintest.js"])
        .pipe(notify("Change Found , Executing Scripts."))
        .pipe(protractor({

            configFile: "conf.js",
            args: ['--baseUrl', 'http://127.0.0.1:8000']


        })).on('error', function (e) {
        throw e
    });
})


gulp.task('default', function () {


    gulp.watch('./webpages/*.js', ['dome']);
    gulp.watch('maintest.js', ['dome']);
    gulp.watch('conf.js', ['dome']);
});

Ссылка на репо.

Ответ 6

У меня нет опыта в транспортире, но концептуально я думаю, что это может сработать.

Я предлагаю установить псевдоним в ~/.cshrc для запуска команд сборки, только если команда diff возвращает true.

#./cshrc

alias build_on_diff 'diff -r branch_dir_1 branch_dir_2\
if ( $status == 1 ) then\
build:prod\
endif'

Просто замените команду diff тем, что использует git, и она должна работать, если она возвращает статус 1 для обнаруженных различий. Мы применяем аналогичный метод на моем рабочем месте, чтобы избежать восстановления файлов, которые не изменились.