Setting up Push-to-Deploy with git – Kris Jordan

Setting up Push-to-Deploy with git

I first set up a push-to-deploy system with git and puppet for a side project a few years back. It worked so well I transitioned NMC‘s development process onto it for all of our new projects starting last year. It offers the simplicity of the “push-to-deploy” model Heroku pioneered, with full control and flexibility over the operating system environment.

I’ve started thinking about my next iteration of this system for Didsum, and using pushing for more than just deployment purposes. The Push-to-______ pattern is powerful and easy to use, once you know how the pieces fit together. In this post, I’ll walk through the setting up Push-to-Deploy from the ground up.

(I’m assuming a working knowledge of: terminal, git, and a scripting language.)

Preparing our Repositories

Let’s keep things straightforward by placing our development git repository, remote git repository, and deploy directory under the same local directory.

mkdir push-to-deploy
cd push-to-deploy
mkdir {development,remote,deploy}

Awesome, now let’s setup the remote git repository. With a real project, this would be a directory on your production server. There is a special setup for git repositories whose purpose is to receive pushes from developers, they’re called “bare” repositories. You can read more about “bare” repositories, but for our purposes their purpose is just to receive pushes.

cd remote
git init --bare
cd ..

Perfect, now let’s setup our development directory with git. (You could also copy one of your git project’s contents into the development folder.)

cd development
git init
echo "Hello, world." >> file.txt
git add file.txt
git commit -m 'First commit.'

We now have a development repository with its first commit. Our last preparation step is to register the “remote” repository. If you’re fuzzy on git remotes, the official git site has you covered.

git remote add production ../remote
git push production master

Boom. You’ve just pushed your commit from development to your bare, ‘remote’ repository. We’re ready to setup push-to-deploy.

Set up Push-to-Deploy

Now that our remote repository is setup, we’re ready to write a script for what it’ll do when it receives a push. Let’s navigate to the hooks folder of our remote repository. Hooks are scripts that git runs when certain events happen.

cd ../remote/hooks
touch post-receive
chmod +x post-receive

The hook we care about for push-to-deploy is post-receive. It is run after receiving and accepting a push of commits. In the commands above, we’re creating the post-receive script file with `touch`, and making sure it’s an executable file.

Next, open the post-receive script file in your preferred text editor. Copy the contents below:

#!/usr/bin/env ruby
# post-receive

# 1. Read STDIN (Format: "from_commit to_commit branch_name")
from, to, branch = " "

# 2. Only deploy if master branch was pushed
if (branch =~ /master$/) == nil
    puts "Received branch #{branch}, not deploying."

# 3. Copy files to deploy directory
deploy_to_dir = File.expand_path('../deploy')
`GIT_WORK_TREE="#{deploy_to_dir}" git checkout -f master`
puts "DEPLOY: master(#{to}) copied to '#{deploy_to_dir}'"

# 4.TODO: Deployment Tasks
# i.e.: Run Puppet Apply, Restart Daemons, etc

Let’s walk through each of the steps:

1. When git runs post-receive, the data about what was received is provided to the script via STDIN. It contains three arguments separated by spaces: the previous HEAD commit ID, the new HEAD commit ID, and the name of the branch being pushed to. We’re reading these values and assigning them to from, to, and branch variables, respectively.

2. Our purpose here is to automate push-to-deploy. Assuming a workflow that keeps production on the master branch, we want to exit this script prior to deploying if the branch being pushed is not master.

3. The first deploy step is to “checkout”, basically export or copy, files from the master branch to the directory where our project is deployed to in production. (Remember, in this demo it’s the fake “deploy” directory, in the real world this might be /var/www, or wherever your project expects to be in production.)

4. Now that our deploy directory is up-to-date, we can run whatever deployment tasks we need to run. This could be applying Puppet scripts (I’ll write a post on this scenario soon), restarting a web or application server, clearing cache files, recompiling static assets, etc. Whatever steps you’d normally need to do manually after updating your project’s files, automate them here!

Save your post-receive hook, and let’s test it out!

Testing with Pushing

We can test our script manually, by creating a new commit in our development directory and pushing:

cd ../../development
echo "New line." >> file.txt
git add file.txt
git commit -m 'Testing push-to-deploy'
git push production master

In the output of the git push command, you should see lines starting with “remote:”. These lines are the output of our post-receive script:

Already on 'master'
DEPLOY: master($TO_ID) copied to 'push-to-deploy/deploy'

The first line is noisy output from the git checkout command in step 3, we can ignore it. The second line, is from the puts command, also from step 3 in our post-receive script.

The directory we’re deploying to should now be populated and up-to-date:

ls ../deploy
diff file.txt ../deploy/file.txt

Pretty awesome, right?

Testing without Pushing

When you’re working on a post-receive hook, it’s annoying to muck up your project’s commit history and push each time you make a change. Luckily, because it’s just a script, we can fake it from the command-line.

cd ../remote
git log -2 --format=oneline --reverse

First, we need to get the IDs of our most recent 2 commits. The git log command, above, will give us these two IDs in the order you’ll want to replace the $FROM_ID and $TO_ID variables with, respectively.

echo "$FROM_ID $TO_ID master" | ./hooks/post-receive

This method makes setting up your post-receive hooks enjoyable, enabling you to quickly iterate on your script and execute it repeatedly.

Next Steps

In this post, we’ve walked through how to setup the push-to-deploy with git. For a real world project, your ‘remote’ and ‘deploy’ folders would usually be setup on a server, not locally. The details of doing that and properly configuring SSH is beyond the post of this scope (note to self: I should write on SSH configuration, too!).

From here, it’s up to your project to determine what actions to automate! Happy pushing!

(If the push-to-X pattern interests you, you should follow me on Twitter, or subscribe to my RSS feed, because I’ve got a few more posts on the subject coming up! Also, feel free to tweet feedback / questions / topics you’d like to read.)

Source: Setting up Push-to-Deploy with git – Kris Jordan


2015-09-21 17:27
[ 亿欧导读 ] 亿欧网9月21日消息,后市场O2O项目“TT快车”今日正式对外宣布获得新浪领投、红杉资本跟投的B轮融资,华兴资本担任此次融资的独家财务顾问。TT快车并未透露B轮融资的具体融资金额,此前于2015年1月宣布获得红衫A轮融资。









Source: TT快车宣布完成B轮融资,新浪领投_亿欧网_驱动创业创新

Make a 3D print from a 2D drawing

Picture of Make a 3D print from a 2D drawing
Using a few open source software tools and very little technical knowledge, it’s possible to turn a 2D vector drawing into an extruded object for 3D printing.  I used this technique to make a bracelet.


  1. Make an .svg file of the shape you want to extrude
  2. Convert it to OpenSCAD format using an Inkscape extension
  3. Use OpenSCAD to render and generate an .stl file
  4. Print the object

Step 1: Make an .svg file of the shape you want to extrude

First get a shape that you want to extrude.  It needs to be in a vector graphics format, not bitmap (or raster) format.  Read up if you’re not familiar with these terms.

To get a vector graphic you have three options:

  1. Download it.  You could use Google Advanced Image Search and limit your search to .svg files, a common vector graphics format on the web.  You want to make sure you have permission before you use anyone else’s drawings, though.
  2. Draw it yourself. Use Inkscape, Illustrator, CorelDRAW, or any of the many other vector graphics applications.  Drawing vector graphics is its own topic worthy of many instructables.
  3. Make a digital trace. If you do have a raster image (bitmap), then you can convert it to a vector graphic with Illustrator’s live trace or Inkscape’s tracefeatures, which are fun to play with.  Keep in mind that these features are not magic, and you’ll have to fiddle around a lot to get the graphic right.

Then save the file as .svg format.

Step 2: Convert the .svg to OpenSCAD format

Picture of Convert the .svg to OpenSCAD format
OpenSCAD is the software that will extrude the object for us.  However, we first need to convert the .svg to OpenSCAD format in Inkscape using the magic ofthis Thing.

Do this:

Install Inkscape.
Download the paths2openscad script at GitHub.
Move the script to your ~/.config/inkscape/extensions folder.
Open Inkscape.
File -> Open to open the .svg file.
Extensions -> Generate from Path -> Paths to OpenSCAD to generate the .scad file.
Save the file with the extension “.scad”
Now you’re ready to render.

Step 3: Render and generate an .stl file

Picture of Render and generate an .stl file
Screen shot 2013-08-20 at 10.47.27 PM.png
Now download and install OpenSCAD.  OpenSCAD is a CAD program that doesn’t have an interactive graphical user interface for drawing objects.  Instead it uses its own scripting language.  Fortunately for our purposes here you don’t need to learn the language.  But now that you know it exists, you’re probably going to want to learn it.  Right?

Getting down to business in OpenSCAD:

File -> Open to open the .scad file made in the last step.  If you get warnings, just ignore them.
Design -> Compile and Render to build the object.  This might take a while, depending on how complex your object is.
Once the rendering is complete, Design -> Export to STL to export the file for printing.
The .stl file should be ready to print!  However, if you first want a better look at your rendered object, you could open it up in SketchUp.

Step 4: Print your object

Picture of Print your object
photo (29).JPG
Print your object.  Here you can see my bracelet being printed on theMakerBot Replicator 2, which Instructables hooked us up with here at Ace Monster Toys.

If you don’t have a 3D printer, have Shapeways print it for you, build a printer,buy one, or better yet, join your local hacker/makerspace or TechShop and use theirs.

Thank you:

davr for showing me how to use a 3D printer
dnewman for developing and sharing the OpenSCAD converter
heilis for playtesting the bracelet
Ace Monster Toys for being an awesome place

Source: Make a 3D print from a 2D drawing