Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

30
"THE BASIC RULE OF THUMB IS THAT YOU SHOULD BE ABLE TO WALK UP TO THE PROJECT WITH A VIRGIN MACHINE, DO A CHECKOUT, AND BE ABLE TO FULLY BUILD THE SYSTEM.” TAME YOUR BUILD AND DEPLOY PROCESS A LOOK AT HUDSON, PHPUNIT, AND SSH WIL MOORE III @WILMOORE HTTP://GITHUB.COM/WILMOORE

description

Wil Moore III's presentation at the January 20, 2011 Front Range PHP Group.

Transcript of Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Page 1: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

"THE BASIC RULE OF THUMB IS THAT YOU SHOULD BE ABLE TO WALK UP TO

THE PROJECT WITH A VIRGIN MACHINE, DO A CHECKOUT, AND BE ABLE TO FULLY BUILD THE SYSTEM.”

TAME YOUR BUILD AND DEPLOY PROCESS

A LOOK AT HUDSON, PHPUNIT, AND SSH

WIL MOORE III@WILMOORE

HTTP://GITHUB.COM/WILMOORE

Page 2: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

• Senior Developer, Technical Lead @ Navigant Healthcarehttp://navigantconsulting.com/industries/healthcare/

• Zend Certified PHP 5.3 Engineer

• Zend Framework Contributor

• Twitter: @wilmoore

About Me

Page 3: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

• Your take-away should be that you understand the steps involved in getting basic continuous integration going.

• You understand that there is no single recipe for success. Each environment is different and Hudson is a single tool.

• You should understand when to use Hudson and when not to use Hudson.

• You should understand that continuous integration isn’t hard.

Goal of this talk

Page 4: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

What is it and what are the benefits?

1. Automates your semi-automated processes and provides instant feedback about these processes.

2. Keeps the team honest as it relates to unit and integration tests.

3. Yet another method of documenting your process.

4. FYI…the name continuous integration sort of sucks.

About Continuous Integration

Page 5: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

There is nothing magical about continuous integration.

It won’t write unit tests for you, and there is no single recipe for setting it all up.

You could automate your infrastructure without a continuous integration server, but you’d be re-inventing the wheel…and you’d still need to understand your process.

You need to understand your process

Page 6: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

It’s free

It has a simple and clean interface

You can also run it from the command-line

It’s easy to install (especially with Ubuntu)

Why Hudson?

Page 7: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

So, how do I get started

Update Ubuntu> sudo apt-get update && sudo apt-get dist-upgrade –f> sudo apt-get autoremove ; sudo apt-get autoclean

Install Vim (or your favorite text editor) and SSH> sudo apt-get install vim ssh –y> sudo update-alternatives --config editor

SSH Security (sudo vim /etc/ssh/sshd_config)PermitRootLogin noPubkeyAuthentication yesPermitEmptyPasswords noPasswordAuthentication no (be careful)

> sudo service ssh restart

Page 8: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Install Java & Hudson

Java (JDK) Installation> sudo sh -c 'echo "deb http://archive.canonical.com/ lucid partner" >> /etc/apt/sources.list.d/ubuntu-partner.list'> sudo apt-get update> sudo apt-get install sun-java6-jdk -y

Install Hudson> wget -q -O - http://pkg.hudson-labs.org/debian/hudson-labs.org.key | sudo apt-key add -> sudo sh -c 'echo "deb http://pkg.hudson-labs.org/debian binary/" >> /etc/apt/sources.list.d/hudson.list’> sudo apt-get update> sudo apt-get install hudson –y

Hudson will be available @ http://localhost:8080

Page 9: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Required plug-ins for this talk• Git (yes, that’s all)

Additional plug-ins to explore xUnit Phing SSH Github Green Balls Mercurial Subversion

Configure Hudson

Page 10: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

How to Setup a Hudson project

New Job (name = Zend Framework Contributions) Build a free-style software project Source Code Management = “Subversion” Repository URL =

http://framework.zend.com/svn/framework/standard/trunk

Choose a Build Trigger Add a build step

Execute Shellcd tests && phpunit Zend/Rest/RouteTest.php

Save, then “Build Now” Click the progress bar to watch the build logs real-time

Note: first time pulling this project down could take a while…

Page 11: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

1. It is inspired by Java’s JUnit framework

2. Instead of writing code first, then using echo, print_r, var_export, you write tests first, then write code that will pass the tests.

3. @dataProvider allows you to pass arbitrary amounts of test data to a single test so you can see multiple permutations of a single test.

4. @group allows you to run specific tests or suites as a group. For instance, you can tag a test (0r group of tests) as corresponding to a bug and run only those tests.

About PHPUnit

Page 12: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Successful Build

Page 13: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

What else should I run besides unit tests?

Run database schema migrations (e.g. Doctrine/Liquibase)

Run your code generation scripts (dynamic proxies, etc.)Publish code coverage statsGenerate and Publish documentation (PHPDoc, Sphinx)Run a database backupRestart apacheSwitch release directories (symlinks)Pre-warm caches (memcached, apc, files, no-sql

databases)Update Solr/Lucene indexesStart an Amazon EC2 server instance

Page 14: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Local VM, DEV, QA, UAT, STAGE, PROD

1. Each should be it’s own hudson job

2. You can create a “template” job in hudson

1. Build DEV automatically upon your source repository changes

2. Build QA on a schedule (nightly, etc.), UAT pushes can be run on-demand, and STAGE/PROD are on-demand just before a new release.

What about other environments

Page 15: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Let’s write some code

cd ~ rm -rf ~/Projects/Personal/example.com.api mkdir -p ~/Projects/Personal/example.com.api cd !$ git init mkdir -p src/lib src/put/lib src/www src/app/controllers

src/app/models ops/etc/apache2/sites-available vim src/www/index.php vim ops/etc/apache2/sites-available/example.com.api.vhost git add . git commit -a -m “Initial Commit”

Page 16: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

1. Create an SSH user that will own the web files

2. Give SSH user permission to restart apache

3. Prepare the application releases directory

4. Configure Hudson to pull from Git repo and transfer via rsync

5. Configure Hudson Build Steps

Can we push yet? Why not?

Page 17: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

1. It’s like telnet, but communication is encrypted as opposed to plain text.

2. You can authenticate with a password or with public/private key pairs.

1. You keep the private key tucked secretly away, and you give the public key away to servers you want to authenticate with. For instance, Github has your public key if you want to push to their service.

2. You can login to a remote server’s shell interactively or you can pass commands to that shell non-interactively.

The least you need to know about SSH

Page 18: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Create an SSH User on target server

NOTE: SSH into target server to run the following commands: sudo useradd api --create-home --skel /etc/skel --shell /bin/bash sudo addgroup deploy sudo usermod -a --groups deploy api ssh-keygen -b 2048 -t rsa -f ~/.ssh/api.pem

NOTE: press enter a few times until done – do not enter a passphrase

cd ~/.ssh mv api.pem.pub api.pub sudo mkdir /var/lib/hudson/.ssh sudo mv api.pem /var/lib/hudson/.ssh sudo chown -R hudson:nogroup /var/lib/hudson/.ssh sudo chmod 700 /var/lib/hudson/.ssh sudo mkdir ~api/.ssh sudo mv api.pub ~api/.ssh/authorized_keys sudo chown -R api:api ~api/.ssh sudo chmod 700 ~api/.ssh sudo chmod 600 ~api/.ssh/authorized_keys

Page 19: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

About the hudson file system structure

1. Hudson is an actual OS user with a shell and a home directory:/var/lib/hudson

1. /var/lib/hudson/jobs/{{job-name}}/workspaceThis is where your files go after a source check-out

2. The workspace ($WORKSPACE) directory is where you run unit tests before pushing via SSH.

Where are my files going?

Page 20: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Grant SSH user specific permissions

Allow the “deploy” group to write and own virtual host configuration files sudo chgrp deploy /etc/apache2/sites-available /etc/apache2/sites-enabled sudo chmod g+w /etc/apache2/sites-available /etc/apache2/sites-enabled sudo chmod g+s /etc/apache2/sites-available /etc/apache2/sites-enabled

EDIT THE "/etc/sudoers" file sudo visudo

NOTE: Ubuntu may default to nano as editor; however, you can change it to vim or something else with the following command:

sudo update-alternatives --config editor

ADD THE FOLLOWING LINE (under the "User privilege specification" section)

api ALL=(root) NOPASSWD: /usr/sbin/service apache2 *

Page 21: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Create the releases directory

NOTE: Login as “hudson” user, then SSH to “api” user.

sudo su – hudson vim ~/.ssh/config

Host 127.0.0.1User apiIdentityFile /var/lib/hudson/.ssh/api.pemPort 22Protocol 2

ssh -i ~/.ssh/api.pem [email protected] mkdir -p ~/apps/api.example.com/releases ~/apps/api.example.com/shared

NOTE: RSA key fingerprint must be accepted once manually in order to automate authentication.

Page 22: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Configure Hudson for Git & Rsync

In Shell git config --global user.name "Hudson” git config --global user.email "[email protected]"

Hudson Job Configuration “example.com.api” >> “Configure” >> “Source Code Management” >> “Git”

URL of Repository: /media/psf/example.com.apiNOTE: I cheated by linking a folder to my VM

“Build” >> “Add Build Step” >> “Execute Shell” >> “Command” rsync -avzH -e ssh --progress $WORKSPACE/

[email protected]:~/apps/api/releases/$BUILD_ID

Page 23: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Configure Build

Hudson Job Configuration (cont.) “Build” >> “Add Build Step” >> “Execute Shell” >> “Command”

ssh [email protected] <<ssh-session########## BEGIN: ssh commands ##########cp ~/apps/api.example.com/releases/${BUILD_ID}/ops/etc/apache2/sites-available/example.com.api.vhost /etc/apache2/sites-available/ln -nfs /etc/apache2/sites-available/example.com.api.vhost /etc/apache2/sites-enabled/ln -nfs ~/apps/api.example.com/releases/${BUILD_ID} ~/apps/api.example.com/currentsudo /usr/sbin/service apache2 restart########## END: ssh commands ##########ssh-session

Now, run build, then browse to http://api.example.com/

Page 24: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

A Restful web service API maps HTTP to code

1. Responds to common HTTP verbs/methods (GET, POST, PUT, DELETE)

2. Exposes a restful (not RPC, not Query) API• Restful: /users/1• RPC: /users/show/1• Query: /users/show?userId=1

3. Responds with a JSON content type (application/json)

Let’s build something more interesting to deploy

Page 25: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

What is a Router class?

1. The “Router” class will allow us to match information of $_SERVER[‘REQUEST_URI’] to a controller class.

1. The “Router” class will allow us to match information of $_SERVER[‘REQUEST_URI’] to an anonymous function.

1. The “Router” class will allow us to match information of $_SERVER[‘REQUEST_URI’] to a global function.

Building the routing class

Page 26: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

A Restful web service API

1. Support output buffering2. Error & Exception Handling3. Route optional segments4. Parameter conditions5. Content-type negotiation6. Correctly respond to HEAD requests

Possible Future Enhancements

Page 27: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

The Files

1. autoload.php.dist2. bootstrap.php3. phpunit.xml.dist4. src/put/lib/RouterTest.php5. src/lib/Router.php6. src/www/index.php

Let’s code it together then deploy it

Page 28: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

1. Bamboo

2. Team City

3. CruiseControl (PHPUnderControl)

4. Team Foundation Server

Hudson Alternatives

Page 29: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Books

Continuous Integration: Improving Software Quality and Reducing Risk Paul M. Duvall, Steve Matyas, Andrew Glover

Refactoring: improving the design of existing code Martin Fowler

Refactoring Databases : Evolutionary Database Design Scott W. Ambler, Pramodkumar J. Sadalage

Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation Jez Humble, David Farley

The Pragmatic Programmer: From Journeyman to Master Andrew Hunt, David Thomas

Agile Testing: A Practical Guide for Testers and Agile Teams Lisa Crispin, Janet Gregory

Page 30: Tame Your Build And Deployment Process With Hudson, PHPUnit, and SSH

Reference

CI Feature Matrixhttp://confluence.public.thoughtworks.org/display/CC/CI+Feature+Matrix

Free Hosted Continuous Integration Environmenthttp://www.fazend.com/

Why are you still not using Hudson?http://blog.uncommons.org/2008/05/09/why-are-you-still-not-using-hudson/

Continuous Integration (Martin Fowler)http://martinfowler.com/articles/continuousIntegration.html