summaryrefslogtreecommitdiffstats
path: root/src/build/tools
diff options
context:
space:
mode:
authorCamVan Nguyen <ctnguyen@us.ibm.com>2018-10-18 13:53:39 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-10-23 11:43:37 -0500
commitc9d3c11613e9a47cf380b0cc60900eeb419d5e72 (patch)
tree796baf030b217a61c887a018efe46c3ee4bfff45 /src/build/tools
parent24f1a6c7c10b70339c61b29593247cce46416686 (diff)
downloadtalos-hostboot-c9d3c11613e9a47cf380b0cc60900eeb419d5e72.tar.gz
talos-hostboot-c9d3c11613e9a47cf380b0cc60900eeb419d5e72.zip
Remove auto-release & hbRelease tools
These tools have been ported to pfd_infra_tools Change-Id: I5bc519689b8f13b48eb97a194b9b9f8ad0cb2840 RTC: 200487 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67707 Reviewed-by: Sameer R Veer <sveer@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/build/tools')
-rwxr-xr-xsrc/build/tools/hbRelease2983
1 files changed, 0 insertions, 2983 deletions
diff --git a/src/build/tools/hbRelease b/src/build/tools/hbRelease
deleted file mode 100755
index 3c0e024ff..000000000
--- a/src/build/tools/hbRelease
+++ /dev/null
@@ -1,2983 +0,0 @@
-#!/usr/bin/perl
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/build/tools/hbRelease $
-#
-# OpenPOWER HostBoot Project
-#
-# Contributors Listed Below - COPYRIGHT 2012,2018
-# [+] International Business Machines Corp.
-#
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# IBM_PROLOG_END_TAG
-
-use strict;
-
-use Getopt::Long qw(:config pass_through);
-use POSIX;
-use Text::Wrap;
-use List::Util 'max';
-use Term::ReadKey;
-use File::Temp qw/tempfile/;
-
-use Data::Dumper;
-
-my $debug = 0;
-my $help = 0;
-
-my %globals = ( branch => "master",
- component => "esw_hbfw",
- cmvcUser => "hostboot",
- email => "hostboot\@us.ibm.com" );
-# Token used by git-CI-tool @execute_discover, update there too
-my $TOKEN = "!@#%^";
-
-# List of files to check into CMVC separated by whitespace
-my $CMVC_FILES = "src/hbfw/img/hostboot.bin ".
- "src/hbfw/img/hostboot_extended.bin ".
- "src/hbfw/img/hostboot_runtime.bin ".
- "src/hbfw/img/makefile ".
- "src/hbfw/fsp.tar ".
- "src/hbfw/makefile ".
- "src/hbfw/releaseNotes.html ".
- "src/hbfw/simics.tar ";
-
-
-if((defined $ENV{'FIPS_RELEASE'}) and
- ($ENV{'FIPS_RELEASE'} =~ m/fips9/))
-{
- # Include all standalone images into the release as well
- $CMVC_FILES .= "src/hbfw/nimbus/nimbus.pnor ".
- "src/hbfw/nimbus/simics.tar ".
- "src/hbfw/cumulus/cumulus.pnor ".
- "src/hbfw/cumulus/simics.tar ".
- "src/hbfw/cumulus_cdimm/cumulus_cdimm.pnor ".
- "src/hbfw/cumulus_cdimm/simics.tar ".
- "src/hbfw/axone/axone.pnor ".
- "src/hbfw/axone/simics.tar ";
-}
-
-# Directory to look up latest release tag for a specific release
-my $HOSTBOOT_GSA_HOME = "/gsa/ausgsa/home/h/o/hostboot";
-my $LATEST_BUILD_DIR = "$HOSTBOOT_GSA_HOME/auto-hb-release/latest-builds";
-
-GetOptions("debug!" => \$debug,
- "help" => \$help,
- "branch:s" => \$globals{"branch"},
- "component:s" => \$globals{"component"},
- "cmvcUser:s" => \$globals{"cmvcUser"},
- "email:s" => \$globals{"email"});
-
-my %commands = ( "define" => \&execute_define,
- "undef" => \&execute_undef,
- "list-levels" => \&config_print_levels,
- "query-gerrit" => \&execute_gerrit_query,
- "query-git" => \&execute_git_query,
- "query-level" => \&execute_level_query,
- "add-patch" => \&execute_add_patch,
- "add-forcedep" => \&execute_add_forcedep,
- "verify-patches" => \&execute_verify_patches,
- "release" => \&execute_release,
- "publish-cq" => \&execute_publish_cq,
- "build-name" => \&execute_build_name,
- "fsp-ci" => \&execute_fsp_ci,
- "gerrit-commit" => \&execute_gerrit_commit,
- "pre-release" => \&execute_pre_release,
- "post-release" => \&execute_post_release,
- "create-track" => \&execute_create_track,
- "checkinBuildToTrack" => \&execute_checkinBuildToTrack,
- "help" => \&execute_help,
- );
-
-if ($help)
-{
- execute_help();
-}
-
-my $command = shift @ARGV;
-if ($commands{$command})
-{
- &{$commands{$command}}();
-}
-else
-{
- execute_help();
-}
-
-foreach my $arg (@ARGV)
-{
- print "Unprocessed arg: $arg\n" if $debug;
-}
-
-############################## Begin Actions ##################################
-
-sub execute_define
-{
- print "Defining new level...\n";
-
- my %level = ();
-
- GetOptions("level:s" => \$level{name},
- "name:s" => \$level{name},
- "baseline:s" => \$level{base},
- "released:s" => \$level{released});
-
- die "Missing level name" if ($level{name} eq "");
- die "Missing baseline name" if ($level{base} eq "");
- die "Missing released level name" if ($level{released} eq "");
-
- print "New level: ".$level{name}.":".$level{base}.":".$level{released}."\n"
- if $debug;
-
- $level{base} = git_resolve_ref($level{base});
- $level{released} = git_resolve_ref($level{released});
-
- config_add_level(\%level);
-}
-
-sub execute_undef
-{
- my $level = shift @ARGV;
-
- die "Level to undefine not given" if ($level eq "");
-
- my $levels = config_list_levels();
- die "Level $level does not exist" if (not defined $levels->{$level});
-
- print "Undefining level $level...\n";
- config_del_level($level);
-}
-
-sub execute_gerrit_query
-{
- my $project = "";
-
- GetOptions("project:s" => \$project);
-
- if ("" eq $project)
- {
- $project = config_project();
- }
-
- my $items = gerrit_query("status:open project:$project ".
- "branch:".$globals{"branch"});
-
- foreach my $item (@$items)
- {
- if (defined $item->{"project"})
- {
- print wrap("","",$item->{"subject"}) . "\n";
- print "\t" . $item->{"id"} . "\n";
- print "\n";
- }
- }
-}
-
-sub execute_git_query
-{
- my $level = "";
-
- GetOptions("name:s" => \$level,
- "level:s" => \$level);
-
- die "Missing level name" if ($level eq "");
-
- $globals{"branch"} = git_resolve_ref($globals{"branch"});
-
- my $level = config_get_level($level);
-
- my $commits = git_commit_history($globals{"branch"}, $level->{base});
-
- foreach my $commit (@{$commits})
- {
- my $subject = git_get_subject($commit);
- print "$subject\n\t$commit\n\n";
- }
-}
-
-sub execute_level_query
-{
- my $level = "";
-
- GetOptions("name:s" => \$level,
- "level:s" => \$level);
-
- die "Missing level name" if ($level eq "");
-
- my $level_info = config_get_level($level);
-
- print "Level $level\n";
- print " Base: \n";
- print " ".git_name_rev($level_info->{base})."\n";
- print " Released:\n";
- print " ".git_name_rev($level_info->{released})."\n";
- if ($globals{"branch"} ne "master")
- {
- print " Branch:\n";
- print " ".$globals{"branch"}."\n";
- }
- print " Patches:\n";
- foreach my $patch (sort @{$level_info->{patches}})
- {
- print " $patch\n";
- }
- print " Forced Deps:\n";
- foreach my $dep (sort keys %{$level_info->{forceDeps}})
- {
- my $deps = $level_info->{forceDeps};
- print " $dep =>\n";
- print " ".$deps->{$dep}."\n";
- }
-}
-
-
-sub execute_add_patch
-{
- my $level = "";
- my $patch = "";
-
- GetOptions("name:s" => \$level,
- "level:s" => \$level,
- "patch:s" => \$patch);
-
- die "Missing level name" if ($level eq "");
- die "Missing patch name" if ($patch eq "");
-
- config_add_patch($level, $patch);
-}
-
-sub execute_add_forcedep
-{
- my $level = "";
- my $from = "";
- my $to = "";
-
- GetOptions("name:s" => \$level,
- "level:s" => \$level,
- "from:s" => \$from,
- "to:s" => \$to);
-
- die "Missing level name" if ($level eq "");
- die "Missing from depend" if ($from eq "");
- die "Missing to depend" if ($to eq "");
-
- config_add_dep($level, $from, $to);
-}
-
-sub execute_verify_patches
-{
- my $level = "";
-
- GetOptions("name:s" => \$level,
- "level:s" => \$level);
-
- die "Missing level name" if ($level eq "");
-
- my $level_info = config_get_level($level);
- my $patches = $level_info->{patches};
-
- $patches = gerrit_resolve_patches($patches);
-
- config_verify_patches($level_info->{base}, $patches);
-}
-
-sub execute_release
-{
- my $level = "";
-
- GetOptions("name:s" => \$level,
- "level:s" => \$level);
-
- die "Missing level name" if ($level eq "");
-
- my $level_info = config_get_level($level);
-
- config_release($level_info,1);
-}
-
-sub execute_publish_cq
-{
- my $level = "";
- my $track = "";
- my $released = "";
-
- GetOptions("name:s" => \$level,
- "level:s" => \$level,
- "track:s" => \$track,
- "released:s" => \$released);
-
- die "Missing level name" if ($level eq "");
- die "Missing track" if ($track eq "");
-
- my $level_info = config_get_level($level);
-
- $released = $level_info->{released} if ($released eq "");
-
- publish_cq($level, $track, $released);
-}
-
-sub execute_build_name
-{
- my $release = "840";
- my $build_letter = "a";
-
- GetOptions("release:s" => \$release,
- "letter:s" => \$build_letter);
-
- system ("date +hb%m%d".$build_letter."_%g%V.$release");
-}
-
-sub execute_fsp_ci
-{
-
- my $patches = "";
- my $discover = 0;
- my %level = ();
- my $branch = $globals{"branch"};
- my $bbuild_hbRel = "";
-
- GetOptions("level:s" => \$level{name},
- "patches:s" => \$patches,
- "discover" => \$discover,
- "basestr:s" => \$level{base},
- "bbuild-hbRel:s" => \$bbuild_hbRel);
-
- die "Missing level name" if ($level{name} eq "");
- die "Missing level base" if ($level{base} eq "");
- die "Missing patches" if ($patches eq "");
- die "Missing bbuild's hostboot release" if ($bbuild_hbRel eq "");
-
- print "Creating Hostboot CI release...\n" if !$discover;
-
- # Parse out csv list of patches
- my @patches = split(/,+/, $patches);
-
- print ">>>Patches\n" if $debug;
- print Dumper @patches if $debug;
- print "<<<End of Patches\n" if $debug;
-
- # Define release
- print "Basestr: " if $debug;
- $level{base} = git_resolve_ref($level{base});
- $level{released} = $level{base};
- config_add_level(\%level);
-
- # Get all commits between level base and the bbuilds hb release
- my @commits = split('\n',`git rev-list $level{base} ^$bbuild_hbRel`);
- # Check all commits between gerrit/<branch> and bbuild's hbRel for any
- # cmvc req's that are needed in the discover step only.
- if ($discover)
- {
- # Check each commit message for CMVC reqs
- foreach my $commit (@commits)
- {
- my @msg_lines = split('\n',git_commit_msg($commit));
- # Search commit message for dependencies
- foreach my $line (@msg_lines)
- {
- # Print out CMVC dependencies
- if ($line =~ m/cmvc-([a-zA-Z]+):/i)
- {
- print "$TOKEN Need ".$line."\n";
- }
- }
- }
- }
- # Print out commits that are in the gerrit branch and not the bbuild hbRel
- else
- {
- print "\n========\n";
- print "Commits in gerrit/$branch but not in bbuild => $bbuild_hbRel\n\n";
- print "**Note these commits may cause problems too, but since they\n";
- print " are merged commits, they should have passed fsp-ci prior.\n";
- print " It is done this way to greatly simply dependencies of your\n";
- print " commit ontop of a hostboot release\n\n";
- my $i=1;
- foreach my $commit (@commits)
- {
- print " $i. $commit\n";
- $i++;
- }
- print "\n";
- }
-
- # Resolve level dependencies
- config_resolve_level_dep($level{name}, $level{base}, @patches);
-
- if(!$discover)
- {
- # Create hb release
- my $level_info = config_get_level($level{name});
- config_release($level_info,0);
- }
-}
-
-sub execute_pre_release
-{
- my $release = "";
- my $level = "";
- my $checkInDir = "";
- my $released = "";
- my $track = "";
- #
- #Pass $cmvcCheckinForceFlag from Jenkins to check in files w/ '-force' option
- #within CMVC to break the file links
-
- my $cmvcCheckinForceFlag = "";
-
- if ( $ENV{CMVC_CHECKIN_FORCEFLAG} eq "-force" )
- {
- $cmvcCheckinForceFlag = "$ENV{CMVC_CHECKIN_FORCEFLAG}";
- }
-
- GetOptions("release:s" => \$release);
- GetOptions("level:s" => \$level);
- GetOptions("checkInDir:s" => \$checkInDir);
- GetOptions("released:s" => \$released);
- GetOptions("track:s" => \$track);
-
- die "Missing release" if ($release eq "");
- die "Missing level" if ($level eq "");
- die "Missing check in directory" if ($checkInDir eq "");
- die "Missing released" if ($released eq "");
-
- if($release =~ m/fips9/)
- {
- $CMVC_FILES .= "src/hbfw/img/hostboot_bootloader.bin ";
- $CMVC_FILES .= "src/hbfw/img/hostboot_securerom.bin ";
- }
-
-
- my $feature = "";
- if($track eq "")
- {
- # CMVC open feature
- my $open_feature = "Feature -open -component $globals{component}";
- $open_feature .= " -remarks \"Hostboot Release - $level\" -verbose";
- # Get the Feature number from the output, should be the only numbers.
- $feature = run_system_command($open_feature);
- $feature =~ s/[^0-9]//g;
-
- # CMVC assign feature
- run_system_command("Feature -assign $feature -owner $globals{cmvcUser} -verbose");
-
- # CMVC accept feature
- run_system_command("Feature -accept $feature -verbose");
-
- # CMVC create track
- run_system_command("Track -create -release $release -feature $feature -verbose");
- }
- else
- {
- $feature = $track;
- }
-
- # Add in cmvc coReqs and cmvc preReqs
- execute_cmvc_reqs($feature,$level,$released,$release);
-
- #Lock Files
- run_system_command("File -lock $CMVC_FILES -release $release -feature $feature -verbose");
-
- #Check In Files
- chdir ($checkInDir);
- run_system_command("File -checkin $CMVC_FILES -top $checkInDir -release $release -feature $feature -verbose $cmvcCheckinForceFlag");
-
- my $featureFile = $ENV{CMVC_FEATURE_FILE};
- open(CMVC_FEATURE,">",$featureFile)
- or die("Cannot open: $featureFile: $!");
- print CMVC_FEATURE "FEATURE=$feature";
- close(CMVC_FEATURE);
-
- #Complete Fix Records
- run_system_command("Fix -complete -feature $feature -release $release -component esw_hbfw -verbose");
-
- #Integrate the track
- run_system_command("Track -integrate -feature $feature -release $release -verbose");
-
- #Get ClearQuest ID
- my $response = run_system_command("Feature -view $feature");
- my ($cq_id) = $response =~ /CQID\s+(.*)/;
- print $cq_id if $debug;
-
- #Print out Debug information
- print_debug_info($level, $feature, $cq_id, $released);
-}
-
-sub execute_create_track
-{
- my $level = "";
- my $release = "";
- my $released = "";
- my $track = "";
-
- GetOptions("level:s" => \$level);
- GetOptions("release:s" => \$release);
- GetOptions("released:s" => \$released);
- GetOptions("track:s" => \$track);
-
- die "Missing level" if ($level eq "");
- die "Missing release" if ($release eq "");
- die "Missing released" if ($released eq "");
-
- #
- my $feature = "";
- my $rel_needs_appr = "";
- my $approval_flag = "yes";
-
- if($track eq "")
- {
- # CMVC open feature
- my $open_feature = "Feature -open -component $globals{component}";
- $open_feature .= " -remarks \"Hostboot Release - $level\" -verbose";
- # Get the Feature number from the output, should be the only numbers.
- print "open_feature=> $open_feature\n";
- $feature = run_system_command($open_feature);
- $feature =~ s/[^0-9]//g;
- #
- print "\n\n--------------------------------------\n";
- print "level (passed as \"RELEASE_NAME\") => $level\n";
- print "release (passed as \"FIPS_RELEASE\") => $release\n";
- print "released (passed as \"PREVIOUS_RELEASE\") => $released\n";
- print "owner=> $globals{cmvcUser}\n";
- print "feature=> $feature\n\n";
- print "\n--------------------------------------\n\n";
-
- # CMVC assign feature
- print "#####-> run_system_command(\"Feature -assign $feature -owner $globals{cmvcUser} -verbose\")\n";
- run_system_command("Feature -assign $feature -owner $globals{cmvcUser} -verbose");
-
- # CMVC accept feature
- print "#####-> run_system_command(\"Feature -accept $feature -verbose\");\n";
- run_system_command("Feature -accept $feature -verbose");
-
- # CMVC create track
- print "#####-> run_system_command(\"Track -create -release $release -feature $feature -verbose\")\n";
- run_system_command("Track -create -release $release -feature $feature -verbose");
-
- # CMVC check track
- print "#####-> $rel_needs_appr = run_system_command(\"Report -g ReleaseView -where \"name='$release'\" -select approve\")\n";
- chomp($rel_needs_appr = run_system_command("Report -g ReleaseView -where \"name='$release'\" -select approve"));
- print "\nrel_needs_appr=> \"$rel_needs_appr\"\n";
- print "\napproval_flag=> \"$approval_flag\"\n";
- }
- else
- {
- $feature = $track;
- }
- #
- my $featureFile = $ENV{CMVC_FEATURE_FILE};
- open(CMVC_FEATURE,">",$featureFile)
- or die("Cannot open: $featureFile: $!");
- print CMVC_FEATURE "FEATURE=$feature";
- close(CMVC_FEATURE);
-
- my $rel_needs_appr_file = $ENV{REL_NEEDS_APPR_FILE};
- open(REL_NEEDS_APPR,">",$rel_needs_appr_file)
- or die("Cannot open: $rel_needs_appr_file: $!");
- print REL_NEEDS_APPR "REL_NEEDS_APPR=$rel_needs_appr";
- close(REL_NEEDS_APPR);
-
- my $notify_email_file = $ENV{'NOTIFY_EMAIL_FILE'};
- open(NOTIFY_EMAIL_TXT,">",$notify_email_file)
- or die("Cannot open: $notify_email_file: $!");
-
- chomp(my $datenow = run_system_command("date"));
- #
- open(TXTRELNOTE, "< ", $ENV{'RELEASENOTESTXT'});
- my $txtrelnote = <TXTRELNOTE>;
- close(TXTRELNOTE);
- #
- my $NEXTJOB=\
- "https://hostboot-jenkins.swg-devops.com/job/Hostboot/job/Release/job/\
- auto-release-HB/job/rel-fips/job/rel-fips-4-checkinBuildToTrack/\
- build?delay=0sec";
- if($rel_needs_appr eq $approval_flag)
- {
- print "(in IF loop)\nYes, found \$rel_needs_appr eq \$approval_flag: ($rel_needs_appr eq $approval_flag)\n";
- print "MUSTFIX_APPROVERS=> $ENV{'MUSTFIX_APPROVERS'}\n";
- print "RELEASE_ADMINS=> $ENV{'RELEASE_ADMINS'}\n";
- my $MAIL_SUB = "Action Required: Your approval required for Track \
- $ENV{'FIPS_RELEASE'}:$feature";
- print NOTIFY_EMAIL_TXT "[$datenow]\n\n\nDear Approver(s) [$ENV{MUSTFIX_APPROVERS}],\n\tThere is a new track/feature opened pending your approval for a mustfix release.\n\tDetails are below, please approve it ASAP, thanks!\n";
- print NOTIFY_EMAIL_TXT "\n\t(Note: Jenkins job will time-out if approval not obtained within a day of receiving this notice)\n\n";
- print NOTIFY_EMAIL_TXT "\tFIPS_RELEASE=$ENV{FIPS_RELEASE}\n\tFEATURE=$feature\n";
- print NOTIFY_EMAIL_TXT "\n\n$txtrelnote\n\n";
- print NOTIFY_EMAIL_TXT "#--------------------------#";
- print NOTIFY_EMAIL_TXT "\n\n\nDear Release_admin(s) [$ENV{'RELEASE_ADMINS'}],\n\tOnce this track is approved, please use following information if/as required to \tretrigger the release job (e.g. if it had timed out beyond the wait-time of 1 day):\n\n";
- print NOTIFY_EMAIL_TXT "\n\tNEXTJOB=$NEXTJOB";
- print NOTIFY_EMAIL_TXT "\n\tREL_FIPS_TRIGGER_PROJ=$ENV{REL_FIPS_TRIGGER_PROJ}\n\tREL_FIPS_TRIGGER_BUILD_NUM=$ENV{REL_FIPS_TRIGGER_BUILD_NUM}\n";
- print NOTIFY_EMAIL_TXT "\n\n\n(A copy of this email has been sent to:\n\t$ENV{'MUSTFIX_APPROVERS'}\n\t$ENV{'RELEASE_ADMINS'}\n\t)\n\n\n";
- print NOTIFY_EMAIL_TXT "#-----------<E-O-F>---------------#\n";
- close(NOTIFY_EMAIL_TXT);
- run_system_command("cat $notify_email_file | mail -s \"$MAIL_SUB\" $ENV{'MUSTFIX_APPROVERS'} $ENV{'RELEASE_ADMINS'}");
- }
- else
- {
-
- print "(in ELSE loop)\nSorry, \$rel_needs_appr ne \$approval_flag: ($rel_needs_appr ne $approval_flag)\n";
- print NOTIFY_EMAIL_TXT "#--------------------------#\n";
- print NOTIFY_EMAIL_TXT "[$datenow]\n\n\nNo approval required for:\nFIPS_RELEASE=$ENV{FIPS_RELEASE}\nFEATURE=$feature\n";
- print NOTIFY_EMAIL_TXT "\n\n$txtrelnote\n\n";
- print NOTIFY_EMAIL_TXT "\nNEXTJOB=$NEXTJOB";
- print NOTIFY_EMAIL_TXT "\nREL_FIPS_TRIGGER_PROJ=$ENV{REL_FIPS_TRIGGER_PROJ}\nREL_FIPS_TRIGGER_BUILD_NUM=$ENV{REL_FIPS_TRIGGER_BUILD_NUM}\n\n";
- print NOTIFY_EMAIL_TXT "\n\n(Since, no approval required, no email or other notification sent out)\n\n";
- print NOTIFY_EMAIL_TXT "#-----------<E-O-F>---------------#\n";
- close(NOTIFY_EMAIL_TXT);
- }
-
- # Add in cmvc coReqs and cmvc preReqs
- print "#####-> execute_cmvc_reqs($feature,$level,$released,$release)\n";
- execute_cmvc_reqs($feature,$level,$released,$release);
-}
-
-sub execute_checkinBuildToTrack
-{
- my $level = "";
- my $release = "";
- my $checkInDir = "";
- my $released = "";
- #
- #Pass $cmvcCheckinForceFlag from Jenkins to check in files w/ '-force' option
- #within CMVC to break the file links
-
- my $cmvcCheckinForceFlag = "";
-
- if ( $ENV{CMVC_CHECKIN_FORCEFLAG} eq "-force" )
- {
- $cmvcCheckinForceFlag = "$ENV{CMVC_CHECKIN_FORCEFLAG}";
- }
-
- GetOptions("level:s" => \$level);
- GetOptions("release:s" => \$release);
- GetOptions("checkInDir:s" => \$checkInDir);
- GetOptions("released:s" => \$released);
-
- die "Missing level" if ($level eq "");
- die "Missing release" if ($release eq "");
- die "Missing check in directory" if ($checkInDir eq "");
- die "Missing released" if ($released eq "");
-
- my $featureFile = $ENV{CMVC_FEATURE_FILE};
- open(CMVC_FEATURE,"<",$featureFile)
- or die("Cannot open: $featureFile: $!");
- #Read the feature from the file:
- my $keyval = <CMVC_FEATURE>;
- my ($key, $feature) = split /=/, $keyval ;
- close(CMVC_FEATURE);
-
- if($release =~ m/fips9/)
- {
- $CMVC_FILES .= "src/hbfw/img/hostboot_bootloader.bin ";
- $CMVC_FILES .= "src/hbfw/img/hostboot_securerom.bin ";
- }
-
- print "\n\n--------------------------------------\n";
- print "level (passed as \"RELEASE_NAME\") => $level\n";
- print "release (passed as \"FIPS_RELEASE\") => $release\n";
- print "checkInDir (passed as \"CMVC_DIR\") => $checkInDir\n";
- print "released (passed as \"PREVIOUS_RELEASE\") => $released\n";
- print "feature (read from the \"$ENV{CMVC_FEATURE_FILE}\" file => $feature\n";
- print "CMVC_FILES => $CMVC_FILES\n";
- print "\n--------------------------------------\n\n";
-
- #Lock Files
- print "#####-> run_system_command(\"File -lock $CMVC_FILES -release $release -feature $feature -verbose\")\n";
- run_system_command("File -lock $CMVC_FILES -release $release -feature $feature -verbose");
- #Check In Files
- print "Present working directory:\n";
- run_system_command("pwd");
- print "Switching directory to \"$checkInDir\" .....\n";
- chdir ($checkInDir);
- run_system_command("pwd");
- print "#####-> run_system_command(\"File -checkin $CMVC_FILES -top $checkInDir -release $release -feature $feature -verbose $cmvcCheckinForceFlag\")\n";
- run_system_command("File -checkin $CMVC_FILES -top $checkInDir -release $release -feature $feature -verbose $cmvcCheckinForceFlag");
-
- #Complete Fix Records
- print "#####-> run_system_command(\"Fix -complete -feature $feature -release $release -component esw_hbfw -verbose\")\n";
- run_system_command("Fix -complete -feature $feature -release $release -component esw_hbfw -verbose");
-
- #Integrate the track
- run_system_command("Track -integrate -feature $feature -release $release -verbose");
-
- #Get ClearQuest ID
- my $response = run_system_command("Feature -view $feature");
- my ($cq_id) = $response =~ /CQID\s+(.*)/;
- print $cq_id if $debug;
-
- #Print out Debug information
- print_debug_info($level, $feature, $cq_id, $released);
-}
-
-sub execute_post_release
-{
- my $feature = "";
- my $release = "";
- my $level = "";
- my $released = "";
-
- GetOptions("feature:s" => \$feature);
- GetOptions("release:s" => \$release);
- GetOptions("level:s" => \$level);
- GetOptions("released:s" => \$released);
-
- die "Missing feature" if ($feature eq "");
- die "Missing release" if ($release eq "");
- die "Missing level" if ($level eq "");
- die "Missing released" if ($released eq "");
-
- #Check for HW image coreq and prereq
- hw_req_check($level, $released);
-
- #Get ClearQuest ID
- my $response = run_system_command("Feature -view $feature");
- my ($cq_id) = $response =~ /CQID\s+(.*)/;
- print $cq_id if $debug;
-
- # Fetch level and Publish release notes to CQ
- chdir($ENV{HOSTBOOT_WORKSPACE});
- run_system_command("git fetch gerrit refs/tags/$level");
- run_system_command("git checkout FETCH_HEAD");
- publish_cq($level, $cq_id, $released);
- print_debug_info($level, $feature, $cq_id, $released);
-}
-
-sub execute_gerrit_commit
-{
- my $patches = "";
-
- GetOptions("patches:s" => \$patches);
-
- die "Missing patches" if ($patches eq "");
-
- # Parse out csv list of patches
- my @patches = split(/,+/, $patches);
-
- my $commits = gerrit_resolve_patchset(\@patches);
- foreach my $commit (@$commits)
- {
- print $commit;
- print "," if( \$commit != \$commits->[-1] )
- }
- print "\n";
-}
-
-sub execute_help
-{
- my $command = shift @ARGV;
-
- if ($command eq "")
- {
- print "hbRelease:\n";
- print " Prepare the hostboot codebase for release.\n";
- print "\n";
- print " Syntax:\n";
- print " hbRelease [options] <tool>\n";
- print "\n";
- print " Available subtools:\n";
- foreach my $key (sort keys %commands)
- {
- print " $key\n";
- }
- print "\n";
- print " Global options:\n";
- print " --debug Enable debug mode.\n";
- print " --help Display help on a specific tool.\n";
- print " --branch Branch to use for release.\n";
- print "\n";
- print " Note: Generally a <commit> can be any git or gerrit\n";
- print " reference. A git commit number, tag, branch, or\n";
- print " a gerrit change-id are all valid.\n";
- }
- elsif (not defined $commands{$command})
- {
- die "Unknown subcommand: $command.\n";
- }
- else
- {
- my %help = (
- "define" =>
-q(
- Define a new level for release.
-
- Options:
- --level=<name> Name for the new level [required].
- --base=<commit> Baseline commit [required].
- --released=<commit> Commit of previous release [required].
-),
- "undef" =>
-q(
- Delete a previously defined release level.
-
- Options:
- --level=<name> Name for the level to delete [required].
-),
- "list-levels" =>
-q(
- Displays a list of currently defined levels.
-),
-
- "query-gerrit" =>
-q(
- Displays a list of open change-sets from the Gerrit server.
-),
- "query-git" =>
-q(
- Displays a list of merged commits which are NOT currently destined
- for a release level.
-
- Options:
- --level=<name> Name for the level to query [required].
- --branch=<commit> Branch to query against [default=master].
-),
- "query-level" =>
-q(
- Displays information about a defined release level.
-
- Options:
- --level=<name> Name for the level to query [required].
-),
- "add-patch" =>
-q(
- Adds a commit to the patch-list for a release.
-
- Options:
- --level=<name> Release to add patch to [required].
- --patch=<commit> Commit to add to patch-list [required].
-),
- "add-forcedep" =>
-q(
- Add a commit-pair as a forced dependency for a release.
-
- Options:
- --level=<name> Release to add dependency to [required].
- --from=<commit> Decendent commit in the dependency [required].
- --to=<commit> Ancestor commit in the dependency [required].
-),
- "verify-patches" =>
-q(
- Verify patch-list to ensure all dependencies are met.
-
- This tool will give a list of dependency candidates if an ancestor
- commit is found modifying the same files as a commit in the
- patch-list.
-
- Options:
- --level=<name> The level to verify [required].
-),
- "release" =>
-q(
- Create a branch / tag based on the definition of a release.
-
- Options:
- --level=<name> The level to release [required].
-),
- "publish-cq" =>
-q(
- Update CQ tracks for any released commits to indicate which Hostboot
- build the commit was added to and which CQ track was used to add the
- HB release to CMVC.
-
- Options:
- --level=<name> The level to publish [required].
- --track=<name> The CQ number used release [required].
- --released=<commit> Alternate starting point for publish [optional].
-),
- "build-name" =>
-q(
- Display a properly formatted build name based on the date.
-
- Ex: hb0402a_1412.810
-
- Options:
- --release=<id> Release name [default=810].
- --letter=[a-z] Build letter [default=a].
-),
- "fsp-ci" =>
-q(
- Creates a hb release based on a list of patches
-
- Options:
- --level=<name> The level to create [required].
- --patches=<csv> CSV of patches to add [required].
- --branch=[a-z] Branch to use for release [default=master].
-),
- "gerrit-commit" =>
-q(
- Get commit number of gerrit change-id, patch-set pairs
-
- Options:
- --patches=<change-id:patchset> CSV of change-id:patchset [required].
-),
- "pre-release" =>
-q(
- This is used by the auto-release process and handles HostBoot release
- steps required before FSP-CI is run. Steps include CMVC feature create
- through file checkin
-
- Options:
- --level=<name> The hostboot release tag name [required].
- --release=<name> Fips release (e.g fips860) [required].
- --checkInDir=<name> Top level CMVC checkout directory path [required].
-),
- "post-release" =>
-q(
- This is used by the auto-release process and handles HostBoot release
- steps required after FSP-CI has passed. Steps include CMVC complete,
- integrat and publishing releast notes to CQ
-
- Options:
- --level=<name> The hostboot release tag name [required].
- --release=<name> Fips release (e.g fips860) [required].
- --feature=<number> CMVC feature associated with release [required].
-),
- );
-
- my $release = "";
- my $level = "";
- my $checkInDir = "";
-
- print "hbRelease $command:";
- print $help{$command};
-
- }
-}
-
-
-######################### Begin Utility Subroutines ###########################
-
-
-
-# sub create_release_notes
-#
-# Generates an HTML file (releaseNotes.html) with the release notes for a
-# release.
-#
-# @param [in] level - The level name to release.
-# @param [in] level_info - The level_info hash (see config_get_level).
-#
-sub create_release_notes
-{
- my $level = shift;
- my $level_info = shift;
-
- my $commits = git_commit_history("HEAD", $level_info->{released});
-
- open RELNOTE, "> ".git_root()."/releaseNotes.html";
- open TXTRELNOTE, "> ".$ENV{'RELEASENOTESTXT'};
- print TXTRELNOTE "The list of commits included for approval are:\n";
- print RELNOTE "<html>\n";
- print RELNOTE " <head><title>Release notes for $level</title></head>\n";
- print RELNOTE <<STYLESHEET;
- <style type="text/css">
- table.release {
- border-width: 1px;
- border-spacing: 2px;
- border-style: outset;
- border-color: gray;
- border-collapse: separate;
- background-color: white;
- }
- table.release th {
- border-width: 1px;
- padding: 1px;
- border-style: inset;
- border-color: gray;
- background-color: white;
- }
- table.release td {
- border-width: 1px;
- padding: 1px;
- border-style: inset;
- border-color: gray;
- background-color: white;
- }
- </style>
-STYLESHEET
- print RELNOTE " <body>\n";
-
- print RELNOTE "<h1>Level: $level</h1>\n";
- print RELNOTE "<h2>Included commits:</h2>\n";
- print RELNOTE "<table class='release'>\n";
- print RELNOTE " <tr>\n";
- print RELNOTE " <th>RTC/CQ Number(s)</th>\n";
- print RELNOTE " <th>Subject</th>\n";
- print RELNOTE " <th>Git Commit</th>\n";
- print RELNOTE " </tr>\n";
-
-
- foreach my $commit (@{$commits})
- {
- my $subject = git_get_subject($commit);
- my $rtc = rtc_workitem_num($commit);
- my $rtc_hyper = "";
- my $cq = cq_workitem_num($commit);
- my $cq_hyper = "";
-
- if ($rtc ne "")
- {
- $rtc_hyper = rtc_hyperlink($rtc);
- $rtc_hyper = "<a href='$rtc_hyper' target='_blank'>$rtc</a>";
- }
- if ($cq ne "")
- {
- $cq_hyper = cq_hyperlink($cq);
- $cq_hyper = "<a href='$cq_hyper' target='_blank'>$cq</a>";
-
- if ($rtc_hyper ne "")
- {
- $cq_hyper = "<br>$cq_hyper";
- }
- }
-
- print RELNOTE " <tr>\n";
- print RELNOTE " <td>$rtc_hyper $cq_hyper</td>\n";
- print RELNOTE " <td>$subject</td>\n";
- print RELNOTE " <td>$commit</td>\n";
- print RELNOTE " </tr>\n";
- print TXTRELNOTE "$commit\n";
- }
- print RELNOTE "</table>\n";
-
- print RELNOTE " </body>\n";
- print RELNOTE "</html>\n";
-
- close RELNOTE;
- close TXTRELNOTE;
-
- system "git add ".git_root()."/releaseNotes.html";
- #system "git add ".git_root()."/releaseNotes.txt";
- system "git commit -m \"Release notes for $level\"";
-
-}
-
-# sub git_resolve_ref
-#
-# Transforms a symbolic git reference into a commit number.
-#
-# @param [in] ref - The reference to resolve.
-#
-# @return string - Resolved git commit number.
-#
-sub git_resolve_ref
-{
- my $ref = shift;
- my $resolve = "";
-
- if (gerrit_is_patch($ref))
- {
- my $gerrit = gerrit_resolve_patches([$ref]);
- $resolve = @{$gerrit}[0];
- }
- else
- {
- open COMMAND, "git log -n1 --pretty=\"%H\" $ref |";
- $resolve = <COMMAND>;
- close COMMAND;
- chomp $resolve;
- }
-
- die "Unable to resolve ref $ref" if ($resolve eq "");
- print "Resolved $ref as $resolve\n" if $debug;
-
- return $resolve;
-}
-
-# sub git_root
-#
-# Determines the path of the root of the git repository.
-#
-# @return string - Root of the git repository.
-sub git_root
-{
- return $globals{git_root} if (defined $globals{git_root});
-
- open COMMAND, "git rev-parse --show-toplevel |";
- my $root = <COMMAND>;
- close COMMAND;
- chomp $root;
-
- die "Unable to determine git_root" if ($root eq "");
- print "Found git_root at $root\n" if $debug;
-
- $globals{git_root} = $root;
- return $root;
-}
-
-# sub git_commit_history
-#
-# Determines all the commits between two points in git history.
-#
-# @param[in] start - Beginning commit.
-# @param[in, optional] not_including - Starting point to exclude.
-#
-# @return array - Commit history.
-#
-sub git_commit_history
-{
- my $start = shift;
- my $not_including = shift;
-
- my @commits = ();
-
- unless ($not_including eq "") { $not_including = "^".$not_including; }
-
- open COMMAND, "git rev-list --cherry-pick $start $not_including |";
- while (my $line = <COMMAND>)
- {
- chomp $line;
- push @commits, $line;
- }
- close COMMAND;
-
- return \@commits;
-}
-
-# sub git_log_changeId
-#
-# Determines if a changeId exists in the base
-#
-# @param[in] base
-# @param[in] changeId
-#
-# @return bool - True if in commit history, False otherwise.
-#
-sub git_log_changeId
-{
- my $base = shift;
- my $changeId = shift;
- my $exists = 0;
- open COMMAND, "git log $base | grep \'Change-Id: $changeId\' |";
- if(<COMMAND> ne "")
- {
- $exists = 1;
- }
- close COMMAND;
-
- return $exists;
-}
-
-# sub git_name_rev
-#
-# Transforms a git commit number to a symbolic name for human readability.
-#
-# @param[in] rev - Git revision (commit number) to name.
-# @return string - The symbolic name git uses for that commit number.
-#
-sub git_name_rev
-{
- my $rev = shift;
-
- open COMMAND, "git name-rev $rev |";
- my $line = <COMMAND>; chomp $line;
- close COMMAND;
-
- return $line;
-}
-
-# sub git_commit_deps
-#
-# Determines a list of dependent commits based on common files touched.
-#
-# @param[in] base - The end point, in git history, of commits to compare.
-# @param[in] commit - The commit to find dependents of.
-#
-# @return array - List of dependent commits.
-#
-sub git_commit_deps
-{
- my $base = shift;
- my $commit = shift;
- chomp($base);
- chomp($commit);
-
- my @deps = ();
-
- print "Searching for deps for $commit against $base\n" if $debug;
-
- my @files = split('\n',`git diff-tree --name-only --no-commit-id -r $commit`);
- foreach my $file (@files)
- {
- # If a commit introduces a new file, don't run rev-list as it fails
- # when the file does not exists in base.
- my $file_in_base = `git log $base -n1 --oneline -- $file`;
- next if ($file_in_base eq "");
-
- my $dep_commit = `git rev-list $commit~1 ^$base $file`;
- if ($dep_commit ne "")
- {
- print "Found dep: $dep_commit" if $debug;
-
- chomp $dep_commit;
- push @deps, $dep_commit;
- }
- }
-
- return \@deps;
-}
-
-# sub git_commit_files
-#
-# Find the files touched by a commit.
-#
-# @param[in] commit - The commit to examine.
-# @return array - List of files touched by the commit.
-#
-sub git_commit_files
-{
- my $commit = shift;
-
- my @files = ();
- open COMMAND, "git diff-tree --name-only --no-commit-id -r $commit |";
- while (my $line = <COMMAND>)
- {
- chomp $line;
- push @files, $line;
- }
- close COMMAND;
-
- return \@files;
-}
-
-# sub git_get_subject
-#
-# Get the subject of the commit message associated with a commit.
-# See git log --oneline.
-#
-# @param[in] commit - The commit to examine.
-# @return string - The subject of the commit.
-#
-sub git_get_subject
-{
- my $commit = shift;
-
- open COMMAND, "git log -n1 --pretty=\"%s\" $commit |";
- my $subject = <COMMAND>; chomp($subject);
- close COMMAND;
-
- return $subject;
-}
-
-# sub git_commit_msg
-#
-# Get the entire commit message associated with a commit.
-#
-# @param[in] commit - The commit to examine.
-# @return string - The commit message.
-#
-sub git_commit_msg
-{
- my $commit = shift;
-
- open COMMAND, "git log -n1 --pretty=%B $commit |";
- my $message = "";
- while (my $line = <COMMAND>)
- {
- $message = $message.$line;
- }
- close COMMAND;
-
- return $message;
-}
-
-# sub git_create_branch
-#
-# Create a branch for a release-level.
-#
-# @param[in] level - The release-level to use as basis for the branch name.
-# @param[in] base - The commit to use as the base for the new branch.
-#
-sub git_create_branch
-{
- my $level = shift;
- my $base = shift;
-
- system("git checkout -b __hbRelease_$level $base");
- die "Could not create branch for $level" if ($?);
-}
-
-# sub git_create_tag
-#
-# Create a tag for a release-level.
-#
-# @param[in] level - The release-level to create a tag for.
-# @param[in] level_info - The level-info associated with the level.
-#
-sub git_create_tag
-{
- my $level = shift;
- my $level_info = shift;
-
- # Create an annotated tag, taking annotation from stdin.
- open COMMAND, "| git tag -a $level -F -" || die;
-
- # Add information about the level to the tag.
- print COMMAND "Release: $level\n\n";
- print COMMAND "Base: ".$level_info->{base}."\n";
- print COMMAND "Previous-Release: ".$level_info->{released}."\n";
- print COMMAND "Branch: ".$globals{"branch"}."\n";
- print COMMAND "\n";
- foreach my $patch (@{$level_info->{patches}})
- {
- print COMMAND "Patch: $patch\n";
- }
- my $forceDeps = $level_info->{forceDeps};
- foreach my $from (keys %{$forceDeps})
- {
- print COMMAND "Forced-Dep: $from:".$forceDeps->{$from}."\n";
- }
-
- # Commit annotated tag.
- close COMMAND;
-}
-
-# sub git_cherry_pick
-#
-# Cherry-pick a commit onto the current branch.
-#
-# @param[in] commit - The commit to cherry-pick.
-#
-# @retval false - Error occurred during cherry-pick.
-sub git_cherry_pick
-{
- my $commit = shift;
-
- system("git cherry-pick -x $commit");
- return ($? == 0);
-}
-
-# sub git_order_commits
-#
-# Order a list of commits so that they are in a good order with regard to
-# dependencies. The order returned should be the most likely to not fail
-# a cherry-pick sequence.
-#
-# @param[in] patches - The list of commits to order.
-# @param[in] level_info - The level_info for the release-level being created.
-#
-# @return array - Re-ordered list of commits (from patches).
-#
-sub git_order_commits
-{
- my $patches = shift;
- my $level_info = shift;
- my $forceDeps = $level_info->{forceDeps};
- my %patch_dep = ();
-
- # Create patch -> { distance -> 0, deps -> [] } hash.
- my %patch_hash =
- map { $_ => \{ distance => 0, deps => [] }} @{$patches};
-
- # Determine dependencies and distance for each patch.
- foreach my $patch (@{$patches})
- {
- # Add dependencies for each patch to the hash.
- my $deps = git_commit_deps($level_info->{base}, $patch);
- push @{${$patch_hash{$patch}}->{deps}}, @{$deps};
-
- # Add dependencies to hash for circular depends check later
- foreach my $dep (@{$deps})
- {
- $patch_dep{$patch}{$dep} = 1;
- }
-
- # Determine the distance from previous release for each patch.
- ${$patch_hash{$patch}}->{distance} =
- scalar @{git_commit_history($patch, $level_info->{released})};
- }
-
- # Determine forced dependencies for each patch.
- foreach my $patch (keys %{$forceDeps})
- {
- my $resolve_from = @{gerrit_resolve_patches([$patch])}[0];
- my $resolve_to =
- @{gerrit_resolve_patches([$forceDeps->{$patch}])}[0];
-
- print "Force dep: $resolve_from : $resolve_to\n" if ($debug);
-
- push @{${$patch_hash{$resolve_from}}->{deps}}, $resolve_to;
- # Add dependencies to hash for circular depends check later
- $patch_dep{$resolve_from}{$resolve_to} = 1;
- }
-
- # Calculate Dijkstra's on the patches.
- my $changed = 1;
- while ($changed != 0)
- {
- $changed = 0;
- foreach my $patch (@{$patches})
- {
- my $distance = 1 + max( map
- {
- # If patches have a circular dependency, ignore distance check.
- next if ($patch_dep{$_}{$patch} && $patch_dep{$patch}{$_});
- ${$patch_hash{$_}}->{distance}
- }
- @{${$patch_hash{$patch}}->{deps}});
- if ($distance > ${$patch_hash{$patch}}->{distance})
- {
- $changed = 1;
- ${$patch_hash{$patch}}->{distance} = $distance;
- }
- }
- }
-
- # Sort the patches based on shortest distance from previous release
- # (after Dijkstra).
- my @commit_order =
- sort { ${$patch_hash{$a}}->{distance} <=>
- ${$patch_hash{$b}}->{distance} }
- @{$patches};
-
- return \@commit_order;
-}
-
-# sub config_filename
-#
-# @return The location of the hbRelease config file.
-#
-sub config_filename
-{
- return git_root()."/.git/hbRelease.config";
-}
-
-# sub config_init
-#
-# Ensures the hbRelease tool is initialized properly.
-#
-sub config_init
-{
- return if (defined $globals{config_init});
-
- unless (-e config_filename())
- {
- open COMMAND, "git config --get remote.gerrit.url |";
- my $url = <COMMAND>;
- close COMMAND;
- chomp $url;
-
- die "Undefined git-remote 'gerrit'" if ($url eq "");
-
- die "Unexpected url found: $url" if (not ($url =~ m/ssh:\/\/.*\/.*/));
-
- my $server = $url;
- my $project = $url;
-
- $server =~ s/ssh:\/\/(.*)\/.*/$1/;
- $project =~ s/.*\/(.*)/$1/;
-
- print "Gerrit Server: ".$server."\n" if $debug;
- print "Gerrit Project: ".$project."\n" if $debug;
-
- open(UNUSED, ">".config_filename()) || die;
- close UNUSED;
-
- system("git config --file ".config_filename().
- " --add releaseLevels.server $server");
- system("git config --file ".config_filename().
- " --add releaseLevels.project $project");
- }
- $globals{config_init} = 1;
-
-}
-
-# sub config_list_levels
-#
-# Determines the previously defined release-levels.
-#
-# @return hash - { level => 1 } for each defined level.
-#
-sub config_list_levels
-{
- return $globals{config_list_levels}
- if (defined $globals{config_list_levels});
-
- config_init();
-
- open COMMAND, "git config --file ".config_filename().
- " --get-all releaseLevels.levelname |";
- my $names = {};
- while (my $line = <COMMAND>)
- {
- chomp $line;
- $names->{$line} = 1;
- }
- close COMMAND;
-
- $globals{config_list_levels} = $names;
- return $names;
-}
-
-# sub config_add_level
-#
-# Add a new level definition to the config file.
-#
-# @param level_def - A level info with the name/base/released for the new level.
-#
-sub config_add_level
-{
- config_init();
-
- my $level_def = shift;
- my $levels = config_list_levels();
-
- if (defined $levels->{$level_def->{name}})
- {
- die "Level ".$level_def->{name}." is already defined";
- }
-
- system("git config --file ".config_filename().
- " --add releaseLevels.levelname ".$level_def->{name});
-
- system("git config --file ".config_filename().
- " --add level.".$level_def->{name}.".base ".$level_def->{base});
-
- system("git config --file ".config_filename().
- " --add level.".$level_def->{name}.".released ".
- $level_def->{released});
-
- if ($globals{"branch"} ne "master")
- {
- system("git config --file ".config_filename().
- " --add level.".$level_def->{name}.".branch ".
- $globals{"branch"});
- }
-}
-
-# sub config_del_level
-#
-# Delete a level definition from the config file.
-#
-# @param level - The level name to delete.
-#
-sub config_del_level
-{
- config_init();
-
- my $level = shift;
-
- system("git config --file ".config_filename().
- " --unset releaseLevels.levelname ^".$level."\$");
-
- system("git config --file ".config_filename().
- " --remove-section level.".$level);
-}
-
-# sub config_add_patch
-#
-# Add a patch to a level definition.
-#
-# @param level - The level to add patch to.
-# @param patch - The patch to add.
-#
-sub config_add_patch
-{
- my $level = shift;
- my $patch = shift;
-
- config_get_level($level);
-
- unless (gerrit_is_patch($patch))
- {
- $patch = git_resolve_ref($patch);
- }
- die "Unknown patch requested" if ($patch eq "");
-
- system("git config --file ".config_filename().
- " --add level.$level.patch $patch");
-}
-
-# sub config_add_dep
-#
-# Add a forced dependency to a level definition.
-#
-# @param level - The level to add to.
-# @param from - The decendent patch.
-# @param to - THe ancestor patch.
-#
-sub config_add_dep
-{
- my $level = shift;
- my $from = shift;
- my $to = shift;
-
- config_get_level($level);
-
- unless (gerrit_is_patch($from))
- {
- $from = git_resolve_ref($from);
- }
- die "Unknown patch requested for 'from' dep" if ($from eq "");
-
- unless (gerrit_is_patch($to))
- {
- $to = git_resolve_ref($to);
- }
- die "Unknown patch requested for 'to' dep" if ($to eq "");
-
- system("git config --file ".config_filename().
- " --add level.$level.forceDep $from:$to");
-}
-
-# sub config_get_level
-#
-# Reads a level's information from the config file.
-#
-# @param level - The level to read.
-#
-# @return hash - { name => level, base => base release,
-# released => previous release,
-# patches => array of patches,
-# forceDep => hash of { from => to } pairs }.
-#
-sub config_get_level
-{
- config_init();
-
- my $level = shift;
- my %level_data = ();
-
- open COMMAND, "git config --file ".config_filename().
- " --get releaseLevels.levelname $level |";
- my $found_level = <COMMAND>; chomp($found_level);
- close COMMAND;
-
- die "Level $level not defined" if ($found_level eq "");
-
- $level_data{name} = $level;
-
- open COMMAND, "git config --file ".config_filename().
- " --get level.$level.base |";
- my $base = <COMMAND>; chomp($base);
- close COMMAND;
-
- $level_data{base} = $base;
-
- open COMMAND, "git config --file ".config_filename().
- " --get level.$level.released |";
- my $released = <COMMAND>; chomp($released);
- close COMMAND;
-
- $level_data{released} = $released;
-
- open COMMAND, "git config --file ".config_filename().
- " --get level.$level.branch |";
- my $branch = <COMMAND>; chomp($branch);
- close COMMAND;
-
- if ($branch ne "")
- {
- $globals{"branch"} = $branch;
- }
-
- my @patches = ();
- open COMMAND, "git config --file ".config_filename().
- " --get-all level.$level.patch |";
- while (my $patch = <COMMAND>)
- {
- chomp($patch);
- push @patches, $patch;
- }
- close COMMAND;
-
- $level_data{patches} = \@patches;
-
- my %forceDeps = ();
- open COMMAND, "git config --file ".config_filename().
- " --get-all level.$level.forceDep |";
- while (my $forceDep = <COMMAND>)
- {
- $forceDep =~ m/(.*):(.*)/;
- $forceDeps{$1} = $2;
- }
- close COMMAND;
-
- $level_data{forceDeps} = \%forceDeps;
-
- return \%level_data;
-}
-
-# sub config_print_levels
-#
-# Displays the name of each defined level.
-#
-sub config_print_levels
-{
- my $levels = config_list_levels();
- foreach my $level (sort keys %$levels)
- {
- print $level."\n";
- }
-}
-
-# sub config_server
-#
-# Gets the Gerrit server name / address from the config file.
-#
-# @return string - The location of the Gerrit server.
-#
-sub config_server
-{
- return $globals{config_server} if (defined $globals{config_server});
-
- config_init();
-
- open COMMAND, "git config --file ".config_filename().
- " --get releaseLevels.server |";
- my $server = <COMMAND>; chomp($server);
- close COMMAND;
-
- die "Server config does not exist" if ($server eq "");
-
- $globals{config_server} = $server;
- return $server;
-
-}
-
-# sub config_project
-#
-# Gets the Gerrit project managed by this repository from the config file.
-#
-# @return string - Project managed by this repository.
-#
-sub config_project
-{
- return $globals{config_project} if (defined $globals{config_project});
-
- config_init();
-
- open COMMAND, "git config --file ".config_filename().
- " --get releaseLevels.project |";
- my $project = <COMMAND>; chomp($project);
- close COMMAND;
-
- die "Project config does not exist" if ($project eq "");
-
- $globals{config_project} = $project;
- return $project;
-}
-
-# sub config_resolve_level_dep
-#
-# Resolves dependencies for patches by parsing the commit messages for the
-# depends-on tag and checking if there are any open parents of a commit.
-# If a patch is dependent on a patch not already in the level, the patch is
-# added.
-#
-# @param[in] - level name
-# @param[in] - Array of patches to process.
-#
-# @TODO RTC:125235 - improve this to support cross project dependencies
-sub config_resolve_level_dep
-{
- print "Resolving level dependencies...\n";
- my $level = shift;
- my $base = shift;
- my @patches = @_;
- my %level_patches = ();
-
- while (@patches)
- {
- my $patchPair = shift @patches;
- my ($patch,$patchSet) = split (":", $patchPair);
-
- # Check if patch has already been added to level
- if ($level_patches{$patch})
- {
- print "Skipping - already added patch = $patch to level\n" if $debug;
- next;
- }
- # Check if patch already exists in release base
- if (git_log_changeId($base, $patch))
- {
- print "Skipping - patch = $patch already exists in release base = $base\n" if $debug;
- next;
- }
-
- # Mark patch as processed
- $level_patches{$patch} = 1;
-
- print "\n===========\nFirst time seeing patch = $patch\n" if $debug;
-
- # Force use of changeId's
- if (!gerrit_is_patch($patch))
- {
- die "Added patch: $patch is not of type changeId\n";
- }
-
- # Add patch to level with resolved git commit.
- print "Adding patch - $patchPair\n" if $debug;
- my $commits = gerrit_resolve_patchset([$patchPair]);
- config_add_patch($level, $commits->[0]);
-
- # Get commit message
- my $patchInfo = gerrit_query_commit($patch);
- my @commitMsgArray = split(/\\n/,$patchInfo->{commitMessage});
- print Dumper @commitMsgArray if $debug;
-
- # Check for OPEN parent
- my $commit_info = gerrit_query_commit($patch);
- my $parent_commit = $commit_info->{currentPatchSet}->{parents}[0];
- # Check if parent already merged into base branch
- if (!commit_local($base, $parent_commit))
- {
- my $parent_info = gerrit_query_commit($parent_commit);
- if ($parent_info->{status} eq "NEW")
- {
- my $parent_id = $parent_info->{id};
- # Add dependency if dependency is not already in base release
- if(!git_log_changeId($base, $parent_id))
- {
- print "Adding forced dependency $patch:$parent_id\n" if $debug;
- config_add_dep($level, $patch, $parent_id);
- }
-
- # Add dependent patch if not already added to level
- if (!exists($level_patches{$parent_id}) )
- {
- push @patches, $parent_id;
- }
- }
- }
-
- # Search commit message for dependencies
- foreach my $line (@commitMsgArray)
- {
- # Check for forced dependencies
- if ($line =~ m/depends-on:/i)
- {
- $line =~ s/([^:]*):\s*//;
- chomp($line);
- print "Found depends-on: $line\n" if $debug;
-
- # Add dependency if dependency is not already in base release
- if(!git_log_changeId($base, $line))
- {
- print "Adding forced dependency $patch:$line\n" if $debug;
- config_add_dep($level, $patch, $line);
- }
-
- # Add dependent patch if not already added to level
- if (!exists($level_patches{$line}) )
- {
- push @patches, $line;
- }
- }
- # Print out CMVC dependencies
- if ($line =~ m/cmvc-([a-zA-Z]+):/i)
- {
- print "$TOKEN Need ".$line."\n";
- }
- }
- }
-}
-
-# sub config_verify_patches
-#
-# Verify patch-list to ensure all dependencies are met
-#
-# @param[in] - level base patch
-# @param[in] - Array of patches to verify.
-#
-sub config_verify_patches
-{
- print "Verifying patches...\n";
-
- config_init();
-
- my $base = shift;
- my $patches = shift;
-
- foreach my $patch (@{$patches})
- {
- print "Deps for $patch\n" if $debug;
- my $displayed_header = 0;
-
- my $deps = git_commit_deps($base, $patch);
-
- foreach my $dep (@{$deps})
- {
- unless (grep {$_ eq $dep} @{$patches})
- {
- unless ($displayed_header)
- {
- print "-------------------------------------------------\n";
- print "Potential missing dependency for:\n";
- print wrap(" "," ",git_get_subject($patch)."\n");
- print "\t$patch\n\n";
- $displayed_header = 1;
- }
-
- print wrap(" ", " ", git_get_subject($dep)."\n");
- print "\t$dep\n";
-
- my $files = array_intersect(git_commit_files($patch),
- git_commit_files($dep));
-
- foreach my $file (@{$files})
- {
- print "\t$file\n";
- }
-
- print "\n";
- }
- }
-
- if ($displayed_header)
- {
- print "-------------------------------------------------\n";
- }
- }
-
-}
-
-# sub config_release
-#
-# Create a branch / tag based on the definition of a release.
-#
-# @param[in] - level info
-# @param[in] - bool to create tag
-#
-sub config_release
-{
- my $level_info = shift;
- my $create_tag = shift;
-
- print "Creating release branch...\n";
- git_create_branch($level_info->{name}, $level_info->{base});
-
- my $patches = $level_info->{patches};
-
- print "Resolving and ordering patches...\n";
- print Dumper $level_info->{patches} if $debug;
- $patches = gerrit_resolve_patches($level_info->{patches});
- $patches = git_order_commits($patches, $level_info);
-
- print "\n========\nDetermined patch order as:\n";
- my $i = 1;
- foreach my $patch (@{$patches})
- {
- print "$i. $patch\n";
- $i++;
- }
-
- print "\n========\nApplying patches...\n";
- $i = 1;
- foreach my $patch (@{$patches})
- {
- print "\n$i. Cherry-picking commit = $patch.\n\n";
- unless (git_cherry_pick($patch))
- {
- print `git status`;
- system("git reset HEAD --hard");
- die "Cherry-pick of $patch failed";
- }
- $i++;
- }
-
- print "\nGenerating release notes...\n";
- create_release_notes($level_info->{name}, $level_info);
-
- if ($create_tag)
- {
- print "\nCreating tag...\n";
- git_create_tag($level_info->{name}, $level_info);
- }
-}
-
-sub publish_cq
-{
- my ($level, $track, $released) = @_;
-
- my $commits = git_commit_history($level, $released);
-
- bq_add_releaseList($level, $track, $commits);
-
- foreach my $commit (@{$commits})
- {
- my $changeid = gerrit_changeid_num($commit);
- my $cq = cq_workitem_num($commit);
- my $commitMessage = git_commit_msg($commit);
- if ($cq ne "")
- {
- print "Change-Id: $changeid\n" if ($debug);
- print "CQ: $cq\n" if ($debug);
-
- bq_add_releasenote($cq, $changeid, $level, $track, $commitMessage);
- }
- }
-}
-
-#
-# Sub print_debug_info
-# @brief This subroutine prints out some important information at the
-# end of Phase 2 of the Automatic Release process.
-#
-
-sub print_debug_info
-{
- my ($level, $feature, $cq_id, $released) = @_;
-
-
- print "\n\nHostboot Release debugging information.....\n";
- print "\nHostboot Official Release Notes\n";
-
- print "Level $level Included commits:\n";
-
- my $commits = git_commit_history($level,$released);
- foreach my $commit (@{$commits})
- {
- my $cq = cq_workitem_num($commit);
- my $rtc = rtc_workitem_num($commit);
- my $changenum = "";
- my $subject = git_get_subject($commit);
-
- # Find if the commit has a CQ # or an RTC #.
- if ($cq ne "")
- {
- $changenum = "$cq ";
- }
- elsif ($rtc ne "")
- {
- $changenum = "$rtc ";
- }
- else
- {
- $changenum = "--------- ";
- }
-
- print "$changenum$subject\n";
- }
-
- print "\nThe Bestquest track number is $cq_id\n";
- print "And the Bestquest link is http://w3.rchland.ibm.com/projects/bestquest/?defect=$cq_id&table=requirement\n\n";
- print "The release feature number is $feature\n";
- print "This release this is based on is $released\n";
-
-}
-
-# sub gerrit_ssh_command
-#
-# Creates a properly formed ssh command based on the server address.
-#
-# @return string - The basic ssh command to connect to the server.
-#
-sub gerrit_ssh_command
-{
- return $globals{gerrit_ssh_command}
- if (defined $globals{gerrit_ssh_command});
-
- my $server = config_server();
- my $port = "";
-
- if ($server =~ m/.*:.*/)
- {
- $port = $server;
- $server =~ s/(.*):.*/$1/;
- $port =~ s/.*:(.*)/$1/;
-
- $port = "-p $port";
- }
-
- my $command = "ssh -qx $port $server gerrit";
- print "SSH command: $command\n" if $debug;
-
- $globals{gerrit_ssh_command} = $command;
- return $command;
-}
-
-# sub gerrit_query
-#
-# Performs a gerrit query and parses the resulting JSON.
-#
-# @param[in] query - The query to perform.
-#
-# @return array - A list of items from the JSON query. Each item is a
-# hash (key-value pair) for the item attributes.
-#
-sub gerrit_query
-{
- my $query = shift;
-
- my @items = ();
-
- open COMMAND, gerrit_ssh_command()." query $query --current-patch-set".
- " --patch-sets --format=JSON |";
-
- while (my $line = <COMMAND>)
- {
- chomp $line;
- push @items, json_parse($line);
- }
-
- return \@items;
-}
-
-# sub gerrit_query_commit
-#
-# Performs a gerrit query on a specific commit.
-#
-# @param[in] commit - The commit to query.
-#
-# @return hash - The parsed JSON for the queried commit.
-#
-sub gerrit_query_commit
-{
- my $commit = shift;
-
- my $project = config_project();
-
-
- my $query_result = gerrit_query("$commit project:$project ".
- "branch:".$globals{"branch"});
- foreach my $result (@{$query_result})
- {
- if ($result->{id} eq $commit ||
- $result->{currentPatchSet}->{revision} =~ m/$commit/)
- {
- return $result;
- }
- else
- {
- # If all patchsets queried, search all of them for the commit
- foreach my $patchset (@{$result->{patchSets}})
- {
- if ($patchset->{revision} =~ m/$commit/)
- {
- return $result;
- }
- }
- }
- }
-}
-
-# sub gerrit_is_patch
-#
-# Determines if a patch identifier is a Gerrit patch or not.
-#
-# @param[in] i_patch - The patch to make determination about.
-#
-# @retval true - Patch is a Gerrit patch ID.
-# @retval false - Patch does not appear to be a Gerrit patch ID.
-sub gerrit_is_patch
-{
- my $i_patch = shift;
- chomp($i_patch);
- return 1 if ($i_patch =~ m/I[0-9a-f]+/);
- return 0;
-}
-
-# sub gerrit_resolve_patches
-#
-# Resolves gerrit patch IDs to git commit numbers and ensures the git
-# commits are fetched from the gerrit server.
-#
-# Any git commit number is left unchanged.
-#
-# @param[in] patches - An array of patches.
-# @return array - An array of git commit numbers.
-#
-sub gerrit_resolve_patches
-{
- my $patches = shift;
- my @result = ();
-
- foreach my $patch (@{$patches})
- {
- if (gerrit_is_patch($patch))
- {
- my $patch_info = gerrit_query_commit($patch);
- gerrit_fetch($patch_info->{currentPatchSet}->{ref});
- push @result, $patch_info->{currentPatchSet}->{revision};
- }
- else
- {
- push @result, $patch;
- }
- }
-
- return \@result;
-}
-
-# sub gerrit_resolve_patchset
-#
-# Resolves an array of gerrit change-id and patch-set pairs to git commit
-# numbers and and ensures the git commits are fetched from the gerrit server.
-#
-# @param[in] patches - An array of change-id, patch-set pairs.
-# @return array - An array of git commit numbers.
-#
-sub gerrit_resolve_patchset
-{
- my $patches = shift;
-
- my @result = ();
- foreach my $patchPair (@{$patches})
- {
- my ($changeId,$patchSet) = split(":",$patchPair);
-
- if (gerrit_is_patch($changeId))
- {
- my $patch_info = gerrit_query_commit($changeId);
- # Fail if patchset DNE
- if ($patchSet > $patch_info->{currentPatchSet}->{number})
- {
- die "$patchSet does not have patch number $patchSet";
- }
- # JSON creates array of patchSets in number order
- my $index = $patchSet - 1;
- gerrit_fetch($patch_info->{patchSets}[$index]->{ref});
- push @result, $patch_info->{patchSets}[$index]->{revision};
- }
- else
- {
- die "Requires gerrit change-id and patch-set";
- }
- }
-
- return \@result;
-}
-
-# sub gerrit_fetch
-#
-# Fetches the contents of a Gerrit revision (refs/changes/*) to the local
-# git repository.
-#
-# @param[in] ref - The revision to fetch from the Gerrit server.
-#
-sub gerrit_fetch
-{
- my $ref = shift;
-
- system("git fetch gerrit $ref -q");
-}
-
-# sub rtc_workitem_num
-#
-# Determines the RTC WorkItem associated with a git commit.
-#
-# @param[in] commit - The git commit.
-#
-# @return string - RTC WorkItem number (or "").
-#
-sub rtc_workitem_num
-{
- my $commit = shift;
- my $message = git_commit_msg($commit);
-
- if ($message =~ m/RTC:\s*([0-9]+)/)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-# sub cq_workitem_num
-#
-# Determine the CQ WorkItem associated with a git commit.
-#
-# @param[in] commit - The git commit.
-#
-# @return string - CQ WorkItem number (or "").
-#
-sub cq_workitem_num
-{
- my $commit = shift;
- my $message = git_commit_msg($commit);
-
- if ($message =~ m/CQ:\s*([A-Z][A-Z][0-9]+)/)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-# sub coreq_workitem_num
-#
-# Search through a git commit for all coReq instances.
-#
-# @param[in] commit - The git commit.
-#
-# @return array of strings - CMVC-Coreq numbers or "".
-#
-
-sub coreq_workitem_num
-{
- my $commit = shift;
-
- my @msg_lines = split('\n',git_commit_msg($commit));
- my @coreqs = ();
-
- foreach my $line (@msg_lines)
- {
- if ($line =~ m/CMVC-Coreq:\s*([0-9]+)/i)
- {
- push @coreqs, $1;
- }
- }
- return @coreqs;
-}
-
-# sub prereq_workitem_num
-#
-# Search through a git commit for all preReq instances.
-#
-# @param[in] commit - The git commit.
-#
-# @return array of strings - CMVC-Prereq numbers or "".
-#
-
-sub prereq_workitem_num
-{
- my $commit = shift;
-
- my @msg_lines = split('\n',git_commit_msg($commit));
- my @prereqs = ();
-
- foreach my $line (@msg_lines)
- {
- if($line =~ m/CMVC-Prereq:\s*([0-9]+)/i)
- {
- push @prereqs, $1;
- }
- }
- return @prereqs;
-}
-
-# sub gerrit_changeid_num
-#
-# Determine the Gerrit Change-Id associated with a git commit.
-#
-# @param[in] commit - The git commit.
-#
-# @return string - Gerrit Change-Id number (or "").
-#
-sub gerrit_changeid_num
-{
- my $commit = shift;
- my $message = git_commit_msg($commit);
-
- if ($message =~ m/Change-Id:\s*(I[0-9a-z]+)/)
- {
- return $1;
- }
- else
- {
- return "";
- }
-}
-
-
-# sub rtc_hyperlink
-#
-# Turn an RTC WorkItem number into the https:// address to the RTC server.
-#
-# @param[in] workitem - RTC workitem number.
-#
-# @return string - The https:// address of the RTC item on the server.
-#
-sub rtc_hyperlink
-{
- my $workitem = shift;
- return "https://jazz07.rchland.ibm.com:13443/jazz/oslc/workitems/".
- "$workitem.hover.html";
-}
-
-# sub cq_hyperlink
-#
-# Turn a CQ WorkItem number into the http:// address to the BQ server.
-#
-# @param[in] workitem - CQ workitem number.
-#
-# @return string - The http:// address of the CQ item on the server.
-#
-sub cq_hyperlink
-{
- my $workitem = shift;
- return "http://w3.rchland.ibm.com/projects/bestquest/?defect=$workitem";
-}
-
-# sub json_parse
-#
-# Parse a line of JSON into an hash-object.
-#
-# @param[in] line - The JSON content.
-#
-# @return hash - The parsed object.
-#
-# @note There are perl modules for doing this but they are not installed on
-# the pool machines. The parsing for JSON (at least the content from
-# the Gerrit server) isn't so bad...
-#
-sub json_parse
-{
- my $line = shift;
-
- die "Invalid JSON format: $line" unless ($line =~ m/^\{.*\}$/);
- $line =~ s/^\{(.*)}$/$1/;
-
- my %object = ();
-
- while($line ne "")
- {
- my $key;
- my $value;
-
- ($key, $line) = json_get_string($line);
- $key =~ s/^"(.*)"$/$1/;
-
- $line =~ s/^://;
- if ($line =~ m/^"/)
- {
- ($value, $line) = json_get_string($line);
- $value =~ s/^"(.*)"$/$1/;
- }
- elsif ($line =~ m/^{/)
- {
- ($value, $line) = json_get_object($line);
- $value = json_parse($value);
- }
- elsif ($line =~ m/^\[/)
- {
- ($value, $line) = json_get_array($line);
- $value = json_parse_array($value);
- }
- else
- {
- $line =~ s/([^,]*)//;
- $value = $1;
- }
-
- $object{$key} = $value;
- }
-
- return \%object;
-}
-
-# sub json_parse_array
-#
-# Utility function for json_parse.
-#
-sub json_parse_array
-{
- my $line = shift;
-
- $line =~ s/^\[(.*)\]$/$1/;
-
- my @array = ();
-
- while ($line ne "")
- {
- my $value;
-
- if ($line =~ m/^"/)
- {
- ($value, $line) = json_get_string($line);
- $value =~ s/^"(.*)"$/$1/;
- }
- elsif ($line =~ m/^\{/)
- {
- ($value, $line) = json_get_object($line);
- $value = json_parse($value);
- }
- elsif ($line =~ m/^\[/)
- {
- ($value, $line) = json_get_array($line);
- $value = json_parse_array($value);
- }
- else
- {
- $line =~ s/([^,]*)//;
- $value = $1;
- }
-
- push @array, $value;
- $line =~ s/^,//;
- }
-
- return \@array;
-}
-
-# sub json_get_string
-#
-# Utility function for json_parse.
-#
-sub json_get_string
-{
- my $line = shift;
-
- $line =~ /("[^"]*")(.*)/;
- my $first = $1;
- my $second = $2;
-
- if ($first =~ m/\\"$/)
- {
- my ($more, $rest) = json_get_string($second);
- return ($first.$more , $rest);
- }
- else
- {
- return ($first, $second);
- }
-}
-
-# sub json_get_object
-#
-# Utility function for json_parse.
-#
-sub json_get_object
-{
- my $line = shift;
-
- $line =~ s/^{//;
- my $object = "{";
- my $frag = "";
-
- my $found_object = 0;
-
- until ((not $found_object) && ($object =~ m/}$/))
- {
- $found_object = 0;
-
- if ($line =~ m/^\{/)
- {
- ($frag, $line) = json_get_object($line);
- $object = $object.$frag;
- $found_object = 1;
- }
- elsif ($line =~ m/^"/)
- {
- ($frag, $line) = json_get_string($line);
- $object = $object.$frag;
- }
- elsif ($line =~ m/^\[/)
- {
- ($frag, $line) = json_get_array($line);
- $object = $object.$frag;
- }
- elsif ($line =~ m/^[:,}]/)
- {
- $line =~ s/^([:,}])//;
- $frag = $1;
- $object = $object.$frag;
- }
- else
- {
- $line =~ s/([^,}]*)//;
- $frag = $1;
- $object = $object.$frag;
- }
- }
-
- return ($object, $line);
-}
-
-# sub json_get_array
-#
-# Utility function for json_parse.
-#
-sub json_get_array
-{
- my $line = shift;
-
- $line =~ s/^\[//;
- my $array = "[";
- my $frag = "";
-
- my $found_array = 0;
-
- until ((not $found_array) && ($array =~ m/]$/))
- {
- $found_array = 0;
-
- if ($line =~ m/^\[/)
- {
- ($frag, $line) = json_get_array($line);
- $array = $array.$frag;
- $found_array;
- }
- elsif ($line =~ m/^\{/)
- {
- ($frag, $line) = json_get_object($line);
- $array = $array.$frag;
- }
- elsif ($line =~ m/^"/)
- {
- ($frag, $line) = json_get_string($line);
- $array = $array.$frag;
- }
- elsif ($line =~ m/^[:,\]]/)
- {
- $line =~ s/^([:,\]])//;
- $frag = $1;
- $array = $array.$frag;
- }
- else
- {
- $line =~ s/([^,]*)//;
- $frag = $1;
- $array = $array.$frag;
- }
- }
-
- return ($array, $line);
-}
-
-# sub array_intersect
-#
-# Perform set intersection on two arrays.
-#
-# @param[in] one - The first array.
-# @param[in] two - The second array.
-#
-# @return array - The set intersection.
-#
-sub array_intersect
-{
- my $one = shift;
- my $two = shift;
-
- my %set = {};
-
- map { $set{$_}++ } (@{$one}, @{$two});
-
- my @result = map { ($set{$_} > 1) ? $_ : () } (keys %set);
-
- return \@result;
-}
-
- # globals used to store the cookie file name for logging into BQ.
-my $cookie_fh = "";
-my $cookie_name = "";
-
-use constant BQ_SERVER => "http://w3.rchland.ibm.com/projects/bestquest/";
-
-# sub bq_login
-#
-# Login to the BestQuest website.
-#
-sub bq_login
-{
- return if ($cookie_name ne "");
-
- my %bq_login_params = ( user => "UNKNOWN",
- passwd => "UNKNOWN",
- database => "AIXOS",
- schema => "STGC_AIX",
- cqserver => "auscqweb.austin.ibm.com",
- cqport => "6600" );
-
- # Read username / password.
- $bq_login_params{user} = $globals{email};
- my $password = `cat $HOSTBOOT_GSA_HOME/private/password`;
- die $? if $?;
- chomp($password);
- $bq_login_params{passwd} = $password;
-
- # Create parameters.
- my $login_post = "verb=login_form_response";
- foreach my $key (keys %bq_login_params)
- {
- $login_post = $login_post."&login_".$key."=".$bq_login_params{$key};
- }
-
- # Create a tempfile to hold the cookies.
- ($cookie_fh, $cookie_name) = tempfile(UNLINK => 1);
-
- # Do login.
- system "wget -q -O - --save-cookies $cookie_name ".
- "--post-data '$login_post' ".BQ_SERVER." > /dev/null";
-}
-
-# sub bq_add_releasenote
-#
-# Adds a string "Change W added to Hostboot level X and released under Y.
-# "Commit Message: Z"
-# to a CQ defect / feature.
-#
-# @param[in] - CQ defect / feature.
-# @param[in] - Corresponding Gerrit Change-Id.
-# @param[in] - Hostboot release level.
-# @param[in] - Hostboot release track.
-# @param[in] - Hostboot commit message
-#
-sub bq_add_releasenote
-{
- my $cq = shift;
- my $change_id = shift;
- my $level = shift;
- my $release = shift;
- my $commitMessage = shift;
-
- my $note = "Change%20$change_id%20added%20to%20Hostboot%20level%20".
- "$level%20and%20released%20under%20$release%0A".
- "Commit%20Message%3A%0A$commitMessage";
-
- # Login to BQ.
- bq_login();
-
- print "Updating release note for $cq.\n";
-
- # Find CQ ID for defect/feature.
- my $cqid_cmd = "wget -q -O - --load-cookies $cookie_name ".
- BQ_SERVER."?defect=$cq | grep 'CQ ID:' -A1 | tail -n1 | ".
- "sed 's/<\\/a.*//' | sed 's/.*recordType=//' | ".
- "sed 's/\">/ /'";
-
- my $cqid_result = `$cqid_cmd`;
- chomp $cqid_result;
-
- my ($cqtype,$cqid) = split / /, $cqid_result;
-
- # Add release comment.
- system "wget -q -O - --load-cookies $cookie_name '".BQ_SERVER.
- "?verb=editnote_form_response&table=$cqtype&id=$cqid&uid=$cq&".
- "note_string=$note' > /dev/null";
-
-}
-
-# sub bq_add_releaseList
-#
-# This function is adding the releaseNotes to the release's BestQuest
-# The build team wanted to know exactly what was included in each release
-# and this is just an easy way to quickly view it.
-#
-# @param[in] - Hostboot release level.
-# @param[in] - Hostboot release track.
-# @param[in] - Array of commits in the hostboot level
-
-sub bq_add_releaseList
-{
- my $level = shift;
- my $track = shift;
- my $commits = shift;
-
- # Note: when adding notes to BestQuest, everything has to be in ASCII
- # for it to display correctly
- # %20:' ', %0A:newline, %3D:'=', %3A:':', %2D:'-'
- my $note = "Hostboot%20Official%20Release%20Notes%0A";
-
- # Adding a seperator ('='x100) between the title and the actual data.
- # This posting method doesn't allow for bolding and it needs an eyecatch
- for (my $i=0; $i <100; $i++)
- {
- $note .= "%3D";
- }
- $note .= "%0A%0ALevel%3A%20$level%0AIncluded%20commits%3A%0A%0A";
-
- foreach my $commit (@{$commits})
- {
- my $cq = cq_workitem_num($commit);
- my $rtc = rtc_workitem_num($commit);
- my $changenum = "";
- my $subject = git_get_subject($commit);
-
- # Find if the commit has a ClearQuest # or an RTC #, if not blank -'s
- if ($cq ne "")
- {
- $changenum = "$cq%20%20"; #additionally, spacing for readability
- }
- elsif ($rtc ne "")
- {
- $changenum = "$rtc%20%20%20%20";
- }
- else
- {
- $changenum = "%2D%2D%2D%2D%2D%2D%2D%2D%2D%20"; #---------
- }
- $note .= "$changenum$subject%20%20%0A";
-
- # Adding in hb commit hash below the Commit number and subject
- $note .= "%20%20%20%20%20%20%20%20%20%20$commit%0A";
- }
-
- # Login to BQ.
- bq_login();
-
- print "Updating release note for hbRelease $level\n";
-
- # Find CQ ID for defect/feature.
- my $cqid_cmd = "wget -q -O - --load-cookies $cookie_name ".
- BQ_SERVER."?defect=$track | grep 'CQ ID:' -A1 | tail -n1 | ".
- "sed 's/<\\/a.*//' | sed 's/.*recordType=//' | ".
- "sed 's/\">/ /'";
-
- my $cqid_result = `$cqid_cmd`;
- chomp $cqid_result;
-
- # Splitting on whitespace to seperate the ClearQuest type and ID
- my ($cqtype,$cqid) = split / /, $cqid_result;
-
- # Add the release notes to the defect for our hbRelease.
- # For all commits in this release: CQ/RTC number - Subject of commit
- system "wget -q -O - --load-cookies $cookie_name '".BQ_SERVER.
- "?verb=editnote_form_response&table=$cqtype&id=$cqid&uid=$track&".
- "note_string=$note' > /dev/null";
-
-}
-
-# sub execute_cmvc_reqs
-#
-# Given a commit, find the CMVC coreqs and prereqs and add these
-# tracks to the auto release track.
-#
-# @param[in] feature - Current Release track in CMVC
-# @param[in] level - hostboot level tag
-# @param[in] released - previously released hostboot level tag
-# @param[in] release - which release this is (e.g. fips910, fips860)
-#
-
-sub execute_cmvc_reqs
-{
- my $feature = shift;
- my $level = shift;
- my $released = shift;
- my $release = shift;
-
- #need to get commit
- my $commits = git_commit_history($level, $released);
-
- foreach my $commit (@{$commits})
- {
- my @coreq_list = coreq_workitem_num($commit);
- foreach my $coreq (@coreq_list)
- {
- if($coreq ne "")
- {
- my $cmd = "/esw/bin/coreqTracks -r $release -t $feature -t2 $coreq -e $globals{email}";
- print "$cmd\n";
- my $output = `echo "y" | $cmd`;
- print $output;
- }
- }
-
- my @prereq_list = prereq_workitem_num($commit);
- foreach my $prereq (@prereq_list)
- {
- if($prereq ne "")
- {
- my $cmd = "/esw/bin/prereqTracks -r $release -t $prereq -t2 $feature -e $globals{email}";
- print "$cmd\n";
- my $output = `echo "y" | $cmd`;
- print $output
- }
- }
- }
-}
-
-# sub hw_req_check
-#
-# Check for Hw-Image requirements, and fail so that a manual
-# check can be run for the specific commit and added as a CMVC
-# requirement.
-#
-sub hw_req_check
-{
- my $level = shift;
- my $released = shift;
-
- my $commits = git_commit_history($level, $released);
-
- foreach my $commit (@{$commits})
- {
- if (($commit =~ m/HW-Image-Coreq:\s*([a-z]+)/i) ||
- ($commit =~ m/HW-Image-Prereq:\s*([0-9]+)/i))
- {
- print "HW Image Req was found:\n$commit\n";
- die "HW-Image-Coreq/Prereq detected.\n";
- }
- }
-}
-
-# sub run_system_command
-#
-# Execute a system command, handle printing command and debug info, and return
-# system output for caller processing
-#
-# E.g. Execute a CMVC line command and return the results.
-#
-# @param[in] cmd - system command to be executed.
-#
-# @return string - output returned from running system command.
-#
-sub run_system_command
-{
- my $cmd = shift;
-
- print "$cmd\n";
- my $output = `$cmd`;
- #print "output=$output\n";
- die "failed running system command $cmd - $?" if ($?);
- print $output if $debug;
-
- return $output;
-}
-
-# sub commit_local
-#
-# Checks if commit is in local tree
-#
-# @param[in] i_commit - The commit to examine.
-#
-# @return bool - true if in local tree
-#
-sub commit_local
-{
- my ($i_base, $i_commit) = @_;
- chomp($i_base);
- chomp($i_commit);
-
- die "Based is not of type commit (SHA hash)" if (!is_commit($i_base));
-
- # Git log will fail if not valid change-id or commit. Note order is check
- # for change-id first as it will also match the regex for is_commit
- if (gerrit_is_patch($i_commit))
- {
- `git log $i_base | grep "Change-Id: $i_commit"`;
- ($?) ? return 0 : return 1;
- }
- elsif(is_commit($i_commit))
- {
- # Note '^commit' used to avoid finding the commit in the commit message
- # somewhere
- `git log $i_base | grep "^commit $i_commit"`;
- ($?) ? return 0 : return 1;
- }
- else
- {
- die "Commit is not of type commit or change-id";
- }
-}
-
-# sub is_commit
-#
-# Determines if a patch identifier is a git commit id or not.
-#
-# @param[in] i_ref - The reference to make determination about.
-#
-# @return bool - Ref is in the style of a git commit
-sub is_commit
-{
- my $i_ref = shift;
- chomp($i_ref);
-
- ($i_ref =~ m/[0-9a-f]{7,40}/) ? return 1 : return 0;
-}
OpenPOWER on IntegriCloud