github.com/fanux/shipyard@v0.0.0-20161009071005-6515ce223235/controller/static/semantic/tasks/admin/components/update.js (about)

     1  /*******************************
     2            Update Repos
     3  *******************************/
     4  
     5  /*
     6  
     7   This task update all SUI individual component repos with new versions of components
     8  
     9    * Commits changes from create repo
    10    * Pushes changes to GitHub
    11    * Tag new releases if version changed in main repo
    12  
    13  */
    14  
    15  var
    16    gulp           = require('gulp'),
    17  
    18    // node dependencies
    19    console        = require('better-console'),
    20    fs             = require('fs'),
    21    path           = require('path'),
    22    git            = require('gulp-git'),
    23    githubAPI      = require('github'),
    24    requireDotFile = require('require-dot-file'),
    25  
    26    // admin files
    27    github         = require('../../config/admin/github.js'),
    28    release        = require('../../config/admin/release'),
    29    project        = require('../../config/project/release'),
    30  
    31  
    32    // oAuth configuration for GitHub
    33    oAuth          = fs.existsSync(__dirname + '/../../config/admin/oauth.js')
    34      ? require('../../config/admin/oauth')
    35      : false,
    36  
    37    // shorthand
    38    version = project.version
    39  ;
    40  
    41  module.exports = function(callback) {
    42  
    43    var
    44      index = -1,
    45      total = release.components.length,
    46      timer,
    47      stream,
    48      stepRepo
    49    ;
    50  
    51    if(!oAuth) {
    52      console.error('Must add oauth token for GitHub in tasks/config/admin/oauth.js');
    53      return;
    54    }
    55  
    56    // Do Git commands synchronously per component, to avoid issues
    57    stepRepo = function() {
    58  
    59      index = index + 1;
    60      if(index >= total) {
    61        callback();
    62        return;
    63      }
    64  
    65      var
    66        component            = release.components[index],
    67        outputDirectory      = path.resolve(path.join(release.outputRoot, component)),
    68        capitalizedComponent = component.charAt(0).toUpperCase() + component.slice(1),
    69        repoName             = release.componentRepoRoot + capitalizedComponent,
    70  
    71        gitURL               = 'https://github.com/' + release.org + '/' + repoName + '.git',
    72        repoURL              = 'https://github.com/' + release.org + '/' + repoName + '/',
    73  
    74        commitArgs = (oAuth.name !== undefined && oAuth.email !== undefined)
    75          ? '--author "' + oAuth.name + ' <' + oAuth.email + '>"'
    76          : '',
    77  
    78        componentPackage = fs.existsSync(outputDirectory + 'package.json' )
    79          ? require(outputDirectory + 'package.json')
    80          : false,
    81  
    82        isNewVersion  = (version && componentPackage.version != version),
    83  
    84        commitMessage = (isNewVersion)
    85          ? 'Updated component to version ' + version
    86          : 'Updated files from main repo',
    87  
    88        gitOptions      = { cwd: outputDirectory },
    89        commitOptions   = { args: commitArgs, cwd: outputDirectory },
    90        releaseOptions  = { tag_name: version, owner: release.org, repo: repoName },
    91  
    92        fileModeOptions = { args : 'config core.fileMode false', cwd: outputDirectory },
    93        usernameOptions = { args : 'config user.name "' + oAuth.name + '"', cwd: outputDirectory },
    94        emailOptions    = { args : 'config user.email "' + oAuth.email + '"', cwd: outputDirectory },
    95        versionOptions =  { args : 'rev-parse --verify HEAD', cwd: outputDirectory },
    96  
    97        localRepoSetup  = fs.existsSync(path.join(outputDirectory, '.git')),
    98        canProceed      = true
    99      ;
   100  
   101  
   102      console.info('Processing repository:' + outputDirectory);
   103  
   104      function setConfig() {
   105        git.exec(fileModeOptions, function() {
   106          git.exec(usernameOptions, function () {
   107            git.exec(emailOptions, function () {
   108              commitFiles();
   109            });
   110          });
   111        });
   112      }
   113  
   114  
   115      // standard path
   116      function commitFiles() {
   117        // commit files
   118        console.info('Committing ' + component + ' files', commitArgs);
   119        gulp.src('**/*', gitOptions)
   120          .pipe(git.add(gitOptions))
   121          .pipe(git.commit(commitMessage, commitOptions))
   122          .on('error', function(error) {
   123            // canProceed = false; bug in git commit <https://github.com/stevelacy/gulp-git/issues/49>
   124          })
   125          .on('finish', function(callback) {
   126            if(canProceed) {
   127              pushFiles();
   128            }
   129            else {
   130              console.info('Nothing new to commit');
   131              nextRepo();
   132            }
   133          })
   134        ;
   135      }
   136  
   137      // push changes to remote
   138      function pushFiles() {
   139        console.info('Pushing files for ' + component);
   140        git.push('origin', 'master', { args: '', cwd: outputDirectory }, function(error) {
   141          console.info('Push completed successfully');
   142          getSHA();
   143        });
   144      }
   145  
   146      // gets SHA of last commit
   147      function getSHA() {
   148        git.exec(versionOptions, function(error, version) {
   149          version = version.trim();
   150          createRelease(version);
   151        });
   152      }
   153  
   154      // create release on GitHub.com
   155      function createRelease(version) {
   156        if(version) {
   157          releaseOptions.target_commitish = version;
   158        }
   159        github.releases.createRelease(releaseOptions, function() {
   160          nextRepo();
   161        });
   162      }
   163  
   164      // Steps to next repository
   165      function nextRepo() {
   166        console.log('Sleeping for 1 second...');
   167        // avoid rate throttling
   168        global.clearTimeout(timer);
   169        timer = global.setTimeout(stepRepo, 1000);
   170      }
   171  
   172  
   173      if(localRepoSetup) {
   174        setConfig();
   175      }
   176      else {
   177        console.error('Repository must be setup before running update components');
   178      }
   179  
   180    };
   181  
   182    stepRepo();
   183  
   184  };