diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2019-02-18 17:05:20 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2019-02-18 17:05:20 +0200 |
| commit | 78181d457b113c25e9ea55b378d6b6bd8e201338 (patch) | |
| tree | ba0134a4b7215fe5490d73e8fa81f4482435f857 /Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs | |
| parent | 473d878e3ae795201223b160fcbc1147e901b038 (diff) | |
| download | Tango-78181d457b113c25e9ea55b378d6b6bd8e201338.tar.gz Tango-78181d457b113c25e9ea55b378d6b6bd8e201338.zip | |
Fixed issue with git ignore, ignoring Publish folders.
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs')
| -rw-r--r-- | Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs new file mode 100644 index 000000000..19f186525 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs @@ -0,0 +1,249 @@ +using CommandLine; +using Ionic.Zip; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; +using Tango.Core.Cryptography; +using Tango.Core.Helpers; +using Tango.MachineStudio.Common.Web; +using Tango.Transport.Web; +using Tango.Web; + +namespace Tango.MachineStudio.Common.Publish +{ + public class MachineStudioPublisher : ExtendedObject + { + private IMachineStudioService _client; + + /// <summary> + /// Occurs on publish progress. + /// </summary> + public event EventHandler<PublishProgressEventArgs> PublishProgress; + + private PublishOptions _options; + /// <summary> + /// Gets or sets the publish options. + /// </summary> + public PublishOptions Options + { + get { return _options; } + set { _options = value; RaisePropertyChangedAuto(); } + } + + /// <summary> + /// Initializes a new instance of the <see cref="MachineStudioPublisher"/> class. + /// </summary> + public MachineStudioPublisher() + { + _client = new MachineStudioService(); + Options = new PublishOptions(); + } + + /// <summary> + /// Initializes a new instance of the <see cref="MachineStudioPublisher"/> class. + /// </summary> + /// <param name="publishOptions">The publish options.</param> + public MachineStudioPublisher(PublishOptions publishOptions) : this() + { + Options = publishOptions; + } + + /// <summary> + /// Gets the latest version. + /// </summary> + /// <returns></returns> + public async Task<String> GetRemoteVersion() + { + _client.Environment = Options.Environment; + var response = await _client.GetLatestVersion(new LatestVersionRequest()); + return response.Version; + } + + /// <summary> + /// Gets the latest version. + /// </summary> + /// <returns></returns> + public async Task<String> GetRemoteVersion(DeploymentSlot environment) + { + _client.Environment = environment; + var response = await _client.GetLatestVersion(new LatestVersionRequest()); + return response.Version; + } + + /// <summary> + /// Gets the latest version. + /// </summary> + /// <returns></returns> + public String GetLocalVersion() + { + return FileVersionInfo.GetVersionInfo(GetMachineStudioExecutablePath()).ProductVersion; + } + + /// <summary> + /// Gets the machine studio executable path. + /// </summary> + /// <returns></returns> + public String GetMachineStudioExecutablePath() + { + String appPath = Path.Combine(Options.GetApplicationPath(), "Tango.MachineStudio.UI.exe"); + return appPath; + } + + /// <summary> + /// Login to machine service and returns an access token. + /// </summary> + /// <returns></returns> + private Task<String> Login() + { + return Task.Factory.StartNew<String>(() => + { + return _client.Login(new LoginRequest() + { + Email = Options.Email, + Password = Options.Password, + Version = GetLocalVersion(), + }).Result.AccessToken; + }); + } + + /// <summary> + /// Publish a machine studio version using the specified <see cref="Options"/>. + /// </summary> + /// <returns></returns> + public Task Publish() + { + _client.Environment = Options.Environment; + + String appPath = GetMachineStudioExecutablePath(); + String folder = Options.GetApplicationPath(); + String accessToken = String.Empty; + + if (!File.Exists(appPath)) + { + throw new FileNotFoundException($"Could not locate the machine studio executable at {appPath}."); + } + + String tempFile = TemporaryManager.CreateFile(); + + return Task.Factory.StartNew(() => + { + try + { + OnPublishProgress(0, 100, $"Logging in to machine service at {Options.Environment.ToAddress()}..."); + accessToken = Login().Result; + + OnPublishProgress(0, 100, $"Fetching remote version from {Options.Environment.ToAddress()}..."); + + String remote_version = GetRemoteVersion().Result; + String local_version = GetLocalVersion(); + + OnPublishProgress(0, 100, $"Remote version: {remote_version}"); + OnPublishProgress(0, 100, $"Local version: {local_version}"); + + if (Version.Parse(local_version) <= Version.Parse(remote_version)) + { + throw new InvalidOperationException($"The local version '{local_version}' is not greater than the remote version '{remote_version}'."); + } + + OnPublishProgress(0, 100, $"Requesting version upload..."); + + var response = _client.UploadVersion(new UploadVersionRequest() + { + AccessToken = accessToken, + Version = local_version, + Comments = Options.Comments, + }).Result; + + OnPublishProgress(0, 100, $"Starting version packaging..."); + + using (ZipFile zip = new ZipFile()) + { + zip.AddDirectory(Path.Combine(folder, "x86"), "/x86"); + zip.AddDirectory(Path.Combine(folder, "x64"), "/x64"); + + var files = Directory.GetFiles(folder, "*.*", SearchOption.TopDirectoryOnly).ToList(); + + foreach (var file in files) + { + zip.AddFile(file, "/"); + } + + zip.SaveProgress += (x, e) => + { + if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry) + { + OnPublishProgress(e.EntriesSaved + 1, e.EntriesTotal, $"Compressing files {(((double)(e.EntriesSaved + 1) / (double)e.EntriesTotal) * 100d).ToString("0.0")}%...", true); + } + }; + + zip.Save(tempFile); + } + + OnPublishProgress(0, 100, $"Starting version upload..."); + + using (StorageBlobUploader uploader = new StorageBlobUploader(response.BlobAddress, tempFile)) + { + uploader.Progress += (x, e) => + { + OnPublishProgress(e.Current, e.Total, $"Uploading to storage {(((double)e.Current / (double)e.Total) * 100d).ToString("0.0")}%...", true); + }; + + uploader.Upload().Wait(); + } + + OnPublishProgress(100, 100, $"Finalizing version upload..."); + + _client.NotifyUploadCompleted(new UploadCompletedRequest() + { + AccessToken = accessToken, + Token = response.Token, + }).Wait(); + + remote_version = GetRemoteVersion().Result; + local_version = GetLocalVersion(); + + OnPublishProgress(0, 0, $"Remote version: {remote_version}"); + OnPublishProgress(0, 0, $"Local version: {local_version}"); + + if (remote_version != local_version) + { + throw new InvalidOperationException("The remote version does not seems to have been updated."); + } + + OnPublishProgress(0, 0, "Version published successfully."); + } + catch (Exception ex) + { + OnPublishProgress(0, 100, $"Failed: {ex.Message}"); + throw ex; + } + finally + { + PathHelper.TryDeleteFile(tempFile); + } + }); + } + + /// <summary> + /// Raises the publish progress event. + /// </summary> + /// <param name="progress">The progress.</param> + /// <param name="total">The total.</param> + /// <param name="message">The message.</param> + protected virtual void OnPublishProgress(double progress, double total, String message, bool singleLine = false) + { + PublishProgress?.Invoke(this, new PublishProgressEventArgs() + { + Progress = progress, + Total = total, + Message = message, + SingleLineRecommended = singleLine, + }); + } + } +} |
