test.ical.ly | getting the web by the balls

Jan/11

7

A continuous deployment process for symfony plugins

For a while I’ve been toying with the idea to set up a fully automated continuous deployment process for my symfony plugins. You can think of continuous deployment as a continuous integration process with automated deployment.

I just didn’t come round to do it as I couldn’t find the time so far. But then I read this article by Toni Schneider about CD at wordpress.com and it got me hooked again.

So I thought lets write down what it takes for a start.

The plugins I would like to build this process for are all Open Source so it only partly applies to proprietory ones but I’m sure you can handle that. ;)

I do all my development using Git and all sources are kept and maintained at GitHub. The develoment itself is done on various computers depending on where I am at the moment.

However the plugin releases live as tags in the official symfony Subversion repository and as packages on the official symfony PEAR server.

Here’s my continuous integration setup so far.

  1. I commit my changes to my local repository
  2. I push my changes to the GitHub repository
  3. the continuous integration server (Hudson) regularily pulls GitHub to see if there is any change
  4. noticing the change the CI server will run automated tests included in the plugin
  5. it will also run a few reports about software metrics and sniffs
  6. and it will compile the API documentation and code coverage reports
  7. when all went well it shows a green light for pass
  8. if it failed at some point it will signal a red light and send me a mail

Extending this with an automated deployment I would expect a new release pushed to the symfony Subversion server as well as the PEAR server.

But unlike Toni at wordpress I don’t fancy rapid releases as the users of plugins are developers who work with it and they don’t want to contantly upgrade of course. So I don’t want to automatically trigger a release for ever small change I make. Instead I still want to be in charge.

So I am thinking about setting a tag on my GitHub repository for each release (I already do that thanks to Benjamin) and use that as a trigger.

And when I already use that trigger to distinguish a release from any other change then I can use it to defer the execution of expensive tasks like the generation of coverage reports and API documentation only for releases, right?

  1. I commit my changes to my local repository
  2. I push my changes to the GitHub repository
  3. the continuous integration server (Hudson) regularily pulls GitHub to see if there is any change
  4. noticing the change the CI server will run automated tests included in the plugin
  5. it will also run a few reports about software metrics and sniffs
  6. when all went well it shows a green light for pass
  7. if it failed at some point it will signal a red light and send me a mail
  8. if no new tag is present we stop here other wise we continue
  9. and compile the API documentation and code coverage reports
  10. then commit the tagged version from GitHub to the symfony Subversion server
  11. update the package.xml from the previous commit messages
  12. then create a PEAR package and commit that to the symfony PEAR server
  13. tweet about the new release

Unfortunately the plugin API of the symfiony website does not provide an interface for uploading a new release but I am sure the existing web interface can be scripted.

Ok, so that’s my todo list for setting up a continuous deployment process unless you know something to add?

· · · · · · · ·



  • http://www.robo47.net robo47

    I wouldn’t automate all that stuff in a single task/job for more flexability, supporting multiple users in future AND forseeing possible own mistakes, keeping CI and CD seperate AND basing the CD on tags which can be applied to commits “afterwards” AND include an automated lookup for tagged commits, not packaged yet.

    Why ?

    Using git or another DVCS often means:
    1) you are probably not the only person working on something
    2) YOUR last commit may NEVER be run through the CI-System, unlike on Subversion where hudson often runs via a commit-Hook for EACH COMMIT, with hudson/git it is mostly using a “check if there are new commits and run a build for the last one” [mainly based on the problem, that on a "main"-DVCS-repository there are no commits which come in, there are pushs containing one or MORE commits.

    Hudson per default checks the git-repository, but it does NOT run for EACH commit [not supported on hudson when I last check], so for example your tagged commit will never be tested/build, because either YOU pushed more than one commit (not the last one was tagged one, it was one with new ideas/changes, … ) or somebody else pushed after you, but before hudson checks again to run, so the tagged commit won’t be build/tested EVER!

    (Some of this won’t apply for every project, but keeping it in mind won’t hurt. :) )

    I would set it up like this:

    You have your standard-CI-Job which runs if it finds new commits, strictly for the Continous Integration-purpose.

    Then you have either a second CI-Job which can be run for a specific commit/hash, [ Could be possible with something like: http://wiki.hudson-ci.org/display/HUDSON/Parameterized+Trigger+Plugin ?!?! ] or your first CI-Job is flexible enought to do that [parameterized builds, ... ].

    Then you have another Job, let’s call it the CD-Job.

    The CD-Job does the following:

    1) Check if there are any tagged commits in the repository which have NOT been “delivered/packaged” yet [or since you already have some releases, only use tagged commits not delivered/packaged yet AND only commits which are tagged after a specific date
    2) For each of them run [in date/time-sorted order] the (second) CI-Job [if not run yet [could be checked via http://wiki.hudson-ci.org/display/HUDSON/Remote+access+API ]] to test those commits builds actually work and aren’t broken.
    3) If the build works for the tagged commit, package/deliver it [order should be important]

    This gives you some benefits:
    – The additional possibility to not only create a package for the last commit
    – TAG a commit later/AFTER a successful build, because for example you wan’t to be able to “manually” check some metrics, output of other qa-tools and other stuff BEFORE a deployment/packaging

  • http://test.ical.ly Christian

    @robo47 wow that’s highly inspirational! thanks for sharing that, I will consider it when setting up the process

  • Pingback: Tweets that mention • A continuous deployment process for symfony plugins | test.ical.ly -- Topsy.com

<<

>>

Theme Design by devolux.nh2.me