'============================================================================= ' This is the new (200902xx) Oasis Prebuild Script ' Author: v1.0 Luke Mason - Initial Version ' ' ' This script will: ' a: get the specified release branch from SVN ' b: get the list of every file to be applied for a specific release ' c: log operations on each file in the list to a log file ' d: attempt to apply a promo group to a file if its from PVCS ' e: write an apply string to an output file for all sql files ' f: create a tag in the svn repository ' g: label the promo group in the PVCS repository '============================================================================= Option Explicit const FOR_READING = 1 const FOR_WRITING = 2 const FOR_APPENDING = 8 const USAGE = "Usage: cscript oasisprebuild.vbs [-tb ] [-bt ] [-e ] [-br ] [-l ]" const log_path = "d:\Build_Logs\" const PVCS_LOCAL = "d:\build\pvcs" const SVN_REMOTE = "http://it28:8000/subversion" const SVN_LOCAL = "d:\build\svn_wc" const bDebug = false const LOG_NORMAL = "NORMAL" const LOG_WARN = "WARNING" const LOG_FAIL = "FAILURE" const LOG_ERROR = "ERROR" dim target_build_name '2009.1, 2009.2 etc dim build_type 'testall, testnew, prod, br dim target_env 'prod, sit, uat etc dim target_br 'only if build_type=br, id of br to build dim file_path_date : file_path_date = fmtDateYYYYMMDD(Now) dim file_path_time : file_path_time = fmtTimeHHMM(Now) Dim rs Dim con Dim sql Dim fso Dim output_file Dim output_file_name Dim output_file_log_name Dim log_file Dim log_file_name Dim target_promo Dim status_ok Dim temp_str Dim svn_repos_oasis Dim svn_repos_bms Dim svn_wc_base : svn_wc_base = SVN_LOCAL Dim svn_wc_oasis : svn_wc_oasis = svn_wc_base & "\oasis" Dim svn_wc_bms : svn_wc_bms = svn_wc_base & "\bms" Dim svn_repos_oasis_tags Dim svn_repos_bms_tags Dim ssDBUserId Dim ssDBPassword Dim ssDBName Dim connStr Dim objShell Dim logformat : logformat = "FILE" status_ok = getScriptParameters() if not status_ok then 'Unable to write to log as not initialised yet Wscript.stderr.writeline("Fatal Error: Unable to get Script Parameters") Wscript.stdout.writeline(USAGE) Wscript.Quit(1) end if 'generate the various file names for this build output_file_name = log_path & file_path_date & "_" & file_path_time & "_" & target_env & "_applySQL.cmd" output_file_log_name = log_path & file_path_date & "_" & file_path_time & "_" & target_env & "_applySQL.log" log_file_name = log_path & file_path_date & "_" & file_path_time & "_" & target_env & "_oasisprebuild.log" connStr = "DSN=SSDEV;UID=" & ssDBUserId & ";PWD=" & ssDBPassword & ";Database=" & ssDBName target_promo = determinePromo(build_type) svn_repos_oasis = SVN_REMOTE & "/Oasis/branches/release/" & target_build_name & "/" svn_repos_bms = SVN_REMOTE & "/BMS/branches/release/" & target_build_name & "/" svn_repos_oasis_tags = SVN_REMOTE & "/Oasis/tags/" & target_build_name & "_" & target_env & "_" & file_path_date svn_repos_bms_tags = SVN_REMOTE & "/BMS/tags/" & target_build_name & "_" & target_env & "_" & file_path_date Set fso = Wscript.CreateObject("Scripting.FileSystemObject") Set objShell = WScript.CreateObject("WScript.Shell") Dim temp_path : temp_path = reverse(mid(reverse(output_file_name), instr(reverse(output_file_name), "\"), len(output_file_name))) if not fso.folderExists(temp_path) then debug("temp_path: " & temp_path) fso.createfolder(temp_path) end if Set output_file = fso.OpenTextFile(output_file_name, FOR_WRITING, true) Set log_file = fso.OpenTextFile(log_file_name, FOR_WRITING, true) Log "Starting prebuild script", "", LOG_NORMAL LogSectionOpen "Display Parameters" Log "Date & Time: " & file_path_date & " " & file_path_time, "", LOG_NORMAL Log "build type: " & build_type, "", LOG_NORMAL Log "target build: " & target_build_name, "", LOG_NORMAL Log "target environment: " & target_env, "", LOG_NORMAL Log "target promo: " & target_promo, "", LOG_NORMAL Log "br id: " & target_br, "", LOG_NORMAL Log "logformat: " & logformat, "", LOG_NORMAL LogSectionClose "Display Parameters" ' Get a copy of the SVN repositories. status_ok = getSVNWorkingCopy(target_build_name, file_path_date) if not status_ok then Log "Unable to get SVN Repositories.", "", LOG_ERROR Wscript.Quit(1) end if ' Create a database connection Set con = Wscript.CreateObject("ADODB.Connection") on error resume next con.Open connStr if err.number <> 0 then Log "Problem connecting to database", "Error Number: " & err.number & "; Error Source: " & err.source & "; Error Desc: " & err.description & "; Connection String: " & connStr, LOG_ERROR err.clear WScript.Quit(1) end if on error goto 0 if (ucase(build_type) = "BR") then sql = "sp_get_combined_build_files 'BR', null, '" & target_env & "', " & target_br elseif (ucase(build_type) = "PROD" or ucase(build_type) = "TESTALL" or ucase(build_type) = "TESTNEW") then sql = "sp_get_combined_build_files '" & build_type & "', '" & target_build_name & "', '" & target_env & "', null" else Log "Unknown Build Type: " & build_type, "", LOG_ERROR Wscript.Quit(1) end if Log "sql: " & sql, "", LOG_NORMAL on error resume next set rs = con.execute(sql) if err.number <> 0 then Log "Problem connecting to database", "Error Number: " & err.number & "; Error Source: " & err.source & "; Error Desc: " & err.description & "; SQL: " & sql, LOG_ERROR err.clear WScript.Quit(1) else on error goto 0 'do stuff if rs.eof then Log "No files returned for build sql", "SQL: " & sql, LOG_ERROR Wscript.Quit(1) elseif not rs.eof then 'if a 1 field recordset is returned, then it only contains an error message. otherwise it's the files. if (rs.fields.count = 1) then Log "Error returned from database", rs.fields(0), LOG_ERROR Wscript.Quit(1) else LogSectionOpen "Process Files" do while not rs.eof LogSectionOpen rs("filename") Log "File Name: " & rs("filename"), "", LOG_NORMAL Log "File Source: " & rs("file_source"), "", LOG_NORMAL Log "File BR: " & rs("br_id"), "", LOG_NORMAL 'get/check file from appropriate repository if(rs("file_source") = "PVCS") then call ProcessPVCSFile(rs("filename"), rs("fq_filename"), rs("filepath"), rs("revision"), target_promo) elseif (rs("file_source") = "SVN") then call ProcessSVNFile(rs("filename"), rs("fq_filename"), rs("filepath")) else Log "Unknown file_source: " & rs("file_source"), "", LOG_WARN end if 'write line to output file. only do this if seq_no is < 7. 7+ implies not a db target. if rs("seq_no") < 7 then temp_str = rs("template_string") temp_str = replace(temp_str, "[db_server]", ifnull(rs("db_server"), "NULL")) temp_str = replace(temp_str, "[db_name]", ifnull(rs("db_name"), "NULL")) temp_str = replace(temp_str, "[db_user]", ifnull(rs("db_user"), "NULL")) temp_str = replace(temp_str, "[db_pass]", ifnull(rs("db_pass"), "NULL")) if rs("file_source") = "PVCS" then temp_str = replace(temp_str, "[fq_filename]", PVCS_LOCAL & replace(rs("fq_filename"), "/", "\")) elseif (rs("file_source") = "SVN") then temp_str = replace(temp_str, "[fq_filename]", SVN_LOCAL & replace(replace(rs("fq_filename"), SVN_REMOTE, ""), "/", "\")) else Log "Unknown file_source: " & rs("file_source"), "", LOG_WARN end if temp_str = replace(temp_str, "[logfile]", ifnull(output_file_log_name, "NULL")) 'TODO - exec these directly, no logging here. output_file.writeline("rem " & rs("filename") & " -> " & rs("dest_name")) output_file.writeline(temp_str) output_file.writeline("") end if LogSectionClose rs("filename") rs.movenext loop LogSectionClose "Process Files" end if end if end if 'Tidy up db objects rs.close set rs = nothing con.close set con = nothing ' This is done as the final step. The SVN one should take moments - the PVCS one will take longer. CreateSVNTag() 'Now run asynchronously ^_^ ApplyPVCSLabel() Log "End of Script", "", LOG_NORMAL output_file.close set output_file = nothing log_file.close set log_file = nothing set fso = nothing '========================================================================== ' Everything above this line is the main script. Everything below it should be helper ' Functions and Subs only. '========================================================================== Function getScriptParameters() debug("Function: getScriptParameters") const INI_FILE_SECTION = "settings" const INI_FILE_NAME = "oasisprebuild.ini" Dim args Dim argOffset Dim currentArg set args = WScript.Arguments If args.Count = 0 Then debug("arg count = 0") getScriptParameters = false Exit Function End If argOffset = 0 do while (argOffset < args.Count) currentArg = LCase(args(argOffset)) if (len(currentArg) > 0) and (Left(currentArg, 1) = "-") then If (currentArg = "-tb" or currentArg = "--target_build") Then argOffset = argOffset + 1 target_build_name = LCase(args(argOffset)) debug("target_build_name: " & target_build_name) ElseIf (currentArg = "-bt" or currentArg = "--build_type") Then argOffset = argOffset + 1 build_type = UCase(args(argOffset)) debug("build_type: " & build_type) ElseIf (currentArg = "-e" or currentArg = "--environment") Then argOffset = argOffset + 1 target_env = UCase(args(argOffset)) debug("target_environment: " & target_env) ElseIf (currentArg = "-br" or currentArg = "--br") Then argOffset = argOffset + 1 target_br = LCase(args(argOffset)) debug("target_br: " & target_br) ElseIf (currentArg = "--help" or currentArg = "-h" or currentArg = "-?" or currentArg = "/?") Then Call displayHelp() WScript.Quit(0) ElseIf (currentArg = "-l" or currentArg = "--logformat") Then argOffset = argOffset + 1 logformat = LCase(args(argOffset)) debug("logformat: " & logformat) Else debug("Unknown argument: " & currentArg & vbcrlf & USAGE) WScript.Quit(1) End If end if argOffset = argOffset + 1 loop If argOffset > args.Count Then debug("argOffset(" & argOffset & ") >= args.count(" & args.count & ")") getScriptParameters = false Exit Function End If ssDBUserId = getINIString( INI_FILE_NAME, INI_FILE_SECTION, "SS_DB_User_Id", "" ) ssDBPassword = getINIString( INI_FILE_NAME, INI_FILE_SECTION, "SS_DB_Password", "" ) ssDBName = getINIString( INI_FILE_NAME, INI_FILE_SECTION, "SS_DB_Name", "" ) getScriptParameters = true End Function Sub displayHelp() debug("Function: displayhelp") With log_file .WriteLine(USAGE) .Writeline("-tb --target_build eg: 2009.1, 2009.2") .Writeline("-bt --build_type ") .Writeline("-e --environment ") .Writeline("-br --br This choice only valid when [-b br] is specified") .Writeline("-l --logformat File by default") .Writeline("-h --help -? /? This message") .writeline("") .writeline("Expects the system environment variables %SYBASEUSER% and %SYBASEPASS% to be defined.") .writeline("Expects an ini file in the same directory called oasisprebuild.ini") .writeline("Expects an ODBC conenction to IT_Support called SSDEV") .writeline("Expects the SVN bin directory to be in the path") .writeline("Expects the PVCS bin directory to be in the path") End With End Sub ' Generic function to read a value from a particular key in an ini file. Function getINIString( fileName, section, keyName, default ) debug("Function: getINIString") dim contents dim posSection dim posEndSection dim sContents dim value dim found dim iniFile found = False Set iniFile = CreateObject("Scripting.FileSystemObject") If Not iniFile.FileExists( fileName ) Then getINIString = default Exit Function End If 'Get contents of the INI file As a string contents = iniFile.OpenTextFile(fileName).ReadAll 'Find section posSection = InStr(1, contents, "[" & Section & "]", vbTextCompare) If posSection > 0 Then 'Section exists. Find end of section posEndSection = InStr(PosSection, contents, vbCrLf & "[") '?Is this last section? If posEndSection = 0 Then posEndSection = Len( contents ) + 1 End If ' Separate section contents sContents = Mid(contents, posSection, posEndSection - posSection) If InStr(1, sContents, vbCrLf & KeyName & "=", vbTextCompare ) > 0 Then found = True 'Separate value of a key. value = separateField(sContents, vbCrLf & keyName & "=", vbCrLf) End If End If If not Found Then value = default End If getINIString = Value Set iniFile = Nothing End Function 'Separates one field between sStart And sEnd Function separateField( ByVal sFrom, ByVal sStart, ByVal sEnd ) Dim PosB: PosB = InStr(1, sFrom, sStart, 1) If PosB > 0 Then PosB = PosB + Len(sStart) Dim PosE: PosE = InStr(PosB, sFrom, sEnd, 1) If PosE = 0 Then PosE = InStr(PosB, sFrom, vbCrLf, 1) If PosE = 0 Then PosE = Len(sFrom) + 1 SeparateField = Mid(sFrom, PosB, PosE - PosB) End If End Function function fmtDateYYYYMMDD(thisDate) 'debug("Function: fmtDateYYYYMMDD") fmtDateYYYYMMDD = PadZero(year(thisDate), 4) & PadZero(month(thisDate), 2) & PadZero(day(thisDate), 2) end function function fmtTimeHHMM(thisTime) 'debug("Function: fmtTimeHHMM") fmtTimeHHMM = PadZero(Hour(thisTime), 2) & PadZero(Minute(thisTime), 2) end function function fmtTimeHHMMSS(thisTime) 'debug("Function: fmtTimeHHMMSS") fmtTimeHHMMSS = PadZero(Hour(thisTime), 2) & PadZero(Minute(thisTime), 2) & PadZero(Second(thisTime), 2) end function function PadZero( thisInt, length ) Dim sTemp sTemp = String(length, "0") sTemp = sTemp & thisInt sTemp = Right(sTemp, length) PadZero = sTemp end Function function Log(msg, detail, msgtype) Dim tc_format : tc_format = "##teamcity[message text='[MSG]' errorDetails='[DETAIL]' status='[MSGTYPE]']" if(ucase(logformat) = "FILE") then log_file.WriteLine(fmtDateYYYYMMDD(Now) & " " & fmtTimeHHMMSS(Now) & " " & msgtype & ": " & msg) end if if(ucase(logformat) = "TEAMCITY") then msg = replace(msg, "|", "||") msg = replace(msg, "'", "|'") msg = replace(msg, "]", "|]") tc_format = replace(tc_format, "[MSG]", msg) tc_format = replace(tc_format, "[DETAIL]", detail) tc_format = replace(tc_format, "[MSGTYPE]", msgtype) Wscript.stdout.writeline(tc_format) end if 'if (bDEBUG) then ' Wscript.stdout.writeline(msgtype & ": " & msg) 'end if Log = true End Function Function LogSectionOpen(section) if(ucase(logformat) = "TEAMCITY") then Wscript.stdout.writeline("##teamcity[blockOpened name='" & section & "']") end if End Function Function LogSectionClose(section) if(ucase(logformat) = "TEAMCITY") then Wscript.stdout.writeline("##teamcity[blockClosed name='" & section & "']") end if End Function function Debug(msg) if (bDEBUG) then if(ucase(logformat) = "TEAMCITY") then Wscript.stdout.writeline("##teamcity[message text='" & replace(msg, "'", "|'") & "' errorDetails='' status='WARNING']") else Wscript.stdout.writeline("DEBUG: " & msg) end if end if End Function function DeterminePromo(build_type) debug("Function: DeterminePromo") 'This is only for PVCS build_type = ucase(build_type) select case build_type case "PROD" DeterminePromo = "PROD" case "TESTALL" DeterminePromo = "TEST" case "TESTNEW" DeterminePromo = "TEST" case else DeterminePromo = "" end select End Function Function getSVNWorkingCopy(target_build_name, file_path_date) debug("Function: getSVNWorkingCopy") Log "Getting SVN Working Copies", "", LOG_NORMAL Dim cmd_oasis : cmd_oasis = "svn checkout --username moneyonedev --password Password1 --quiet --non-interactive --revision HEAD " & svn_repos_oasis & " " & svn_wc_oasis Dim cmd_bms : cmd_bms = "svn checkout --username moneyonedev --password Password1 --quiet --non-interactive --revision HEAD " & svn_repos_bms & " " & svn_wc_bms Dim return_code Dim status_ok : status_ok = true if not fso.FolderExists(svn_wc_base) then debug("!Exist: " & svn_wc_base) fso.CreateFolder(svn_wc_base) end if if not fso.FolderExists(svn_wc_oasis) then debug("!Exist: " & svn_wc_oasis) fso.CreateFolder(svn_wc_oasis) end if if not fso.FolderExists(svn_wc_bms) then debug("!Exist: " & svn_wc_bms) fso.CreateFolder(svn_wc_bms) end if return_code = runCmd(cmd_oasis) if return_code <> 0 then Log "Couldn't check out Oasis SVN Working Copy", "Error cmd: " & cmd_oasis & "; Error code: " & return_code, LOG_ERROR status_ok = false else Log "Success: Got Oasis SVN Working Copy", "", LOG_NORMAL end if return_code = runCmd(cmd_bms) if return_code <> 0 then Log "Couldn't check out BMS SVN Working Copy", "Error cmd: " & cmd_oasis & "; Error code: " & return_code, LOG_ERROR status_ok = false else Log "Success: Got BMS SVN Working Copy", "", LOG_NORMAL end if getSVNWorkingCopy = status_ok End Function ' generic function to run a command and log the standard output. ' returns the exit code. Function runCmd(cmd) debug("Function: runCmd") Dim objExecObject Dim strText Set objExecObject = objShell.Exec(cmd) ' wait for it to finish do while objExecObject.Status = 0 WScript.Sleep 100 loop LogSectionOpen "runCmd" do while not objExecObject.StdOut.AtEndOfStream strText = objExecObject.StdOut.ReadLine() Log strText, "", LOG_NORMAL loop LogSectionClose "runCmd" runCmd = objExecObject.ExitCode End Function Function runCmdAsynch(cmd) debug("Function: runCmdAsynch") Dim objExecObject Dim strText 'the false on the end say "don't wait" Set objExecObject = objShell.Exec(cmd) runCmdAsynch = 0 End Function Function ProcessPVCSFile(filename, fq_filename, filepath, revision, target_promo) Dim cmd Dim return_code ' apply the promotion group '-q cmd = "vcs -cV:\PVCS\archives\ctpkppx1.cfg -#3 -Y -g" & target_promo & ":" & revision & " v:\pvcs\archives" & replace(fq_fileName, "/", "\") return_code = runCmd(cmd) if return_code <> 0 then Log "Failure: Couldn't apply " & target_promo & " promotion group. Code: " & return_code & "; Command: " & cmd, "", LOG_FAIL else Log "Success: Applied promo group " & target_promo & " to " & filename, "", LOG_NORMAL end if 'get the file - adding run -y to the front says answer yes to any questions (overwrite, etc) cmd = "pcli run -y get -prv:\PVCS -nm -a" & PVCS_LOCAL & " -o -bp/ -r" & revision & " " & fq_fileName return_code = runCmd(cmd) if return_code <> 0 then Log "Failure: Couldn't get " & fileName & ". Code: " & return_code & "; Command: " & cmd, "", LOG_FAIL else Log "Success: Got " & filename, "", LOG_NORMAL end if End Function Function ProcessSVNFile(filename, fq_filename, filepath) if not fso.FileExists(SVN_LOCAL & replace(replace(fq_filename, SVN_REMOTE, ""), "/", "\")) then Log "Failure: File " & filename & " does not exist at " & filepath, "", LOG_FAIL else Log "Success: File " & filename & " exists", "", LOG_NORMAL end if End Function Function CreateSVNTag() Dim cmd Dim return_code 'create the tag cmd = "svn copy " & svn_repos_oasis & " " & svn_repos_oasis_tags & " --username moneyonedev --password Password1 -m ""Automatic tag of the " & target_build_name & " Oasis Release Branch for a build""" return_code = runCmd(cmd) if return_code <> 0 then Log "Failure: Could not create tag Error Code: " & return_code, "", LOG_FAIL else Log "Success: Created SVN tag for Oasis", "", LOG_NORMAL end if 'create the tag cmd = "svn copy " & svn_repos_bms & " " & svn_repos_bms_tags & " --username moneyonedev --password Password1 -m ""Automatic tag of the " & target_build_name & " BMS Release Branch for a build""" return_code = runCmd(cmd) if return_code <> 0 then Log "Failure: Could not create tag. Code: " & return_code, "", LOG_FAIL else Log "Success: Created SVN tag for BMS", "", LOG_NORMAL end if End Function Function ApplyPVCSLabel() Dim cmd Dim return_code Dim label : label = target_promo & "_" & file_path_date 'Apply label cmd = "pcli run -y label -prv:\pvcs -z -v""" & label & """ -r" & target_promo & " /Oasis" return_code = runCmdAsynch(cmd) if return_code <> 0 then Log "Failure: Could not apply label. Code: " & return_code, "", LOG_FAIL else Log "Success: Applied PVCS Label: " & label, "", LOG_NORMAL end if End Function Public Function Reverse(sIn) Dim nC Dim sOut For nC = Len(sIn) To 1 Step -1 sOut = sOut & Mid(sIn, nC, 1) Next Reverse = sOut End Function Function ifnull(str, alternative) ifnull = str if isnull(str) then ifnull = alternative end if if len(str) < 1 then ifnull = alternative end if End Function