diff --git a/support/buildbot/bootstrap.pl b/support/buildbot/bootstrap.pl index 0a96d544..d3f136da 100755 --- a/support/buildbot/bootstrap.pl +++ b/support/buildbot/bootstrap.pl @@ -9,6 +9,8 @@ use File::Path; my ($myself, $path) = fileparse($0); chdir($path); +use FindBin; +use lib $FindBin::Bin; require 'helpers.pm'; #Go back above build dir diff --git a/support/buildbot/package.pl b/support/buildbot/package.pl deleted file mode 100755 index 10517889..00000000 --- a/support/buildbot/package.pl +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/perl -# vim: set ts=4 sts=4 sw=4 tw=99 noet: - -use strict; -use Cwd; -use File::Basename; -use File::stat; -use File::Temp qw/ tempfile :seekable/; -use Net::FTP; -use Archive::Tar; -use Time::localtime; - -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'; - -my ($version); -$version = Build::ProductVersion(Build::PathFormat('../../product.version')); -$version .= '-git' . Build::GitRevNum('.'); - -#Switch to the output folder. -chdir(Build::PathFormat('../../../OUTPUT')); - -my $needNewGeoIP = 1; -if (-e '../GeoLite2-Country.tar.gz') -{ - my $stats = stat('../GeoLite2-Country.tar.gz'); - if ($stats->size != 0) - { - my $fileModifiedTime = $stats->mtime; - my $fileModifiedMonth = localtime($fileModifiedTime)->mon; - my $currentMonth = localtime->mon; - my $thirtyOneDays = 60 * 60 * 24 * 31; - - # GeoIP file only updates once per month - if ($currentMonth == $fileModifiedMonth || (time() - $fileModifiedTime) < $thirtyOneDays) - { - $needNewGeoIP = 0; - } - } -} - -if ($needNewGeoIP) -{ - print "Downloading GeoLite2-Country.mmdb...\n"; - system('wget -q -O ../GeoLite2-Country.tar.gz https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.tar.gz'); -} -else -{ - print "Reusing existing GeoLite2-Country.mmdb\n"; -} - -my $geoIPfile = 'packages/base/addons/amxmodx/data/GeoLite2-Country.mmdb'; -if (-e $geoIPfile) { - unlink($geoIPfile); -} - -my $next = Archive::Tar->iter('../GeoLite2-Country.tar.gz', 1, {filter => qr/\.mmdb$/}); -while (my $file = $next->()) { - $file->extract($geoIPfile) or warn "Extraction failed"; -} - -my (@packages,@mac_exclude); -@packages = ('base', 'cstrike', 'dod', 'esf', 'ns', 'tfc', 'ts'); -@mac_exclude = ('esf', 'ns', 'ts'); - -my ($major,$minor) = ($version =~ /^(\d+)\.(\d+)/); - -my ($i); -for ($i = 0; $i <= $#packages; $i++) { - my ($filename); - next if (($^O eq "darwin") && ($packages[$i] ~~ @mac_exclude)); - - if ($^O eq "linux") { - $filename = "amxmodx-$version-" . $packages[$i] . "-linux.tar.gz"; - } elsif ($^O eq "darwin") { - $filename = "amxmodx-$version-" . $packages[$i] . "-mac.zip"; - } else { - $filename = "amxmodx-$version-" . $packages[$i] . "-windows.zip"; - } - unlink($filename); - - chdir(Build::PathFormat("packages/" . $packages[$i])); - if ($^O eq "linux") { - Build::Command("tar zcvf $filename addons"); - } else { - Build::Command("zip -r $filename addons"); - } - Build::Move($filename, Build::PathFormat('../../')); - chdir(Build::PathFormat('../..')); -} - -my ($ftp); -$ftp_path .= "/$major.$minor"; - -$ftp = Net::FTP->new($ftp_host, Debug => 0, Passive => 1) - 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(); -for ($i = 0; $i <= $#packages; $i++) { - my ($filename); - my ($latest); - if ($^O eq "linux") { - $filename = "amxmodx-$version-" . $packages[$i] . "-linux.tar.gz"; - $latest = "amxmodx-latest-" . $packages[$i] . "-linux"; - } elsif ($^O eq "darwin") { - next if ($packages[$i] ~~ @mac_exclude); - $filename = "amxmodx-$version-" . $packages[$i] . "-mac.zip"; - $latest = "amxmodx-latest-" . $packages[$i] . "-mac"; - } else { - $filename = "amxmodx-$version-" . $packages[$i] . "-windows.zip"; - $latest = "amxmodx-latest-" . $packages[$i] . "-windows"; - } - - my ($tmpfh, $tmpfile) = tempfile(); - print $tmpfh $filename; - $tmpfh->seek( 0, SEEK_END ); - - print "Uploading $filename...\n"; - $ftp->put($filename) - or die "Cannot drop file $filename ($ftp_path): " . $ftp->message . "\n"; - - print "Uploading $latest...\n"; - $ftp->put($tmpfile, $latest) - or die "Cannot drop file $latest ($ftp_path): " . $ftp->message . "\n"; -} - -$ftp->close(); - -print "Files sent to drop site -- build succeeded.\n"; - -exit(0); \ No newline at end of file diff --git a/support/buildbot/package.py b/support/buildbot/package.py new file mode 100644 index 00000000..19495c5e --- /dev/null +++ b/support/buildbot/package.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 +# vim: set ts=4 sw=4 tw=99 et: +import argparse +import datetime +import ftplib +import os +import platform +import re +import shutil +import subprocess +import time + +kPackages = ['base', 'cstrike', 'dod', 'esf', 'ns', 'tfc', 'ts'] +kMacExclude = set(['esf', 'ns', 'ts']) + +class PackageBuilder(object): + def __init__(self, args): + self.args_ = args + + if platform.system() == 'Linux': + self.os_ = 'linux' + elif platform.system() == 'Windows': + self.os_ = 'windows' + elif platform.system() == 'Darwin': + self.os_ = 'mac' + else: + raise Exception('Unknown platform: {}'.format(platform.system())) + + if self.os_ == 'linux': + self.archive_type_ = 'tar.gz' + else: + self.archive_type_ = 'zip' + self.packages_ = [] + + def run(self): + self.read_ftp_info() + self.read_product_version() + + # Switch to the output folder. + with Chdir(os.path.join('..', 'OUTPUT')): + self.build() + self.upload() + + def build(self): + print("Creating package for {}".format(self.version_)) + + for package in kPackages: + if self.os_ == 'mac' and package in kMacExclude: + continue + + package_dir = os.path.join('packages', package) + with Chdir(package_dir): + package_name, alt_name = self.build_package(package) + + if os.path.exists(package_name): + os.unlink(package_name) + + src_path = os.path.join(package_dir, package_name) + shutil.move(src_path, package_name) + + self.packages_.append((package_name, alt_name)) + + def upload(self): + + m = re.search("^(\d+)\.(\d+)", self.version_) + ftp_path = '{}/{}.{}'.format(self.ftp_path_, m.group(1), m.group(2)) + + print("Connecting to drop site: {}".format(ftp_path)) + ftp = ftplib.FTP(self.ftp_host_) + ftp.login(self.ftp_user_, self.ftp_pass_) + ftp.set_pasv(True) + ftp.cwd(ftp_path) + + for package_file, alt_file in self.packages_: + self.upload_package(ftp, package_file, package_file) + self.upload_package(ftp, package_file, alt_file) + + print("Files sent to drop site -- build succeeded.") + + def upload_package(self, ftp, package_file, dest_name): + with open(package_file, 'rb') as fp: + print("Sending {} as {}".format(package_file, dest_name)) + ftp.storbinary('STOR {}'.format(dest_name), fp) + + def build_package(self, package): + package_file = 'amxmodx-{}-{}-{}.{}'.format(self.version_, package, self.os_, + self.archive_type_) + if os.path.exists(package_file): + os.unlink(package_file) + + if self.archive_type_ == 'tar.gz': + Run(['tar', 'zcvf', package_file, 'addons']) + else: + Run(['zip', '-r', package_file, 'addons']) + + alt_name = 'amxmodx-latest-{}-{}.{}'.format(package, self.os_, self.archive_type_) + return package_file, alt_name + + def read_ftp_info(self): + with open(self.args_.ftp_file, 'rt') as fp: + lines = [line.strip() for line in fp.read().splitlines()] + self.ftp_host_ = lines[0] + self.ftp_user_ = lines[1] + self.ftp_pass_ = lines[2] + self.ftp_path_ = lines[3] + + def read_product_version(self): + with open('product.version', 'rt') as fp: + self.version_ = fp.read().strip() + + output = subprocess.check_output(['git', 'rev-list', '--count', 'HEAD'], + universal_newlines = True, + stderr = subprocess.STDOUT) + output = output.strip() + if output: + self.version_ += '-git' + output + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('ftp_file', type = str, help = 'FTP config file') + + args = parser.parse_args() + + builder = PackageBuilder(args) + builder.run() + +class Chdir(object): + def __init__(self, target): + self.prevdir_ = None + self.target_ = target + + def __enter__(self): + prevdir = os.getcwd() + os.chdir(self.target_) + self.prevdir_ = prevdir + return self + + def __exit__(self, exc_type, exc_value, traceback): + if self.prevdir_: + os.chdir(self.prevdir_) + return False + +def Run(argv): + try: + output = subprocess.check_output(argv, stderr = subprocess.STDOUT, + universal_newlines = True) + print(output) + except subprocess.CalledProcessError as e: + print(e.output.decode('utf-8')) + raise + +if __name__ == '__main__': + main() diff --git a/support/buildbot/startbuild.pl b/support/buildbot/startbuild.pl index 6b17ddb9..dc4ee322 100755 --- a/support/buildbot/startbuild.pl +++ b/support/buildbot/startbuild.pl @@ -5,6 +5,8 @@ use File::Basename; my ($myself, $path) = fileparse($0); chdir($path); +use FindBin; +use lib $FindBin::Bin; require 'helpers.pm'; chdir('../../../OUTPUT');