1267 lines
42 KiB
Plaintext
Executable File
1267 lines
42 KiB
Plaintext
Executable File
//reference * will cause the dll created from this script to inherit all references from the parent app
|
|
|
|
using OozyBuild; /// reference *
|
|
using Microsoft.Win32;
|
|
using P4API;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Controls;
|
|
using System.Xml.Serialization;
|
|
|
|
namespace sga_merge_prebuild
|
|
{
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
public static class ProjectExtension
|
|
{
|
|
public static SgaPrebuildSettings Settings( this OozyBuild.Project project )
|
|
{
|
|
return project.customSettings as SgaPrebuildSettings;
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
public class SgaPrebuildSettings : OozyBuild.CustomSettings
|
|
{
|
|
public SgaPrebuildSettings()
|
|
{
|
|
//Defaults. These values are persisted, and so will only be set as default on new projects, or if settings are wiped
|
|
visualStudioVersion = "2019";
|
|
|
|
buildBreakers = new SerializableDictionary<Guid, List<BuildBreaker>>();
|
|
|
|
packageDir = "";
|
|
packageLimit = 5;
|
|
transferDir = @"";
|
|
|
|
logDir = @"tools_ng\script\util\BuildDept\GTA5_GEN9_BuildTool_V2\BuildTool\CI_Logs";
|
|
|
|
lastCIChangelist = -1;
|
|
obscureSlackMessages = true;
|
|
|
|
lastResult = new CIResult();
|
|
lastNightbuildResult = new CIResult();
|
|
|
|
branchStatus = new SerializableDictionary<string, BranchStatus>();
|
|
}
|
|
|
|
public void Setup( Project inProject )
|
|
{
|
|
project = inProject;
|
|
|
|
if( Oozy.continuous )
|
|
{
|
|
sendEmail = false;
|
|
}
|
|
if( string.IsNullOrEmpty( Project.IncredibuildExe ) || !File.Exists( Project.IncredibuildExe ) )
|
|
{
|
|
incredibuild_IsEnabled = false;
|
|
}
|
|
else
|
|
{
|
|
incredibuild_IsEnabled = true;
|
|
}
|
|
}
|
|
|
|
public void EnableButton( Button button, bool enable )
|
|
{
|
|
if( button == null )
|
|
{
|
|
return;
|
|
}
|
|
if( System.Windows.Application.Current != null )
|
|
{
|
|
System.Windows.Application.Current.Dispatcher.BeginInvoke( (Action)(() =>
|
|
{
|
|
button.IsEnabled = enable;
|
|
}) );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
** SPECIAL VARIABLES which are used internally if they exist
|
|
******************************************************************************************************************/
|
|
|
|
public bool playBoredMessage { get; set; }
|
|
|
|
//Don't make public, this should be un-editable. If undefined, the newest version found will be used.
|
|
string visualStudioVersion { get; set; }
|
|
|
|
[PropertyToolTip( "Nightbuild" )]
|
|
public bool nightBuild { get; set; }
|
|
|
|
[PropertyToolTip( "Log dir" )]
|
|
public string logDir { get; set; }
|
|
|
|
[PropertyToolTip("Upload symbols")]
|
|
public bool uploadSymbols { get; set; }
|
|
|
|
[PropertyToolTip( "Create Package" )]
|
|
public bool createPackage { get; set; }
|
|
|
|
[PropertyToolTip( "Package dir" )]
|
|
public string packageDir { get; set; }
|
|
|
|
[PropertyToolTip( "Transfer Package" )]
|
|
public bool transferPackage { get; set; }
|
|
|
|
[PropertyToolTip( "Transfer dir" )]
|
|
public string transferDir { get; set; }
|
|
|
|
[PropertyToolTip( "Keep this many packages in Package Dir. Last nightbuild is always kept" )]
|
|
[XmlIgnore]
|
|
public int packageLimit { get; set; }
|
|
|
|
[ContinuousMode]
|
|
[PropertyToolTip( "Requires slack.ini containing URL=<url>" )]
|
|
public bool postSlackMessages { get; set; }
|
|
|
|
[ContinuousMode]
|
|
[PropertyToolTip( "Don't put identifiable information in the slack messages" )]
|
|
public bool obscureSlackMessages { get; set; }
|
|
|
|
[ContinuousMode]
|
|
[PropertyToolTip( "Send email on CI or package" )]
|
|
public bool sendEmail { get; set; }
|
|
|
|
[ContinuousMode]
|
|
[PropertyToolTip( "Submit scc outputs defined in NOM to p4" )]
|
|
public bool submitP4 { get; set; }
|
|
|
|
/******************************************************************************************************************
|
|
** END OF SPECIAL VARIABLES
|
|
******************************************************************************************************************/
|
|
|
|
[ContinuousMode]
|
|
public bool createLabels { get; set; }
|
|
|
|
public int lastCIChangelist { get; set; }
|
|
public SerializableDictionary<Guid, List<BuildBreaker>> buildBreakers { get; set; }
|
|
|
|
public int filesSyncedToday { get; set; }
|
|
|
|
public SerializableDictionary<string, BranchStatus> branchStatus { get; set; }
|
|
|
|
public SerializableDictionary<Guid, BuiltInfo> lastBuildStatus;
|
|
|
|
public bool incredibuild { get; set; }
|
|
bool incredibuild_IsEnabled { get; set; }
|
|
|
|
public CIResult lastResult { get; set; }
|
|
public CIResult lastNightbuildResult { get; set; }
|
|
|
|
[XmlIgnore]
|
|
public Project project;
|
|
|
|
[XmlIgnore]
|
|
public BuildExtension extension;
|
|
}
|
|
|
|
public class FileToMerge
|
|
{
|
|
public string source;
|
|
public string dest;
|
|
}
|
|
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
public class BuildExtension : GTA5Extension
|
|
{
|
|
string packageUser;
|
|
|
|
bool buildOnlyIfSynced;
|
|
|
|
//Dictionary of branches and whether changelist/bugstar information needs to be stored, along with p4 paths relevant to building
|
|
protected override Dictionary<string, BranchSyncInfo> branchPaths { get; set; }
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
public static BuildExtension Init( Project inProject )
|
|
{
|
|
return new BuildExtension( inProject );
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
public BuildExtension( Project inProject )
|
|
{
|
|
project = inProject;
|
|
SgaPrebuildSettings settings = new SgaPrebuildSettings();
|
|
settings.Setup( inProject );
|
|
settings.extension = this;
|
|
|
|
branchPaths = new Dictionary<string, BranchSyncInfo>()
|
|
{
|
|
{ "dev_gen9_sga_merge", new BranchSyncInfo() { storeChanges = true, syncPaths = new List<string>()
|
|
{
|
|
@"gta5\titleupdate\dev_gen9_sga_merge\...",
|
|
@"gta5\src\dev_gen9_sga_merge\...",
|
|
@"gta5\script\dev_gen9_sga_merge\...",
|
|
@"gta5\assets_gen9_sga\GameText\dev_gen9_sga_merge\...",
|
|
@"gta5\assets_gen9_sga\metadata\...",
|
|
@"gta5\assets_gen9_sga\titleupdate\dev_gen9_sga_merge\...",
|
|
@"gta5\assets_gen9_sga\maps\ParentTxds.xml",
|
|
@"gta5\build\disk_images\...",
|
|
@"gta5_dlc\mpPacks\mpSum2\build\dev_gen9_sga\...",
|
|
@"gta5_dlc\mpPacks\mpSum2\assets_gen9_disc\gametext\...",
|
|
@"gta5_dlc\patchPacks\patchDay27NG\build\dev_gen9_sga\...",
|
|
@"gta5\tools_ng\...",
|
|
}
|
|
}
|
|
},
|
|
};
|
|
|
|
//Setting customSettings will serialize in persisted data
|
|
project.customSettings = settings;
|
|
|
|
//ensure any new or un-persisted branch infos are setup to save having null checks all over the place
|
|
if( settings.branchStatus == null )
|
|
{
|
|
settings.branchStatus = new SerializableDictionary<string, BranchStatus>();
|
|
}
|
|
foreach( var pair in branchPaths )
|
|
{
|
|
if( !settings.branchStatus.ContainsKey( pair.Key ) )
|
|
{
|
|
settings.branchStatus[pair.Key] = new BranchStatus();
|
|
}
|
|
}
|
|
|
|
project.OnContinuous += OnContinuous;
|
|
project.OnNightbuild += OnNightbuild;
|
|
|
|
project.AddLog( "sga_merge_prebuild loaded" );
|
|
}
|
|
|
|
object PackageBuild( QueueEntry queueEntry )
|
|
{
|
|
SgaPrebuildSettings settings = project.Settings();
|
|
|
|
DateTime start = DateTime.Now;
|
|
project.builder.buildStartingTime = start;
|
|
string logPath = project.builder.GetBuilderLogPath( start );
|
|
Program.PushLogPath( logPath );
|
|
|
|
package = true;
|
|
packageUser = queueEntry.testingUser;
|
|
|
|
string msg = "";
|
|
if( !string.IsNullOrEmpty( packageUser ) )
|
|
{
|
|
msg += DateTime.Now.ToString( "dd/MM/yyyy HH:mm" ) + ": PackageBuild started for " + packageUser + "\n";
|
|
}
|
|
else
|
|
{
|
|
msg += DateTime.Now.ToString( "dd/MM/yyyy HH:mm" ) + ": PackageBuild started\n";
|
|
}
|
|
|
|
string silentStr = queueEntry.values["silent"];
|
|
bool silent = string.Compare( silentStr, "true", true ) == 0;
|
|
|
|
bool oldPost = settings.postSlackMessages;
|
|
bool oldSubmit = settings.submitP4;
|
|
bool oldCreateLabel = settings.createLabels;
|
|
bool oldSendEmail = settings.sendEmail;
|
|
|
|
if( silent )
|
|
{
|
|
settings.postSlackMessages = false;
|
|
settings.submitP4 = false;
|
|
settings.createLabels = false;
|
|
settings.sendEmail = false;
|
|
}
|
|
|
|
|
|
BuildParams buildParams = new BuildParams();
|
|
buildParams.rebuild = false;
|
|
buildParams.flags = BuildTypeFlags.Packaging;
|
|
|
|
msg += "Options:\n";
|
|
foreach( var pair in queueEntry.values )
|
|
{
|
|
if( string.IsNullOrEmpty( pair.Value ) )
|
|
{
|
|
msg += pair.Key + "\n";
|
|
}
|
|
else
|
|
{
|
|
msg += pair.Key + " = " + pair.Value + "\n";
|
|
}
|
|
buildParams[pair.Key] = pair.Value;
|
|
}
|
|
|
|
if( buildParams.ContainsKey( "installer" ) )
|
|
{
|
|
buildParams["installer"] = "-platformpackage";
|
|
}
|
|
if( buildParams.ContainsKey( "skipinitial" ) )
|
|
{
|
|
buildParams["skipinitial"] = "-skipinitpackage";
|
|
}
|
|
project.StartBuildThread( msg );
|
|
project.AddLog( msg );
|
|
|
|
VariableParser.GetValueDelegate getEnv = ( string var, List<string> values ) =>
|
|
{
|
|
string val;
|
|
if( buildParams.TryGetValue( var, out val ) )
|
|
{
|
|
values.Add( val );
|
|
}
|
|
};
|
|
VariableParser.GetValue += getEnv;
|
|
|
|
CIResult result = null;
|
|
try
|
|
{
|
|
int retry = 10;
|
|
while( result == null && retry > 0 )
|
|
{
|
|
result = DoBuild( project.builder, buildParams );
|
|
if( result == null )
|
|
{
|
|
project.AddError( "PackageBuild failed with something more than likely p4 related, waiting to try again" );
|
|
Thread.Sleep( 10 * 1000 );
|
|
}
|
|
}
|
|
}
|
|
catch( Exception ex )
|
|
{
|
|
project.AddError( "PackageBuild exception" );
|
|
project.PostBuildError( App.LogException( ex ) );
|
|
}
|
|
VariableParser.GetValue -= getEnv;
|
|
|
|
if( silent )
|
|
{
|
|
settings.postSlackMessages = oldPost;
|
|
settings.submitP4 = oldSubmit;
|
|
settings.createLabels = oldCreateLabel;
|
|
settings.sendEmail = oldSendEmail;
|
|
}
|
|
|
|
packageUser = "";
|
|
package = false;
|
|
bool ret = result != null && result.ranNormally;
|
|
project.PostBuildMessage( "Package Complete." );
|
|
if( ret )
|
|
{
|
|
project.StopBuildThreadSuccess();
|
|
}
|
|
else
|
|
{
|
|
project.StopBuildThreadError();
|
|
}
|
|
Program.PopLogPath();
|
|
return ret;
|
|
}
|
|
|
|
int Execute( out string outLog, string dir, string command, string args )
|
|
{
|
|
project.AddLog( "[" + dir + "] " + command + " " + args );
|
|
int ret = -1;
|
|
try
|
|
{
|
|
BuildCommand symbol = new BuildCommand( dir, command, args );
|
|
|
|
Task<int> th = project.builder.Execute( symbol );
|
|
th.Wait();
|
|
ret = th.Result;
|
|
BuildLog log = symbol.log;
|
|
StringBuilder buildLog = new StringBuilder( 4096 );
|
|
foreach( var l in log.Log() )
|
|
{
|
|
switch( l.level )
|
|
{
|
|
case OutputLevel.StdOut:
|
|
project.AddLog( l.info );
|
|
break;
|
|
case OutputLevel.StdErr:
|
|
project.AddError( l.info );
|
|
break;
|
|
case OutputLevel.Info:
|
|
case OutputLevel.Warning:
|
|
project.AddWarning( l.info );
|
|
break;
|
|
}
|
|
Program.Log( l.info );
|
|
buildLog.Append( l.info + "\n" );
|
|
}
|
|
outLog = buildLog.ToString();
|
|
}
|
|
catch( Exception ex )
|
|
{
|
|
ret = -1;
|
|
outLog = ex.Message;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static string symbolServer = @"\\rsgdndnas1.rockstar.t2.corp\rsgdnd_symbolserver$\";
|
|
int UploadProsperoSymbols( string projectName, int changelist, string branch, out string log )
|
|
{
|
|
int ret = Execute( out log, project.builder.workingDirectory,
|
|
Path.Combine( Environment.ExpandEnvironmentVariables( "%SCE_PROSPERO_SDK_DIR%" ), @"host_tools\bin\prospero-symupload.exe" ),
|
|
@"add /f " + Path.Combine( project.builder.workingDirectory, @"titleupdate\" + branch + @"\" ) + @"*.elf /s " + symbolServer + " /compress /tag " + changelist + " /o" );
|
|
if( ret == 0 )
|
|
{
|
|
Program.Log( "Prospero symbols uploaded" );
|
|
}
|
|
else
|
|
{
|
|
Program.Log( "Prospero symbols failed" );
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int UploadScarlettSymbols( string projectName, int changelist, string branch, out string log )
|
|
{
|
|
int ret = Execute( out log, project.builder.workingDirectory,
|
|
Path.Combine( Environment.ExpandEnvironmentVariables( "%ProgramFiles(x86)%" ), @"Windows Kits\10\Debuggers\x64\symstore.exe" ),
|
|
@"add /f " + Path.Combine( project.builder.workingDirectory, @"titleupdate\" + branch + @"\" ) + @"game_scarlett*.exe /s " + symbolServer + " /compress /t " + projectName + " /v " + changelist + " /o" );
|
|
if( ret == 0 )
|
|
{
|
|
ret = Execute( out log, project.builder.workingDirectory,
|
|
Path.Combine( Environment.ExpandEnvironmentVariables( "%ProgramFiles(x86)%" ), @"Windows Kits\10\Debuggers\x64\symstore.exe" ),
|
|
@"add /f " + Path.Combine( project.builder.workingDirectory, @"titleupdate\" + branch + @"\" ) + @"game_scarlett*.pdb /s " + symbolServer + " /compress /t " + projectName + " /v " + changelist + " /o" );
|
|
}
|
|
if( ret == 0 )
|
|
{
|
|
Program.Log( "Scarlett symbols uploaded" );
|
|
}
|
|
else
|
|
{
|
|
Program.Log( "Scarlett symbols failed" );
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int UploadWin64Symbols( string projectName, int changelist, string branch, out string log )
|
|
{
|
|
int ret = Execute( out log, project.builder.workingDirectory,
|
|
Path.Combine( Environment.ExpandEnvironmentVariables( "%ProgramFiles(x86)%" ), @"Windows Kits\10\Debuggers\x64\symstore.exe" ),
|
|
@"add /f " + Path.Combine( project.builder.workingDirectory, @"titleupdate\" + branch + @"\" ) + @"game_win64*.exe /s " + symbolServer + " /compress /t " + projectName + " /v " + changelist + " /o" );
|
|
if( ret == 0 )
|
|
{
|
|
ret = Execute( out log, project.builder.workingDirectory,
|
|
Path.Combine( Environment.ExpandEnvironmentVariables( "%ProgramFiles(x86)%" ), @"Windows Kits\10\Debuggers\x64\symstore.exe" ),
|
|
@"add /f " + Path.Combine( project.builder.workingDirectory, @"titleupdate\" + branch + @"\" ) + @"game_win64*.pdb /s " + symbolServer + " /compress /t " + projectName + " /v " + changelist + " /o" );
|
|
}
|
|
if( ret == 0 )
|
|
{
|
|
Program.Log( "Scarlett symbols uploaded" );
|
|
}
|
|
else
|
|
{
|
|
Program.Log( "Scarlett symbols failed" );
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//bool UpdateVersion( int cl, string file, string branch, P4 p4 = null )
|
|
//{
|
|
// string versionFile = Path.Combine( project.builder.workingDirectory, file );
|
|
// if( !File.Exists( versionFile ) )
|
|
// {
|
|
// project.AddError( "Missing " + versionFile );
|
|
// return false;
|
|
// }
|
|
// if( p4 == null )
|
|
// {
|
|
// p4 = new P4( project.p4IniFile );
|
|
// if( !p4.Connect() )
|
|
// {
|
|
// project.AddError( "Failed to connect to p4" );
|
|
// return false;
|
|
// }
|
|
// }
|
|
// project.AddLog( "Sync " + versionFile );
|
|
// p4.Sync( versionFile, autoResolve: true, clobberWritable: true );
|
|
// project.AddLog( "Checkout " + versionFile );
|
|
// p4.OpenForEdit( versionFile );
|
|
// string[] lines = File.ReadAllLines( versionFile );
|
|
// Regex version = new Regex( @"^\s*\[VERSION_NUMBER\]\s*$" );
|
|
// bool found = false;
|
|
// for( int i = 0; i < lines.Length; ++i )
|
|
// {
|
|
// if( version.Match( lines[i] ).Success )
|
|
// {
|
|
// ++i;
|
|
// lines[i] = cl.ToString() + "-" + branch;
|
|
// project.AddLog( "Set version to " + lines[i] );
|
|
// found = true;
|
|
// break;
|
|
// }
|
|
// }
|
|
// if( found )
|
|
// {
|
|
// project.AddLog( "Writing " + versionFile );
|
|
// File.WriteAllLines( versionFile, lines );
|
|
// }
|
|
// else
|
|
// {
|
|
// project.AddError( "Failed to find [VERSION_NUMBER] in" );
|
|
// for( int i = 0; i < lines.Length; ++i )
|
|
// {
|
|
// project.AddError( "\t " + lines[i] );
|
|
// }
|
|
// }
|
|
// return found;
|
|
//}
|
|
|
|
//int UpdateVersion( string file, string branch )
|
|
//{
|
|
// int ret = -1;
|
|
// SgaPrebuildSettings settings = project.Settings();
|
|
// int cl = currentChangelist;
|
|
// cl = cl == 0 ? settings.lastChangelist : cl;
|
|
|
|
// if( cl != 0 )
|
|
// {
|
|
// ret = UpdateVersion( cl, file, branch ) ? 0 : 1;
|
|
// }
|
|
// return ret;
|
|
//}
|
|
|
|
/******************************************************************************************************************
|
|
** TODO put this version into the api
|
|
******************************************************************************************************************/
|
|
public IList<Perforce.P4.Changelist> GetChangelistsAtRevision( P4 p4, IList<Perforce.P4.FileSpec> specs )
|
|
{
|
|
Perforce.P4.ChangesCmdFlags flags = Perforce.P4.ChangesCmdFlags.None;
|
|
Perforce.P4.ChangesCmdOptions options = new Perforce.P4.ChangesCmdOptions( flags, "", 1, Perforce.P4.ChangeListStatus.Submitted, "", 0 );
|
|
IList<Perforce.P4.Changelist> changes = p4.rep.GetChangelists( options, specs.ToArray() );
|
|
return changes;
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
** Called from .nom. Syncs files relevant to the branch
|
|
******************************************************************************************************************/
|
|
int SyncBranch( string branchName, string outputFile = "" )
|
|
{
|
|
P4 p4 = SetupP4();
|
|
if (p4 == null)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
SgaPrebuildSettings settings = project.Settings();
|
|
IList<Perforce.P4.FileSpec> files = SyncBranches( p4, branchName, autoResolve: false );
|
|
if( files == null )
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
BranchStatus branchStatus = settings.branchStatus[branchName];
|
|
if( files.Count > 0 )
|
|
{
|
|
List<string> buildPaths = new List<string>();
|
|
AddBuildInfo( GetBuildInfoFromFiles( p4, buildPaths, files, branchStatus.lastChangelist, branchStatus.syncedChangelist ) );
|
|
}
|
|
|
|
//Don't need to do anymore if no outputFile
|
|
if( string.IsNullOrEmpty( outputFile ) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
List<string> paths = GetBranchPaths( branchName );
|
|
IList<Perforce.P4.FileSpec> specs = new List<Perforce.P4.FileSpec>( paths.Count );
|
|
foreach( string path in paths )
|
|
{
|
|
specs.Add( new Perforce.P4.FileSpec( new Perforce.P4.LocalPath( Path.Combine( p4root, path) ) ) );
|
|
}
|
|
specs = p4.Where( specs );
|
|
specs.SetVersion( new Perforce.P4.HaveRevision() );
|
|
IList<Perforce.P4.Changelist> changes = GetChangelistsAtRevision( p4, specs );
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
foreach( Perforce.P4.Changelist change in changes )
|
|
{
|
|
sb.Append( "Change " + change.Id + " on " + change.ModifiedDate.ToString( "yyyy/mm/dd" ) + " by " + change.OwnerName + "'" + change.Description.WordWrap( 18 ).Replace('\n', ' ') + "'" + Environment.NewLine);
|
|
}
|
|
try
|
|
{
|
|
string dir = Path.GetDirectoryName( outputFile );
|
|
Util.MakeDirectory( dir );
|
|
File.WriteAllText( outputFile, sb.ToString() );
|
|
}
|
|
catch( Exception ex )
|
|
{
|
|
App.LogException( ex );
|
|
return ex.HResult;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
void QuickOnOutput( object sender, string output, OutputLevel level )
|
|
{
|
|
switch( level )
|
|
{
|
|
case OutputLevel.Info:
|
|
case OutputLevel.StdOut:
|
|
project.AddLog( output );
|
|
break;
|
|
case OutputLevel.Warning:
|
|
project.AddWarning( output );
|
|
break;
|
|
case OutputLevel.StdErr:
|
|
project.AddError( output );
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
public void Activate()
|
|
{
|
|
if ( Oozy.continuous )
|
|
{
|
|
SgaPrebuildSettings settings = project.Settings();
|
|
|
|
project.SetContinuous( new TimeSpan( 0, 0, 0 ) );
|
|
int hour = 00;
|
|
int min = 00;
|
|
DateTime now = DateTime.Now;
|
|
project.SetNightbuild( new DateTime( now.Year, now.Month, now.Day, hour, min, 0 ) );
|
|
|
|
project.builder.builderLogPath = Path.Combine( project.enginePath, settings.logDir );
|
|
|
|
project.builder.buildQueue.Register( "PackageBuild", BuildTypeFlags.Packaging, PackageBuild );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
public void DeActivate()
|
|
{
|
|
if( Oozy.continuous )
|
|
{
|
|
project.builder.buildQueue.Unregister( "PackageBuild" );
|
|
project.SetContinuous( null );
|
|
project.SetNightbuild( null );
|
|
}
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
private void IPStateChanged( IPInfo info, IPInfo.State oldState, IPInfo.State newState )
|
|
{
|
|
string user = project.GetSlackUser( info.user );
|
|
if( oldState == IPInfo.State.Dead && newState == IPInfo.State.Alive )
|
|
{
|
|
project.PostSlackMessage( new List<string>() { user }, "Your PC lives." );
|
|
}
|
|
else if( oldState == IPInfo.State.Alive && newState == IPInfo.State.Dead )
|
|
{
|
|
project.PostSlackMessage( new List<string>() { user }, "Your PC has gone away." );
|
|
}
|
|
if( !info.initiallyReported )
|
|
{
|
|
info.initiallyReported = true;
|
|
if( oldState == IPInfo.State.Unknown && newState == IPInfo.State.Alive )
|
|
{
|
|
project.PostSlackMessage( new List<string>() { user }, "Your PC is currently alive." );
|
|
}
|
|
else if( oldState == IPInfo.State.Unknown && newState == IPInfo.State.Dead )
|
|
{
|
|
project.PostSlackMessage( new List<string>() { user }, "Your PC is currently dead." );
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
void ReplaceCommand( Builder builder, string xmlDefinedName, string displayName, string command )
|
|
{
|
|
BuildEntry build = builder.GetBuildByName( xmlDefinedName );
|
|
if( build != null )
|
|
{
|
|
build.displayName = displayName;
|
|
BuildBatchFile batch = build as BuildBatchFile;
|
|
if( batch != null )
|
|
{
|
|
foreach( var subBuild in batch.builds )
|
|
{
|
|
if( subBuild is BuildCommand )
|
|
{
|
|
build.displayName = displayName;
|
|
(subBuild as BuildCommand).command = command;
|
|
return;
|
|
}
|
|
}
|
|
Console.Error.WriteLine( xmlDefinedName + " couldn't find a BuildCommand, you been nom fiddling?" );
|
|
return;
|
|
}
|
|
Console.Error.WriteLine( xmlDefinedName + ": isn't a BuildBatchFile, you been nom fiddling?" );
|
|
return;
|
|
}
|
|
Console.Error.WriteLine( "Couldn't find \"" + xmlDefinedName + "\" in build list" );
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
** This is called when any build related options have changed. "building" is set when GenerateBuild is called for doing the actual build
|
|
******************************************************************************************************************/
|
|
public bool GeneratePackageBuild( Builder builder, BuildParams buildParams )
|
|
{
|
|
bool ret = true;
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
bool OnNightbuild( Builder builder )
|
|
{
|
|
bool reboot = SystemUpdates.PendingReboot();
|
|
if( reboot )
|
|
{
|
|
project.PostBuildError( "I have pending updates and stuff, looks like I need to be rebooted. If I do it myself I won't auto-restart." );
|
|
}
|
|
|
|
SgaPrebuildSettings settings = project.Settings();
|
|
|
|
DateTime now = DateTime.Now;
|
|
string msg = now.ToString( "dd/MM/yyyy HH:mm" ) + ": Nightbuild started";
|
|
project.StartBuildThread( msg );
|
|
project.AddLog( msg );
|
|
//Friday will have had changes probably, and it's "nightbuild" will happen on saturday. Hence check monday here to cater for no changes on sunday
|
|
buildOnlyIfSynced = (now.DayOfWeek == DayOfWeek.Saturday || now.DayOfWeek == DayOfWeek.Sunday || now.DayOfWeek == DayOfWeek.Monday);
|
|
|
|
nightbuild = true;
|
|
CIResult result = null;
|
|
BuildParams buildParams = new BuildParams();
|
|
buildParams.rebuild = true;
|
|
buildParams.flags = BuildTypeFlags.Nightbuild;
|
|
try
|
|
{
|
|
int retry = 10;
|
|
while( result == null && retry > 0 )
|
|
{
|
|
result = DoBuild( builder, buildParams );
|
|
if( result == null )
|
|
{
|
|
project.AddError( "Nightbuild failed with something more than likely p4 related, waiting to try again" );
|
|
Thread.Sleep( 10 * 1000 );
|
|
}
|
|
}
|
|
}
|
|
catch( Exception ex )
|
|
{
|
|
project.AddError( "OnNightbuild exception" );
|
|
project.PostBuildError( App.LogException( ex ) );
|
|
}
|
|
settings.filesSyncedToday = 0;
|
|
buildOnlyIfSynced = false;
|
|
nightbuild = false;
|
|
|
|
project.PostBuildMessage( "Nightbuild Complete." );
|
|
if( result != null && result.ranNormally )
|
|
{
|
|
project.StopBuildThreadSuccess();
|
|
}
|
|
else
|
|
{
|
|
project.StopBuildThreadError();
|
|
}
|
|
|
|
if( result == null )
|
|
{
|
|
return true; //want that log
|
|
}
|
|
return result.ranNormally;
|
|
}
|
|
|
|
static public int SetupIB( string[] args )
|
|
{
|
|
try
|
|
{
|
|
using( RegistryKey keyBase = RegistryKey.OpenBaseKey( RegistryHive.LocalMachine, RegistryView.Registry32 ) )
|
|
{
|
|
if( null == keyBase )
|
|
{
|
|
return 1;
|
|
}
|
|
using( RegistryKey builderKey = keyBase.CreateSubKey( @"SOFTWARE\WOW6432Node\Xoreax\IncrediBuild\Builder" ) )
|
|
{
|
|
builderKey.SetValue( "UseMSBuild", "1", RegistryValueKind.String );
|
|
}
|
|
using( RegistryKey buildServiceKey = keyBase.CreateSubKey( @"SOFTWARE\WOW6432Node\Xoreax\IncrediBuild\BuildService" ) )
|
|
{
|
|
buildServiceKey.SetValue( "CoordHost", "Rsgibc", RegistryValueKind.String );
|
|
buildServiceKey.SetValue( "CoordPort", "31104", RegistryValueKind.String );
|
|
buildServiceKey.SetValue( "BackupCoordHost", "10.39.18.36", RegistryValueKind.String );
|
|
buildServiceKey.SetValue( "BackupCoordPort", "31104", RegistryValueKind.String );
|
|
buildServiceKey.SetValue( "BackupCoordDisplay", "Rsgldnibc4", RegistryValueKind.String );
|
|
}
|
|
}
|
|
string exe = @"N:\RSGEDI\Outsource\Ruffian\Ruffian Tools\Utils\IBSetupConsole.exe";
|
|
Builder builder = new Builder();
|
|
builder.test = false;
|
|
|
|
BuildEntry entry = new BuildCommand( Path.GetDirectoryName( exe ), exe, "/Install /Components=Agent /Coordinator=Rsgibc" );
|
|
|
|
Task build = builder.Execute( entry );
|
|
build.Wait();
|
|
|
|
return entry.errorCode;
|
|
}
|
|
catch( Exception ex )
|
|
{
|
|
App.LogException( ex );
|
|
return ex.HResult;
|
|
}
|
|
}
|
|
|
|
string InstallIB()
|
|
{
|
|
if( 0 != Program.RunLocalFunction( this, SetupIB, new string[1] ) )
|
|
{
|
|
return "Failed to FixIB";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
bool OnContinuous( Builder builder )
|
|
{
|
|
CIResult result = null;
|
|
SgaPrebuildSettings settings = project.Settings();
|
|
|
|
try
|
|
{
|
|
project.AddLog( DateTime.Now.ToString( "dd/MM/yyyy HH:mm" ) + ": Continuous started" );
|
|
BuildParams buildParams = new BuildParams();
|
|
buildParams.flags = BuildTypeFlags.Continuous;
|
|
result = DoBuild( builder, buildParams );
|
|
}
|
|
catch( Exception ex )
|
|
{
|
|
project.AddError( "OnContinuous exception\n" + App.LogException( ex ) );
|
|
}
|
|
if( result == null )
|
|
{
|
|
return true; //want that log
|
|
}
|
|
return result.ranNormally;
|
|
}
|
|
|
|
/******************************************************************************************************************
|
|
**
|
|
******************************************************************************************************************/
|
|
CIResult DoBuild( Builder builder, BuildParams buildParams )
|
|
{
|
|
SgaPrebuildSettings settings = project.Settings();
|
|
|
|
P4 p4 = SetupP4();
|
|
if( p4 == null )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
bool syncedFiles = false;
|
|
|
|
int currentChangelist = -1;
|
|
foreach( var pair in settings.branchStatus )
|
|
{
|
|
project.AddLog( "Last changelist for " + pair.Key + " was " + pair.Value.lastChangelist );
|
|
}
|
|
|
|
bool skipForWeekend = false;
|
|
|
|
IList<Perforce.P4.FileSpec> syncFiles = new List<Perforce.P4.FileSpec>();
|
|
IList<Perforce.P4.Changelist> latest = p4.GetChangelists( 1, Perforce.P4.ChangeListStatus.Submitted );
|
|
buildInfo = null;
|
|
buildPaths = new List<string>();
|
|
if( latest.Count > 0 )
|
|
{
|
|
currentChangelist = latest[0].Id;
|
|
bool preview = project.builder.test;
|
|
IList<Perforce.P4.FileSpec> files = SyncBranches( p4, currentChangelist: currentChangelist );
|
|
if( files == null )
|
|
{
|
|
//The api will never return null unless p4 has failed somewhere
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
if( nightbuild || package )
|
|
{
|
|
project.PostBuildMessage( "Synced " + files.Count + " files.\nNumber of files synced today is " + settings.filesSyncedToday );
|
|
}
|
|
if( !preview )
|
|
{
|
|
p4.RevertUnchangedFiles();
|
|
}
|
|
|
|
settings.filesSyncedToday += files.Count;
|
|
if( !(nightbuild || package) && (files == null || files.Count == 0) )
|
|
{
|
|
project.AddError( "P4: No files synced." );
|
|
settings.lastCIChangelist = currentChangelist;
|
|
return new CIResult();
|
|
}
|
|
if( (nightbuild || package) && buildOnlyIfSynced && settings.filesSyncedToday == 0 )
|
|
{
|
|
project.AddWarning( "It's nightbuild, it's the weekend and nothing has changed today." );
|
|
project.PostBuildMessage( "It's nightbuild, it's the weekend and nothing has changed today." );
|
|
settings.lastCIChangelist = currentChangelist;
|
|
skipForWeekend = true;
|
|
}
|
|
}
|
|
|
|
if( files.Count > 0 )
|
|
{
|
|
syncedFiles = true;
|
|
|
|
buildInfo = GetBuildInfoFromFiles( p4, buildPaths, files, settings.lastCIChangelist, currentChangelist );
|
|
if( buildInfo == null )
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
//pump it at the project, to handle changes
|
|
CIResult result = null;
|
|
bool createPackage = settings.createPackage;
|
|
if( skipForWeekend )
|
|
{
|
|
result = settings.lastNightbuildResult;
|
|
}
|
|
else
|
|
{
|
|
bool retry = false;
|
|
project.buildEnvironment["RSG_AUTOMATION_CODEBUILDER_SRC_CL"] = currentChangelist.ToString();
|
|
|
|
bool oldCreatePackage = settings.createPackage;
|
|
//just make nightbuild act as CI
|
|
if( (nightbuild && !package) && !settings.nightBuild )
|
|
{
|
|
settings.createPackage = false;
|
|
}
|
|
//do a time check, disallow nightbuild but allow hand requested packages
|
|
if( !package && nightbuild )
|
|
{
|
|
DateTime StartHols = new DateTime( 2021, 12, 11, 12, 0, 0 );
|
|
DateTime EndHols = new DateTime( 2022, 1, 4, 12, 0, 0 );
|
|
DateTime now = DateTime.Now;
|
|
if( now > StartHols && now < EndHols )
|
|
{
|
|
project.AddLog( "Skipping package, it's Christmas" );
|
|
settings.createPackage = false;
|
|
}
|
|
}
|
|
|
|
if( syncedFiles )
|
|
{
|
|
AddBuildInfo( buildInfo );
|
|
}
|
|
else
|
|
{
|
|
buildInfo = new List<BuildInfo>();
|
|
}
|
|
if( syncedFiles && buildParams.flags.HasFlag( BuildTypeFlags.Packaging ) )
|
|
{
|
|
project.PostBuildMessage( "Files were synced, doing a CI pass." );
|
|
BuildTypeFlags oldFlags = buildParams.flags;
|
|
buildParams.flags &= ~BuildTypeFlags.Packaging;
|
|
buildParams.flags |= BuildTypeFlags.Continuous;
|
|
result = project.HandleFileChanges( buildParams, retry, p4, currentChangelist, buildInfo, buildPaths );
|
|
buildParams.flags = oldFlags;
|
|
if( result.ranNormally && project.projectStatus == ProjectStatus.Success )
|
|
{
|
|
project.PostBuildMessage( "Doing package pass." );
|
|
result = project.HandleFileChanges( buildParams, retry, p4, currentChangelist, buildInfo, buildPaths );
|
|
}
|
|
else
|
|
{
|
|
project.PostBuildError( "Skipping package pass, something went wrong." );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = project.HandleFileChanges( buildParams, retry, p4, currentChangelist, buildInfo, buildPaths );
|
|
}
|
|
|
|
settings.createPackage = oldCreatePackage;
|
|
}
|
|
if( nightbuild )
|
|
{
|
|
settings.lastNightbuildResult = result;
|
|
}
|
|
else
|
|
{
|
|
settings.lastResult = result;
|
|
}
|
|
|
|
string msg = "";
|
|
List<string> sendToUsers = new List<string>();
|
|
Stopwatch symbolTime = null;
|
|
string tmpLabel = "GTA5_GEN9_PREBUILD_TMP";
|
|
string QALabel = "GTA5_GEN9_PREBUILD";
|
|
if( result.ranNormally )
|
|
{
|
|
if( nightbuild || package )
|
|
{
|
|
List<string> QA = new List<string>()
|
|
{
|
|
"gen9qa",
|
|
};
|
|
bool showReport = false;
|
|
if( !skipForWeekend )
|
|
{
|
|
project.PostBuildMessage( "Processing post build." );
|
|
if( project.projectStatus == ProjectStatus.Success )
|
|
{
|
|
//clear out build info, this could cause unwanted growth otherwise
|
|
foreach( var pair in branchPaths )
|
|
{
|
|
//maybe clear out package info after 7 days?
|
|
if( nightbuild )
|
|
{
|
|
settings.branchStatus[pair.Key].sinceNightbuild.Clear();
|
|
}
|
|
settings.branchStatus[pair.Key].current.Clear();
|
|
}
|
|
|
|
bool uploadSymbols = !builder.test && settings.uploadSymbols;
|
|
bool prosperoOk = false;
|
|
bool scarlettOk = false;
|
|
bool win64Ok = false;
|
|
string prosperoOutput;
|
|
string scarlettOutput;
|
|
string win64Output;
|
|
if( uploadSymbols )
|
|
{
|
|
string branch = "";
|
|
if( !buildParams.TryGetValue( "packagename", out branch ) )
|
|
{
|
|
if( !buildParams.TryGetValue( "branch", out branch ) )
|
|
{
|
|
branch = "dev_gen9_sga_merge";
|
|
}
|
|
}
|
|
symbolTime = new Stopwatch();
|
|
symbolTime.Start();
|
|
project.PostBuildMessage( "Uploading prospero symbols for " + branch + "." );
|
|
prosperoOk = UploadProsperoSymbols( "GTAO", currentChangelist, branch, out prosperoOutput ) == 0 /*&& UploadProsperoSymbols("GTAO", currentChangelist, "dev_gen9_trailer", out prosperoOutput) == 0*/;
|
|
project.PostBuildMessage( "Uploading scarlett symbols for " + branch + "." );
|
|
scarlettOk = UploadScarlettSymbols( "GTAO", currentChangelist, branch, out scarlettOutput ) == 0 /*&& UploadScarlettSymbols("GTAO", currentChangelist, "dev_gen9_trailer", out scarlettOutput) == 0*/;
|
|
project.PostBuildMessage( "Uploading x64 symbols for " + branch + "." );
|
|
win64Ok = UploadWin64Symbols( "GTAO", currentChangelist, branch, out win64Output ) == 0 /*&& UploadWin64Symbols("GTAO", currentChangelist, "dev_gen9_trailer", out win64Output) == 0*/;
|
|
symbolTime.Stop();
|
|
}
|
|
|
|
if( createPackage )
|
|
{
|
|
if( !builder.test )
|
|
{
|
|
if( settings.createLabels )
|
|
{
|
|
//Create/get temp label
|
|
Perforce.P4.Label label = p4.GetLabel( tmpLabel );
|
|
label.Description = "Synced to @" + currentChangelist;
|
|
//set the description
|
|
p4.UpdateLabel( label );
|
|
|
|
//Add the range of files we synced to
|
|
List<Perforce.P4.FileSpec> specs = new List<Perforce.P4.FileSpec>();
|
|
specs.AddRange( syncFiles );
|
|
|
|
//add files that have been submited due to the build
|
|
if( result.filesCheckedIn.Count > 0 )
|
|
{
|
|
specs.AddRange( result.filesCheckedIn );
|
|
}
|
|
|
|
//Tag all the files in this label
|
|
p4.Tag( label.Id, specs );
|
|
|
|
//Get rid of the previous label
|
|
p4.DeleteLabel( QALabel );
|
|
p4.CopyLabel( QALabel, label.Id );
|
|
p4.DeleteLabel( label.Id );
|
|
}
|
|
}
|
|
sendToUsers = QA;
|
|
showReport = true;
|
|
}
|
|
|
|
if( uploadSymbols )
|
|
{
|
|
if( !prosperoOk )
|
|
{
|
|
msg += "`Looks like the Prospero symbols didn't upload.`\n";
|
|
}
|
|
if( !scarlettOk )
|
|
{
|
|
msg += "`Looks like the Scarlett symbols didn't upload.`\n";
|
|
}
|
|
if( !win64Ok )
|
|
{
|
|
msg += "`Looks like the Win64 symbols didn't upload.`\n";
|
|
}
|
|
}
|
|
}
|
|
else if( createPackage )
|
|
{
|
|
showReport = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( DateTime.Now.DayOfWeek == DayOfWeek.Monday )
|
|
{
|
|
sendToUsers = QA;
|
|
msg += "Nothing was built as there was no need, previous package details follows:\n";
|
|
showReport = true;
|
|
}
|
|
}
|
|
if( showReport )
|
|
{
|
|
if( project.projectStatus == ProjectStatus.Success )
|
|
{
|
|
string packages = string.Join( ", ", result.branchInfo.Select( a => a.Value.name ) );
|
|
if( package )
|
|
{
|
|
msg += "Packages " + packages + " complete, sync to *@" + QALabel + "* which has been built to _" + result.builtToChangelist + "_.\n";
|
|
}
|
|
else
|
|
{
|
|
msg += "Nightbuild complete, sync to *@" + QALabel + "* which has been built to _" + result.builtToChangelist + "_.\n";
|
|
}
|
|
|
|
if( settings.createPackage )
|
|
{
|
|
foreach( var pair in result.branchInfo )
|
|
{
|
|
if( string.IsNullOrEmpty( pair.Value.packageDir ) )
|
|
{
|
|
msg += "'For some reason it looks like no files were copied for " + pair.Key + "`\n";
|
|
}
|
|
else
|
|
{
|
|
msg += "Packages for " + pair.Key + " can be found in ```" + SlackClient.MakeFileHyperLink( pair.Value.packageDir, pair.Value.packageDir ) + "```\n";
|
|
string prosperoDeployBat = Path.Combine( pair.Value.packageDir, "CopyAndDeployProspero.bat" );
|
|
msg += "Use " + SlackClient.MakeFileHyperLink( prosperoDeployBat, prosperoDeployBat ) + " to copy and deploy.\n";
|
|
string scarlettDeployBat = Path.Combine( pair.Value.packageDir, "CopyAndDeployScarlett.bat" );
|
|
msg += "Scarlett: " + SlackClient.MakeFileHyperLink( scarlettDeployBat, scarlettDeployBat ) + " \n";
|
|
if( pair.Key != result.branchInfo.Last().Key )
|
|
{
|
|
msg += "-----------------------------";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( package )
|
|
{
|
|
if( !string.IsNullOrEmpty( packageUser ) )
|
|
{
|
|
sendToUsers = new List<string>( 1 ) { packageUser };
|
|
msg += "`Sorry, package failed, no new build for you yet.`";
|
|
}
|
|
}
|
|
else if( nightbuild )
|
|
{
|
|
sendToUsers = QA;
|
|
msg += "`Sorry, nightbuild failed, no new build for you yet.`";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
settings.lastCIChangelist = currentChangelist;
|
|
settings.lastBuildStatus = project.buildStatus;
|
|
}
|
|
bool showTimings = !string.IsNullOrEmpty( msg );
|
|
|
|
if( nightbuild && SystemUpdates.PendingReboot() )
|
|
{
|
|
msg += "`I have pending updates and stuff, looks like I need to be rebooted. If I do it myself I won't auto-restart.`\n";
|
|
}
|
|
List<SlackMessageResponse> response = null;
|
|
if( showTimings )
|
|
{
|
|
String addendum = "Build Took: " + result.buildDuration.OozyTime() + "\n";
|
|
if( symbolTime != null )
|
|
{
|
|
addendum += "Upload Symbols Took: " + symbolTime.Elapsed.OozyTime() + "\n";
|
|
}
|
|
addendum += "Copy Took: " + result.copyDuration.OozyTime() + "\n";
|
|
addendum += "Total Copied: " + ((float)(result.copySize) / 1024.0 / 1024.0 / 1024.0).ToString( "0.00" ) + " GB\n";
|
|
|
|
if( !sendToUsers.Empty() )
|
|
{
|
|
response = project.NotifySlackUsers( sendToUsers, msg );
|
|
}
|
|
else
|
|
{
|
|
response = project.PostSlackMessage( msg );
|
|
}
|
|
if( response != null && !string.IsNullOrEmpty( addendum ) )
|
|
{
|
|
project.PostSlackMessage( addendum, response );
|
|
}
|
|
}
|
|
if( nightbuild && settings.transferPackage )
|
|
{
|
|
try
|
|
{
|
|
foreach( var pair in result.branchInfo )
|
|
{
|
|
string dest = Path.GetFileName( pair.Value.packageDir );
|
|
dest = Path.Combine( settings.transferDir, pair.Key, dest );
|
|
project.PostSlackMessage( "Copying " + pair.Value.packageDir + " to " + dest, response );
|
|
Program.CopyFiles( pair.Value.packageDir, dest, throwOnFail: true );
|
|
project.PostSlackMessage( "Completed.", response );
|
|
}
|
|
}
|
|
catch( Exception ex )
|
|
{
|
|
msg = App.LogException( ex );
|
|
project.PostSlackMessage( msg, response );
|
|
}
|
|
}
|
|
|
|
bool submitProjectFiles = !builder.test;
|
|
if( submitProjectFiles && settings.submitP4 )
|
|
{
|
|
RemoveProjGen( p4, true );
|
|
}
|
|
project.buildEnvironment["RSG_AUTOMATION_CODEBUILDER_SRC_CL"] = "";
|
|
|
|
return result;
|
|
}
|
|
|
|
}
|
|
}
|