зеркало из https://github.com/mozilla/gecko-dev.git
framework changes for bootstrap b=352230 r=preed
This commit is contained in:
Родитель
4b4a6b69ab
Коммит
a53b6f184e
|
@ -5,11 +5,14 @@
|
|||
package Bootstrap::Step;
|
||||
use MozBuild::Util;
|
||||
use Config::General;
|
||||
use POSIX qw(strftime);
|
||||
|
||||
my $DEFAULT_TIMEOUT = 3600;
|
||||
|
||||
# shared static config
|
||||
my $conf = new Config::General("bootstrap.cfg");
|
||||
if (not $conf) {
|
||||
die "Config is null: $!";
|
||||
die "Config is null!";
|
||||
}
|
||||
|
||||
sub new {
|
||||
|
@ -25,23 +28,32 @@ sub Shell {
|
|||
my %args = @_;
|
||||
my $cmd = $args{'cmd'};
|
||||
my $dir = $args{'dir'};
|
||||
my $timeout = $args{'timeout'};
|
||||
my $timeout = $args{'timeout'} ? $args{'timeout'} : $DEFAULT_TIMEOUT;
|
||||
my $logFile = $args{'logFile'};
|
||||
my $rv = '';
|
||||
|
||||
if ($dir) {
|
||||
chdir($dir) || die "Cannot chdir to $dir: $!";
|
||||
$this->Log('msg' => 'Changing directory to ' . $dir);
|
||||
chdir($dir) or die "Cannot chdir to $dir: $!";
|
||||
$this->Log('msg' => 'Running shell command ' . $cmd . ' in dir ' . $dir);
|
||||
} else {
|
||||
$this->Log('msg' => 'Running shell command ' . $cmd);
|
||||
}
|
||||
|
||||
$this->Log('msg' => 'Starting time is ' . $this->CurrentTime());
|
||||
|
||||
print "Timeout: $timeout\n";
|
||||
|
||||
if ($timeout) {
|
||||
$rv = MozBuild::Util::RunShellCommand(
|
||||
'command' => "$cmd",
|
||||
'timeout' => "$timeout",
|
||||
'logfile' => "$logFile",
|
||||
);
|
||||
} else {
|
||||
$rv = MozBuild::Util::RunShellCommand(
|
||||
'command' => "$cmd",
|
||||
'logfile' => "$logFile",
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -49,28 +61,32 @@ sub Shell {
|
|||
my $timedOut = $rv->{'timedOut'};
|
||||
my $signalName = $rv->{'signalName'};
|
||||
my $dumpedCore = $rv->{'dumpedCore'};
|
||||
if ($exitValue) {
|
||||
if ($exitValue != 0) {
|
||||
$this->Log('msg' => "output: $rv->{'output'}");
|
||||
die("shell call returned bad exit code: $exitValue");
|
||||
}
|
||||
}
|
||||
my $pid = $rv->{'pid'};
|
||||
print "Pid: $pid\n";
|
||||
if ($timedOut) {
|
||||
$this->Log('msg' => "output: $rv->{'output'}");
|
||||
$this->Log('msg' => "output: $rv->{'output'}") if $rv->{'output'};
|
||||
die("FAIL shell call timed out after $timeout seconds");
|
||||
}
|
||||
if ($signalName) {
|
||||
$this->Log('msg' => "output: $rv->{'output'}");
|
||||
print ("WARNING shell recieved signal $signalName");
|
||||
}
|
||||
if ($dumpedCore) {
|
||||
$this->Log('msg' => "output: $rv->{'output'}");
|
||||
$this->Log('msg' => "output: $rv->{'output'}") if $rv->{'output'};
|
||||
die("FAIL shell call dumped core");
|
||||
}
|
||||
if ($exitValue) {
|
||||
if ($exitValue != 0) {
|
||||
$this->Log('msg' => "output: $rv->{'output'}") if $rv->{'output'};
|
||||
die("shell call returned bad exit code: $exitValue");
|
||||
}
|
||||
}
|
||||
|
||||
if($rc->{'output'}) {
|
||||
if ($rv->{'output'} && not defined($logFile)) {
|
||||
$this->Log('msg' => "output: $rv->{'output'}");
|
||||
}
|
||||
|
||||
# current time
|
||||
$this->Log('msg' => 'Ending time is ' . $this->CurrentTime());
|
||||
}
|
||||
|
||||
sub Log {
|
||||
|
@ -89,8 +105,8 @@ sub Config {
|
|||
|
||||
my %config = $conf->getall();
|
||||
|
||||
if ($config{'app'}{'firefox'}{'release'}{'1.5.0.7'}{$var}) {
|
||||
return $config{'app'}{'firefox'}{'release'}{'1.5.0.7'}{$var};
|
||||
if ($config{'app'}{$var}) {
|
||||
return $config{'app'}{$var};
|
||||
} else {
|
||||
die("No such config variable: $var\n");
|
||||
}
|
||||
|
@ -105,30 +121,41 @@ sub CheckLog {
|
|||
my $checkFor = $args{'checkFor'};
|
||||
my $checkForOnly = $args{'checkForOnly'};
|
||||
|
||||
open (FILE, "< $log") || die "Cannot open file $log: $!";
|
||||
if (not defined($log)) {
|
||||
die "No log file specified";
|
||||
}
|
||||
|
||||
open (FILE, "< $log") or die "Cannot open file $log: $!";
|
||||
my @contents = <FILE>;
|
||||
close FILE || die "Cannot close file $log: $!";
|
||||
close FILE or die "Cannot close file $log: $!";
|
||||
|
||||
if ($notAllowed) {
|
||||
my @errors = grep(/$notAllowed/i, @contents);
|
||||
if (@errors) {
|
||||
die "Errors in log ($log): \n\n @errors \n $!";
|
||||
die "Errors in log ($log): \n\n @errors \n";
|
||||
}
|
||||
}
|
||||
if ($checkFor) {
|
||||
if (not grep(/$checkFor/i, @contents)) {
|
||||
die "$checkFor is not present in file $log: $!";
|
||||
die "$checkFor is not present in file $log \n";
|
||||
}
|
||||
}
|
||||
if ($checkForOnly) {
|
||||
if (not grep(/$checkForOnly/i, @contents)) {
|
||||
die "$checkForOnly is not present in file $log: $!";
|
||||
die "$checkForOnly is not present in file $log \n";
|
||||
}
|
||||
my @errors = grep(!/$checkForOnly/i, @contents);
|
||||
if (@errors) {
|
||||
die "Errors in log ($log): \n\n @errors \n $!";
|
||||
die "Errors in log ($log): \n\n @errors \n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub CurrentTime() {
|
||||
my $this = shift;
|
||||
my $args = @_;
|
||||
|
||||
return strftime("%T %D", localtime());
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package MozBuild::Util;
|
||||
|
||||
# Stolen from the code for bug 336463
|
||||
use File::Path;
|
||||
|
||||
my $EXEC_TIMEOUT = '600';
|
||||
|
||||
sub RunShellCommand {
|
||||
my %args = @_;
|
||||
my $shellCommand = $args{'command'};
|
||||
my $logfile = $args{'logfile'};
|
||||
|
||||
# optional
|
||||
my $timeout = exists($args{'timeout'}) ? $args{'timeout'} : $EXEC_TIMEOUT;
|
||||
|
@ -24,20 +24,31 @@ sub RunShellCommand {
|
|||
my $dumpedCore;
|
||||
my $timedOut;
|
||||
my $output = '';
|
||||
my $pid;
|
||||
|
||||
eval {
|
||||
local $SIG{'ALRM'} = sub { die "alarm\n" };
|
||||
alarm $timeout;
|
||||
|
||||
if (! $redirectStderr || $shellCommand =~ "2>&1") {
|
||||
open CMD, "$shellCommand |" or die "Could not run command $shellCommand: $!";
|
||||
if (! $redirectStderr or $shellCommand =~ "2>&1") {
|
||||
$pid = open CMD, "$shellCommand |" or die "Could not run command $shellCommand: $!";
|
||||
} else {
|
||||
open CMD, "$shellCommand 2>&1 |" or die "Could not close command $shellCommand: $!";
|
||||
$pid = open CMD, "$shellCommand 2>&1 |" or die "Could not close command $shellCommand: $!";
|
||||
}
|
||||
|
||||
if (defined($logfile)) {
|
||||
open(LOGFILE, ">> $logfile") or die "Could not open logfile $logfile: $!";
|
||||
LOGFILE->autoflush(1);
|
||||
}
|
||||
while (<CMD>) {
|
||||
$output .= $_;
|
||||
print $_ if ($printOutputImmediately);
|
||||
if (defined($logfile)) {
|
||||
print LOGFILE $_;
|
||||
}
|
||||
}
|
||||
if (defined($logfile)) {
|
||||
close(LOGFILE) or die "Could not close logfile $logfile: $!";
|
||||
}
|
||||
|
||||
close CMD;# or die "Could not close command: $!";
|
||||
|
@ -51,13 +62,14 @@ sub RunShellCommand {
|
|||
if ($@) {
|
||||
if ($@ eq "alarm\n") {
|
||||
$timedOut = 1;
|
||||
kill(9, $pid) or die "Could not kill timed-out $pid: $!";
|
||||
} else {
|
||||
warn "Error running $shellCommand: $@\n";
|
||||
$output = $@;
|
||||
}
|
||||
}
|
||||
|
||||
if ($exitValue || $timedOut || $dumpedCore || $signalNum) {
|
||||
if ($exitValue or $timedOut or $dumpedCore or $signalNum) {
|
||||
if ($timedOut) {
|
||||
# callers expect exitValue to be non-zero if request timed out
|
||||
$exitValue = 1;
|
||||
|
@ -68,7 +80,32 @@ sub RunShellCommand {
|
|||
exitValue => $exitValue,
|
||||
sigName => $sigName,
|
||||
output => $output,
|
||||
dumpedCore => $dumpedCore };
|
||||
dumpedCore => $dumpedCore,
|
||||
pid => $pid,
|
||||
};
|
||||
}
|
||||
|
||||
## This is a wrapper function to get easy true/false return values from a
|
||||
## mkpath()-like function. mkpath() *actually* returns the list of directories
|
||||
## it created in the pursuit of your request, and keeps its actual success
|
||||
## status in $@.
|
||||
|
||||
sub MkdirWithPath
|
||||
{
|
||||
my %args = @_;
|
||||
|
||||
my $dirToCreate = $args{'dir'};
|
||||
my $printProgress = $args{'printProgress'};
|
||||
my $dirMask = $args{'dirMask'};
|
||||
|
||||
die "ASSERT: MkdirWithPath() needs an arg" if not defined($dirToCreate);
|
||||
|
||||
## Defaults based on what mkpath does...
|
||||
$printProgress = defined($printProgress) ? $printProgress : 0;
|
||||
$dirMask = defined($dirMask) ? $dirMask : 0777;
|
||||
|
||||
eval { mkpath($dirToCreate, $printProgress, $dirMask) };
|
||||
return defined($@);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -4,10 +4,33 @@ Bootstrap Release
|
|||
Bootstrap is a release automation tool.
|
||||
Use "release -h" for help.
|
||||
|
||||
Tools run first
|
||||
Pre-flight Checklist
|
||||
-----------------
|
||||
* checklist/config generator
|
||||
* version bump tool
|
||||
There are a number of manual steps that must be performed, so a default
|
||||
end-to-end run will generally not work.
|
||||
|
||||
Before any steps:
|
||||
|
||||
* verify shipped-locales
|
||||
* edit bootstrap.cfg
|
||||
* edit tinder-config.pl/mozconfig
|
||||
* version bump
|
||||
|
||||
After Build and Repack steps:
|
||||
|
||||
* rsync builds to candidates dir
|
||||
|
||||
After the Update step:
|
||||
|
||||
* edit patcher config
|
||||
* edit mozilla/testing/release/updates/updates.cfg
|
||||
|
||||
After Sign step:
|
||||
|
||||
* create bouncer links
|
||||
* rsync builds to mirrors
|
||||
* wait 12 hours for mirrors to catch up
|
||||
* rsync production AUS config
|
||||
|
||||
Steps are in dependency order. The process may be restarted at any step as
|
||||
long as all previous steps are satisfied.
|
||||
|
@ -16,53 +39,46 @@ PASS/FAIL verification is run after every step.
|
|||
|
||||
Steps
|
||||
-----------------
|
||||
1) tag
|
||||
2) build
|
||||
2.1) push
|
||||
2.2) announce
|
||||
3) source
|
||||
4) repack
|
||||
4.1) push
|
||||
4.2) announce
|
||||
5) updates
|
||||
5.1) push
|
||||
5.2) announce
|
||||
6) stage
|
||||
6.1) merge
|
||||
6.2) announce
|
||||
7) sign
|
||||
8) release
|
||||
8.1) announce
|
||||
1) Tag
|
||||
2) Build
|
||||
2.1) Push
|
||||
2.2) Announce
|
||||
3) Source
|
||||
4) Repack
|
||||
4.1) Push
|
||||
4.2) Announce
|
||||
5) Updates
|
||||
5.1) Push
|
||||
5.2) Announce
|
||||
6) Stage
|
||||
6.1) Merge
|
||||
6.2) Announce
|
||||
7) Sign
|
||||
|
||||
Details
|
||||
-----------------
|
||||
tag
|
||||
_RELEASE and _RCn for mozilla and talkback
|
||||
build
|
||||
Tag
|
||||
_RELEASE and _RCn for mozilla, l10n and talkback
|
||||
Build
|
||||
en-US build from source (based on tag)
|
||||
push to stage
|
||||
announce
|
||||
source
|
||||
bz2 archive based on tag
|
||||
Source
|
||||
bz2 archive (based on tag)
|
||||
push to stage
|
||||
repack
|
||||
repack l10n, uses en-US build
|
||||
Repack
|
||||
repack l10n, uses en-US build (based on tag)
|
||||
push to stage
|
||||
announce
|
||||
updates
|
||||
Updates
|
||||
uses patcher
|
||||
generate partials and AUS config ("snippets")
|
||||
push to stage
|
||||
announce
|
||||
stage
|
||||
Stage
|
||||
uses groom-files
|
||||
create release directory/filename structure
|
||||
merge updates
|
||||
announce
|
||||
sign
|
||||
Sign
|
||||
manual
|
||||
release
|
||||
create bouncer links
|
||||
rsync builds to mirrors
|
||||
rsync production AUS config
|
||||
announce
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
<app firefox>
|
||||
<release 1.5.0.7>
|
||||
productTag = FIREFOX_1_5_0_7
|
||||
branchTag = MOZILLA_1_8_0_7
|
||||
pullDate = 2006-09-06 18:00 PDT
|
||||
rc = 1
|
||||
version = 1.5.0.7
|
||||
appName = browser
|
||||
product = firefox
|
||||
buildDir = /builds/tinderbox/
|
||||
pushDate = 2006090601
|
||||
</release>
|
||||
<app>
|
||||
productTag = FIREFOX_1_6_0_7
|
||||
branchTag = MOZILLA_1_8_0_BRANCH
|
||||
pullDate = 2006-11-03 12:00 PDT
|
||||
rc = 1
|
||||
version = 1.6.0.7
|
||||
oldVersion = 1.5.0.7
|
||||
appName = browser
|
||||
product = firefox
|
||||
buildDir = /builds/tinderbox/Fx-Mozilla1.8.0-Release
|
||||
l10n-buildDir = /builds/tinderbox/Fx-Mozilla1.8.0-l10n-Release
|
||||
pushDate = 2006-10-30-22
|
||||
logDir = /builds/release/logs
|
||||
mozillaCvsroot = /builds/cvsmirror/cvsroot
|
||||
l10nCvsroot = /builds/cvsmirror/l10n
|
||||
mofoCvsroot = /builds/cvsmirror/mofo
|
||||
stageHome = /data/cltbld
|
||||
updateDir = /builds/updates
|
||||
verifyDir = /builds/verify
|
||||
patcherConfig = moz180-branch-patcher2.cfg
|
||||
tagDir = /builds/tags
|
||||
buildPlatform = Linux_2.4.21-37.EL_Depend
|
||||
</app>
|
||||
|
|
|
@ -33,7 +33,7 @@ sub main {
|
|||
sub ProcessArgs {
|
||||
GetOptions(
|
||||
\%config,
|
||||
"step|s=s", "only|o=s", "list|l", "help|h",
|
||||
"step|s=s", "only|o=s", "list|l", "help|h", "execute|e", "verify|v",
|
||||
);
|
||||
|
||||
if ($config{'list'}) {
|
||||
|
@ -45,10 +45,12 @@ sub ProcessArgs {
|
|||
}
|
||||
|
||||
if ($config{'help'}) {
|
||||
print "Usage: release [-l] [-s Step] [-o Step] [-h]\n";
|
||||
print "Usage: release [-l] [-s Step] [-o Step] [-e | v] [-h]\n";
|
||||
print " -l list all Steps\n";
|
||||
print " -s start at Step\n";
|
||||
print " -o only run one Step\n";
|
||||
print " -e only run Execute\n";
|
||||
print " -v only run Verify\n";
|
||||
print " -h this usage message\n";
|
||||
exit(0);
|
||||
}
|
||||
|
@ -103,8 +105,16 @@ sub PerformStep {
|
|||
print "Bootstrap running $stepName\n";
|
||||
my $step = "Bootstrap::Step::$stepName"->new();
|
||||
eval {
|
||||
$step->Execute();
|
||||
$step->Verify();
|
||||
if (defined($config{'execute'})) {
|
||||
print "Bootstrap only running Execute\n";
|
||||
$step->Execute();
|
||||
} elsif (defined($config{'verify'})) {
|
||||
print "Bootstrap only running Verify\n";
|
||||
$step->Verify();
|
||||
} else {
|
||||
$step->Execute();
|
||||
$step->Verify();
|
||||
}
|
||||
};
|
||||
if ($@)
|
||||
{
|
||||
|
|
|
@ -12,7 +12,7 @@ sub Execute {
|
|||
}
|
||||
|
||||
eval {
|
||||
$this->Shell( 'cmd' => 'true' );
|
||||
$this->Shell( 'cmd' => 'true', logFile => 't/test.log' );
|
||||
};
|
||||
|
||||
if ($@) {
|
||||
|
@ -20,7 +20,7 @@ sub Execute {
|
|||
}
|
||||
|
||||
eval {
|
||||
$this->Shell( 'cmd' => 'false' );
|
||||
$this->Shell( 'cmd' => 'false', logFile => 't/test.log' );
|
||||
};
|
||||
|
||||
if (not $@) {
|
||||
|
@ -63,7 +63,7 @@ sub Execute {
|
|||
|
||||
sub Verify {
|
||||
my $this = shift;
|
||||
$this->Shell('cmd' => 'echo Verify tag');
|
||||
$this->Shell('cmd' => 'echo Verify tag', logFile => 't/test.log');
|
||||
$this->Log('msg' => 'finished');
|
||||
}
|
||||
|
||||
|
|
|
@ -2,3 +2,10 @@ success
|
|||
failed
|
||||
success
|
||||
failed
|
||||
Verify tag
|
||||
Verify tag
|
||||
Verify tag
|
||||
Verify tag
|
||||
Verify tag
|
||||
Verify tag
|
||||
Verify tag
|
||||
|
|
Загрузка…
Ссылка в новой задаче