static List <GitLogElems> parseGitLogFileIntoGitLogElemsList(string gitLogFilePath) { GitRepositoryInfo gitRepoInfo = new GitRepositoryInfo(); string gitLog = File.ReadAllText(gitLogFilePath); List <string> lines = gitLog.Split(new string[] { _lineSeparatorString }, StringSplitOptions.RemoveEmptyEntries).ToList(); //List<string> lines = System.IO.File.ReadLines(gitLogFilePath).ToList(); List <string> logElemList = new List <string>(); GitLogElems gitLogElems; List <GitLogElems> gitLogElemsList = new List <GitLogElems>(); foreach (string line in lines) { logElemList = line.Split(new string[] { _elemSeparatorString }, StringSplitOptions.None).ToList(); gitLogElems = new GitLogElems(); gitLogElems.commitNumber = logElemList[0]; gitLogElems.author = logElemList[1]; gitLogElems.date = logElemList[2]; gitLogElems.comment = logElemList[3]; gitLogElems.authorEmail = logElemList[4]; gitLogElemsList.Add(gitLogElems); } return(gitLogElemsList); }
private static GitRepositoryInfo parseJSONStringToGitRepoInfo(string jsonString) { GitRepositoryInfo gri = new GitRepositoryInfo(); try { gri = JsonConvert.DeserializeObject <GitRepositoryInfo>(jsonString); } catch (Exception ee) { } if (gri == null) { gri = new GitRepositoryInfo(); } if (gri.master == null) { gri.master = new List <GitLogElems>(); } if (gri.tags == null) { gri.tags = new List <GitLogElems>(); } return(gri); }
static void mergeNewGitLogFileToGitRepositoryInfo(GitRepositoryInfo gitRepoInfo, EnumBranch eBranch, string gitLogFile, string buildSessionId, string buildResult, string branchName, bool hasPackageFile, bool hasBuildFailFile) { if (!File.Exists(gitLogFile)) { return; } //List<GitLogElems> newLogList = parseGitLogFileIntoGitLogElemsList(gitLogFile); List <GitLogElems> newLogList = parseGitLogFileIntoGitLogElemsListNew(gitLogFile); updateFirstCommitBuildResult(newLogList, buildSessionId, buildResult, hasPackageFile, hasBuildFailFile); if (eBranch == EnumBranch.Master) { gitRepoInfo.master.InsertRange(0, newLogList); } else if (eBranch == EnumBranch.Tag) { if (newLogList != null && newLogList.Count > 0) { GitLogElems gle = newLogList[0]; gle.commitNumber = branchName; gitRepoInfo.tags.Insert(0, gle); } } }
static void buildCodeAndMergeResult(GitRepositoryInfo gitRepoInfo, string vmName, EnumBranch eBranch, string gitLogFilePath, string buildLogFilePath, string buildResultFilePath, string branchName, List <string> notifyEmails) { string vmExecStatus = string.Empty; string vmExecStatuFilePath = Path.Combine(_projectWorkRootDir, _vmExecStatusFileName); string vmExecStatusFinishedFilePath = Path.Combine(_projectWorkRootDir, _vmExecStatusFinished); string vmGetBuildLogBackupFilePath = Path.Combine(_projectWorkRootDir, _vmGetBuildLogBackupFileName); string buildScriptLogFilePath = Path.Combine(_projectWorkRootDir, _buildScriptLogFileName); string buildResult = string.Empty; string projectSharedDir = string.Empty; string backupProjectReleasePackageDirPath = string.Empty; List <string> copyFileExtensionList = new List <string>(); copyFileExtensionList.Add(".zip"); //Project shared folder is the folder which the host computer shares VM for each project. projectSharedDir = Path.Combine(_ps.localSharedDir, gitRepoInfo.project_name); if (!Directory.Exists(projectSharedDir)) { Directory.CreateDirectory(projectSharedDir); } //The path for backing up generated packages (Can be an independant folder path). backupProjectReleasePackageDirPath = Path.Combine(_ps.releasePackageDirPath, gitRepoInfo.project_name); if (!Directory.Exists(backupProjectReleasePackageDirPath)) { Directory.CreateDirectory(backupProjectReleasePackageDirPath); } if (File.Exists(vmExecStatuFilePath)) { File.Delete(vmExecStatuFilePath); } if (File.Exists(buildScriptLogFilePath)) { File.Delete(buildScriptLogFilePath); } if (File.Exists(vmExecStatusFinishedFilePath)) { File.Delete(vmExecStatusFinishedFilePath); } //After running the VM, the git log file and the build result file will be generated _vboxOp.StartVMByName(vmName); Logger.Write(string.Format("VM : {0} gets started", vmName)); string prevVmExecStatus = string.Empty; //Keep reading the VM's execution status to see if it has finished the source code building. int indexOfDebug = 0; while (true) { if (indexOfDebug > 10000) { indexOfDebug = 0; } System.Threading.Thread.Sleep(SCAN_SLEEP_TIME_SECONDS * 1000); Console.Clear(); Console.WriteLine(string.Format("debug a {0} ({1})", (++indexOfDebug).ToString(), vmExecStatus)); if (File.Exists(vmExecStatusFinishedFilePath)) { break; } Console.WriteLine(string.Format("debug b {0} ({1})", (++indexOfDebug).ToString(), vmExecStatus)); if (File.Exists(vmExecStatuFilePath)) { Console.WriteLine(string.Format("debug c {0} ({1})", (++indexOfDebug).ToString(), vmExecStatus)); vmExecStatus = getFileText(vmExecStatuFilePath); Console.WriteLine(string.Format("debug d {0} ({1})", (++indexOfDebug).ToString(), vmExecStatus)); vmExecStatus = vmExecStatus.Trim(new char[] { ' ', '\r', '\n' }); Console.WriteLine(string.Format("debug f {0} ({1})", (++indexOfDebug).ToString(), vmExecStatus)); if (prevVmExecStatus != vmExecStatus) { Logger.Write(vmExecStatus); prevVmExecStatus = vmExecStatus; } Console.WriteLine(string.Format("debug g {0} ({1})", (++indexOfDebug).ToString(), vmExecStatus)); } Console.WriteLine(string.Format("debug h {0} ({1})", (++indexOfDebug).ToString(), vmExecStatus)); //System.Threading.Thread.Sleep(SCAN_SLEEP_TIME_SECONDS * 1000); //Console.WriteLine(string.Format("debug i {0} ({1})", (++indexOfDebug).ToString(), vmExecStatus)); } _vboxOp.StopCurrentlyRunningVMs(); Logger.Write("VM : Shut down all running VMs"); if (File.Exists(buildResultFilePath)) { buildResult = File.ReadAllText(buildResultFilePath); buildResult = buildResult.Trim(new char[] { ' ', '\r', '\n' }); } List <GitLogElems> newLogList = new List <GitLogElems>(); if (File.Exists(gitLogFilePath)) { newLogList = parseGitLogFileIntoGitLogElemsListNew(gitLogFilePath); } //We will get a build session id after the build //The build session id for master branch -> master-{commit_number} //The build session id for a tag branch -> tag_number string buildSessionId = string.Empty; if (File.Exists(buildLogFilePath)) { buildSessionId = File.ReadAllLines(buildLogFilePath)[0]; buildSessionId = buildSessionId.Trim(new char[] { ' ', '\r', '\n' }); } //Prepare the emails list that we're going to send. *start* if (newLogList.Count > 0) { MailMessager.SendToList.Add(newLogList[0].authorEmail); } List <GitLabOperation.UserInfo> projectUsers = GitLabOperation.GetProjectUsers(gitRepoInfo.project_name); if (projectUsers != null && projectUsers.Count > 0) { foreach (GitLabOperation.UserInfo u in projectUsers) { MailMessager.SendToList.Add(u.email); } } if (notifyEmails != null && notifyEmails.Count > 0) { MailMessager.SendToList.AddRange(notifyEmails); } if (_ps.notifyCcEmailsList != null && _ps.notifyCcEmailsList.Count > 0) { MailMessager.SendCcList.AddRange(_ps.notifyCcEmailsList); } List <string> attachFileList = new List <string>(); //Prepare the emails list that we're going to send. *end* string gitContentInEmail = "<br>The latest commit: <br>" + "====== " + newLogList[0].commitNumber + " =====<br>" + newLogList[0].comment; //Copy release package zip files to the backup project release package folder. if (buildResult == _buildSuccessMessage) { Logger.Write(string.Format("Project {0} {1} branch build code -> Success!", gitRepoInfo.project_name, branchName)); copyFilesByExtensions(projectSharedDir, backupProjectReleasePackageDirPath, copyFileExtensionList); attachFileList.Add(buildLogFilePath); #if EMAIL_NOTIFY MailMessager.SendMessage("Protech OS Build Server's Message(There is a SUCCESSFUL build)", "Good job! Your latest source code committed to the project of " + gitRepoInfo.project_name + " can be built up successfully.<br>" + gitContentInEmail, attachFileList); #endif } else if (buildResult == _buildErrorMessage) { Logger.Write(string.Format("Project {0} {1} branch build code -> Fail!", gitRepoInfo.project_name, branchName)); File.Copy(buildLogFilePath, Path.Combine(projectSharedDir, buildSessionId), true); attachFileList.Add(buildLogFilePath); #if EMAIL_NOTIFY MailMessager.SendMessage("Protech OS Build Server's Message(There is a FAILED build)", "We are regret to inform you that your latest source committed to the project of " + gitRepoInfo.project_name + " cannot be successfully built.<br>" + gitContentInEmail, attachFileList); #endif } //House keeping for release packages if (eBranch == EnumBranch.Master) { houseKeepingForReleasePackages(projectSharedDir, backupProjectReleasePackageDirPath); } bool hasPackageFile = false; bool hasBuildFailFile = false; if (File.Exists(Path.Combine(projectSharedDir, string.Format("{0}.zip'", buildSessionId)))) { hasPackageFile = true; } if (File.Exists(Path.Combine(projectSharedDir, string.Format("{0}'", buildSessionId)))) { hasBuildFailFile = true; } mergeNewGitLogFileToGitRepositoryInfo(gitRepoInfo, eBranch, gitLogFilePath, buildSessionId, buildResult, branchName, hasPackageFile, hasBuildFailFile); }
static void Main(string[] args) { loadSettingsConf(); prepareSystemRelatedPaths(); _gitOp = new GitOperations(); _vboxOp = new VirtualboxOperations(_ps.virtualBoxExePath); GitRepositoryInfo gitRepoInfo = new GitRepositoryInfo(); MailMessager.GmailUserName = _ps.notifyEmailUserName; MailMessager.GmailPassword = _ps.notifyEmailUserPassword; Logger.Start(Path.Combine(_buildServerLogDir, _buildHelperLogFileName)); Logger.Write("BuildHelper get started"); //1. Check if there is any Virtual Box file running at this moment. // If yes, stop them from running. _vboxOp.StopCurrentlyRunningVMs(); Logger.Write("Stopped all running VMs"); //2. Check the config file and run VMs. // The config file format : // {The project name} - {The corresponding VM for building source code} - {The build script path} string projectWorkDir = string.Empty; string jsonString = string.Empty; string projectBuildResultJsonFilePath = string.Empty; string projectBuildResultJsonFileText = string.Empty; string totalProjectBuildResultJsonFileText = string.Empty; string vmName = string.Empty; string projectBuildResultJsonOutputDir = string.Empty; foreach (ProjectConfigInfo project in _projectConfigInfoList) { Logger.Write(string.Format("================== Start working Project {0} ==================", project.projectName)); projectWorkDir = Path.Combine(_projectWorkRootDir, project.projectName); _gitLogFilePath = Path.Combine(projectWorkDir, _gitLogFileName); _buildResultFilePath = Path.Combine(projectWorkDir, _buildResultFileName); _buildLogFilePath = Path.Combine(projectWorkDir, _buildLogFileName); Logger.Write(string.Format("Checking the project working folder({0}) existence", projectWorkDir)); if (!Directory.Exists(projectWorkDir)) { Directory.CreateDirectory(projectWorkDir); } Logger.Write(string.Format("Checked the project working folder({0}) - OK!", projectWorkDir)); projectBuildResultJsonFilePath = Path.Combine(_buildResultJsonFilesDirRealPath, string.Format("BuildResult_{0}.json", project.projectName)); projectBuildResultJsonFileText = string.Empty; if (File.Exists(projectBuildResultJsonFilePath)) { projectBuildResultJsonFileText = File.ReadAllText(projectBuildResultJsonFilePath).Trim(); } gitRepoInfo = parseJSONStringToGitRepoInfo(projectBuildResultJsonFileText); gitRepoInfo.project_name = project.projectName; _gitOp.SetGitUrlAndAuth(project.gitUrl, project.gitUser, project.gitPassword); _gitOp.CheckTheLatestCommit(); string masterHeadCommitNumber = _gitOp.MasterHeadCommitNumber; List <string> tagList = _gitOp.TagList; vmName = _vboxOp.GetVMNameByVDIFilePath(project.vdiFilePath); if (string.IsNullOrEmpty(vmName)) { Logger.Write(string.Format("{0} does not have a corresponding VM", project.vdiFilePath)); continue; } _vboxOp.SetVMCpuCount(vmName, _ps.vmCpuCount); Logger.Write(string.Format("VM's CPU count = {0}", _ps.vmCpuCount)); _vboxOp.SetVMRamSizeInMB(vmName, _ps.vmRamSizeInMB); Logger.Write(string.Format("VM's RAM size in MB = {0}", _ps.vmRamSizeInMB)); _vboxOp.AddShareFolder(vmName, Path.GetFileName(_ps.localSharedDir), _ps.localSharedDir); Logger.Write(string.Format("Mounted {0} as the shared folder", _ps.localSharedDir)); //Make a comment here... //3. Wait for the VM to finish building if ((gitRepoInfo.master != null && gitRepoInfo.master.Count == 0) || (gitRepoInfo.master[0].commitNumber != null && !masterHeadCommitNumber.StartsWith(gitRepoInfo.master[0].commitNumber))) { Logger.Write(string.Format("Project {0} : Found one new commit. Start building process...", project.projectName)); createUbuntuOSBuildScript(project, project.buildTrunk); buildCodeAndMergeResult(gitRepoInfo, vmName, EnumBranch.Master, _gitLogFilePath, _buildLogFilePath, _buildResultFilePath, _ps.buildTrunk, project.notifyPeople); } else { Logger.Write(string.Format("Project {0} : No new commit to build", project.projectName)); } #if BUILD_TAGS foreach (string tag in tagList) { if (gitRepoInfo.tags.FindIndex(t => t.commitNumber == tag) < 0) { Logger.Write(string.Format("Project {0} : Found one new tag {1}. Start building process...", project.projectName, tag)); createUbuntuOSBuildScript(project, tag); buildCodeAndMergeResult(gitRepoInfo, vmName, EnumBranch.Tag, _gitLogFilePath, _buildLogFilePath, _buildResultFilePath, tag, project.notifyPeople); } } #endif jsonString = JsonConvert.SerializeObject(gitRepoInfo); Logger.Write(string.Format("Creating json-formatted build string for {0}...", project.projectName)); File.WriteAllText(projectBuildResultJsonFilePath, jsonString); Logger.Write(string.Format("Finished json-formatted build string for {0}...", project.projectName)); totalProjectBuildResultJsonFileText += jsonString + ","; Logger.Write(string.Format("================== Finish working Project {0} ==================", project.projectName)); } totalProjectBuildResultJsonFileText = totalProjectBuildResultJsonFileText.TrimEnd(new char[] { ',' }); File.WriteAllText(_totalProjectBuildResultJsonFilePath, totalProjectBuildResultJsonFileText); Logger.Write("BuildHelper says, \"Let's call it day!\""); }