Browse files

Cache RubyGems and NPM packages.

  • Loading branch information...
1 parent a040c71 commit 1c127c6774b979511b8958e1c74c72ee1ef724c5 @rwjblue rwjblue committed Dec 19, 2013
Showing with 191 additions and 5 deletions.
  1. +0 −1 .gitignore
  2. +3 −4 .travis.yml
  3. +60 −0 bin/cached-bundle
  4. +55 −0 bin/cached-npm
  5. +73 −0 bin/s3-put
View
1 .gitignore
@@ -1,4 +1,3 @@
-bin/
.bundle
bundle
tmp/
View
7 .travis.yml
@@ -2,15 +2,14 @@
rvm:
- 1.9.3
install:
-- "npm install"
-- "bundle install --deployment"
+- "bin/cached-npm install"
+- "bin/cached-bundle install --deployment"
- sudo apt-get update && sudo apt-get install git
script: rake test[all]
after_success: bundle exec rake publish_build
-notifications:
- webhooks: http://emberjs-master-builds.herokuapp.com/upload/data
env:
global:
+ - S3_BUILD_CACHE_BUCKET=emberjs-build-cache
- S3_BUCKET_NAME=builds.emberjs.com
- secure: ! 'S+DIdzEPvqQenk1cFq5UjbkoEKDY4j3E/g+Wlz798xxyTkrKQZxoazLXng8I
View
60 bin/cached-bundle
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+# Usage: cached-bundle install --deployment
+#
+# After running `bundle`, caches the `vendor/bundle` directory to S3.
+# On the next run, restores the cached directory before running `bundle`.
+# When `Gemfile.lock` changes, the cache gets rebuilt.
+#
+# Requirements:
+# - Gemfile.lock
+# - TRAVIS_REPO_SLUG
+# - TRAVIS_RUBY_VERSION
+# - S3_BUILD_CACHE_BUCKET
+# - script/s3-put
+# - bundle
+# - curl
+#
+# Author: Mislav Marohnić
+
+set -e
+
+compute_md5() {
+ local output="$(openssl md5)"
+ echo "${output##* }"
+}
+
+download() {
+ curl --tcp-nodelay -qsfL "$1" -o "$2"
+}
+
+script_dir=$(dirname "${BASH_SOURCE[0]}")
+bundle_path="vendor/bundle"
+cache_buster="${BUNDLE_GEMFILE:-Gemfile}.lock"
+if [ ! -f $cache_buster ]; then
+ cache_buster="$GEMSPEC"
+fi
+cache_busting_hash="$(compute_md5 <"$cache_buster")"
+
+cache_name="bundler-${TRAVIS_RUBY_VERSION}-${cache_busting_hash}.tgz"
+fetch_url="http://${S3_BUILD_CACHE_BUCKET}.s3.amazonaws.com/${TRAVIS_REPO_SLUG}/${cache_name}"
+
+if download "$fetch_url" "$cache_name"; then
+ echo "Reusing cached bundle ${cache_name}"
+ tar xzf "$cache_name"
+fi
+
+bundle "$@"
+
+if [ ! -f "$cache_name" ]; then
+ if [ -z "$S3_SECRET_ACCESS_KEY" ] || [ -z "$S3_ACCESS_KEY_ID" ]
+ then
+ echo "Enviroment variables not set. Exiting..."
+ exit 0
+ fi
+
+ echo "Caching \`${bundle_path}' to S3"
+ tar czf "$cache_name" "$bundle_path"
+ $script_dir/s3-put "$cache_name" "${S3_BUILD_CACHE_BUCKET}:${TRAVIS_REPO_SLUG}/${cache_name}"
+fi
+
+# vim: filetype=sh
View
55 bin/cached-npm
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+# Usage: cached-npm install
+#
+# After running `npm`, caches the `node_modules` directory to S3.
+# On the next run, restores the cached directory before running `npm`.
+# When `package.json` changes, the cache gets rebuilt.
+#
+# Requirements:
+# - Gemfile.lock
+# - TRAVIS_REPO_SLUG
+# - TRAVIS_NODE_VERSION
+# - S3_BUILD_CACHE_BUCKET
+# - script/s3-put
+# - bundle
+# - curl
+#
+# Author: Mislav Marohnić
+
+set -e
+
+compute_md5() {
+ local output="$(openssl md5)"
+ echo "${output##* }"
+}
+
+download() {
+ curl --tcp-nodelay -qsfL "$1" -o "$2"
+}
+
+script_dir=$(dirname "${BASH_SOURCE[0]}")
+bundle_path="node_modules npm_cache"
+cache_busting_hash="$(compute_md5 < package.json)"
+cache_name="npm-${TRAVIS_NODE_VERSION}-${cache_busting_hash}.tgz"
+fetch_url="https://${S3_BUILD_CACHE_BUCKET}.s3.amazonaws.com/${TRAVIS_REPO_SLUG}/${cache_name}"
+
+if download "$fetch_url" "$cache_name"; then
+ echo "Reusing cached bundle ${cache_name}"
+ tar xzf "$cache_name"
+fi
+
+NPM_CONFIG_CACHE=./npm_cache npm "$@"
+
+if [ ! -f "$cache_name" ]; then
+ if [ -z "$S3_SECRET_ACCESS_KEY" ] || [ -z "$S3_ACCESS_KEY_ID" ]
+ then
+ echo "Enviroment variables not set. Exiting..."
+ exit 0
+ fi
+
+ echo "Caching \`${bundle_path}' to S3"
+ tar czf "$cache_name" $bundle_path
+ $script_dir/s3-put "$cache_name" "${S3_BUILD_CACHE_BUCKET}:${TRAVIS_REPO_SLUG}/${cache_name}"
+fi
+
+# vim: filetype=sh
View
73 bin/s3-put
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+# Usage: s3-put <FILE> <S3_BUCKET>[:<PATH>] [<CONTENT_TYPE>]
+#
+# Uploads a file to the Amazon S3 service.
+# Outputs the URL for the newly uploaded file.
+#
+# Requirements:
+# - S3_ACCESS_KEY_ID
+# - S3_SECRET_ACCESS_KEY
+# - openssl
+# - curl
+#
+# Author: Mislav Marohnić
+
+set -e
+
+authorization() {
+ local signature="$(string_to_sign | hmac_sha1 | base64)"
+ echo "AWS ${S3_ACCESS_KEY_ID?}:${signature}"
+}
+
+hmac_sha1() {
+ openssl dgst -binary -sha1 -hmac "${S3_SECRET_ACCESS_KEY?}"
+}
+
+base64() {
+ openssl enc -base64
+}
+
+bin_md5() {
+ openssl dgst -binary -md5
+}
+
+string_to_sign() {
+ echo "$http_method"
+ echo "$content_md5"
+ echo "$content_type"
+ echo "$date"
+ echo "x-amz-acl:$acl"
+ printf "/$bucket/$remote_path"
+}
+
+date_string() {
+ LC_TIME=C date "+%a, %d %h %Y %T %z"
+}
+
+file="$1"
+bucket="${2%%:*}"
+remote_path="${2#*:}"
+content_type="$3"
+
+if [ -z "$remote_path" ] || [ "$remote_path" = "$bucket" ]; then
+ remote_path="${file##*/}"
+fi
+
+http_method=PUT
+acl="public-read"
+content_md5="$(bin_md5 < "$file" | base64)"
+date="$(date_string)"
+
+url="https://$bucket.s3.amazonaws.com/$remote_path"
+
+curl -qsSf -T "$file" \
+ -H "Authorization: $(authorization)" \
+ -H "x-amz-acl: $acl" \
+ -H "Date: $date" \
+ -H "Content-MD5: $content_md5" \
+ -H "Content-Type: $content_type" \
+ "$url"
+
+echo "$url"
+
+# vim: filetype=sh

0 comments on commit 1c127c6

Please sign in to comment.