Skip to content

Instantly share code, notes, and snippets.

@slaith
Last active September 23, 2016 10:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slaith/7864f7056dcf828e11885cf026bfce2e to your computer and use it in GitHub Desktop.
Save slaith/7864f7056dcf828e11885cf026bfce2e to your computer and use it in GitHub Desktop.
GULP: Amazon S3 publish with git based checking
{
"staging":{
"uploadPath":"/reactcode"
},
"uat":{
"uploadPath":"/reactcodeuat"
},
"production":{
"dangerous":true,
"uploadPath":"/reactcodelive"
}
}
/* So we were using gulp to build react code and wanted it to do a little more than just build the minfied(and combined) file.
* We wanted it to upload directly to amazon s3.
* So we made use of gulp-awspublish to publish it to s3
*
*/
var gulp = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var babel = require('gulp-babel');
var browserSync = require('browser-sync');
var concat = require('gulp-concat');
var eslint = require('gulp-eslint');
var filter = require('gulp-filter');
var newer = require('gulp-newer');
var notify = require('gulp-notify');
var plumber = require('gulp-plumber');
var s3 = require("gulp-s3");
var awspublish = require('gulp-awspublish');
var rename = require("gulp-rename");
var fs = require("fs");
var reload = browserSync.reload;
//var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var insert = require('gulp-insert');
var minimist = require('minimist');
var gutil = require('gulp-util');
var prompt = require("gulp-prompt");
var gulpif = require("gulp-if");
var git = require ("gulp-git");
var exec = require('child_process').exec;
var onError = function(err) {
notify.onError({
title: "Error",
message: "<%= error %>",
})(err);
this.emit('end');
};
var plumberOptions = {
errorHandler: onError,
};
var jsFiles = {
vendor: [
'app/lib/*.js'
],
source: [
'app/src/*.jsx',
'app/src/**/*.jsx',
'app/src/*.js',
'app/src/**/*.js'
]
};
// Lint JS/JSX files
gulp.task('eslint', function() {
return gulp.src(jsFiles.source)
.pipe(eslint({
baseConfig: {
"ecmaFeatures": {
"jsx": true
}
}
}))
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});
// Copy react.js and react-dom.js to assets/js/src/vendor
// only if the copy in node_modules is "newer"
gulp.task('copy-react', function() {
return gulp.src('app/lib/build/react.js')
.pipe(newer('assets/js/src/vendor/react.js'))
.pipe(gulp.dest('assets/js/src/vendor'));
});
gulp.task('copy-react-dom', function() {
return gulp.src('app/lib/build/react-dom.js')
.pipe(newer('assets/js/src/vendor/react-dom.js'))
.pipe(gulp.dest('assets/js/src/vendor'));
});
// Copy assets/js/vendor/* to assets/js
gulp.task('copy-js-vendor', function() {
return gulp
.src([
'assets/js/src/vendor/react.js',
'assets/js/src/vendor/react-dom.js'
])
.pipe(gulp.dest('assets/js'));
});
// Concatenate jsFiles.vendor and jsFiles.source into one JS file.
// Run copy-react and eslint before concatenating
gulp.task('concat', ['eslint','copy-react-dom','copy-react'], function() {
return gulp.src(['assets/js/src/vendor/react.js','assets/js/src/vendor/react-dom.js'].concat(jsFiles.vendor.concat(jsFiles.source)))
.pipe(sourcemaps.init())
.pipe(babel({
only: [
'app/**/*.jsx',
],
compact: false
}))
.pipe(concat('app.js'))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('assets/js'));
});
// Compile Sass to CSS
gulp.task('sass', function() {
var autoprefixerOptions = {
browsers: ['last 2 versions'],
};
var filterOptions = '**/*.css';
var reloadOptions = {
stream: true,
};
var sassOptions = {
includePaths: [
]
};
return gulp.src('assets/sass/**/*.scss')
.pipe(plumber(plumberOptions))
.pipe(sourcemaps.init())
.pipe(sass(sassOptions))
.pipe(autoprefixer(autoprefixerOptions))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('assets/css'))
.pipe(filter(filterOptions))
.pipe(reload(reloadOptions));
});
// Watch JS/JSX and Sass files
gulp.task('watch', function() {
gulp.watch('app/src/**/*.{js,jsx}', ['concat']);
// gulp.watch('app/**/*.scss', ['sass']);
});
// BrowserSync
gulp.task('browsersync', function() {
browserSync({
server: {
baseDir: './'
},
open: false,
online: false,
notify: false,
});
});
var minify = require('gulp-minify');
gulp.task('compress',['concat'], function() {
gulp.src('assets/js/app.js')
.pipe(minify({
ext:{
src:'-debug.js',
min:'.min.js'
},
exclude: ['tasks'],
ignoreFiles: ['.combo.js', '-min.js']
}))
.pipe(insert.prepend('\n/*'+(new Date()).toString()+' */\n'))
.pipe(gulp.dest('assets/js/'));
});
/* publish runs after build. It picks up the file and publishes to the repository. We maintain a static bucket for the built files*/
gulp.task("publish",["gitty","build"],function(){
var aws = JSON.parse(fs.readFileSync('./aws-react-static.json'));
var environments = JSON.parse(fs.readFileSync('./environments.json'));
var knownOptions = {
string: 'env',
default: { env: process.env.NODE_ENV || null }
};
var options = minimist(process.argv.slice(2), knownOptions);
if(!options.env){
gutil.log("Environment not specified");
throw new gutil.PluginError({
plugin: 'publish',
message: 'environment not specified'
});
}
var environment=options.env;
var env_settings=environments[environment];
gutil.log("Deploying to environment: ",environment);
if(!env_settings){
gutil.log("Invalid environment");
throw new gutil.PluginError({
plugin: 'publish',
message: 'Environment config not found in environments.json'
});
}
var publisher = awspublish.create({
region: aws.region,
params: {
Bucket: aws.bucket
},
accessKeyId: aws.key,
secretAccessKey: aws.secret
}, {
cacheFileName: 'your-cache-location'
});
gulp.src('assets/js/app.min.js')
.pipe(rename(function (path) {
path.dirname += env_settings.uploadPath;
}))
.pipe(gulpif(env_settings.dangerous,prompt.confirm("Are you sure you want to deploy on production?"))) // only minify in production
.pipe(publisher.publish())
.pipe(awspublish.reporter({
states: ['create', 'update', 'delete']
}));
})
/* We run the status command to check if there are commits unpbublished in the directory*/
gulp.task("gitty",function(){
git.status({quiet:true}, function (err, stdout) {
if (err) throw err;
var pushcheck= /Your branch is ahead of /;
var commitCheck= /Changes not staged/;
if(stdout.match(commitCheck)){
gutil.log("Uncommitted changes present ");
throw new gutil.PluginError({
plugin: 'gitty',
message: "Some changes are not committed"
});
}
if(stdout.match(pushcheck)){
gutil.log("Changes are not pushed to repository ");
throw new gutil.PluginError({
plugin: 'gitty',
message: "Some changes are not pushed"
});
}
});
})
gulp.task("pullstatus", function(){
exec("git remote update", function (err, stdout, stderr) {
if(err) {
throw err
} else {
exec("git status -uno", function(err, stdout, stderr) {
console.log(err, stdout, stderr)
var branch_behind = "Your branch is behind";
})
}
});
})
gulp.task('build', ['copy-react','copy-react-dom', 'copy-js-vendor', 'concat',"compress"]);
gulp.task('default', ['build', 'browsersync', 'watch']);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment