Continuous Delivery

By Uchit Vyas

[email protected] www.attuneuniversity.com

Table of Content

I. Getting started II. Version Controlling with Git III. Git with Eclipse (EGit) IV. Eclipse SSH Configuration V. Installing VI. Installing Ruby with RVM VII. Creating a job in Jenkins VIII. Configuring the Tools

Continuous Delivery 1

About Author

Uchit Vyas a B.Tech. Graduate in Computer Science with a research interest in ESB & Cloud and is a certified by Cisco (CCNA), VMware (VSP) and Red Hat (RHCE) professional. He has an energetic strength to work on multiple platforms at a time and ability to integrate open source technologies. He works as a Sr. Consultant and looking afterAWS – Cloud, Mule ESB, Alfresco, Liferay and deploying Portal, ECM system. He was previously working with TCS as Assistant System Engineer.

Over 3+ years of hands on experience on Open Source technologies, he manages to guide the team and deliver the projects and trainings. He has provided 13+ trainings on , Continuous Delivery, Alfresco and Liferay in couple of months. During past years he moved over 80% of Attune Infocom business processes to the Cloud with implementing agile SDLC methodology on Amazon, Rackspace and private clouds like , Openstack. His skills are not limited as his designing and managing Cloud environment/infrastructure, server architecture. He is also active in shell scripting, auto deployment, supporting hundreds of Linux and Windows physical & virtual servers hosting databases, and applications with Continuous delivery using Jenkins / Cruise Control with Puppet / Chef scripting.

2 Continuous Delivery

Getting started

Continuous Delivery (CD) is a pattern language used in software development to automate and improve the process of software delivery. Techniques such as automated testing, and continuous deployment allow software to be developed to a high standard and easily packaged and deployed to test environments, resulting in the ability to rapidly, reliably and repeatedly push out enhancements and bug fixes to customers at low risk and with minimal manual overhead. The technique was one of the assumptions of extreme programming but at an enterprise level has developed into a discipline of its own, with job descriptions for roles such as "buildmaster" calling for CD skills as mandatory.

Figure 1 : Continuous Delivery Pattern Continuous delivery treats the commonplace notion of a deployment pipeline as a set of validations through which a piece of software must pass

Continuous Delivery 3

on its way to release. Code is compiled if necessary and then packaged by a build server every time a change is committed to a source control repository, then tested by a number of different techniques (possibly including manual testing) before it can be marked as releasable.

Figure 2 : Architecture for Continuous Delivery Developers use to a long cycle time may need to change their mindset when working in a CD environment. It is important to understand that any code commit may be released to customers at any point. Patterns such as feature toggles can be very useful for committing code early which is not yet ready for use by end users. Other useful techniques for developing code in isolation such as code branching are not obsolete in a CD world, but must be adapted to fit the principles of CD - for example, running multiple long-lived code branches can prove impractical, as a releasable artifact must be built early in the CD process from a single code branch if it is to pass through all phases of the pipeline.

4 Continuous Delivery

Continuous Delivery Tools List

I usually shy away from giving a list of tools that we use because people have their particular tool preferences and are sometimes indignant in considering others. However, I realize it's helpful for people to understand the tool landscape when it comes to Continuous Delivery in the Cloud just so they know where to start looking. After reading my Continuous Integration book, this is often the most common question I get from readers.

I want to say up front that I'm not advocating the use of any of these tools, just that we've used some of the tools or investigated when creating Continuous Delivery systems. I'm sure some of the tools that we use on a daily basis won't make it to this list.

The precise toolset a team may choose to use depends upon numerous factors including project, cost and customer constraints – to name a few. Therefore, I suggest that you focus more on the type of tool and determine which one meets their particular needs for their Continuous Delivery ecosystem. Just because I'm not mentioning a particular tool doesn't mean I'm not using it or that I don't think it's a good tool; these are meant to be illustrative. We tend to focus more on freely-available tools because people can download and use them quickly. There are good reasons to choose commercial tools. As implied before, you don't need to be using all of these tools to get significant benefit from Continuous Delivery. Start small and build it up. I've listed some of the tools in each category for the Java, .NET and Ruby platforms. Since, we lean heavily toward Cloud tools; you'll see that we opt for the SaaS-based tools, when applicable. Let me know if your

Continuous Delivery 5

preferred tool didn't make the list. Ok, there's my disclaimer. On with the list: Application Containers – JBoss, Tomcat, IIS, Mongrel. NOTE: there are so many app containers; I'm not going to try to list all of them.

Build Tools – Ant, AntContrib, NAnt, MSBuild, Buildr, Gant, Gradle, make, Maven, Rak e Code Review - Crucible Code Insight – Fisheye Continuous Integration – Bamboo, Jenkins, AntHill Pro, Go, TeamCity, TFS 2010 Cloud IaaS - AWS EC2, AWS S3 , Windows Azure Cloud PaaS – Google App Engine, AWS Elastic Beanstalk, Heroku Database – Hibernate, MySQL, Liquibase, Oracle, PostgreSQL, SQL Server, SimpleDB, SQL Azure, Ant, MongoDB Database Change Management – dbdeploy, Liquibase Configuration Automation – Capistrano, Cobbler, BMC Bladelogic, CFEngine, IBM Tivoli Provisioning Manager, Puppet, Chef, Bcfg2, AWS Cloud Formation, Windows Azure AppFabric NOTE: There are many names and overlap for this tool "category". Dependency Management – Ivy, Archiva, Nexus, Artifactory, Bundler Deployment Automation – Java Secure Channel, ControlTier, Altiris, Capistrano, Fabric, Func Information Sharing – Confluence, Google Apps Installer – InstallShield, IzPack Integrated Development Environment (IDE) – Eclipse, IDEA, Visual Studio

6 Continuous Delivery

Issue Tracking - Greenhopper, JIRA Multi-Type – rPath Passwords – PassPack, PasswordSafe Protected Configuration – ESCAPE, ConfigGen Project Management – JIRA, Pivotal Tracker, SmartSheet Provisioning - JEOS, BoxGrinder, CLIP, Eucalyptus, AppLogic Reporting/Documentation – Doxygen, Grand, GraphViz, JavaDoc, NDoc, SchemaSpy, UmlGraph Static Analysis - CheckStyle, Clover, Cobertura, FindBugs, FxCop, JavaNCSS, JDepend, P MD, Sonar, Simian Systems Monitoring – CloudKick, Nagios, Zabbix, Zenoss Testing – AntUnit, Cucumber, DbUnit, webrat, easyb, Fitnesse, JMeter, JUnit, NBeh ave, SoapUI, Selenium, RSpec,SauceLabs Version-Control System – SVN/Subversion, git, Perforce

Continuous Delivery 7

Version Controlling with Git

There are many options for version control, but the Rails community has largely standardized on Git, a distributed version control system originally developed by Linus Torvalds to host the Linux kernel. Git is a large subject, and we‘ll only be scratching the surface in this book, but there are many good free resources online; I especially recommend Pro Git by Scott Chacon (Apress, 2009). Putting your source code under version control with Git is strongly recommended, not only because it‘s nearly a universal practice in the Rails world, but also because it will allow you to share your code more easily and deploy your application right here in the first chapter.

Installing Git Let‘s get into using some Git. First things first—you have to install it. You can get it a number of ways; the two major ones are to install it from source or to install an existing package for your platform.

Installing from Source If you can, it‘s generally useful to install Git from source, because you‘ll get the most recent version. Each version of Git tends to include useful UI enhancements, so getting the latest version is often the best route if you feel comfortable compiling software from source. It is also the case that many Linux distributions contain very old packages; so unless you‘re on a very up-to-date distro or are using backports, installing from source may be the best bet.

To install Git, you need to have the following libraries that Git depends on: curl, zlib, openssl, expat, and libiconv. For example, if you‘re on a system 8 Continuous Delivery

that has (such as Fedora) or -get (such as a Debian based system), you can use one of these commands to install all of the dependencies:

$ yum install curl-devel expat-devel gettext-devel \

openssl-devel zlib-devel

$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \

libz-dev libssl-dev

When you have all the necessary dependencies, you can go ahead and grab the latest snapshot from the Git web site: http://git-scm.com/download

Then, compile and install:

$ tar -zxf git-1.7.2.2.tar.gz

$ cd git-1.7.2.2

$ make prefix=/usr/local all

$ sudo make prefix=/usr/local install

After this is done, you can also get Git via Git itself for updates:

$ git clone git://git.kernel.org/pub/scm/git/git.git

First-time system setup After installing Git, you should perform a set of one-time setup steps. These are system setups, meaning you only have to do them once per computer:

$ git config --global user.name "Your Name"

$ git config --global user.email [email protected]

Continuous Delivery 9

I also like to use co in place of the more verbose checkout command, which we can arrange as follows:

$ git config --global alias.co checkout

This tutorial will usually use the full checkout command, which works for systems that don‘t haveco configured, but in real life I nearly always use git co.

As a final setup step, you can optionally set the editor Git will use for commit messages. If you use a graphical editor such as Sublime Text, TextMate, gVim, or MacVim, you need to use a flag to make sure that the editor stays attached to the shell instead of detaching immediately:

$ git config --global core.editor "subl -w"

Replace "subl -w" with "mate -w" for TextMate, "gvim -f" for gVim, or "mvim -f" for MacVim.

First-time repository setup Now we come to some steps that are necessary each time you create a new repository. First navigate to the root directory of the first app and initialize a new repository:

$ git init

Initialized empty Git repository in /Users/mhartl/rails_projects/first_app/.git/

The next step is to add the project files to the repository. There‘s a minor complication, though: by default Git tracks the changes of all the files, but there are some files we don‘t want to track. For example, Rails creates log files to record the behavior of the application; these files change frequently, 10 Continuous Delivery

and we don‘t want our version control system to have to update them constantly. Git has a simple mechanism to ignore such files: simply include a file called .gitignore in the application root directory with some rules telling Git which files to ignore.

We see that the rails command creates a default .gitignore file in the application root directory.

# See http://help.github.com/ignore-files/ for more about ignoring files.

#

# If you find yourself ignoring temporary files generated by your text editor

# Or , you probably want to add a global ignore instead:

# git config --global core.excludesfile ~/.gitignore_global

# Ignore bundler config

/.bundle

# Ignore the default SQLite database.

/db/*.sqlite3

# Ignore all logfiles and tempfiles.

/log/*.log

/tmp

This causes Git to ignore files such as log files, Rails temporary (tmp) files, and SQLite databases. (For example, to ignore log files, which live in the log/ directory, we use log/*.log to ignore all files that end in .log.) Most Continuous Delivery 11

of these ignored files change frequently and automatically, so including them under version control is inconvenient; moreover, when collaborating with others they can cause frustrating and irrelevant conflicts.

The .gitignore file is probably sufficient for this tutorial. This augmented .gitignore arranges to ignore Rails documentation files, Vim and Emacs swap files, and (for OS X users) the weird.DS_Store directories created by the Mac Finder application. If you want to use this broader set of ignored files, open up .gitignore in your favorite text editor and fill it with the contents.

An augmented .gitignore file.

# Ignore bundler config

/.bundle

# Ignore the default SQLite database.

/db/*.sqlite3

# Ignore all logfiles and tempfiles.

/log/*.log

/tmp

# Ignore other unneeded files. doc/

*.swp

*~

.project

.DS_Store

12 Continuous Delivery

.idea

Adding and Committing Finally, we‘ll add the files in your new Rails project to Git and then commit the results. You can add all the files (apart from those that match the ignore patterns in .gitignore) as follows:

$ git add .

Here the dot ‗.‘ represents the current directory, and Git is smart enough to add the files recursively, so it automatically includes all the subdirectories. This command adds the project files to a staging area, which contains pending changes to your project; you can see which files are in the staging area using the status command.

$ git status

# On branch master

#

# Initial commit

#

# Changes to be committed:

# (use "git rm --cached ..." to unstage)

#

# new file: README.rdoc

# new file: Rakefile

(The results are long, so I‘ve used vertical dots to indicate omitted output.)

Continuous Delivery 13

To tell Git you want to keep the changes, use the commit command:

$ git commit -m "Initial commit"

[master (root-commit) df0a62f] Initial commit

42 files changed, 8461 insertions(+), 0 deletions(-) create mode 100644 README.rdoc create mode 100644 Rakefile

The -m flag lets you add a message for the commit; if you omit -m, Git will open the editor you set and have you enter the message there.

It is important to note that Git commits are local, recorded only on the machine on which the commits occur. This is in contrast to the popular open-source version control system called Subversion, in which a commit necessarily makes changes on a remote repository. Git divides a Subversion-style commit into its two logical pieces: a local recording of the changes (git commit) and a push of the changes up to a remote repository (git push). By the way, you can see a list of your commit messages using the log command:

$ git log commit df0a62f3f091e53ffa799309b3e32c27b0b38eb4

Initial commit To exit git log, you may have to type q to quit.

What good does Git do you? It‘s probably not entirely clear at this point why putting your source under version control does you any good, so let me give just one example. (We‘ll

14 Continuous Delivery

see many others in the chapters ahead.) Suppose you‘ve made some accidental changes, such as deleting the critical app/controllers/directory:

$ ls app/controllers/ application_controller.rb

$ rm -rf app/controllers/

$ ls app/controllers/ ls: app/controllers/: No such file or directory

Here we‘re using the Unix ls command to list the contents of the app/controllers/ directory and the rm command to remove it. The - rf flag means ―recursive force‖, which recursively removes all files, directories, subdirectories, and so on, without asking for explicit confirmation of each deletion.

Let‘s check the status to see what‘s up:

$ git status

# On branch master

# Changed but not updated:

# (use "git add/rm ..." to update what will be committed)

# (use "git checkout -- ..." to discard changes in working directory)

#

# deleted: app/controllers/application_controller.rb

# no changes added to commit (use "git add" and/or "git commit -a")

Continuous Delivery 15

We see here that a file has been deleted, but the changes are only on the ―working tree‖; they haven‘t been committed yet. This means we can still undo the changes easily by having Git check out the previous commit with the checkout command (and a -f flag to force overwriting the current changes):

$ git checkout -f

$ git status

# On branch master nothing to commit (working directory clean)

$ ls app/controllers/ application_controller.rb

The missing directory and file are back. That‘s a relief!

GitHub Now that you‘ve put your project under version control with Git, it‘s time to push your code up to GitHub, a social code site optimized for hosting and sharing Git repositories. Putting a copy of your Git repository at GitHub serves two purposes: it‘s a full backup of your code (including the full history of commits), and it makes any future collaboration much easier. This step is optional, but being a GitHub member will open the door to participating in a wide variety of open-source projects.

16 Continuous Delivery

Figure 3 : Creating the first app repository at GitHub GitHub has a variety of paid plans, but for open-source code their services are free, so sign up for a free GitHub account if you don‘t have one already. (You might have to follow the GitHub tutorial on creating SSH keys first.) After signing up, click on the link to create a repository and fill in the information. (Take care not to initialize the repository with a README file, as rails new create one of those automatically.) After submitting the form, push up your first application as follows:

$ git remote add origin git@.com:/first_app.git

$ git push -u origin master

These commands tell Git that you want to add GitHub as the origin for your main (master) branch and then push your repository up to GitHub. (Don‘t worry about what the -u flag does; if you‘re curious, do a web search for ―git set upstream‖.) Of course, you should

Continuous Delivery 17

replace with your actual username. For example, the command I ran for the rails tutorial user was

$ git remote add origin [email protected]:railstutorial/first_app.git

The result is a page at GitHub for the first application repository, with file browsing, full commits history, and lots of other goodies.

Figure 4 : A GitHub repository page GitHub also has native applications to augment the command-line interface, so if you‘re more comfortable with GUI apps you might want to check out GitHub for Windows or GitHub for Mac. (GitHub for Linux is still just Git, it seems.)

Branch, edit, commit, merge In our case, since the project is a Rails application generated using the rails command, the README file is the one that comes with Rails. Because of the .rdoc extension on the file, GitHub ensures that it is formatted nicely, but the contents aren‘t helpful at all, so in this section we‘ll make our first edit by changing the README to describe our project 18 Continuous Delivery

rather than the Rails framework itself. In the process, we‘ll see a first example of the branch, edit, commit, merge workflow that I recommend using with Git.

Figure 5 : The initial (rather useless) README file for our project at GitHub Branch Git is incredibly good at making branches, which are effectively copies of a repository where we can make (possibly experimental) changes without modifying the parent files. In most cases, the parent repository is the master branch, and we can create a new topic branch by using checkout with the-b flag:

$ git checkout -b modify-README

Switched to a new branch 'modify-README'

$ git branch master

Continuous Delivery 19

* modify-README

Here the second command, git branch, just lists all the local branches, and the asterisk *identifies which branch we‘re currently on. Note that git checkout -b modify-README both creates a new branch and switches to it, as indicated by the asterisk in front of the modify-README branch. (If you set up the co alias, you can use git co -b modify-README instead.)

The full value of branching only becomes clear when working on a project with multiple developers, but branches are helpful even for a single- developer tutorial such as this one. In particular, the master branch is insulated from any changes we make to the topic branch, so even if we really screw things up we can always abandon the changes by checking out the master branch and deleting the topic branch. We‘ll see how to do this at the end of the section.

By the way, for a change as small as this one I wouldn‘t normally bother with a new branch, but it‘s never too early to start practicing good habits.

Edit After creating the topic branch, we‘ll edit it to make it a little more descriptive. I prefer the Markdown markup language to the default RDoc for this purpose, and if you use the file extension.md then GitHub will automatically format it nicely for you. So, first we‘ll use Git‘s version of the Unix mv (―move‖) command to change the name, and then fill it in with the contents:

$ git mv README.rdoc README.md

$ subl README.md

20 Continuous Delivery

Commit With the changes made, we can take a look at the status of our branch:

$ git status

# On branch modify-README

# Changes to be committed:

# (use "git reset HEAD ..." to unstage)

#

# renamed: README.rdoc -> README.md

#

# Changed but not updated:

# (use "git add ..." to update what will be committed)

# (use "git checkout -- ..." to discard changes in working directory)

#

# modified: README.md

#

At this point, we could use git add . but Git provides the -a flag as a shortcut for the (very common) case of committing all modifications to existing files (or files created using git mv, which don‘t count as new files to Git):

$ git commit -a -m "Improve the README file"

2 files changed, 5 insertions(+), 243 deletions(-) delete mode 100644 README.rdoc create mode 100644 README.md Continuous Delivery 21

Be careful about using the -a flag improperly; if you have added any new files to the project since the last commit, you still have to tell Git about them using git add first.

Note that we write the commit message in the present tense. Git models commits as a series of patches, and in this context it makes sense to describe what each commit does, rather than what it did. Moreover, this usage matches up with the commit messages generated by Git commands themselves. See the GitHub post Shiny new commit styles for more information.

Merge Now that we‘ve finished making our changes, we‘re ready to merge the results back into our master branch:

$ git checkout master

Switched to branch 'master'

$ git merge modify-README

Updating 34f06b7..2c92bef

Fast forward

README.rdoc | 243 ------

README.md | 5 +

2 files changed, 5 insertions(+), 243 deletions(-) delete mode 100644 README.rdoc create mode 100644 README.md

22 Continuous Delivery

Note that the Git output frequently includes things like 34f06b7, which are related to Git‘s internal representation of repositories. Your exact results will differ in these details, but otherwise should essentially match the output shown above.

After you‘ve merged in the changes, you can tidy up your branches by deleting the topic branch using git branch -d if you‘re done with it:

$ git branch -d modify-README

Deleted branch modify-README (was 2c92bef).

This step is optional, and in fact it‘s quite common to leave the topic branch intact. This way you can switch back and forth between the topic and master branches, merging in changes every time you reach a natural stopping point.

As mentioned above, it‘s also possible to abandon your topic branch changes, in this case with git branch -D:

# For illustration only; don't do this unless you mess up a branch

$ git checkout -b topic-branch

$

$ git add .

$ git commit -a -m "Major screw up"

$ git checkout master

$ git branch -D topic-branch

Continuous Delivery 23

Unlike the -d flag, the -D flag will delete the branch even though we haven‘t merged in the changes.

Push Now that we‘ve updated the README, we can push the changes up to GitHub to see the result. Since we have already done one push, on most systems we can omit origin master, and simply run git push:

$ git push

As promised, GitHub nicely formats the new file using Markdown.

Figure 6 : Formated file by Github Git with Eclipse (EGit)

Create a new Java project HelloWorld in eclipse.

Figure 7 : Java project creation

Select the project, click File > Team > Share Project

24 Continuous Delivery

Select repository type Git and click Next

Figure 8 : Repository plug-in selection

To configure the Git repository select the new project HelloWorld

Figure 9 : Configuring Git repository

Click Create Repository to initialize a new Git repository for the HelloWorld project. If your project already resides in the

Continuous Delivery 25

working tree of an exisiting Git repository the repository is chosen automatically.

Figure 10 : Configuring Project

Click Finish to close the wizard.

The decorator text "[master]" behind the project shows that this project is tracked in a repository on the master branch and the question mark decorators show that the .classpath and .project and the .settings files are not yet under version control.

Figure 11 : Files before version control

26 Continuous Delivery

Click Team > Add on the project node. (This menu item may read Add to Index on recent versions of Egit)

The + decorators show that now the project's files have been added to version control

Mark the "bin" folder as "ignored by Git", either by right-clicking on it and selecting Team > Ignore or by creating a file .gitignore in the project folder with the following content

/bin

This excludes the bin folder from Git's list of tracked files.

Add .gitignore to version control (Team > Add):

Figure 12 : Files after Version Control You may have to set your Package Explorer filters in order to see .gitignore displayed in the Package Explorer. To access filters, select the down arrow at right of Package Explorer tab to display View Menu.

Continuous Delivery 27

Figure 13 : Accessing Filters Select Filters... from the View Menu and you will be presented with the Java Element Filters dialog. Unselect the top entry to display files that begin with . (period) such as .gitignore.

Figure 14 : Filters Menu

Click Team > Commit in the project context menu Enter a commit message explaining your change; the first line (followed by an empty line) will become the short log for this commit. By default the author and committer are taken from

the .gitconfig file in your home directory.

You may click Add Signed-off-by to add a Signed-off-by: tag.

28 Continuous Delivery

If you are committing the change of another author you may alter the author field to give the name and email address of the author.

Click Commit to commit your first change.

Figure 15 : Commit stage Note that the decorators of the committed files changed.

Figure 16 : Commited files When creating new projects and repositories, you will be given the option to make them private:

Continuous Delivery 29

Figure 17 : Gitorious Repository On the next screen you can see the URLs you may use to access your fresh new repository:

Figure 18 : Configuring SSH

Click SSH to choose the SSH protocol. It can be used for read and write access Click HTTP to choose the HTTP protocol. It can also be used for read and write access. Click Git Read-Only to choose the anonymous git protocol for cloning. It's the most efficient protocol git supports. Since the git

30 Continuous Delivery

protocol doesn't support authentication it's usually used to provide efficient read-only access to public repositories.

Eclipse SSH Configuration

Open the Eclipse Preferences and ensure that your SSH2 home is configured correctly (usually this is ~/.ssh) and contains your SSH2 keys

Figure 19 : Key management and SSH If you don't have SSH keys yet you may generate them on the second tab Key Management of this dialog, use a good pass phrase to protect your private key,

Upload your public SSH key to your GitHub account settings.

Push Upstream Click Team > Remote > Push... and copy and paste the SSH URL of your new github repository

Continuous Delivery 31

If you are behind a firewall which doesn't allow SSH traffic use the github HTTPS URL instead and provide your github user and password instead of using the uploaded public SSH key. To store your credentials into the Eclipse secure store click Store in Secure Store.

Note: many HTTP proxies are configured to block HTTP URLs containing a user name, since disclosing a user name in an HTTP URL is considered a security risk. In that case remove the username from the HTTP URL and only provide it in the user field. It will be sent as an HTTP header.

Figure 20 : Pushing upstrem

Click Next and on first connection accept GitHub's host key. Enter your SSH key's passphrase and click OK.

32 Continuous Delivery

On the next wizard page click Add all branches spec to map your local branch names 1:1 to the same branch names in the destination repository.

Figure 21 : Refs selection to push

Click Next. The push confirmation dialog will show a preview of the changes that will be pushed to the destination repository.

Continuous Delivery 33

Figure 22 : Preview page for upstream pushing

Click Finish to confirm that you want to push these changes. The next dialog reports the result of the push operation.

Figure 23 : Result page

34 Continuous Delivery

Point your browser at your GitHub repository to see that your new repository content has arrived.

Installing Jenkins

Installing Jenkins is a breeze, as debian packages have been set up,

$ wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -

$ sudo vi /etc/apt/sources.list.d/jenkins.list

Add "deb http://pkg.jenkins-ci.org/debian binary/"

$ sudo apt-get update

$ sudo apt-get install jenkins

This automatically creates an account called jenkins. We will need to login as this user later so set a password for jenkins with: sudo passwd jenkins

You should now be able to view the Jenkins dashboard at http://your.server:8080/

Now that Jenkins is installed, we want to get a headless display configured for our browser based tests. First up hit Manage Jenkins > Manage Plugins > Available and install the Hudson Xvnc plugin (this works with Jenkins despite its name). Schedule Jenkins to restart to pick up the plug-in. With Jenkins configured we need to ensure the required software is installed on the server:

$ sudo apt-get install vnc4server

Continuous Delivery 35

vncserver requires a password to be set before it can be used, this needs to be set before Jenkins can make use of the vncserver. For this we need to switch to the jenkins user and set a password.

$ sudo -Hiu jenkins

$ vncserver

Enter a password, and verify it

$ vncserver -kill :1 # or whichever display the vncserver output mentioned.

When Jenkins runs it doesn‘t need to know this password, but if you want to watch a running job you can connect to the running vnc session with that password and watch the tests in real time.

Installing Ruby with RVM

The job I want to run is a set of acceptance tests written in Cucumber with automation done using Capybara (Selenium-Webdriver under the hood). So it‘s a Ruby job, and all good Ruby jobs use RVM.

$ sudo apt-get install curl bison build-essential zlib1g-dev libssl-dev libreadline5-dev libxml2-dev git-core

$ sudo -Hiu jenkins

$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

Or

\curl -L https://get.rvm.io | bash -s stable --ruby

36 Continuous Delivery

Once RVM is configured, run rvm notes to find the full list of dependencies you need to install for your required version of Ruby.

$ source ~/.rvm/scripts/rvm

$ rvm notes

$ sudo apt-get install build-essential bison openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6- dev ncurses-dev

Note that I didn‘t give the jenkins user sudo rights, so I installed all packages through my usual admin account on the server.

RVM can be configured to allow the automatic installation of Ruby versions and gemsets by adding the following to ~/.rvmrc for the jenkins user: rvm_install_on_use_flag=1 rvm_project_rvmrc=1 rvm_gemset_create_on_use_flag=1

Installing Firefox sudo apt-get install firefox

This is the default browser that selenium will select.

At this point the Jenkins server should be fully configured to run headless jobs, so let‘s dive in and create one. Create a new freestyle job. Notice there is a new option available under the ‗Build Environment‘ section call ‗Run Xvnc during build‘, check this to have the plugin automatically do its magic.

Continuous Delivery 37

For my example, I didn‘t bother with checking projects out source control, I simply created a project in the /tmp directory. You‘ll want to enable the appropriate SCM plugin and configure a checkout. Under the build section add an Execute shell step with the following:

#!/bin/bash -e cd /tmp/selenium-test source "$HOME/.rvm/scripts/rvm"

[[ -s ".rvmrc" ]] && source .rvmrc bundle install cucumber

The -e flag in #!/bin/bash -e ensures the script stops after any errors. You will notice that the script sources the .rvmrc file directly for the project, this ensures the correct version of Ruby is used with a gemset appropriate for your project. My .rvmrc looked something like: rvm --create use ruby-1.9.2@selenium-test

Calling bundle install automatically installs bundler, reads the Gemfile.lock and installs all required gems. Finally cucumber kicks off the actual cucumber scenarios, and fingers crossed, they should pass with flying colours.

As the headless display is running in vncserver, you can connect to the vnc session and watch the tests run in real time. Just use your regular VNC client and connect to your.server:59xx where xx is the display number output on the Jenkins console for the running job. You will need to enter the password you set the first time you ran vncserver.

38 Continuous Delivery

If you are getting error regarding VNC SERVER,

login as the hudson user run the command "vncserver" once (for example "vncserver") answer the password prompt (to create a VNC desktop password), then kill that VNC session (for example "vncserver -kill :1")

ON jenkins Console Output:

Terminating xvnc.

$ vncserver -kill :33

Killing Xvnc4 process ID 6873

Finished: SUCCESS Creating a job in Jenkins

First of all when we click on the following link http://localhost:8080/

You will be asked for username and password credentials. So please enter your credentials in those appropriate text-boxes.

Now, you should see a screen like the one shown in Figure, ―The Jenkins start page‖.

You are now ready to take your first steps with Jenkins!

Continuous Delivery 39

Figure 24 : Jenkins job creation page Configuring the Tools

Before we get started, we do need to do a little configuration. More precisely, we need to tell Jenkins about the build tools and JDK versions we will be using for our builds.

Click on the Manage Jenkins link on the home page (see Figure, ―The Jenkins start page‖). This will take you to the Manage Jenkins page, the central one-stop-shop for your entire Jenkins configuration. From this screen, you can configure your Jenkins server, install and upgrade plug-ins, keep track of system load, manage distributed build servers, and more! For now, however, we‘ll keep it simple. Just click on the Configuring System link at the top of the list (see Figure, ―The Manage Jenkins screen‖).

40 Continuous Delivery

Figure 25 : The Manage Jenkins screen This will take you to Jenkins‘s main configuration screen (see Figure , ―The Configure Jenkins screen‖).

From here you can configure everything from security configuration and build tools to email servers, version control systems and integration with third-party software.

The screen contains a lot of information, but most of the fields contain sensible default values, so you can safely ignore them for now.

Continuous Delivery 41

Figure 26 : Configure Jenkins screen For now, you will just need to configure the tools required to build our sample project. The application we will be building is a Java application, built using Maven.

Figure 27 : Setting up your first build job in Jenkins Once you click on OK, Jenkins will display the project configuration screen.

42 Continuous Delivery

In general manner use free style project while creating new job.

For Windows here is what we need:

Tomcat or another web container Ensure the default ports are changed, for my examples I used 8082 for tomcat You have a Java project checked into github.com A github account (see github.com) Remember to setup the SSH keys Jenkins (see http://jenkins-ci.org/) Download the lastest war file github client software http://help.github.com/ for linux

Start Jenkins java -jar jenkins.war Visit http://localhost:8080/ to access Jenkins Install Jenkins as a service Instructions is here: https://wiki.jenkins- ci.org/display/JENKINS/Installing+Jenkins+as+a+linux+service

Jenkins Service installed: Jenkins running on http://localhost:8080/

Continuous Delivery 43

Add github support to Jenkins Manage Jenkins Under the github section provide the path to git.exe

Git Plugin section: Global Config user.name Value {Your git username} Global Config user.email Value {email address}

SSH keys Generate ssh keys which guided by github. Add them to github.com

Setup email notifications, using gmail

In the E-mail Notification section, add the following SMTP Server:smtp.gmail.com Sender e-mail address:{username}@gmail.com Click Use SMTP Authentication Username:{username}@gmail.com Password:{gmail pass} Click Use SSL SMTP Port 465 Confirm by using the Test configuration by sending test e-mail option Adding plugins to Jenkins Manage Jenkins\Manage Plugins\Available and Add the following plugins:

44 Continuous Delivery

"Deploy to container Plugin" "Jenkins GIT plugin" "GitHub plugin"

Create a Dynamic Java Project and

Creating a New Job

Click New Job Provide a job name Use a Build a free-style software project configuring the Job Options

Under the Source code Management section pulling code from gitbub

Click the git button Enter you repository url, something like: [email protected]:uchit/demo.git

Github project name like: https://github.com/uchit/demo/ which is given to gitgub readonly board

Calling Ant In the build section, click the Add Build Step button, select Invoke Ant Provide the Targets to run in a commas separated list or just remain blank in this target.

Continuous Delivery 45

Post-build actions

select Deploy war/ear to a container Give parameters like in 1st: **/*.war or full path In second give tomcat 7x or whatever we use. Deploying to Tomcat, automatically In the Post-build actions section Check Deploy war/ear to container WAR/EAR files:**/*.war Container: Tomcat 7.x Manager user name: tomcat Manager password: {password} Tomcat url: http:localhost:8081 Sending email notification on failure Check Email-notifications Enter your email address Check Send e-mail for every unstable build Building your project

From the Jenkins dashboard, click on the project name Click Build Now on the left hand side Select the Build from the Build history section Select Console output to view the build information

Things to watch out:

Ant paths, since they will be running under the jobs directory try not to hard code any absolute paths 46 Continuous Delivery

SSH keys with github Ports ensure Web Container and Jenkins isn‘t using the same port.

Here Are Sample screenshots for references:

Figure 28 : Repository configuration

Figure 29 : Build Configuration

Continuous Delivery 47

Figure 30 : Post Build Configuration

Figure 31 : Container Configuration

48 Continuous Delivery

Figure 32 : Git URL for configuration in Jenkins In this repository I have put whole Liferay plug-in folder. If you get redeployment error in tomcat, just restart your tomcat.

Continuous Delivery 49