/// <summary> /// method tries to push to repository /// </summary> /// <param name="committerName">committer name</param> /// <param name="committerEmail">committer detail</param> /// <param name="authorEmail">author email id</param> /// <param name="solutionFile">solution file info</param> /// <param name="solutionFilePath">path of file that contains list of solution to be released</param> /// <param name="hashSet">hash set to store release solution</param> private static void TryPushToRepository( string committerName, string committerEmail, string authorEmail, SolutionFileInfo solutionFile, string solutionFilePath, HashSet <string> hashSet) { RepositoryConfigurationConstants.ResetLocalDirectory(); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueuemPushingToStatus; solutionFile.Update(); GitDeploy.GitRepositoryManager gitRepositoryManager = GetRepositoryManager(committerName, committerEmail, authorEmail, solutionFile); gitRepositoryManager.UpdateRepository(); PopulateHashset(solutionFilePath, hashSet); if (!hashSet.Contains(solutionFile.SolutionFileZipName) && solutionFile.IncludeInRelease) { hashSet.Add(solutionFile.SolutionFileZipName); } SaveHashSet(solutionFilePath, hashSet); gitRepositoryManager.CommitAllChanges(solutionFile, solutionFilePath); gitRepositoryManager.PushCommits(); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueuemPushToRepositorySuccessStatus; solutionFile.Update(); }
/// <summary> /// method tries to push to repository /// </summary> /// <param name="committerName">committer name</param> /// <param name="committerEmail">committer detail</param> /// <param name="authorEmail">author email id</param> /// <param name="solutionFile">solution file info</param> /// <param name="solutionFilePath">path of file that contains list of solution to be released</param> /// <param name="hashSet">hash set to store release solution</param> /// <param name="gitRepositoryManager">object initialization for class RepositoryManager</param> private void TryPushToRepository( string committerName, string committerEmail, string authorEmail, SolutionFileInfo solutionFile, string solutionFilePath, HashSet <string> hashSet, GitDeploy.GitRepositoryManager gitRepositoryManager) { ////RepositoryConfigurationConstants.ResetLocalDirectory(); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueuemPushingToStatus; solutionFile.Solution.Attributes["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); Workspace workspace = null; ////GitDeploy.GitRepositoryManager gitRepositoryManager = GetRepositoryManager(committerName, committerEmail, authorEmail, solutionFile); if (solutionFile.Repository != Constants.SourceControlAzureDevOpsServer) { gitRepositoryManager.UpdateRepository(); } ////433710000 value for Yes if (solutionFile.SolutionsTxt == 433710000 && File.Exists(solutionFilePath)) { File.WriteAllText(solutionFilePath, string.Empty); hashSet.Clear(); } this.PopulateHashset(solutionFilePath, hashSet); if (!hashSet.Contains(solutionFile.SolutionFileZipName) && solutionFile.IncludeInRelease) { hashSet.Add(solutionFile.SolutionFileZipName); } if (solutionFile.Repository == Constants.SourceControlAzureDevOpsServer) { workspace = gitRepositoryManager.ConnectTFSMap(solutionFile, solutionFilePath, hashSet); } else { this.SaveHashSet(solutionFilePath, hashSet); gitRepositoryManager.CommitAllChanges(solutionFile, solutionFilePath, null); gitRepositoryManager.PushCommits(); } solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueuemPushToRepositorySuccessStatus; solutionFile.Solution.Attributes["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); }
/// <summary> /// Method merges solution components into Master solution and exports along with unzip file /// </summary> /// <param name="serviceProxy">organization service proxy</param> /// <param name="solutionFile">solution file info</param> private void ExportMasterSolution(OrganizationServiceProxy serviceProxy, SolutionFileInfo solutionFile) { this.MergeSolutions(solutionFile, serviceProxy); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueueExportStatus; solutionFile.Solution.Attributes["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); this.ExportSolution(serviceProxy, solutionFile, solutionFile.SolutionUniqueName, "Downloading Master Solution: ", solutionFile.ExportAsManaged); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueueExportSuccessful; solutionFile.Solution.Attributes["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); this.ImportSolutionToTargetInstance(serviceProxy, solutionFile); if (solutionFile.CheckInSolution) { if (string.IsNullOrEmpty(solutionFile.GitRepoUrl)) { solutionFile.Solution[Constants.SourceControlQueueAttributeNameForRepositoryUrl] = this.RepositoryUrl; } if (string.IsNullOrEmpty(solutionFile.BranchName)) { solutionFile.Solution[Constants.SourceControlQueueAttributeNameForBranch] = this.Branch; } if (string.IsNullOrEmpty(solutionFile.RemoteName)) { solutionFile.Solution[Constants.SourceControlQueueAttributeNameForRemote] = this.RemoteName; } solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueueExportStatus; solutionFile.Solution.Attributes["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); this.ExportSolution(serviceProxy, solutionFile, solutionFile.SolutionUniqueName, "Downloading Unmanaged Master Solution: ", false); this.ExportSolution(serviceProxy, solutionFile, solutionFile.SolutionUniqueName, "Downloading Managed Master Solution: ", true); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueueExportSuccessful; solutionFile.Solution.Attributes["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); solutionFile.ProcessSolutionZipFile(this.SolutionPackagerPath); } }
/// <summary> /// Method publish all the customization /// </summary> /// <param name="serviceProxy">organization service proxy</param> /// <param name="solutionFile">solution File</param> public void PublishAllCustomizationChanges(OrganizationServiceProxy serviceProxy, SolutionFileInfo solutionFile) { PublishAllXmlRequest publishAllXmlRequest = new PublishAllXmlRequest(); serviceProxy.Timeout = new TimeSpan(0, 10, 0); serviceProxy.Execute(publishAllXmlRequest); Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine("Successfully published solution components." + "<br>"); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueuePublishSuccessfulStatus; solutionFile.Solution.Attributes["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); Singleton.SolutionFileInfoInstance.UploadFiletoDynamics(Singleton.CrmConstantsInstance.ServiceProxy, solutionFile.Solution); }
/// <summary> /// Method exports solution /// </summary> /// <param name="serviceProxy">organization service proxy</param> /// <param name="solutionFile">solution file info</param> private void ExportSolution(OrganizationServiceProxy serviceProxy, SolutionFileInfo solutionFile) { if (solutionFile.SolutionsToBeMerged.Count > 0) { this.MergeSolutions(solutionFile, serviceProxy); } if (!solutionFile.CheckInSolution) { return; } solutionFile.Solution[Constants.SourceControlQueueAttributeNameForRepositoryUrl] = this.RepositoryUrl; solutionFile.Solution[Constants.SourceControlQueueAttributeNameForBranch] = this.Branch; solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueueExportStatus; solutionFile.Update(); ExportSolutionRequest exportRequest = new ExportSolutionRequest { Managed = false, SolutionName = solutionFile.SolutionUniqueName }; Console.WriteLine("Downloading Solution " + solutionFile.SolutionUniqueName); ExportSolutionResponse exportResponse = (ExportSolutionResponse)serviceProxy.Execute(exportRequest); // Handles the response byte[] downloadedSolutionFile = exportResponse.ExportSolutionFile; solutionFile.SolutionFilePath = Path.GetTempFileName(); File.WriteAllBytes(solutionFile.SolutionFilePath, downloadedSolutionFile); string solutionExport = string.Format("Solution Successfully Exported to {0}", solutionFile.SolutionUniqueName); Console.WriteLine(solutionExport); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueueExportSuccessful; solutionFile.Update(); solutionFile.ProcessSolutionZipFile(this.SolutionPackagerPath); }
/// <summary> /// Method tries to configure repository /// </summary> /// <param name="solutionFiles">solution files</param> /// <param name="committerName">committer name</param> /// <param name="committerEmail">committer email</param> /// <param name="authorEmail">author email</param> /// <param name="solutionFilePath">solution file path</param> /// <returns> returns repository manager</returns> public GitDeploy.GitRepositoryManager ConfigureRepository(SolutionFileInfo solutionFiles, string committerName, string committerEmail, string authorEmail, string solutionFilePath) { int timeOut = Convert.ToInt32(Singleton.CrmConstantsInstance.SleepTimeoutInMillis); GitDeploy.GitRepositoryManager gitRepositoryManager = null; try { // todo: enable solutions file clear from crm portal this.PopulateHashset(solutionFilePath, new HashSet <string>()); gitRepositoryManager = this.GetRepositoryManager(committerName, committerEmail, authorEmail, solutionFiles); } catch (Exception ex) { Console.Write(ex.Message); Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(" " + ex.Message + "<br>"); solutionFiles.Solution[Constants.SourceControlQueueAttributeNameForStatus] = "Error +" + ex.Message; solutionFiles.Solution.Attributes["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFiles.Update(); Singleton.SolutionFileInfoInstance.UploadFiletoDynamics(Singleton.CrmConstantsInstance.ServiceProxy, solutionFiles.Solution); System.Threading.Thread.Sleep(timeOut); } return(gitRepositoryManager); }
/// <summary> /// Method gets deployment instance record /// </summary> /// <param name="serviceProxy">organization service proxy</param> /// <param name="solutionFile">solution file info</param> private void ImportSolutionToTargetInstance(OrganizationServiceProxy serviceProxy, SolutionFileInfo solutionFile) { Entity sourceControl = solutionFile.Solution; EntityCollection deploymentInstance = this.FetchDeplopymentInstance(serviceProxy, sourceControl.Id); var checkTarget = false; if (deploymentInstance.Entities.Count > 0) { foreach (Entity instance in deploymentInstance.Entities) { ClientCredentials clientCredentials = new ClientCredentials(); clientCredentials.UserName.UserName = instance.Attributes["syed_name"].ToString(); clientCredentials.UserName.Password = this.DecryptString(instance.Attributes["syed_password"].ToString()); ////Resetting password instance.Attributes["syed_password"] = "******"; serviceProxy.Update(instance); OrganizationServiceProxy targetserviceProxy = new OrganizationServiceProxy(new Uri(instance.Attributes["syed_instanceurl"].ToString()), null, clientCredentials, null); targetserviceProxy.EnableProxyTypes(); List <EntityCollection> componentDependency = this.GetDependentComponents(serviceProxy, new Guid(solutionFile.MasterSolutionId), solutionFile.SolutionUniqueName); SolutionManager sol = new SolutionManager(serviceProxy); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<br><br><table cellpadding='5' cellspacing='0' style='border: 1px solid #ccc;font-size: 9pt;font-family:Arial'><tr><th style='background-color: #B8DBFD;border: 1px solid #ccc'>Dependent Components in Source Instance</th><th style='background-color: #B8DBFD;border: 1px solid #ccc'>Required Components</th></tr>"); if (componentDependency.Count > 0) { foreach (var comDependency in componentDependency) { if (comDependency != null && comDependency.Entities != null && comDependency.Entities.Count > 0) { foreach (Entity dependency in comDependency.Entities) { Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<tr>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<td style='width:100px;background-color:#FFCC99;border: 1px solid #ccc'>"); sol.GetComponentDetails(null, null, dependency, ((OptionSetValue)dependency.Attributes["dependentcomponenttype"]).Value, (Guid)dependency.Attributes["dependentcomponentobjectid"], "dependentcomponenttype", null); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</td>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<td style='width:100px;background-color:#FFCC99;border: 1px solid #ccc'>"); sol.GetComponentDetails(null, null, dependency, ((OptionSetValue)dependency.Attributes["requiredcomponenttype"]).Value, (Guid)dependency.Attributes["requiredcomponentobjectid"], "requiredcomponenttype", null); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</td>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</tr>"); } } } } else { Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<tr>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<td style='width:100px;background-color:#FFCC99;border: 1px solid #ccc'>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("There is no missing dependent component to display"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</td>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<td style='width:100px;background-color:#FFCC99;border: 1px solid #ccc'>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("----"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</td>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</tr>"); } Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</table><br><br>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<table cellpadding='5' cellspacing='0' style='border: 1px solid #ccc;font-size: 9pt;font-family:Arial'><tr><th style='background-color: #B8DBFD;border: 1px solid #ccc'> Missing Dependent Components in Target Instance</th><th style='background-color: #B8DBFD;border: 1px solid #ccc'>Components Details</th></tr>"); if (componentDependency.Count > 0) { foreach (var comDependency in componentDependency) { checkTarget = this.CheckDependency(targetserviceProxy, comDependency, sol, checkTarget, serviceProxy); } } if (!checkTarget) { Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<tr>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<td style='width:100px;background-color:tomato;border: 1px solid #ccc'>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("All dependent components are present in target instance"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</td>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("<td style='width:100px;background-color:tomato;border: 1px solid #ccc'>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("----"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</td>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</tr>"); Singleton.SolutionFileInfoInstance.WebJobsLog.Append("</table><br><br>"); this.ImportSolution(targetserviceProxy, solutionFile, new Uri(instance.Attributes["syed_instanceurl"].ToString())); } else { Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(" Target Instance missing Required components. <br> "); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueueMissingComponents; solutionFile.Solution["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); Singleton.SolutionFileInfoInstance.UploadFiletoDynamics(serviceProxy, solutionFile.Solution); solutionFile.Update(); } } } }
/// <summary> /// Method import master solution to deployment instance /// </summary> /// <param name="serviceProxy">organization service proxy</param> /// <param name="solutionFile">solution file</param> /// <param name="uri">URL of Instance</param> public void ImportSolution(OrganizationServiceProxy serviceProxy, SolutionFileInfo solutionFile, Uri uri) { string solutionImportPath = solutionFile.SolutionFilePathManaged ?? solutionFile.SolutionFilePath; Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(" Started importing solution to Organization " + uri + "<br>"); Console.WriteLine("Started importing solution to Organization " + uri); byte[] fileBytes = File.ReadAllBytes(solutionImportPath); ImportSolutionRequest impSolReq = new ImportSolutionRequest() { CustomizationFile = fileBytes, ImportJobId = Guid.NewGuid(), OverwriteUnmanagedCustomizations = true, SkipProductUpdateDependencies = true, PublishWorkflows = false, }; ExecuteAsyncRequest importRequest = new ExecuteAsyncRequest() { Request = impSolReq }; ExecuteAsyncResponse importRequestResponse = (ExecuteAsyncResponse)serviceProxy.Execute(importRequest); string solutionImportResult = string.Empty; while (solutionImportResult == string.Empty) { Guid asyncJobId = importRequestResponse.AsyncJobId; Entity job = (Entity)serviceProxy.Retrieve("asyncoperation", asyncJobId, new ColumnSet(new string[] { "asyncoperationid", "statuscode", "message" })); int jobStatusCode = ((OptionSetValue)job["statuscode"]).Value; switch (jobStatusCode) { ////Success case 30: solutionImportResult = "success"; Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(" Solution imported successfully to the Organization " + uri + "<br>"); Console.WriteLine("Solution imported successfully to the Organization " + uri); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueueImportSuccessfulStatus; solutionFile.Solution["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); break; ////Pausing case 21: solutionImportResult = "pausing"; Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(string.Format(" Solution Import Pausing: {0}{1}", jobStatusCode, job["message"]) + "<br>"); Console.WriteLine(string.Format("Solution Import Pausing: {0} {1}", jobStatusCode, job["message"])); break; ////Cancelling case 22: solutionImportResult = "cancelling"; Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(string.Format("Solution Import Cancelling: {0}{1}", jobStatusCode, job["message"]) + "<br>"); Console.WriteLine(string.Format("Solution Import Cancelling: {0}{1}", jobStatusCode, job["message"])); break; ////Failed case 31: solutionImportResult = "failed"; Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(string.Format("Solution Import Failed: {0}{1}", jobStatusCode, job["message"]) + "<br>"); Console.WriteLine(string.Format("Solution Import Failed: {0}{1}", jobStatusCode, job["message"])); break; ////Cancelled case 32: Console.WriteLine(string.Format("Solution Import Cancelled: {0}{1}", jobStatusCode, job["message"])); Singleton.SolutionFileInfoInstance.WebJobsLog.AppendLine(string.Format("Solution Import Cancelled: {0}{1}", jobStatusCode, job["message"])); throw new Exception(string.Format("Solution Import Cancelled: {0}{1}", jobStatusCode, job["message"])); default: break; } } if (solutionImportResult == "success") { this.PublishAllCustomizationChanges(serviceProxy, solutionFile); solutionFile.Solution[Constants.SourceControlQueueAttributeNameForStatus] = Constants.SourceControlQueuePublishSuccessfulStatus; } solutionFile.Solution.Attributes["syed_webjobs"] = Singleton.SolutionFileInfoInstance.WebJobs(); solutionFile.Update(); }