├── .gitignore ├── yuicompressor-2.4.7.jar ├── .gitmodules ├── config.sample.php ├── post-receive.sample ├── README.md └── git-deploy-s3 /.gitignore: -------------------------------------------------------------------------------- 1 | /config.php 2 | -------------------------------------------------------------------------------- /yuicompressor-2.4.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradt/git-deploy-s3/HEAD/yuicompressor-2.4.7.jar -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "aws-sdk-for-php"] 2 | path = aws-sdk-for-php 3 | url = git://github.com/amazonwebservices/aws-sdk-for-php.git 4 | [submodule "aws-sdk"] 5 | path = aws-sdk 6 | url = git://github.com/amazonwebservices/aws-sdk-for-php.git 7 | -------------------------------------------------------------------------------- /config.sample.php: -------------------------------------------------------------------------------- 1 | S3 bucket name / object path 8 | $paths = array( 9 | 'public_html/assets/css/style.css' => 'assets-spiceweasel-com/css/style.css', 10 | 'public_html/assets/images' => 'assets-spiceweasel-com/images', 11 | 'public_html/assets/js' => 'assets-spiceweasel-com/js' 12 | ); 13 | 14 | // Path to YUI Compressor 15 | $yuic_path = dirname( __FILE__ ) . '/yuicompressor-2.4.7.jar'; 16 | 17 | // File extensions to run through YUI Compressor (if defined above) 18 | $yuic_file_extensions = array( 'js', 'css' ); 19 | 20 | -------------------------------------------------------------------------------- /post-receive.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script for the "post-receive" event. 4 | # 5 | # The "post-receive" script is run after receive-pack has accepted a pack 6 | # and the repository has been updated. It is passed arguments in through 7 | # stdin in the form 8 | # 9 | # For example: 10 | # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master 11 | 12 | while read oldrev newrev refname 13 | do 14 | if [ "$refname" == "refs/heads/master" ]; then 15 | break; 16 | fi 17 | done 18 | 19 | if [ "$refname" != "refs/heads/master" ]; then 20 | exit; 21 | fi 22 | 23 | PUBLIC_HTML="$HOME/public_html" 24 | cd $PUBLIC_HTML || exit 25 | unset GIT_DIR 26 | 27 | echo -n "Deploying assets to S3..." 28 | 29 | $HOME/git-deploy-s3/git-deploy-s3 $oldrev $newrev 30 | 31 | echo "done." 32 | 33 | exec git-update-server-info 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | git-deploy-s3 2 | ============= 3 | 4 | A CLI script that picks up changes to your git repo assets and deploys them 5 | to Amazon S3. 6 | 7 | The script takes two commit hashes, gets a list of files added/modified/deleted, 8 | and uploads them to S3 or deletes them from S3 as appropriate. Of course, you 9 | get to specify exactly which files and directories you would like this script to 10 | work with and all other files will be ignored. 11 | 12 | You can also choose to automatically compress JS and/or CSS files using 13 | YUI Compressor before uploading to S3. 14 | 15 | This script was built specifically to work with git's `post-receive` hook and 16 | automate the deployment process. See the included `post-receive.sample`. 17 | 18 | Usage 19 | ----- 20 | 21 | Run the following from the root of your working copy. 22 | 23 | $ /path/to/git-deploy-s3 24 | 25 | See `config.sample.php` for configuration options. 26 | 27 | Installation 28 | ------------ 29 | 30 | 1. Clone this repo 31 | 1. Copy `config.sample.php` to `config.php` and edit it as needed 32 | 33 | Author 34 | ------ 35 | 36 | Brad Touesnard (http://bradt.ca) 37 | 38 | License 39 | ------- 40 | 41 | Copyright (c) 2012 Brad Touesnard 42 | 43 | This program is free software; you can redistribute it and/or 44 | modify it under the terms of the GNU General Public License 45 | as published by the Free Software Foundation; either version 2 46 | of the License, or (at your option) any later version. 47 | 48 | This program is distributed in the hope that it will be useful, 49 | but WITHOUT ANY WARRANTY; without even the implied warranty of 50 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 51 | GNU General Public License for more details. 52 | 53 | You should have received a copy of the GNU General Public License 54 | along with this program; if not, write to the Free Software 55 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 56 | 57 | -------------------------------------------------------------------------------- /git-deploy-s3: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php -d disable_functions= 2 | \n"; 7 | exit; 8 | } 9 | 10 | $cmd = "git diff --name-status $argv[1] $argv[2]"; 11 | $diff = shell_exec( $cmd ); 12 | 13 | if ( !$diff ) exit; 14 | 15 | $lines = explode( "\n", trim( $diff ) ); 16 | 17 | $deletes = $uploads = array(); 18 | foreach ( $lines as $line ) { 19 | list( $flag, $file ) = explode( "\t", $line ); 20 | foreach ( $paths as $path => $remote_path ) { 21 | $regex = '^' . preg_quote( $path, '@' ); 22 | $is_dir = is_dir( $path ); 23 | if ( !$is_dir ) { 24 | $regex .= '$'; 25 | } 26 | 27 | if ( !preg_match( '@' . $regex . '@', $file ) ) continue; 28 | 29 | if ( $is_dir ) { 30 | $_path = preg_replace( '@^' . $path . '@', '', $file ); 31 | $remote_path = $remote_path . '/' . ltrim( $_path, '/' ); 32 | } 33 | 34 | if ( 'D' == $flag ) { 35 | $deletes[$file] = $remote_path; 36 | } 37 | else { 38 | $uploads[$file] = $remote_path; 39 | } 40 | } 41 | } 42 | 43 | //print_r( $deletes ); print_r( $uploads ); exit; 44 | 45 | if ( empty( $deletes ) && empty( $uploads ) ) exit; 46 | 47 | require_once 'aws-sdk/sdk.class.php'; 48 | 49 | $s3 = new AmazonS3(array( 50 | 'key' => $aws_key, 51 | 'secret' => $aws_secret 52 | )); 53 | 54 | @$s3->disable_ssl_verification(); 55 | 56 | function split_s3_path( $path ) { 57 | $first_slash = strpos( $path, '/' ); 58 | $bucket_name = substr( $path, 0, $first_slash ); 59 | $object = substr( $path, $first_slash+1 ); 60 | return compact( 'bucket_name', 'object' ); 61 | } 62 | 63 | foreach ( $deletes as $remote_path ) { 64 | extract( split_s3_path( $remote_path ) ); 65 | $s3->batch()->delete_object( $bucket_name, $object ); 66 | echo "Delete $bucket_name/$object \n"; 67 | } 68 | 69 | $do_compress = isset( $yuic_path ) && file_exists( $yuic_path ); 70 | 71 | foreach ( $uploads as $file => $remote_path ) { 72 | $ext = pathinfo( $file, PATHINFO_EXTENSION ); 73 | if ( $do_compress && in_array( $ext, $yuic_file_extensions ) ) { 74 | if ( !isset( $tmp_path ) ) { 75 | $tmp_path = dirname( __FILE__ ) . '/tmp-' . time(); 76 | mkdir( $tmp_path); 77 | } 78 | $file_name = basename( $file ); 79 | echo `java -jar $yuic_path -o $tmp_path/$file_name $file`; 80 | $file = "$tmp_path/$file_name"; 81 | } 82 | 83 | $opts = array( 84 | 'fileUpload' => $file, 85 | 'acl' => AmazonS3::ACL_PUBLIC 86 | ); 87 | extract( split_s3_path( $remote_path ) ); 88 | $s3->batch()->create_object( $bucket_name, $object, $opts ); 89 | //echo $file, "\n"; 90 | echo "Copy $bucket_name/$object \n"; 91 | } 92 | 93 | $response = $s3->batch()->send(); 94 | if ( !$response->areOK() ) { 95 | echo "Error sending batch.\n"; 96 | print_r($response); 97 | } 98 | 99 | if ( isset( $tmp_path ) ) { 100 | echo `rm -Rf $tmp_path`; 101 | } 102 | 103 | //echo "Done.\n"; 104 | 105 | --------------------------------------------------------------------------------