Question

I have been reading for a while and got a few answers, but I just need some more help.

I am trying to automatically deploy a website when a certain change set is committed to a branch, so I release my different versions from different branches. For example, there is a live branch that whenever is updated, the new change sets are merged into the the current live website.

My repository (on a Subversion version control system) is on the same server as the live server, so all I need to do is to transfer the files to a different directory.

I know I need to edit repo/hooks/post-commit file, and I have got this working, however I am not sure on the contents of this file to do what I need to do.

Was it helpful?

Solution

Do not use hooks for deployment purposes. Use build tool (Ant, Maven, whatever) and continuous integration tool (CruiseControl, CruiseControl.rb, Hudson, etc). Using hooks is just wrong because of the several reasons:

  1. Scaling. Hooks do not scale. It is difficult to make hook script do what they are not supposed to as, for example, deployment, which always requires some tricks to perform successfully.
  2. Flexibility. Hooks are not flexible enough. You need to rewrite them every time there are changes in your processes. And your corrections might break something you managed to do with hooks previously.
  3. Security. Are you going to store login/password for ftp/ssh deployment directly in your hook? That will be a huge mistake. You might find workaround, but it will be no good either as long as hooks are not the place for security management.
  4. Complexity. Deployment usually requires a lot of specific actions to do even when at first it seems that it does not. If you start to do deployment in your hook scripts, they will turn out to be swollen and unmanageable.
  5. Source control. You cannot put hooks under source control. If you will try to put it under source control, you will definitely regret it later as long as it is difficult to store hooks together with your project sources, in one place.

All you need to is to:

  1. Write build script where you describe your deployment steps
  2. Install continuous integration tool
  3. Make continuous integration tool use your build script and repository
  4. Configure continuous integration tool to perform build on commit
  5. Perform commit to the repository and see how your changes will be automatically built & deployed according to the build script you've written.

Personally I use Ant and CruiseControl.rb for the purpose you've described. Here is the example of build script to deploy my changes over ftp protocol:

<?xml version="1.0"?>
<project name="myproject" default="deploy-local">
    <property file="build.properties"/>
    <target name="deploy-local">
        <echo message="Deploying version ${version}" />
        <delete dir="${deploy.path.local}" />
        <copy todir="${deploy.path.local}">
            <fileset dir="." includes="**/*" >
                <exclude name=".svn/**" />
                <exclude name="build.*" />
            </fileset>
        </copy>
    </target>
    <target name="deploy-remote">
        <echo message="Deploying project" />
        <ftp action="del"
             server="${deploy.remote.server}" 
             userid="${deploy.remote.login}"
             password="${deploy.remote.pass}">
            <fileset>
              <include name="${deploy.path.remote}"/>
            </fileset>
        </ftp>
        <ftp action="mkdir"
             server="${deploy.remote.server}" 
             userid="${deploy.remote.login}"
             password="${deploy.remote.pass}"
             remotedir="${deploy.path.remote}">
        </ftp>
        <ftp server="${deploy.remote.server}" 
             userid="${deploy.remote.login}"
             password="${deploy.remote.pass}"
             remotedir="${deploy.path.remote}"
             passive="yes">
             <fileset dir="." includes="**/*" >
                <exclude name=".svn/**" />
                <exclude name="build.*" />
            </fileset>
        </ftp>
    </target>
</project>

build.properties file has following content:

deploy.path.local = C:\\apache\\htdocs\\myproject
deploy.path.remote = /http/deploy
deploy.remote.server = ftp.myproject.com
deploy.remote.login = mylogin
deploy.remote.pass = mypass

I would recommend spending some time to learn basics of build management (Ant) and continuous integration (CruiseControl) to perform deployment in a most appropriate fashion. Even though it might seem to be not what you requested and little bit more complex, it is a right thing to do.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top