Child_process.exec/spawn вызывает обратный вызов/закрытие с командой установки npm (через Gulp/Shipit)

  • Я использую Shipit для развертывания.
  • При развертывании Shipit проверяет текущий Git Sha, на каталог tmp, затем я запускаю npm install, а затем gulp build, затем продолжайте развертывание.
  • Shipit использует Orchestrator для потока задач, как это делает Gulp.
  • У Shipit есть собственный CLI, поэтому я могу развернуть с shipit development deploy.

Все, что работает выше. Я пытаюсь создать задачу gulp deploy, которая будет инициализировать Shipit напрямую, вместо использования CLI. Выглядит примерно так:

gulp.task('shipit:deploy', function() {
  var deployToEnv = argv['deploy-to'] || false;
  var shipit;
  return inquirer.prompt([{
    type: 'list',
    name: 'deployToEnv',
    default: deployToEnv,
    message: 'Deploy to environment:',
    choices: envs
  }]).then(function(answers) {
    deployToEnv = answers.deployToEnv;
    shipit = new Shipit({environment: deployToEnv});
    shipit.initialize();
    shipit.start('deploy');
  });
});

Соответствующая конфигурация shipit:

  shipit.initConfig(config);
  shipit.blTask('build', function() {
    return shipit.local('npm install --silent', {
      cwd: shipit.config.workspace
    }).then(function() {
      return shipit.local('gulp build', {
        cwd: shipit.config.workspace
      });
    });
  });

  shipit.on('fetched', function() {
    shipit.start('build');
  });

Кажется, что работа работает с одной проблемой: на самом деле она не выполняет npm install!

Running "npm install --silent" on local. Running "gulp build" on local.

Итак, казалось бы, что-то в команде npm install преждевременно разрешает обещание, но я не уверен, как и почему.

У меня была аналогичная проблема (только с использованием shipit cli) с предупреждениями npm, которая была, когда я обнаружил, что использование -silent arg разрешило это.

В качестве теста я оставил код как есть, но заменил npm install --silent на sleep 10. Конечно, он ожидал за 10 секунд до выполнения gulp build. Таким образом, казалось бы, что-то специфическое с командой npm install.

Любая помощь приветствуется!

Обновление # 1:

shipit.local использует child_process.exec. Я попытался преобразовать это, чтобы использовать child_process.spawn, но имел тот же результат.

Обновление # 2:

Если я изменю команду на sudo npm install, все будет работать так, как ожидалось! Итак... что это значит и как я могу избежать его с помощью sudo?

Обновление № 3:

Все еще не удалось сделать это без sudo, но я попытался добавить флаг --verbose с этими результатами:

Без sudo:

@ npm info it worked if it ends with ok
@ npm verb cli [ '/Users/timkelty/.nvm/versions/node/v0.12.0/bin/node',
@ npm verb cli   '/Users/timkelty/.nvm/versions/node/v0.12.0/bin/npm',
@ npm verb cli   'install',
@ npm verb cli   '--verbose' ]
@ npm info using [email protected]
@ npm info using [email protected]
@ npm verb install where, deps [ '/Users/timkelty/tmp/edwards-garment-website', [] ]
@ npm verb install where, peers [ '/Users/timkelty/tmp/edwards-garment-website', [] ]
@ npm info preinstall [email protected]
@ npm info build /Users/timkelty/tmp/edwards-garment-website
@ npm verb linkStuff [ false, false, false, '/Users/timkelty/tmp' ]
@ npm info linkStuff [email protected]
@ npm verb linkBins [email protected]
@ npm verb linkMans [email protected]
@ npm verb rebuildBundles [email protected]
@ npm info install [email protected]
@ npm info postinstall [email protected]
@ npm verb exit [ 0, true ]
@ npm info ok
Running "gulp build" on local.
@ [15:14:32] Local gulp not found in ~/tmp/edwards-garment-website
@ [15:14:32] Try running: npm install gulp
'build' errored after 755 ms
Error: Command failed: /bin/sh -c gulp build

С sudo:

Running "sudo npm install --verbose" on local.
@ npm info it worked if it ends with ok
@ npm verb cli [ '/Users/timkelty/.nvm/versions/node/v0.12.0/bin/node',
@ npm verb cli   '/Users/timkelty/.nvm/versions/node/v0.12.0/bin/npm',
@ npm verb cli   'install',
@ npm verb cli   '--verbose' ]
@ npm info using [email protected]
@ npm info using [email protected]
@ npm verb install where, deps [ '/Users/timkelty/tmp/edwards-garment-website',
@ npm verb install   [ 'Select2',
@ npm verb install     'autoprefixer-core',
@ npm verb install     'babel',

... поэтому по какой-то причине при запуске без sudo команда установки npm кажется, что у нее нет никаких зависимостей для установки, поэтому она заканчивается без ошибок и продолжает мою следующую задачу.

Ответ 1

Я нашел решение!

Проблема заключалась в том, что я пытался установить devDependencies, но когда я запустил команду gulp deploy, NODE_ENV был настроен на производство, которое не устанавливает devDependencies.

Следовательно, изменение команды на NODE_ENV=development npm install похоже на ее исправление!

Ответ 2

После обновления # 2 у меня есть больше возможностей для написания, почему эта комбинация не работает/Прежде всего, нам нужно выяснить, какой пользователь выполняет команды. Для этого вам нужно выполнить команду whoami и увидеть результат (вы можете сделать это с помощью ssh или задачи shipit). Прямой вопрос заключается в том, что у priveleges нет пользователя для установки пакетов.

Возможное решение # 1:

Пользователь не имеет прав на папку tmp. Мы можем проверить это через ls -ld /path/to/tmp, ожидаемый результат:

drwxrwxrwt 13 root root 280 May  8 19:42 /tmp

Вам нужно проверить, что все пользователи могут писать в tmp dir: drwxrwxrwx. Если нет, вы можете установить значение chmod -R 755.

Возможное решение # 2:

Выполнение на npm предоставляется только пользователю/группе владельца, а наш пользователь не имеет. Мы можем проверить это через ls -lL $(which npm). Ожидаемый результат:

-rwxr-xr-x 1 root root 1881 Apr 19 07:12 /usr/../lib/node_modules/npm/bin/npm-cli.js

Если в файле отсутствует разрешение x, выполните sudo chmod +x $(which npm).

UPDATE: После question может возникнуть проблема не с вашей папкой tmp, а с папкой debug для npm. Попробуйте выполнить поиск и проверьте разрешение.

Надеемся, что все варианты, которые мы можем выполнить.