<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Michael J</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/michael_j/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/michael_j/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/michael_j//472</id>
    <updated>2011-04-21T09:56:43Z</updated>
    <subtitle>A blog about the Perl programming language</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.38</generator>

<entry>
    <title>Deploying Perl code with git, local::lib, Minicpan and cpanminus</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/michael_j/2011/04/deploying-perl-code-with-git-locallib-minicpan-and-cpanminus.html" />
    <id>tag:blogs.perl.org,2011:/users/michael_j//472.1678</id>

    <published>2011-04-21T08:45:48Z</published>
    <updated>2011-04-21T09:56:43Z</updated>

    <summary>At $work we&apos;re nearing the end of a long upgrade process, that&apos;s included moving from Debian etch to lenny, from svk to git, from Perl 5.8 to 5.10, from Apache 1.3 to Apache 2 (and then to Plack), and moving...</summary>
    <author>
        <name>Michael J</name>
        
    </author>
    
    <category term="perlgitlocallibminicpancpandeployment" label="perl git locallib minicpan cpan deployment" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/michael_j/">
        <![CDATA[<p>At $work we're nearing the end of a long upgrade process, that's included moving from Debian etch to lenny, from svk to git, from Perl 5.8 to 5.10, from Apache 1.3 to Apache 2 (and then to <a href="http://search.cpan.org/perldoc?Plack">Plack</a>), and moving to recent versions of DBIC and Catalyst (which had previously been pegged at a pre-<a href="http://search.cpan.org/perldoc?Moose">Moose</a> state).</p>

<p>For code deployment we had been packaging all <a href="http://www.perl.org/">Perl</a> modules as Debian packages and keeping our own CPAN repository, but wanted a more 'Perl-ish' solution avoiding the various pitfalls with OS packaging and Perl. </p>

<p><strong><big>THE STRUCTURE</big></strong></p>

<p>The system that we implemented consists of the following parts:</p>

<ul>
<li>a main git repository for code development - with a 'stage' branch for code ready to be pushed out to a stage server (and then to live)</li>
<li>a git repository for <a href="http://search.cpan.org/perldoc?minicpan">Minicpan</a> - with two branches, dev and master</li>
<li>a git repository for a development <a href="http://search.cpan.org/perldoc?local::lib">local::lib</a></li>
<li>a git repository for a master ('live') local::lib</li>
<li>a build server - with the main and Minicpan repositories checked out, and both dev and master branches of the local::lib repository checked out into separate directories.
</li>
</ul>

<p><em>(Click to enlarge)</em><br />
<a href="http://blogs.perl.org/users/michael_j/assets_c/2011/04/deployment_diagram-489.html" onclick="window.open('http://blogs.perl.org/users/michael_j/assets_c/2011/04/deployment_diagram-489.html','popup','width=814,height=567,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blogs.perl.org/users/michael_j/assets_c/2011/04/deployment_diagram-thumb-300x208-489.png" width="300" height="208" alt="deployment_diagram.png" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></p>

<p><big><strong>THE PROCESS</strong></big><br />
  <br />
The new build process works as follows:</p>

<ul>
<li>code is developed in a git branch, and merged into the final 'stage' branch when ready</li>
<li>a 'bump' script is run to ready a distribution for deployment. This does the following:
  <ol>
    <li>on the user's local machine:
      <ul>
        <li>checks that everything is checked in and commited in git</li>
        <li>runs the tests (via prove)</li>
        <li>updates the package version number and commits and pushes the change to origin</li>
      </ul>
    </li>
    <li>on the build server
      <ul>
        <li>updates the git repository on the build server</li>
        <li>runs the tests and makefile on the build server</li>
        <li>'injects' the distribution into a new branch in the minicpan repository - branch is named with package, version and date</li>
        <li>merges this branch into the dev branch</li>
        <li>uses <a href="http://search.cpan.org/perldoc?App::cpanminus">cpanminus</a> to install the distribution into the development local::lib repository</li>
      </ul>
    </li>
  </ol>
</li>
</ul>

<p>Once packages are installed into the local::lib they can be deployed onto any development server via rsync.</p>

<p>The process of deployment to a live server (our 'push live' script) works as follows:</p>

<ul>
<li>on the build server, retrieves the list of branches in the minicpan repository. Each branch is a new version of a package</li>
<li>uses this list (with package, version, date) to prompt the user to select which distributions are to be pushed to live. The prompt also contains a link to <a href="http://search.cpan.org/dist/Gitalist/">Gitalist</a> to show the relevant code changes in the update.</li>
<li>merges any chosen branches into the master branch of the minicpan repository</li>
<li>deletes chosen package branches (so they no longer appear in the selection list)</li>
<li>uses cpanminus to install the distribution into the master local::lib repository</li>
</ul>

<p>Then once packages are installed into the master local::lib they can be deployed onto any live server via rsync (We rsync the whole of the relevant lib, man and bin directories). We can deploy updates to individual machines, or server groups, but aim to update every server at least weekly. </p>

<p>The 'rollout' script can also run apt-get, restart webservers, run Puppet, etc, as required.</p>

<p><br />
<big><strong>CPAN MODULES</strong></big></p>

<p>The system allows modules from CPAN to be deployed by using a script to inject a distribution file (tar.gz) into a new branch in the Minicpan git repository. The branch is titled with the name, date and version, and can be selected during the 'push live' stage to be deployed to the live servers.</p>

<p>An update script uses the minicpan update_mirror() feature to download the latest distribution files, so that they can be injected if an update is required.</p>

<p><strong><big>GIT</big></strong></p>

<p>We looked at Git modules on CPAN, but ended up just writing our own library, calling the commands with IPC::Run3. Other than git's inconsitent usage of STDOUT and STDERR this has been a simple process.</p>

<p><strong><big>NOTES</big></strong></p>

<p>We use cpanminus with the 'mirror' and 'mirror-only' options, to specify that all dependencies should be pulled in from our local minicpan repository. Using cpanminus means that dependencies are automatically pulled in easily - the occasional module that causes problems for cpanminus (for example, one with a non-standard version numbering system) can be injected manually by finding the distribution file.</p>

<p>Note that our situation is simpler than other organisations:</p>

<ul>
	<li>small development team</li>
<li>all code runs on our own hardware (no third-party deployment)</li>
<li>all hardware runs the same OS (and same version)</li>
<li>only one version of a package needs to be live at any time (while different servers can be running different versions, this is never required for long periods, only during a bugfix for example).</li>
<li>all development machines can have the same version of a package installed (which can be overridden locally)</li>
</ul>]]>
        
    </content>
</entry>

<entry>
    <title>Syntax highlighting comment keywords in TextMate (TODO, FIXME, etc)</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/michael_j/2010/08/syntax-highlighting-comment-keywords-in-textmate-todo-fixme-etc.html" />
    <id>tag:blogs.perl.org,2010:/users/michael_j//472.884</id>

    <published>2010-08-11T17:05:04Z</published>
    <updated>2010-08-11T17:17:38Z</updated>

    <summary>mst&apos;s State of the Velociraptor talk at YAPC::EU inspired me to start a blog here, although this first post has nothing to do with Perl... After reading Chisel&apos;s post on highlighting useful words like TODO in Vim, I decided to...</summary>
    <author>
        <name>Michael J</name>
        
    </author>
    
    <category term="syntaxhighlightingtextmateeditorcomments" label="syntaxhighlighting textmate editor comments" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/michael_j/">
        <![CDATA[<p>mst's State of the Velociraptor talk at YAPC::EU inspired me to start a blog here, although this first post has nothing to do with Perl...</p>

<p>After reading Chisel's post on <a href="http://blogs.perl.org/users/chisel/2010/08/hack-hack-bodge.html">highlighting useful words like TODO in Vim</a>, I decided to see if TextMate could do the same. After a bit of trial-and-error and a brief glance at the documentation, the following worked for me:</p>

<ol>
<li><em>Bundles / Bundle Editor / Edit Languages</em> (and choose Perl if not already selected)</li>
<li>Find this section in the language grammar definition:
<pre><code class="prettyprint">
	repository = {
               ...
		line_comment = {
			patterns = (
				{	name = 'meta.comment.full-line.perl';
					match = '^((#).*$\n?)';
					captures = {
						1 = { name = 'comment.line.number-sign.perl'; };
						2 = { name = 'punctuation.definition.comment.perl'; };
					};
				},
				{	name = 'comment.line.number-sign.perl';
					match = '(#).*$\n?';
					captures = { 1 = { name = 'punctuation.definition.comment.perl'; }; };
				},
			);
		};
</code><pre>
</li>
<li>Change it to:
<pre><code class="prettyprint">
	repository = {
               ...
		line_comment = {
			patterns = (
				{	name = 'meta.comment.full-line.perl';
					match = '^((#)\s?((TODO|FIXME|BUG|XXX):?)?.*$\n?)';
					captures = {
						1 = { name = 'comment.line.number-sign.perl'; };
						2 = { name = 'punctuation.definition.comment.perl'; };
						3 = { name = 'comment.keyword.string.perl'; };
					};
				},
				{	name = 'comment.line.number-sign.perl';
					match = '(#)\s?((TODO|FIXME|BUG|XXX):?)?.*$\n?';
					captures = {
						1 = { name = 'punctuation.definition.comment.perl'; };
						2 = { name = 'comment.keyword.string.perl'; };
					};
				},
			);
		};
</code></pre>
and click 'Test'
</li>
<li>Now open <em>TextMate / Preferences...</em> and open the <em>Fonts & Colours</em> tab</li>
<li>Create a new element, set <i>Scope Selector</i> to 'comment.keyword', and choose foreground and background colours as appropriate - I picked yellow background and red text too, but if you don't have a black background then something else may be more appropriate</li>
<li>Done!</li>
 </ol>

<p>The TextMate Perl language grammar defines two comment items - a comment line and a comment string (i.e. a partial line) - to both we've added an optional section to the regex and an extra capture. It could be further improved by matching the keyword anywhere within the comment if required, and unlike the Vim syntax highlighting, this only matches within comments, which I think is probably preferable.<br />
</p>]]>
        
    </content>
</entry>

</feed>
