public static void CopyWithManifest(string sourcePath, string destinationPath, IDeploymentManifestReader previousManifest, bool skipOldFiles = true) { sourcePath = Path.GetFullPath(sourcePath); destinationPath = Path.GetFullPath(destinationPath); using (var progressWriter = new ProgressWriter()) { progressWriter.Start(); if (previousManifest != null) { var previousFiles = new HashSet<string>(previousManifest.GetPaths(), StringComparer.OrdinalIgnoreCase); SmartCopy(sourcePath, destinationPath, previousFiles.Contains, new DirectoryInfoWrapper(new DirectoryInfo(sourcePath)), new DirectoryInfoWrapper(new DirectoryInfo(destinationPath)), path => new DirectoryInfoWrapper(new DirectoryInfo(path))); } else { // On first deployment, delete the contents of the destination path before copying FileSystemHelpers.DeleteDirectoryContentsSafe(destinationPath); // If there's no manifest then there's nothing to copy FileSystemHelpers.Copy(sourcePath, destinationPath); } } }
public string ExecuteMSBuild(ITracer tracer, string arguments, params object[] args) { using (var writer = new ProgressWriter()) { writer.Start(); return _msbuildExe.Execute(tracer, arguments, args).Item1; } }
public string Install(ITracer tracer, ProgressWriter writer) { return Execute(tracer, output => { writer.WriteOutLine(output); return true; }, error => { writer.WriteOutLine(error); return true; }, Console.OutputEncoding, "install").Item1; }
private string RunCommandWithProgress(ITracer tracer, ProgressWriter writer, string command) { return Execute(tracer, output => { writer.WriteOutLine(output); return true; }, error => { writer.WriteOutLine(error); return true; }, Console.OutputEncoding, command).Item1; }
public async Task DeployAsync(IRepository repository, ChangeSet changeSet, string deployer, bool clean, bool needFileUpdate = true) { using (var deploymentAnalytics = new DeploymentAnalytics(_analytics, _settings)) { Exception exception = null; ITracer tracer = _traceFactory.GetTracer(); IDisposable deployStep = null; ILogger innerLogger = null; string targetBranch = null; // If we don't get a changeset, find out what branch we should be deploying and get the commit ID from it if (changeSet == null) { targetBranch = _settings.GetBranch(); changeSet = repository.GetChangeSet(targetBranch); if (changeSet == null) { throw new InvalidOperationException(String.Format("The current deployment branch is '{0}', but nothing has been pushed to it", targetBranch)); } } string id = changeSet.Id; IDeploymentStatusFile statusFile = null; try { deployStep = tracer.Step("DeploymentManager.Deploy(id)"); // Remove the old log file for this deployment id string logPath = GetLogPath(id); FileSystemHelpers.DeleteFileSafe(logPath); statusFile = GetOrCreateStatusFile(changeSet, tracer, deployer); statusFile.MarkPending(); ILogger logger = GetLogger(changeSet.Id); if (needFileUpdate) { using (tracer.Step("Updating to specific changeset")) { innerLogger = logger.Log(Resources.Log_UpdatingBranch, targetBranch ?? id); using (var writer = new ProgressWriter()) { // Update to the specific changeset or branch repository.Update(targetBranch ?? id); } } } if (_settings.ShouldUpdateSubmodules()) { using (tracer.Step("Updating submodules")) { innerLogger = logger.Log(Resources.Log_UpdatingSubmodules); repository.UpdateSubmodules(); } } if (clean) { tracer.Trace("Cleaning {0} repository", repository.RepositoryType); innerLogger = logger.Log(Resources.Log_CleaningRepository, repository.RepositoryType); repository.Clean(); } // set to null as Build() below takes over logging innerLogger = null; // Perform the build deployment of this changeset await Build(changeSet, tracer, deployStep, repository, deploymentAnalytics); } catch (Exception ex) { exception = ex; if (innerLogger != null) { innerLogger.Log(ex); } if (statusFile != null) { MarkStatusComplete(statusFile, success: false); } tracer.TraceError(ex); deploymentAnalytics.Error = ex.ToString(); if (deployStep != null) { deployStep.Dispose(); } } // Reload status file with latest updates statusFile = _status.Open(id); if (statusFile != null) { await _hooksManager.PublishEventAsync(HookEventTypes.PostDeployment, statusFile); } if (exception != null) { throw new DeploymentFailedException(exception); } } }
public void Deploy() { var tracer = _traceFactory.GetTracer(); IDisposable deployStep = null; try { deployStep = tracer.Step("Deploy"); PushInfo pushInfo = _serverRepository.GetPushInfo(); // Something went wrong here since we weren't able to if (pushInfo == null || !pushInfo.Branch.IsMaster) { if (pushInfo == null) { tracer.TraceWarning("Push info was null. Post receive hook didn't execute correctly"); } else { tracer.Trace("Non-master branch deployed {0}", pushInfo.Branch.Name); _globalLogger.Log(Resources.Log_NonMasterBranchPushed, pushInfo.Branch.Name); } ReportCompleted(); deployStep.Dispose(); return; } // Get the pushed branch's id string id = pushInfo.Branch.Id; // If nothing changed then do nothing if (IsActive(id)) { tracer.Trace("Deployment '{0}' already active", id); _globalLogger.Log(Resources.Log_DeploymentAlreadyActive, id); ReportCompleted(); deployStep.Dispose(); return; } ILogger logger = CreateAndPopulateStatusFile(tracer, id); using (tracer.Step("Update to " + pushInfo.Branch.Name)) { logger.Log(Resources.Log_UpdatingBranch, pushInfo.Branch.Name); using (var progressWriter = new ProgressWriter()) { progressWriter.Start(); // Update to the default branch _serverRepository.Update(); } } Build(id, tracer, deployStep); } catch (Exception ex) { _globalLogger.Log(ex); tracer.TraceError(ex); if (deployStep != null) { deployStep.Dispose(); } ReportCompleted(); } }
public void Deploy(IRepository repository, ChangeSet changeSet, string deployer, bool clean) { ITracer tracer = _traceFactory.GetTracer(); IDisposable deployStep = null; ILogger innerLogger = null; string targetBranch = null; var deploymentRepository = new DeploymentRepository(repository); // If we don't get a changeset, find out what branch we should be deploying and get the commit ID from it if (changeSet == null) { targetBranch = _settings.GetBranch(); changeSet = deploymentRepository.GetChangeSet(targetBranch); } string id = changeSet.Id; IDeploymentStatusFile statusFile = null; try { deployStep = tracer.Step("DeploymentManager.Deploy(id)"); // Remove the old log file for this deployment id string logPath = GetLogPath(id); FileSystemHelpers.DeleteFileSafe(logPath); statusFile = GetOrCreateStatusFile(changeSet, tracer, deployer); statusFile.MarkPending(); ILogger logger = GetLogger(changeSet.Id); using (tracer.Step("Updating to specific changeset")) { innerLogger = logger.Log(Resources.Log_UpdatingBranch, targetBranch ?? id); using (var writer = new ProgressWriter()) { // Update to the the specific changeset deploymentRepository.Update(id); } } using (tracer.Step("Updating submodules")) { innerLogger = logger.Log(Resources.Log_UpdatingSubmodules); deploymentRepository.UpdateSubmodules(); } if (clean) { tracer.Trace("Cleaning {0} repository", repository.RepositoryType); innerLogger = logger.Log(Resources.Log_CleaningRepository, repository.RepositoryType); deploymentRepository.Clean(); } // set to null as Build() below takes over logging innerLogger = null; // Perform the build deployment of this changeset Build(id, tracer, deployStep); } catch (Exception ex) { if (innerLogger != null) { innerLogger.Log(ex); } if (statusFile != null) { statusFile.MarkFailed(); } tracer.TraceError(ex); if (deployStep != null) { deployStep.Dispose(); } throw; } }
// this is used for long running command that requires ongoing progress such as job, build script etc. public Tuple<string, string> ExecuteWithProgressWriter(ILogger logger, ITracer tracer, string arguments, params object[] args) { try { using (var writer = new ProgressWriter()) { return ExecuteInternal(tracer, output => { writer.WriteOutLine(output); logger.Log(output); return true; }, error => { writer.WriteErrorLine(error); logger.Log(error, LogEntryType.Warning); return true; }, Console.OutputEncoding, arguments, args); } } catch (CommandLineException exception) { // in case of failure without stderr, we log error explicitly if (String.IsNullOrEmpty(exception.Error)) { logger.Log(exception); } throw; } catch (Exception exception) { // in case of other failure, we log error explicitly logger.Log(exception); throw; } }
/// <summary> /// Download node packages as part of the deployment. /// </summary> private void DownloadNodePackages(DeploymentContext context) { // Check to see if there's a package.json file string packagePath = Path.Combine(context.OutputPath, PackageJsonFile); if (!File.Exists(packagePath)) { // If the package.json file doesn't exist then don't bother to run npm install return; } ILogger innerLogger = context.Logger.Log(Resources.Log_RunningNPM); using (context.Tracer.Step("Downloading node packages")) { var npm = new NpmExecutable(context.OutputPath); if (!npm.IsAvailable) { context.Tracer.TraceError(Resources.Log_NpmNotInstalled); innerLogger.Log(Resources.Log_NpmNotInstalled, LogEntryType.Error); return; } // Set the npm proxy settings based on the default settings var proxy = WebRequest.DefaultWebProxy; var httpUrl = new Uri("http://registry.npmjs.org/"); var httpsUrl = new Uri("https://registry.npmjs.org/"); var proxyHttpProxyUrl = proxy.GetProxy(httpUrl); var proxyHttpsProxyUrl = proxy.GetProxy(httpsUrl); if (proxyHttpProxyUrl != httpUrl) { npm.EnvironmentVariables["HTTP_PROXY"] = proxyHttpProxyUrl.ToString(); } if (proxyHttpsProxyUrl != httpsUrl) { npm.EnvironmentVariables["HTTPS_PROXY"] = proxyHttpsProxyUrl.ToString(); } npm.SetHomePath(_homePath); // REVIEW: Do we still need this? try { // Use the http proxy since https is failing for some reason npm.Execute("config set registry \"http://registry.npmjs.org/\""); } catch (Exception ex) { // This fails if it's already set context.Tracer.TraceError(ex); } try { string log = null; using (var writer = new ProgressWriter()) { writer.Start(); // Run install on the output directory log = npm.Install(context.Tracer, writer); } if (String.IsNullOrWhiteSpace(log)) { innerLogger.Log(Resources.Log_PackagesAlreadyInstalled); } else { innerLogger.Log(log); } } catch (Exception ex) { // Log the exception innerLogger.Log(ex); // re-throw throw; } } }
public Tuple<string, string> ExecuteWithProgressWriter(ILogger logger, ITracer tracer, Func<string, bool> shouldFilterOut, string arguments, params object[] args) { using (var writer = new ProgressWriter()) { writer.Start(); return Execute(tracer, output => { if (shouldFilterOut(output)) { return false; } writer.WriteOutLine(output); logger.Log(output); return true; }, error => { writer.WriteErrorLine(error); logger.Log(error, LogEntryType.Error); return true; }, Console.OutputEncoding, arguments, args); } }
public void Deploy(IRepository repository, string deployer) { var tracer = _traceFactory.GetTracer(); IDisposable deployStep = null; var deploymentRepository = new DeploymentRepository(repository); try { deployStep = tracer.Step("Deploy"); ReceiveInfo receiveInfo = deploymentRepository.GetReceiveInfo(); string targetBranch = _settings.GetValue(SettingsKeys.Branch); tracer.Trace("Deploying branch '{0}'", targetBranch); // Something went wrong here since we weren't able to deploy if receiveInfo is null if (receiveInfo == null || !targetBranch.Equals(receiveInfo.Branch.Name, StringComparison.OrdinalIgnoreCase)) { if (receiveInfo == null) { tracer.TraceWarning("Push info was null. Post receive hook didn't execute correctly"); } else { tracer.Trace("Unexpected branch deployed '{0}'.", receiveInfo.Branch.Name); _globalLogger.Log(Resources.Log_UnexpectedBranchPushed, receiveInfo.Branch.Name, targetBranch); } ReportCompleted(); deployStep.Dispose(); return; } // Get the pushed branch's id string id = receiveInfo.Branch.Id; // If nothing changed then do nothing if (IsActive(id)) { tracer.Trace("Deployment '{0}' already active", id); _globalLogger.Log(Resources.Log_DeploymentAlreadyActive, id); ReportCompleted(); deployStep.Dispose(); return; } ChangeSet changeSet = deploymentRepository.GetChangeSet(id); ILogger logger = GetOrCreateStatusFile(changeSet, tracer, deployer); logger.Log(Resources.Log_NewDeploymentReceived); using (tracer.Step("Update to " + receiveInfo.Branch.Name)) { logger.Log(Resources.Log_UpdatingBranch, receiveInfo.Branch.Name); using (var progressWriter = new ProgressWriter()) { progressWriter.Start(); // Update to the target branch deploymentRepository.Update(targetBranch); } } using (tracer.Step("Update submodules")) { logger.Log(Resources.Log_UpdatingSubmodules); using (var progressWriter = new ProgressWriter()) { progressWriter.Start(); deploymentRepository.UpdateSubmodules(); } } Build(id, tracer, deployStep); } catch (Exception ex) { _globalLogger.Log(ex); tracer.TraceError(ex); if (deployStep != null) { deployStep.Dispose(); } ReportCompleted(); } }
internal string Rebuild(ITracer tracer, ProgressWriter writer) { return RunCommandWithProgress(tracer, writer, "rebuild"); }
public string Install(ITracer tracer, ProgressWriter writer) { return RunCommandWithProgress(tracer, writer, "install --production"); }
public string ExecuteMSBuild(ITracer tracer, string arguments, params object[] args) { using (var writer = new ProgressWriter()) { writer.Start(); // The line with the MSB3644 warnings since it's not important return _msbuildExe.Execute(tracer, output => { if (output.Contains("MSB3644:") || output.Contains("MSB3270:")) { return false; } writer.WriteOutLine(output); return true; }, error => { writer.WriteErrorLine(error); return true; }, Console.OutputEncoding, arguments, args).Item1; } }