function processBatch(jobs, plugins, manager, concurrent) {
  return (
    // batchStart
    runLifecycle('batchStart', plugins, manager)

      // for each job, processJob
      .then(() => {
        if (concurrent) {
          return processJobsConcurrently(jobs, plugins, manager);
        }

        return processJobsSerially(jobs, plugins, manager);
      })

      // batchEnd
      .then(() => runLifecycle('batchEnd', plugins, manager))
      .catch((err) => {
        manager.recordError(err);
        errorSync(err, plugins, manager);
      })
  );
}
Runs through the batch-level lifecycle events of a batch. This includes the processing of each
individual job.

Returns a promise resolving when all jobs in the batch complete.

@param jobs
@param {Array<HypernovaPlugin>} plugins
@param {BatchManager} manager
@returns {Promise}