about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonathan "Duke" Leto <jonathan@leto.net>2011-04-28 12:04:48 -0700
committerJonathan "Duke" Leto <jonathan@leto.net>2011-04-28 12:04:48 -0700
commit2d8ded73a3ac395839ce4abe0ec59dabfdfba0bf (patch)
tree98402ccc9cc8db654a942ef27b20c844bf0232d8
parentAdd on_failure_to_email and on_pass_to_email config keys (diff)
parentPrevent a use of uninitialized value warning (diff)
downloadjitterbug-2d8ded73a3ac395839ce4abe0ec59dabfdfba0bf.tar.gz
Merge branch 'reuse_repo'
-rw-r--r--Build.PL1
-rw-r--r--README43
-rw-r--r--README.md49
-rw-r--r--config.yml1
-rw-r--r--example.yml53
-rw-r--r--lib/jitterbug/Builder.pm74
-rw-r--r--public/js/common.js2
-rw-r--r--scripts/build_rakudo_and_spectest.sh10
-rwxr-xr-xscripts/capsule.sh2
-rw-r--r--t/004_project.t7
-rw-r--r--t/lib/jitterbug/Test.pm7
11 files changed, 180 insertions, 69 deletions
diff --git a/Build.PL b/Build.PL
index 926267d..10991a6 100644
--- a/Build.PL
+++ b/Build.PL
@@ -24,6 +24,7 @@ my $builder = Module::Build->new(
         'Dancer::Template::Xslate' => 0,
         'Dancer::Plugin::DBIC'     => 0,
         'DBIx::Class'              => 0,
+        'DateTime::Format::SQLite' => 0,
         'SQL::Translator'          => 0,
         'Digest::MD5'              => 0,
         'App::perlbrew'            => 0,
diff --git a/README b/README
deleted file mode 100644
index 8ce74fd..0000000
--- a/README
+++ /dev/null
@@ -1,43 +0,0 @@
-Jitterbug : A continuous integration system built on Dancer and git hooks
-
-Jitterbug is written in Perl 5 and depends on various CPAN modules, such
-as Dancer, DBIx::Class and Git::Repository.
-
-Installing Jitterbug
-===================
-
-perl Build.PL
-
-# You can also use Makefile.PL, but you will then have to manually 
-# install dependencies
-# perl Makefile.PL
-
-# install missing dependencies
-./Build installdeps
-
-# start the jitterbug Dancer app, which by default binds to port 3000
-perl jitterbug.pl
-
-# If you need to start it on a different port use -p
-# perl jitterbug.pl -p 3001
-
-In another terminal, deploy a DBIx::Class schema ( which is SQLite by default, 
-change the values in config.yml to tweak) :
-
-perl scripts/jitterbug_db --config config.yml --deploy
-
-Now add a post-receive hook to your github project that hits the /hook/ URL
-on the server that the jitterbug Dancer app is running on, i.e.
-
-    http://example.com:3001/hook/
-
-Now you must start the builder, which actually clones a new git repo for
-each task (this could be network-intensive) and actually runs the build
-and test commands for each project.
-
-    perl scripts/builder.pl -c config.yml
-
-Now, when you commit to a project that has a Jitterbug post-receive hook,
-the builder check every 30 seconds for a new task and build and test your
-projects!
-
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c42076a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,49 @@
+## Jitterbug : Cross Language Continuous integration for Git
+
+
+### What is Jitterbug?
+
+Jitterbug is written in Perl 5 and depends on various CPAN modules, such
+as Moose, Dancer, DBIx::Class and others.
+
+### Installing Jitterbug
+
+    # You can also use Makefile.PL, but you will then have to manually 
+    perl Build.PL
+    # perl Makefile.PL
+
+    # install missing dependencies
+    ./Build installdeps
+
+    # you can also use cpanm
+    # cpanm --installdeps .
+
+    # Look at config.yaml or example.yaml for how to configure your Jitterbug instance
+    $EDITOR config.yaml
+
+    # start the jitterbug Dancer app, which by default binds to port 3000
+    perl jitterbug.pl
+
+    # If you need to start it on a different port use -p
+    perl jitterbug.pl -p 3001
+
+In another terminal, deploy a DBIx::Class schema ( which is SQLite by default, 
+change the values in config.yml to tweak) :
+
+    perl scripts/jitterbug_db --config config.yml --deploy
+
+Now add a post-receive hook to your github project that hits the /hook/ URL
+on the server that the jitterbug Dancer app is running on, i.e.
+
+    http://example.com:3001/hook/
+
+Now you must start the builder, which actually clones a new git repo for
+each task (this could be network-intensive) and actually runs the build
+and test commands for each project.
+
+    perl scripts/builder.pl -c config.yml
+
+Now, when you commit to a project that has a Jitterbug post-receive hook,
+the builder check periodically for a new task and build and test your
+projects!
+
diff --git a/config.yml b/config.yml
index 47f4f42..53a50c1 100644
--- a/config.yml
+++ b/config.yml
@@ -32,6 +32,7 @@ jitterbug:
     on_pass_from_email: donotreply@example.com
     on_pass_header:
     on_pass_footer:
+    reuse_repo:    1
   options:
     perlbrew: 1
     email_on_pass: 0
diff --git a/example.yml b/example.yml
new file mode 100644
index 0000000..fc3f72e
--- /dev/null
+++ b/example.yml
@@ -0,0 +1,53 @@
+layout: "main"
+logger: "file"
+appname: "jitterbug"
+
+builds_per_feed: 5
+template: "xslate"
+engines:
+  xslate:
+    path: /
+    type: text
+    cache: 0
+
+jitterbug:
+  reports:
+    dir: /tmp/jitterbug
+  build:
+    dir: /tmp/build
+  build_process:
+    builder: ./scripts/capsule.sh
+    builder_variables: ""
+    on_failure: "jitterbug::Emailer"
+    on_failure_to_email: jonathan@leto.net
+    on_failure_cc_email:
+    on_failure_from_email: jitterbug@leto.net
+    on_failure_subject_prefix: "[jitterbug] FAIL "
+    on_failure_header: "Jitterbug Web Interace : http://new.leto.net:3000\n%%PROJECT%% : http://new.leto.net:8090/project/%%PROJECT%%\nFailing Commit Diff: https://github.com/parrot/%%PROJECT%%/commit/%%SHA1%%\n\n%%SUMMARY%%\n\n"
+    on_failure_footer: "Sorry, but your Princess is in another castle!"
+    on_pass: "jitterbug::Emailer"
+    on_pass_to_email:
+    on_pass_cc_email: jonathan@leto.net
+    on_pass_subject_prefix: "[jitterbug] PASS "
+    on_pass_from_email: jitterbug@leto.net
+    on_pass_footer: "Amazingly, everything WORKED!"
+    on_pass_header: "Great job!"
+    reuse_repo:    1
+  options:
+    perlbrew: 1
+    email_on_pass: 0
+  branches:
+    parrot: master|smoke-me
+  projects:
+    rakudo:
+      builder: ./scripts/build_rakudo_and_spectest.sh
+
+plugins:
+  DBIC:
+    schema:
+      skip_automake: 1
+      pckg: "jitterbug::Schema"
+      connect_info:
+        - dbi:SQLite:dbname=jitterbug.db
+
+
diff --git a/lib/jitterbug/Builder.pm b/lib/jitterbug/Builder.pm
index f6fb41e..366878f 100644
--- a/lib/jitterbug/Builder.pm
+++ b/lib/jitterbug/Builder.pm
@@ -12,10 +12,11 @@ use Getopt::Long qw/:config no_ignore_case/;
 use File::Basename;
 use Git::Repository;
 use jitterbug::Schema;
+use Cwd;
 #use Data::Dumper;
 
 local $| = 1;
-use constant DEBUG => 0;
+use constant DEBUG => $ENV{DEBUG} || 0;
 
 sub new {
     my $self = bless {} => shift;
@@ -81,10 +82,12 @@ sub sleep {
 }
 
 sub run_task {
-    my $self   = shift;
-    my ($task) = @_;
-    my $desc   = JSON::decode_json( $task->commit->content );
-    my $conf   = $self->{'conf'};
+    my ($self,$task)   = @_;
+
+    my $desc    = JSON::decode_json( $task->commit->content );
+    my $conf    = $self->{'conf'};
+    my $buildconf = $conf->{'jitterbug'}{'build_process'};
+    my $project = $task->project;
 
     my $dt = DateTime->now();
     $task->update({started_when => $dt});
@@ -93,28 +96,55 @@ sub run_task {
 
     my $report_path = dir(
         $conf->{'jitterbug'}{'reports'}{'dir'},
-        $task->project->name,
+        $project->name,
         $task->commit->sha256,
     );
+    my $dir = $conf->{'jitterbug'}{'build'}{'dir'};
+    mkdir $dir unless -d $dir;
 
-    my $build_dir = dir(
-        $conf->{'jitterbug'}{'build'}{'dir'},
-        $task->project->name,
-    );
-
-    debug("Removing $build_dir");
-    rmtree($build_dir, { error => \my $err } );
-    warn @$err if @$err;
-
-    $self->sleep(1); # avoid race conditions
+    my $build_dir = dir($dir, $project->name);
 
+    my $r;
     my $repo    = $task->project->url . '.git';
-    my $r       = Git::Repository->create( clone => $repo => $build_dir );
+    unless ($buildconf->{reuse_repo}) {
+        debug("Removing $build_dir");
+        rmtree($build_dir, { error => \my $err } );
+        warn @$err if @$err;
+        $r       = Git::Repository->create( clone => $repo => $build_dir );
+    } else {
+        # If this is the first time, the repo won't exist yet
+        debug("build_dir = $build_dir");
+        if( -d $build_dir ){
+            my $pwd = getcwd;
+            chdir $build_dir;
+            # TODO: Error Checking
+            debug("Cleaning git repo");
+            system("git clean -dfx");
+            debug("Fetching new commits into $repo");
+            system("git fetch");
+            debug("Checking out correct commit");
+            system("git checkout " . $task->commit->sha256 );
+            chdir $pwd;
+        } else {
+            debug("Creating new repo");
+            my $pwd = getcwd;
+            debug("pwd=$pwd");
+            chdir $build_dir;
+            system("git clone $repo $build_dir");
+            chdir $pwd;
+        }
+    }
+    $self->sleep(1); # avoid race conditions
 
     debug("Checking out " . $task->commit->sha256 . " from $repo into $build_dir\n");
-    $r->run( 'checkout', $task->commit->sha256 );
+    # $r->run( 'checkout', $task->commit->sha256 );
+    my $pwd = getcwd;
+    chdir $build_dir;
+    system("git checkout " . $task->commit->sha256 );
+    chdir $pwd;
 
-    my $builder         = $conf->{'jitterbug'}{'build_process'}{'builder'};
+    my $builder       =    $conf->{'jitterbug'}{'projects'}{$project->name}{'builder'}
+                        || $conf->{'jitterbug'}{'build_process'}{'builder'};
 
     my $perlbrew      = $conf->{'jitterbug'}{'options'}{'perlbrew'};
     my $email_on_pass = $conf->{'jitterbug'}{'options'}{'email_on_pass'};
@@ -122,7 +152,9 @@ sub run_task {
     debug("email_on_pass = $email_on_pass");
     debug("perlbrew      = $perlbrew");
 
-    my $builder_variables = $conf->{'jitterbug'}{'build_process'}{'builder_variables'};
+    # If the project has custom builder variables, use those. Otherwise, use the global setting
+    my $builder_variables =    $conf->{'jitterbug'}{'projects'}{$project->name}{'builder_variables'}
+                            || $conf->{'jitterbug'}{'build_process'}{'builder_variables'} || '';
 
     my $builder_command = "$builder_variables $builder $build_dir $report_path $perlbrew";
 
@@ -139,6 +171,8 @@ sub run_task {
         while (<$fh>){
             $lines .= $_;
         }
+        # if $result is undefined, either there was a build failure
+        # or the test output is not from a TAP harness
         ($result) = $lines =~ /Result:\s(\w+)/;
         my ( $name, ) = basename($version);
         $name =~ s/\.txt//;
diff --git a/public/js/common.js b/public/js/common.js
index 646f80e..93c080a 100644
--- a/public/js/common.js
+++ b/public/js/common.js
@@ -4,6 +4,7 @@ $(document).ready(function() {
         var class = "#commits-day-" + day;
         $(class).toggle();
     });
+    /* This times out on large test outputs
     $('.builds a').click(function() {
         var url = $(this).attr("href");
         var id = $(this).parents('.commit').attr('id');
@@ -12,4 +13,5 @@ $(document).ready(function() {
         });
         return false;
     })
+    */
 })
diff --git a/scripts/build_rakudo_and_spectest.sh b/scripts/build_rakudo_and_spectest.sh
new file mode 100644
index 0000000..423b8b5
--- /dev/null
+++ b/scripts/build_rakudo_and_spectest.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# This serves as an example of a custom build script, which builds
+# Rakudo Perl 6 and times a spectest run
+
+make realclean
+perl Configure.pl --gen-parrot
+make
+make t/spec
+time make spectest
diff --git a/scripts/capsule.sh b/scripts/capsule.sh
index 30c3877..9fca79e 100755
--- a/scripts/capsule.sh
+++ b/scripts/capsule.sh
@@ -20,6 +20,8 @@ function jitterbug_build () {
         perl Build.PL >> $logfile 2>&1
         # ./Build installdeps is not available in older Module::Build's
         cpanm --installdeps . >> $logfile 2>&1
+        # Run this again in case our Build is out of date (suboptimal)
+        perl Build.PL >> $logfile 2>&1
         HARNESS_VERBOSE=1 ./Build test --verbose >> $logfile 2>&1
     elif [ -f 'Makefile.PL' ]; then
         echo "Found Makefile.PL"
diff --git a/t/004_project.t b/t/004_project.t
index 4d00338..568ffc0 100644
--- a/t/004_project.t
+++ b/t/004_project.t
@@ -10,9 +10,10 @@ use Dancer::Test;
 
 jitterbug::Test->init();
 
-my $response;
+my $r;
 
 {
-    $response = dancer_response(GET => '/project/Dancer');
-    is $response->status, 404;
+    local $TODO = "non-existent project gives a 500 instead of a 404";
+    $r = dancer_response(GET => '/project/Dancer');
+    is $r->status, 404 or diag $r->content;
 }
diff --git a/t/lib/jitterbug/Test.pm b/t/lib/jitterbug/Test.pm
index ee6a13d..2326e83 100644
--- a/t/lib/jitterbug/Test.pm
+++ b/t/lib/jitterbug/Test.pm
@@ -10,12 +10,13 @@ use File::Spec;
 use File::Temp qw/tempdir/;
 
 sub init {
-    my $db_dir = tempdir( CLEANUP => 1 );
-    my $db_file = File::Spec->catfile( $db_dir, 'jitterbug.db' );
+    #my $db_dir = tempdir( CLEANUP => 1 );
+    # TODO: this should be pulled from the config file
+    my $db_file = File::Spec->catfile( qw/t data jitterbug.db/ );
     my $dsn     = 'dbi:SQLite:dbname=' . $db_file;
     my $schema  = jitterbug::Schema->connect($dsn);
     _setting($dsn);
-    $schema->deploy;
+    $schema->deploy unless -s $db_file;
 }
 
 sub _setting {