diff --git a/.ci/build.sh b/.ci/build.sh new file mode 100755 index 00000000..2f2202c0 --- /dev/null +++ b/.ci/build.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +if [ $TRAVIS_BRANCH == "master" ]; then + + gulp build --production + +else + + gulp build + +fi; + +exit; diff --git a/.ci/deploy.sh b/.ci/deploy.sh new file mode 100755 index 00000000..acdfedc7 --- /dev/null +++ b/.ci/deploy.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -e; + +gulp s3:assets + +gulp cdn + +rsync --recursive --delete --delete-excluded --checksum --verbose -e "ssh" $TRAVIS_BUILD_DIR/_site/ kremalicious.com@ftp.kremalicious.com:/nfs/c08/h04/mnt/126308/domains/kremalicious.com/html/ diff --git a/.ci/setup.sh b/.ci/setup.sh new file mode 100755 index 00000000..f98e24f0 --- /dev/null +++ b/.ci/setup.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e; + +npm install gulp bower -g +npm install +bower install +bundle install diff --git a/.travis.yml b/.travis.yml index 387986b3..d7b0b2a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,24 @@ sudo: false language: ruby rvm: -- 2.2.2 -- 1.9.3 -cache: bundler + - 2.2.2 + - 1.9.3 +cache: + bundler: true + directories: + - node_modules + - bower_components addons: - apt: - packages: - - libgsl0-dev -before_script: -- npm install gulp bower -g -- npm install -- bower install -- bundle install -script: gulp build + apt: + packages: + - libgsl0-dev +before_script: .ci/setup.sh +script: .ci/build.sh +# deploy: +# provider: script +# script: .ci/deploy.sh +# on: +# branch: master notifications: - slack: - secure: Ki6tFSrxaUnAugBFnmM2ydI/38/Ahyoaf9lhohoOCNnPk/QIYrI8MBlBXNVI04v2GOhFTvVljY5yJPlzrAUjH3eu34f6ObBe6rh3LjfvtE9eA94pBoSLJE/eSqB6FUBr324kxXpsWHRv93gyQ9I6Hk2CURv58de2z9Ytkwu2Epo= + slack: + secure: Ki6tFSrxaUnAugBFnmM2ydI/38/Ahyoaf9lhohoOCNnPk/QIYrI8MBlBXNVI04v2GOhFTvVljY5yJPlzrAUjH3eu34f6ObBe6rh3LjfvtE9eA94pBoSLJE/eSqB6FUBr324kxXpsWHRv93gyQ9I6Hk2CURv58de2z9Ytkwu2Epo= diff --git a/README.md b/README.md index bac5433e..e04e3db7 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ kremalicious3 > [kremalicious.com](http://kremalicious.com) based on [Jekyll](http://jekyllrb.com). Neat. [ ![Codeship Status for kremalicious/kremalicious3](https://www.codeship.io/projects/f6973090-9f04-0131-a2b7-625e8177ce9a/status?branch=master)](https://www.codeship.io/projects/18092) +[![Build Status](https://travis-ci.org/kremalicious/kremalicious3.svg?branch=master)](https://travis-ci.org/kremalicious/kremalicious3) [![Dependency Status](https://gemnasium.com/kremalicious/kremalicious3.svg)](https://gemnasium.com/kremalicious/kremalicious3) @@ -41,7 +42,7 @@ Run the following command from the repository's root folder to install all depen npm install && bower install && bundle install ``` -### Development build +### Development server This generates the site and assets and starts a local dev server combined with a livereloading watch task under `http://localhost:1337`. @@ -54,7 +55,7 @@ gulp Runs almost the same tasks as `gulp server` but additionally versions all assets and optimizes all image assets. ```bash -gulp build +gulp build --production ``` diff --git a/gulpfile.js b/gulpfile.js index 2dbb5ffd..e9e1e09a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -7,7 +7,8 @@ var gulp = require('gulp'), chalk = require('chalk'), merge = require('merge-stream'), pkg = require('./package.json'), - parallelize = require('concurrent-transform'); + parallelize = require('concurrent-transform'), + revAll = require('gulp-rev-all'); // Temporary solution until gulp 4 // https://github.com/gulpjs/gulp/issues/355 @@ -19,6 +20,9 @@ var onError = function(error) { this.emit('end'); } +// 'development' is just default, production overrides are triggered +// by adding the production flag to the gulp command e.g. `gulp build --production` +var isProduction = ($.util.env.production === true ? true : false); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // Terminal Banner @@ -44,6 +48,8 @@ var src = '_src', s3path = '/', s3region = 'eu-central-1'; +var manifest = gulp.src(dist + '/assets/rev-manifest.json'); + // icons var icons = { entypo: { @@ -109,20 +115,37 @@ gulp.task('clean', function(cb) { // gulp.task('jekyll', function(cb) { var spawn = require('child_process').spawn; - var jekyll = spawn('bundle', ['exec', 'jekyll', 'build', '--drafts', '--future'], { stdio: 'inherit' }); + + if (isProduction) { + var jekyll = spawn('bundle', ['exec', 'jekyll', 'build', '--lsi'], { stdio: 'inherit' }); + } else { + var jekyll = spawn('bundle', ['exec', 'jekyll', 'build', '--drafts', '--future'], { stdio: 'inherit' }); + } jekyll.on('exit', function(code) { cb(code === 0 ? null : 'ERROR: Jekyll process exited with code: ' + code); }); }); -gulp.task('jekyll:production', function(cb) { - var spawn = require('child_process').spawn; - var jekyll = spawn('bundle', ['exec', 'jekyll', 'build', '--lsi'], { stdio: 'inherit' }); - jekyll.on('exit', function(code) { - cb(code === 0 ? null : 'ERROR: Jekyll process exited with code: ' + code); - }); +// +// HTML +// +gulp.task('html', function() { + return gulp.src(dist + '/**/*.html') + .pipe($.if(isProduction, $.uglify())).on('error', onError) + .pipe($.if(isProduction, $.htmlmin({ + collapseWhitespace: true, + conservativeCollapse: true, + removeComments: true, + useShortDoctype: true, + collapseBooleanAttributes: true, + removeRedundantAttributes: true, + removeEmptyAttributes: true, + removeEmptyAttributes: true + }))) + //.pipe($.if(isProduction, revAll())) + .pipe(gulp.dest(dist)) }); @@ -136,7 +159,11 @@ gulp.task('css', function() { ]) .pipe($.stylus({ 'include css': true })).on('error', onError) .pipe($.autoprefixer({ browsers: 'last 2 versions' })).on('error', onError) + .pipe($.if(isProduction, $.combineMq({ beautify: false }))) + .pipe($.if(isProduction, $.cssmin())) + .pipe($.if(isProduction, $.header(banner, { pkg: pkg }))) .pipe($.rename({ suffix: '.min' })) + //.pipe($.if(isProduction, revAll())) .pipe(gulp.dest(dist + '/assets/css/')) .pipe($.connect.reload()) }); @@ -151,7 +178,9 @@ gulp.task('js:libraries', function() { return gulp.src([ 'node_modules/picturefill/dist/picturefill.js' ]) + .pipe($.if(isProduction, $.uglify())).on('error', onError) .pipe($.rename({ suffix: '.min'})) + //.pipe($.if(isProduction, revAll())) .pipe(gulp.dest(dist + '/assets/js/')) }); @@ -160,6 +189,9 @@ gulp.task('js:project', function() { return gulp.src(src + '/_assets/js/*.js') .pipe($.include()).on('error', onError) .pipe($.concat('kremalicious3.min.js')) + .pipe($.if(isProduction, $.uglify())).on('error', onError) + .pipe($.if(isProduction, $.header(banner, { pkg: pkg }))) + //.pipe($.if(isProduction, revAll())) .pipe(gulp.dest(dist + '/assets/js/')) .pipe($.connect.reload()) }); @@ -183,22 +215,13 @@ gulp.task('icons', function() { .pipe($.rename({ prefix: iconset.prefix })) .pipe(gulp.dest(iconset.dist)) .pipe($.filter('**/*.svg')) - .pipe($.imagemin({ svgoPlugins: [{ removeViewBox: false }] })) + .pipe($.if(isProduction, $.imagemin({ svgoPlugins: [{ removeViewBox: false }] }))) .pipe($.svgSprite(spriteConfig)) + //.pipe($.if(isProduction, revAll())) .pipe(gulp.dest(iconset.dist)) }); -// -// Generate SVG fallbacks -// -gulp.task('svg:fallbacks', function() { - return gulp.src(dist + '/assets/img/*.svg') - .pipe($.svg2png()).on('error', onError) - .pipe(gulp.dest(dist + '/assets/img/')) -}); - - // // Copy images // @@ -207,6 +230,14 @@ gulp.task('images', function() { src + '/_assets/img/**/*', '!' + src + '/_assets/img/entypo/**/*' ]) + .pipe($.if(isProduction, $.imagemin({ + optimizationLevel: 5, // png + progressive: true, // jpg + interlaced: true, // gif + multipass: true, // svg + svgoPlugins: [{ removeViewBox: false }] + }))) + //.pipe($.if(isProduction, revAll())) .pipe(gulp.dest(dist + '/assets/img/')) }); @@ -216,6 +247,7 @@ gulp.task('images', function() { // gulp.task('fonts', function() { return gulp.src(src + '/_assets/fonts/**/*') + //.pipe($.if(isProduction, revAll())) .pipe(gulp.dest(dist + '/assets/fonts/')) }); @@ -229,72 +261,10 @@ gulp.task('media', function() { }); -// -// Optimize css -// -gulp.task('optimize:css', function() { - return gulp.src(dist + '/assets/css/*.css') - .pipe($.combineMq({ beautify: false })) - .pipe($.cssmin()) - .pipe($.header(banner, { pkg: pkg })) - .pipe(gulp.dest(dist + '/assets/css/')) -}); - - -// -// Optimize js -// -gulp.task('optimize:js', function() { - return gulp.src(dist + '/assets/js/*.js') - .pipe($.uglify()).on('error', onError) - .pipe($.header(banner, { pkg: pkg })) - .pipe(gulp.dest(dist + '/assets/js/')) -}); - - -// -// Optimize HTML -// -gulp.task('optimize:html', function() { - return gulp.src(dist + '/**/*.html') - .pipe($.htmlmin({ - collapseWhitespace: true, - conservativeCollapse: true, - removeComments: true, - useShortDoctype: true, - collapseBooleanAttributes: true, - removeRedundantAttributes: true, - removeEmptyAttributes: true, - removeEmptyAttributes: true - })) - .pipe(gulp.dest(dist)) -}); - - -// -// Optimize images -// -gulp.task('optimize:images', function() { - return gulp.src([ - dist + '/**/*.{png,jpg,jpeg,gif,svg,webp}', - '!' + dist + '/media/**/*', - '!' + dist + '/assets/img/sprite*' - ]) - .pipe($.cache($.imagemin({ - optimizationLevel: 5, // png - progressive: true, // jpg - interlaced: true, // gif - multipass: true, // svg - svgoPlugins: [{ removeViewBox: false }] - }))) - .pipe(gulp.dest(dist)) -}); - - // // Revision static assets // -gulp.task('revision', function() { +gulp.task('rev', function() { return gulp.src(dist + '/assets/**/*.{css,js,png,jpg,jpeg,svg,eot,ttf,woff}') .pipe($.rev()) .pipe(gulp.dest(dist + '/assets/')) @@ -308,7 +278,7 @@ gulp.task('revision', function() { // Replace all links to assets in files // from a manifest file // -gulp.task('revision:replace', function() { +gulp.task('rev:replace', function() { var manifest = gulp.src(dist + '/assets/rev-manifest.json'); @@ -387,54 +357,41 @@ gulp.task('connect', function() { // gulp.task('watch', function() { gulp.watch([src + '/_assets/styl/**/*.styl'], ['css']) - gulp.watch([src + '/_assets/js/*.js'], ['js:project']) + gulp.watch([src + '/_assets/js/*.js'], ['js']) gulp.watch([src + '/_assets/img/**/*.{png,jpg,jpeg,gif}'], ['images']) gulp.watch([src + '/_assets/img/**/*.{svg}'], ['icons']) gulp.watch([src + '/_media/**/*'], ['media']) - gulp.watch([src + '/**/*.{html,xml,json,txt,md}'], ['jekyll-build']) + gulp.watch([src + '/**/*.{html,xml,json,txt,md}'], ['jekyll']) }); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // Task sequences // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -gulp.task('jekyll-build', function(cb) { - runSequence( - 'jekyll', - ['css', 'js', 'images', 'fonts', 'media'], - 'icons', - cb - ); -}); // // Dev Server // gulp.task('default', function(cb) { runSequence( - 'clean', - 'jekyll-build', - 'watch', - 'connect', + 'build', + ['watch', 'connect'], cb ); }); + // -// Production build +// Full build // gulp.task('build', function(cb) { + + console.log(chalk.green('Building ' + ($.util.env.production ? 'production' : 'dev') + ' version...')); + runSequence( 'clean', - 'jekyll:production', - ['css', 'js', 'images', 'fonts', 'media'], - 'icons', - 'svg:fallbacks', - 'revision', - 'revision:replace', - 'cdn', - ['optimize:html', 'optimize:images', 'optimize:css', 'optimize:js'], - 's3:assets', + 'jekyll', + ['css', 'js', 'images', 'icons', 'fonts', 'media', 'html'], cb ); }); diff --git a/package.json b/package.json index 7506ddbf..47a91513 100644 --- a/package.json +++ b/package.json @@ -34,18 +34,21 @@ "gulp-filter": "^2.0.2", "gulp-header": ">=1.2.2", "gulp-htmlmin": ">=1.1.2", + "gulp-if": "^1.2.5", "gulp-imagemin": ">=2.2.1", "gulp-include": ">=2.0.2", "gulp-load-plugins": ">=0.10.0", "gulp-rename": ">=1.2.2", "gulp-replace": ">=0.5.3", "gulp-rev": ">=4.0.0", + "gulp-rev-all": "^0.8.21", "gulp-rev-replace": ">=0.4.1", "gulp-stylus": ">=2.0.3", "gulp-svg-sprite": ">=1.2.2", "gulp-svg2png": ">=0.3.0", "gulp-uglify": ">=1.2.0", "gulp-uncss": ">=1.0.1", + "gulp-util": "^3.0.6", "merge-stream": ">=0.1.7", "run-sequence": ">=1.1.0", "stylus": ">=0.45.0",