From 824d9953d9578af53e66d73704c549cea555547f Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 4 Apr 2010 16:07:37 -0700 Subject: [PATCH] Initial import of bootstrapig for buildbot. --- product.version | 1 + support/buildbot/bootstrap.pl | 44 +++++ support/buildbot/helpers.pm | 145 ++++++++++++++ support/buildbot/package.pl | 78 ++++++++ support/buildbot/startbuild.pl | 183 ++++++++++++++++++ support/buildbot/symstore.pl | 2 + .../versionchanger.pl | 81 ++------ 7 files changed, 466 insertions(+), 68 deletions(-) create mode 100644 product.version create mode 100755 support/buildbot/bootstrap.pl create mode 100644 support/buildbot/helpers.pm create mode 100755 support/buildbot/package.pl create mode 100755 support/buildbot/startbuild.pl create mode 100755 support/buildbot/symstore.pl rename versionchanger.pl => support/versionchanger.pl (66%) mode change 100644 => 100755 diff --git a/product.version b/product.version new file mode 100644 index 00000000..00f91b85 --- /dev/null +++ b/product.version @@ -0,0 +1 @@ +1.8.1-dev diff --git a/support/buildbot/bootstrap.pl b/support/buildbot/bootstrap.pl new file mode 100755 index 00000000..551ddd72 --- /dev/null +++ b/support/buildbot/bootstrap.pl @@ -0,0 +1,44 @@ +#!/usr/bin/perl + +use strict; +use Cwd; +use File::Basename; + +my ($myself, $path) = fileparse($0); +chdir($path); + +require 'helpers.pm'; + +#Go to main source dir +chdir(Build::PathFormat('../..')); + +#Do the annoying revision bumping. +#Linux needs some help here. +if ($^O eq "linux") +{ + Build::Command("flip -u modules.versions"); + Build::Command("flip -u support/versionchanger.pl"); + Build::Command("chmod +x support/versionchanger.pl"); +} +Build::Command(Build::PathFormat('support/versionchanger.pl') . ' --buildstring="-dev"'); + +open(DIRECTIONS, '>installer/builder/directions.info'); +if ($^O eq "linux") { + print DIRECTIONS "compress = /bin/tar\n"; +} else { + print DIRECTIONS "compress = C:\\WINDOWS\\zip.exe\n"; +} +print DIRECTIONS "source = " . Cwd::abs_path('.') . "\n"; +print DIRECTIONS "makeopts = \n"; +print DIRECTIONS "output = " . Cwd::abs_path('../OUTPUT') . "\n"; +if ($^O eq "linux") { + print DIRECTIONS "devenv = /usr/bin/make\n"; +} else { + print DIRECTIONS "devenv = C:\\Program Files\\Microsoft Visual Studio 8\\Common7\\IDE\\devenv.com\n"; +} +print DIRECTIONS "release = amxmodx-" . Build::ProductVersion('product.version') . + "-hg" . Build::HgRevNum('.') . "\n"; +close(DIRECTIONS); +Build::Delete("" . Cwd::abs_path('../OUTPUT')); +Build::Command("mkdir \"" . Cwd::abs_path('../OUTPUT') . "\""); + diff --git a/support/buildbot/helpers.pm b/support/buildbot/helpers.pm new file mode 100644 index 00000000..704a7b17 --- /dev/null +++ b/support/buildbot/helpers.pm @@ -0,0 +1,145 @@ +#!/usr/bin/perl + +use strict; +use Cwd; + +package Build; + +our $SVN = "/usr/bin/svn"; +our $SVN_USER = 'dvander'; +our $SVN_ARGS = ''; + +sub HgRevNum +{ + my ($path) = (@_); + my ($cd, $text, $rev); + + $cd = Cwd::cwd(); + chdir($path); + $text = `hg identify -n`; + chdir($cd); + + chomp $text; + if ($text =~ /^(\d+)/) + { + return $1; + } + + return 0; +} + +sub SvnRevNum +{ + my ($str)=(@_); + + my $data = Command('svnversion -c ' . $str); + if ($data =~ /(\d+):(\d+)/) + { + return $2; + } elsif ($data =~ /(\d+)/) { + return $1; + } else { + return 0; + } +} + +sub ProductVersion +{ + my ($file) = (@_); + my ($version); + open(FILE, $file) or die "Could not open $file: $!\n"; + $version = ; + close(FILE); + chomp $version; + return $version; +} + +sub Delete +{ + my ($str)=(@_); + if ($^O =~ /MSWin/) + { + Command("del /S /F /Q \"$str\""); + Command("rmdir /S /Q \"$str\""); + } else { + Command("rm -rf $str"); + } + return !(-e $str); +} + +sub Copy +{ + my ($src,$dest)=(@_); + if ($^O =~ /MSWin/) + { + Command("copy \"$src\" \"$dest\" /y"); + } else { + Command("cp \"$src\" \"$dest\""); + } + return (-e $dest); +} + +sub Move +{ + my ($src,$dest)=(@_); + if ($^O =~ /MSWin/) + { + Command("move \"$src\" \"$dest\""); + } else { + Command("mv \"$src\" \"$dest\""); + } + return (-e $dest); +} + +sub Command +{ + my($cmd)=(@_); + print "$cmd\n"; + return `$cmd`; +} + +sub PathFormat +{ + my ($str)=(@_); + if ($^O =~ /MSWin/) + { + $str =~ s#/#\\#g; + } else { + $str =~ s#\\#/#g; + } + return $str; +} + +sub SVN_Remove +{ + my ($file)=(@_); + my ($path, $name); + if ($^O =~ /MSWin/) + { + ($path, $name) = ($file =~ /(.+)\/([^\/]+)$/); + } else { + ($path, $name) = ($file =~ /(.+)\\([^\\]+)$/); + } + my $dir = Cwd::cwd(); + chdir($path); + Command($SVN . ' ' . $SVN_ARGS . ' delete ' . $name); + chdir($dir); +} + +sub SVN_Add +{ + my ($file)=(@_); + my ($path, $name); + if ($^O =~ /MSWin/) + { + ($path, $name) = ($file =~ /(.+)\/([^\/]+)$/); + } else { + ($path, $name) = ($file =~ /(.+)\\([^\\]+)$/); + } + my $dir = Cwd::cwd(); + chdir($path); + Command($SVN . ' ' . $SVN_ARGS . ' add ' . $name); + chdir($dir); +} + +return 1; diff --git a/support/buildbot/package.pl b/support/buildbot/package.pl new file mode 100755 index 00000000..85263457 --- /dev/null +++ b/support/buildbot/package.pl @@ -0,0 +1,78 @@ +#!/usr/bin/perl + +use strict; +use Cwd; +use File::Basename; +use Net::FTP; + +my ($ftp_file, $ftp_host, $ftp_user, $ftp_pass, $ftp_path); + +$ftp_file = shift; + +open(FTP, $ftp_file) or die "Unable to read FTP config file $ftp_file: $!\n"; +$ftp_host = ; +$ftp_user = ; +$ftp_pass = ; +$ftp_path = ; +close(FTP); + +chomp $ftp_host; +chomp $ftp_user; +chomp $ftp_pass; +chomp $ftp_path; + +my ($myself, $path) = fileparse($0); +chdir($path); + +require 'helpers.pm'; + +#Switch to the output folder. +chdir(Build::PathFormat('../../OUTPUT')); + +my ($version); + +$version = Build::ProductVersion(Build::PathFormat('../product.version')); +$version .= '-hg' . Build::HgRevNum('..'); + +my ($filename); +$filename = 'mmsource-' . $version; +if ($^O eq "linux") +{ + $filename .= '.tar.gz'; + print "tar zcvf $filename addons\n"; + system("tar zcvf $filename addons"); +} +else +{ + $filename .= '.zip'; + print "zip -r $filename addons\n"; + system("zip -r $filename addons"); +} + +my ($major,$minor) = ($version =~ /^(\d+)\.(\d+)/); +$ftp_path .= "/$major.$minor"; + +my ($ftp); + +$ftp = Net::FTP->new($ftp_host, Debug => 0) + or die "Cannot connect to host $ftp_host: $@"; + +$ftp->login($ftp_user, $ftp_pass) + or die "Cannot connect to host $ftp_host as $ftp_user: " . $ftp->message . "\n"; + +if ($ftp_path ne '') +{ + $ftp->cwd($ftp_path) + or die "Cannot change to folder $ftp_path: " . $ftp->message . "\n"; +} + +$ftp->binary(); +$ftp->put($filename) + or die "Cannot drop file $filename ($ftp_path): " . $ftp->message . "\n"; + +$ftp->close(); + +print "File sent to drop site as $filename -- build succeeded.\n"; + +exit(0); + diff --git a/support/buildbot/startbuild.pl b/support/buildbot/startbuild.pl new file mode 100755 index 00000000..59d8a835 --- /dev/null +++ b/support/buildbot/startbuild.pl @@ -0,0 +1,183 @@ +#!/usr/bin/perl + +use File::Basename; + +our (@LIBRARIES); +my ($myself, $path) = fileparse($0); +chdir($path); + +require 'helpers.pm'; + +#Get to top of source tree +chdir('..'); +chdir('..'); + +# Folder .vcproj Engine Binary Suffix type Platform +Build('loader', 'mm_loader', '', 'server', 'full', 'both'); +Build('loader', 'mm_loader', 'Left4Dead2', 'server_linux', '', 'linux'); +Build('core-legacy', 'mm_core-legacy', '', 'metamod.1.ep1', '', 'both'); +Build('core', 'mm_core', 'OrangeBox', 'metamod.2.ep2', '', 'both'); +Build('core', 'mm_core', 'OrangeBoxValve', 'metamod.2.ep2v', '', 'both'); +Build('core', 'mm_core', 'Left4Dead', 'metamod.2.l4d', '', 'both'); +Build('core', 'mm_core', 'Left4Dead2', 'metamod.2.l4d2', '', 'both'); +Build('core', 'mm_core', 'DarkMessiah', 'metamod.2.darkm', '', 'windows'); + +#Structure our output folder +mkdir('OUTPUT'); +mkdir(Build::PathFormat('OUTPUT/addons')); +mkdir(Build::PathFormat('OUTPUT/addons/metamod')); +mkdir(Build::PathFormat('OUTPUT/addons/metamod/bin')); + +my ($i); +for ($i = 0; $i <= $#LIBRARIES; $i++) +{ + my $library = $LIBRARIES[$i]; + Copy($library, Build::PathFormat('OUTPUT/addons/metamod/bin')); +} +Copy(Build::PathFormat('support/metaplugins.ini'), + Build::PathFormat('OUTPUT/addons/metamod')); +Copy(Build::PathFormat('support/README.txt'), + Build::PathFormat('OUTPUT/addons/metamod')); + +sub Copy +{ + my ($a, $b) = (@_); + + die "Could not copy $a to $b!\n" if (!Build::Copy($a, $b)); +} + +sub Build +{ + my ($srcdir, $vcproj, $objdir, $binary, $suffix, $platform) = (@_); + + if ($^O eq "linux") + { + if ($platform eq "windows") + { + return; + } + + if ($suffix eq 'full') + { + $binary .= '_i486.so'; + } + else + { + $binary .= '.so'; + } + + BuildLinux($srcdir, $objdir, $binary); + } + else + { + if ($platform eq "linux") + { + return; + } + + $binary .= '.dll'; + BuildWindows($srcdir, $vcproj, $objdir, $binary); + } +} + +sub BuildWindows +{ + my ($srcdir, $vcproj, $build, $binary) = (@_); + my ($dir, $file, $param, $vcbuilder, $cmd); + + $dir = getcwd(); + chdir("$srcdir\\msvc9"); + + $param = "Release"; + if ($build eq "OrangeBox") + { + $param = "Release - Orange Box"; + } + if ($build eq "OrangeBoxValve") + { + $param = "Release - Orange Box Valve"; + } + elsif ($build eq "Left4Dead") + { + $param = "Release - Left 4 Dead"; + } + elsif ($build eq "Left4Dead2") + { + $param = "Release - Left 4 Dead 2"; + } + elsif ($build eq "DarkMessiah") + { + $param = "Release - Dark Messiah"; + } + + print "Clean building $srcdir...\n"; + $vcbuilder = $ENV{'VC9BUILDER'}; + $cmd = "\"$vcbuilder\" /rebuild \"$vcproj.vcproj\" \"$param\""; + print "$cmd\n"; + system($cmd); + CheckFailure(); + + $file = "$param\\$binary"; + + die "Output library not found: $file\n" if (!-f $file); + + chdir($dir); + + push(@LIBRARIES, "$srcdir\\msvc9\\$file"); +} + +sub BuildLinux +{ + my ($srcdir, $build, $binary) = (@_); + my ($dir, $file, $param); + + $dir = getcwd(); + chdir($srcdir); + + $param = ""; + $file = "Release"; + if ($build eq "OrangeBox") + { + $param = "ENGINE=orangebox"; + $file .= '.orangebox'; + } + if ($build eq "OrangeBoxValve") + { + $param = "ENGINE=orangeboxvalve"; + $file .= '.orangeboxvalve'; + } + elsif ($build eq "Left4Dead") + { + $param = "ENGINE=left4dead"; + $file .= '.left4dead'; + } + elsif ($build eq "Left4Dead2") + { + $param = "ENGINE=left4dead2"; + $file .= '.left4dead2'; + } + $file .= '/' . $binary; + + print "Cleaning $srcdir...\n"; + system("make $param clean"); + CheckFailure(); + + print "Building $srcdir for $binary...\n"; + print "$param\n"; + system("make $param"); + CheckFailure(); + + die "Output library not found: $file\n" if (!-f $file); + + chdir($dir); + + push(@LIBRARIES, $srcdir . '/' . $file); +} + +sub CheckFailure +{ + die "Build failed: $!\n" if $? == -1; + die "Build died :(\n" if $^O eq "linux" and $? & 127; + die "Build failed with exit code: " . ($? >> 8) . "\n" if ($? >> 8 != 0); +} + diff --git a/support/buildbot/symstore.pl b/support/buildbot/symstore.pl new file mode 100755 index 00000000..d838a0b6 --- /dev/null +++ b/support/buildbot/symstore.pl @@ -0,0 +1,2 @@ +#!/usr/bin/perl + diff --git a/versionchanger.pl b/support/versionchanger.pl old mode 100644 new mode 100755 similarity index 66% rename from versionchanger.pl rename to support/versionchanger.pl index c1b7ab36..ce5f6f62 --- a/versionchanger.pl +++ b/support/versionchanger.pl @@ -7,9 +7,8 @@ our %arguments = 'minor' => '0', 'revision' => '0', 'build' => undef, - 'svnrev' => 'global', 'path' => '', - 'modules' => '', + 'buildstring' => '', ); my $arg; @@ -20,20 +19,6 @@ foreach $arg (@ARGV) $arguments{$arg[0]} = $arg[1]; } -our (%allowed); -if ($arguments{'modules'} ne "") -{ - my @l = split(/,/, $arguments{'modules'}); - my $i; - - for ($i=0; $i<=$#l; $i++) - { - $allowed{$l[$i]} = 1; - } -} else { - $allowed{'*'} = 1; -} - #Set up path info if ($arguments{'path'} ne "") { @@ -88,25 +73,28 @@ if (exists($modules{'PRODUCT'})) { $arguments{'revision'} = $modules{'PRODUCT'}{'revision'}; } - if (exists($modules{'PRODUCT'}{'svnrev'})) - { - $arguments{'svnrev'} = $modules{'PRODUCT'}{'svnrev'}; - } } #Get the global SVN revision if we have none my $rev; if ($arguments{'build'} == undef) { - $rev = GetRevision(undef); -} else { + my ($text); + $text = `hg identif -n -i`; + chomp $text; + $text =~ s/\+//g; + my ($id,$num) = split(/ /, $text); + $rev = "$num:$id"; +} +else +{ $rev = int($arguments{'build'}); } my $major = $arguments{'major'}; my $minor = $arguments{'minor'}; my $revision = $arguments{'revision'}; -my $svnrev = $arguments{'svnrev'}; +my $buildstr = $arguments{'buildstring'}; #Go through everything now my $mod_i; @@ -117,10 +105,6 @@ while ( ($cur_module, $mod_i) = each(%modules) ) { next; } - if (!$allowed{'*'} && !$allowed{$cur_module}) - { - next; - } #Prepare path my %mod = %{$mod_i}; my $infile = $mod{'in'}; @@ -138,22 +122,6 @@ while ( ($cur_module, $mod_i) = each(%modules) ) { die "File $infile is not a file.\n"; } - my $global_rev = $rev; - my $local_rev; - - if ($arguments{'build'} == undef) - { - $local_rev = GetRevision($mod{'folder'}); - } - else - { - $local_rev = $rev; - } - - if ($arguments{'svnrev'} eq 'local') - { - $global_rev = $local_rev; - } #Start rewriting open(INFILE, $infile) or die "Could not open file for reading: $infile\n"; open(OUTFILE, '>'.$outfile) or die "Could not open file for writing: $outfile\n"; @@ -162,34 +130,11 @@ while ( ($cur_module, $mod_i) = each(%modules) ) s/\$PMAJOR\$/$major/g; s/\$PMINOR\$/$minor/g; s/\$PREVISION\$/$revision/g; - s/\$GLOBAL_BUILD\$/$rev/g; - s/\$LOCAL_BUILD\$/$local_rev/g; + s/\$BUILD_ID\$/$rev/g; + s/\$BUILD_STRING\$/$buildstr/g; print OUTFILE $_; } close(OUTFILE); close(INFILE); } -sub GetRevision -{ - my ($path)=(@_); - my $rev; - if (!$path) - { - $rev = `svnversion --committed`; - } else { - $rev = `svnversion --committed $path`; - } - if ($rev =~ /exported/) - { - die "Path specified is not a working copy\n"; - } elsif ($rev =~ /(\d+):(\d+)/) { - $rev = int($2); - } elsif ($rev =~ /(\d+)/) { - $rev = int($1); - } else { - die "Unknown svnversion response: $rev\n"; - } - return $rev; -} -