code: function (next) {
      if (this.cancelled) return;
  
      debug('Running phase', this.phase);
  
      var tasks = [];
      var started = new Date();
      var self = this;
      var path = [];
      var env = _.cloneDeep(this.config.env);
  
      // need to clone the repo first
      if (this.phase === 'prepare') {
        tasks.push(this.provider.fetch.bind(this.provider, self.pluginContext(this.provider.id, env, path)));
      }
  
      this.plugins.forEach(function (plugin) {
        debug('Running plugin', plugin.id);
        // all plugins will get the final, fully populated env object
        _.extend(env, ('function' === typeof plugin.env) ? plugin.env(self.phase) : plugin.env);
  
        if ('string' === typeof plugin.path) {
          path.push(plugin.path);
        } else {
          path = path.concat('function' === typeof plugin.path ? plugin.path(self.phase) : plugin.path);
        }
  
        tasks.push(function (next) {
          utils.runPlugin(self.phase, plugin, self.pluginContext(plugin.id, env, path), next);
        });
      });
  
      async.series(tasks, this.phaseDone.bind(this, next, started));
    }
docs: collect `env` from all plugins for the current phase, and execute plugin.runPhase(context) for each plugin in series