diff --git a/.ci/build.sh b/.ci/build.sh new file mode 100755 index 00000000..2184ed02 --- /dev/null +++ b/.ci/build.sh @@ -0,0 +1,9 @@ +#!/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..48c46ac8 --- /dev/null +++ b/.ci/deploy.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -e; + +echo "$(tput setaf 136)" +echo " Starting assets CDN " +echo "=============================================" +echo "$(tput sgr0)" # reset + +gulp s3:assets +gulp cdn + +echo "$(tput setaf 64)" # green +echo "---------------------------------------------" +echo " ✓ done assets CDN" +echo "$(tput sgr0)" # reset + + +echo "$(tput setaf 136)" +echo " Starting rsync deployment " +echo "=============================================" +echo "$(tput sgr0)" # reset + +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/ + +echo "$(tput setaf 64)" # green +echo "---------------------------------------------" +echo " ✓ done rsync deployment " +echo "$(tput sgr0)" # reset diff --git a/.ci/setup.sh b/.ci/setup.sh new file mode 100755 index 00000000..a1876915 --- /dev/null +++ b/.ci/setup.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -e; + +echo "$(tput setaf 136)" +echo " Installing dependencies " +echo "=============================================" +echo "$(tput sgr0)" # reset + +npm install gulp bower -g +npm install +bower install +bundle install + +echo "$(tput setaf 64)" # green +echo "---------------------------------------------" +echo " ✓ done installing dependencies" +echo "$(tput sgr0)" # reset diff --git a/.travis.yml b/.travis.yml index 387986b3..f60bf0d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,25 @@ 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 + - _site/media/gen 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..34708455 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,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,9 +41,9 @@ 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`. +This generates the site with the dev build task `gulp build` and starts a local dev server combined with a livereloading watch task under `http://localhost:1337`. ```bash gulp @@ -51,10 +51,8 @@ gulp ### Production build -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..355a62bc 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -19,6 +19,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 @@ -37,9 +40,9 @@ console.log(""); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // paths -var src = '_src', - dist = '_site', - cdn = 'https://cdn.kremalicious.com', +var src = '_src', + dist = '_site', + cdn = 'https://cdn.kremalicious.com', s3bucket = 'kremalicious.com', s3path = '/', s3region = 'eu-central-1'; @@ -109,20 +112,35 @@ 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, $.htmlmin({ + collapseWhitespace: true, + conservativeCollapse: true, + removeComments: true, + useShortDoctype: true, + collapseBooleanAttributes: true, + removeRedundantAttributes: true, + removeEmptyAttributes: true, + removeEmptyAttributes: true + }))) + .pipe(gulp.dest(dist)) }); @@ -136,6 +154,9 @@ 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(gulp.dest(dist + '/assets/css/')) .pipe($.connect.reload()) @@ -149,10 +170,11 @@ gulp.task('css', function() { // Libraries gulp.task('js:libraries', function() { return gulp.src([ - 'node_modules/picturefill/dist/picturefill.js' - ]) - .pipe($.rename({ suffix: '.min'})) - .pipe(gulp.dest(dist + '/assets/js/')) + 'node_modules/picturefill/dist/picturefill.js' + ]) + .pipe($.if(isProduction, $.uglify())).on('error', onError) + .pipe($.rename({ suffix: '.min'})) + .pipe(gulp.dest(dist + '/assets/js/')) }); // Project js @@ -160,6 +182,8 @@ 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(gulp.dest(dist + '/assets/js/')) .pipe($.connect.reload()) }); @@ -183,22 +207,12 @@ 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(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 +221,13 @@ 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(gulp.dest(dist + '/assets/img/')) }); @@ -229,77 +250,15 @@ 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($.if(isProduction, $.rev())) .pipe(gulp.dest(dist + '/assets/')) // output rev manifest for next replace task - .pipe($.rev.manifest()) + .pipe($.if(isProduction, $.rev.manifest())) .pipe(gulp.dest(dist + '/assets/')) }); @@ -308,12 +267,12 @@ 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'); return gulp.src(dist + '/**/*.{html,xml,txt,json,css,js,png,jpg,jpeg,svg,eot,ttf,woff}') - .pipe($.revReplace({ manifest: manifest })) + .pipe($.if(isProduction, $.revReplace({ manifest: manifest }))) .pipe(gulp.dest(dist)) }); @@ -387,54 +346,43 @@ 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', + ['html', 'css', 'js', 'images', 'icons', 'fonts', 'media'], + 'rev', + 'rev:replace', cb ); }); diff --git a/package.json b/package.json index 7506ddbf..8f9f41fd 100644 --- a/package.json +++ b/package.json @@ -31,9 +31,10 @@ "gulp-concat": ">=2.5.2", "gulp-connect": ">=2.0.5", "gulp-cssmin": ">=0.1.7", - "gulp-filter": "^2.0.2", + "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", @@ -46,10 +47,11 @@ "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", - "vinyl": "^0.4.6" + "vinyl": ">=0.4.6" }, "engines": { "node": ">=0.10.29"