aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2019-02-18 17:05:20 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2019-02-18 17:05:20 +0200
commit78181d457b113c25e9ea55b378d6b6bd8e201338 (patch)
treeba0134a4b7215fe5490d73e8fa81f4482435f857
parent473d878e3ae795201223b160fcbc1147e901b038 (diff)
downloadTango-78181d457b113c25e9ea55b378d6b6bd8e201338.tar.gz
Tango-78181d457b113c25e9ea55b378d6b6bd8e201338.zip
Fixed issue with git ignore, ignoring Publish folders.
-rw-r--r--.gitignore1
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/MachineStudioPublisher.cs249
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishOptions.cs87
-rw-r--r--Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishProgressEventArgs.cs16
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PPCPublisher.cs352
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishOptions.cs112
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishProgressEventArgs.cs16
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/SequenceItem.cs63
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/SynchronizationOptions.cs22
9 files changed, 917 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index b4243b6b9..328672b46 100644
--- a/.gitignore
+++ b/.gitignore
@@ -143,7 +143,6 @@ DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
-publish/
# Publish Web Output
*.[Pp]ublish.xml
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,
+ });
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishOptions.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishOptions.cs
new file mode 100644
index 000000000..047d7c0b4
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishOptions.cs
@@ -0,0 +1,87 @@
+using CommandLine;
+using CommandLine.Text;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Web;
+
+namespace Tango.MachineStudio.Common.Publish
+{
+ public class PublishOptions : ExtendedObject
+ {
+ public event EventHandler EnvironmentChanged;
+ public event EventHandler BuidConfigChanged;
+ public event EventHandler BasicInfoChanged;
+
+ private String basePath;
+ [Option("path", HelpText = "Specifies the application base path.", Required = false)]
+ public String BasePath
+ {
+ get { return basePath; }
+ set { basePath = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _buildConfig;
+ [Option("build", HelpText = "Specifies the build configuration.", Required = false, DefaultValue = "Release")]
+ public String BuildConfig
+ {
+ get { return _buildConfig; }
+ set { _buildConfig = value; RaisePropertyChangedAuto(); BuidConfigChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private String _email;
+ [Option("email", HelpText = "Email account used for login to the machine service.", Required = true)]
+ public String Email
+ {
+ get { return _email; }
+ set { _email = value; RaisePropertyChangedAuto(); BasicInfoChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private String _password;
+ [Option("pass", HelpText = "Password used for login to the machine service.", Required = true)]
+ public String Password
+ {
+ get { return _password; }
+ set { _password = value; RaisePropertyChangedAuto(); BasicInfoChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private String _comments;
+ [Option("comments", HelpText = "Optional comments that are attached to this release.", Required = false, DefaultValue = "No comments.")]
+ public String Comments
+ {
+ get { return _comments; }
+ set { _comments = value; RaisePropertyChangedAuto(); BasicInfoChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private DeploymentSlot _environment;
+ [Option("env", HelpText = "Specifies the target environment to publish.", Required = true)]
+ public DeploymentSlot Environment
+ {
+ get { return _environment; }
+ set { _environment = value; RaisePropertyChangedAuto(); EnvironmentChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private String _installerProject;
+ [Option("installer-project-file", HelpText = "Specifies the advanced installer project file to build and upload.", Required = false)]
+ public String InstallerProject
+ {
+ get { return _installerProject; }
+ set { _installerProject = value; RaisePropertyChangedAuto(); }
+ }
+
+ public PublishOptions()
+ {
+ BasePath = AppDomain.CurrentDomain.BaseDirectory + "..\\";
+ BuildConfig = "Release";
+ }
+
+ public String GetApplicationPath()
+ {
+ return Path.Combine(BasePath, BuildConfig);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishProgressEventArgs.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishProgressEventArgs.cs
new file mode 100644
index 000000000..ff550b9de
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Publish/PublishProgressEventArgs.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.MachineStudio.Common.Publish
+{
+ public class PublishProgressEventArgs : EventArgs
+ {
+ public double Progress { get; set; }
+ public double Total { get; set; }
+ public String Message { get; set; }
+ public bool SingleLineRecommended { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PPCPublisher.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PPCPublisher.cs
new file mode 100644
index 000000000..1c69f0934
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PPCPublisher.cs
@@ -0,0 +1,352 @@
+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.Helpers;
+using Tango.PPC.Common.Web;
+using Tango.SQLExaminer;
+using Tango.Transport.Web;
+using Tango.Web;
+
+namespace Tango.PPC.Common.Publish
+{
+ public class PPCPublisher : ExtendedObject
+ {
+ private IPPCWebService _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="PPCPublisher"/> class.
+ /// </summary>
+ public PPCPublisher()
+ {
+ _client = new PPCWebService();
+ Options = new PublishOptions();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PPCPublisher"/> class.
+ /// </summary>
+ /// <param name="publishOptions">The publish options.</param>
+ public PPCPublisher(PublishOptions publishOptions) : this()
+ {
+ Options = publishOptions;
+ }
+
+ /// <summary>
+ /// Gets the latest version.
+ /// </summary>
+ /// <returns></returns>
+ public async Task<String> GetRemoteVersion(String machineVersionGuid)
+ {
+ _client.Environment = Options.Environment;
+ var response = await _client.GetLatestVersion(new LatestVersionRequest()
+ {
+ MachineVersionGuid = machineVersionGuid,
+ });
+ 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(GetPPCExecutablePath()).ProductVersion;
+ }
+
+ /// <summary>
+ /// Gets the PPC executable path.
+ /// </summary>
+ /// <returns></returns>
+ public String GetPPCExecutablePath()
+ {
+ String appPath = Path.Combine(Options.GetApplicationPath(), "Tango.PPC.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()
+ {
+ Mode = LoginMode.User,
+ Email = Options.Email,
+ Password = Options.Password,
+ }).Result.AccessToken;
+ });
+ }
+
+ /// <summary>
+ /// Publish a PPC version using the specified <see cref="Options"/>.
+ /// </summary>
+ /// <returns></returns>
+ public Task Publish()
+ {
+ _client.Environment = Options.Environment;
+
+ String appPath = GetPPCExecutablePath();
+ String folder = Options.GetApplicationPath();
+ String accessToken = String.Empty;
+
+ if (!File.Exists(appPath))
+ {
+ throw new FileNotFoundException($"Could not locate the PPC executable at {appPath}.");
+ }
+
+ return Task.Factory.StartNew(() =>
+ {
+ String tempFile = TemporaryManager.CreateFile(".zip");
+
+ 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(Options.MachineVersionGuid).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()
+ {
+ Comments = Options.Comments,
+ Version = local_version,
+ MachineVersionGuid = Options.MachineVersionGuid,
+ AccessToken = accessToken,
+ }).Result;
+
+ CreateTupPackage(tempFile).Wait();
+
+ OnPublishProgress(0, 100, $"Starting version upload...");
+
+ using (StorageBlobUploader uploader = new StorageBlobUploader(response.BlobAddress, tempFile))
+ {
+ uploader.Progress += (x, e) =>
+ {
+ InvokeUINow(() =>
+ {
+ 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,
+ });
+
+ remote_version = GetRemoteVersion(Options.MachineVersionGuid).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>
+ /// Creates a Tango Update Package (.tup) file.
+ /// </summary>
+ /// <param name="filePath">The file path.</param>
+ /// <returns></returns>
+ public Task CreateTupPackage(String filePath)
+ {
+ return Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ OnPublishProgress(0, 100, "Generating .tup file...");
+
+ String appPath = GetPPCExecutablePath();
+ String folder = Options.GetApplicationPath();
+
+ if (!File.Exists(appPath))
+ {
+ throw new FileNotFoundException($"Could not locate the PPC executable at {appPath}.");
+ }
+
+ if (!File.Exists(Options.TfpPath))
+ {
+ throw new FileNotFoundException($"Could not locate TFP file at {Options.TfpPath}.");
+ }
+
+ var tempFile = filePath;
+
+ using (ZipFile zip = new ZipFile())
+ {
+ zip.AddFile(Options.TfpPath, "/");
+
+ String provision_dir = "Provision Scripts";
+
+ zip.AddDirectoryByName(provision_dir);
+
+ ExaminerSequenceConfiguration provision_config = new ExaminerSequenceConfiguration();
+
+ OnPublishProgress(0, 100, "Processing provisioning scripts...");
+
+ foreach (var item in Options.Synchronization.ProvisionSequenceItems)
+ {
+ OnPublishProgress(0, 100, $"Processing provisioning script '{item.Name}'...");
+
+ provision_config.Items.Add(new ExaminerSequenceItem()
+ {
+ Direction = item.Direction,
+ FileName = item.FileName,
+ Index = item.Index,
+ Name = item.Name,
+ Type = item.Type,
+ RequiresSerialNumber = item.RequiresSerialNumber
+ });
+
+ zip.AddFile(item.FilePath, provision_dir);
+ }
+
+ String provision_config_file = TemporaryManager.CreateFile(".zip");
+ provision_config.ToFile(provision_config_file);
+
+ var cf = zip.AddFile(provision_config_file, provision_dir);
+ cf.FileName = provision_dir + "\\config.xml";
+
+ String update_dir = "Update Scripts";
+
+ zip.AddDirectoryByName(update_dir);
+
+ ExaminerSequenceConfiguration update_config = new ExaminerSequenceConfiguration();
+
+ OnPublishProgress(0, 100, "Processing update scripts...");
+
+ foreach (var item in Options.Synchronization.UpdateSequenceItems)
+ {
+ OnPublishProgress(0, 100, $"Processing update script '{item.Name}'...");
+
+ update_config.Items.Add(new ExaminerSequenceItem()
+ {
+ Direction = item.Direction,
+ FileName = item.FileName,
+ Index = item.Index,
+ Name = item.Name,
+ Type = item.Type,
+ RequiresSerialNumber = item.RequiresSerialNumber
+ });
+
+ zip.AddFile(item.FilePath, update_dir);
+ }
+
+ String update_config_file = TemporaryManager.CreateFile(".zip");
+ update_config.ToFile(update_config_file);
+
+ var cuf = zip.AddFile(update_config_file, update_dir);
+ cuf.FileName = update_dir + "\\config.xml";
+
+ foreach (var file in Directory.GetFiles(folder, "*.*", SearchOption.TopDirectoryOnly))
+ {
+ 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(100, 100, "TUP file generated successfully.");
+ }
+ }
+ catch (Exception ex)
+ {
+ OnPublishProgress(0, 100, $"Failed: {ex.Message}");
+ throw ex;
+ }
+ });
+ }
+
+ /// <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,
+ });
+ }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishOptions.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishOptions.cs
new file mode 100644
index 000000000..fa04d8331
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishOptions.cs
@@ -0,0 +1,112 @@
+using CommandLine;
+using CommandLine.Text;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Web;
+
+namespace Tango.PPC.Common.Publish
+{
+ public class PublishOptions : ExtendedObject
+ {
+ public event EventHandler EnvironmentChanged;
+ public event EventHandler BuidConfigChanged;
+ public event EventHandler BasicInfoChanged;
+ public event EventHandler MachineVersionGuidChanged;
+
+ private String basePath;
+ [Option("path", HelpText = "Specifies the application base path.", Required = false)]
+ public String BasePath
+ {
+ get { return basePath; }
+ set { basePath = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _buildConfig;
+ [Option("build", HelpText = "Specifies the build configuration.", Required = false, DefaultValue = "Release")]
+ public String BuildConfig
+ {
+ get { return _buildConfig; }
+ set { _buildConfig = value; RaisePropertyChangedAuto(); BuidConfigChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private String _email;
+ [Option("email", HelpText = "Email account used for login to the machine service.", Required = true)]
+ public String Email
+ {
+ get { return _email; }
+ set { _email = value; RaisePropertyChangedAuto(); BasicInfoChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private String _password;
+ [Option("pass", HelpText = "Password used for login to the machine service.", Required = true)]
+ public String Password
+ {
+ get { return _password; }
+ set { _password = value; RaisePropertyChangedAuto(); BasicInfoChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private String _comments;
+ [Option("comments", HelpText = "Optional comments that are attached to this release.", Required = false, DefaultValue = "No comments.")]
+ public String Comments
+ {
+ get { return _comments; }
+ set { _comments = value; RaisePropertyChangedAuto(); BasicInfoChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private DeploymentSlot _environment;
+ [Option("env", HelpText = "Specifies the target environment to publish.", Required = true)]
+ public DeploymentSlot Environment
+ {
+ get { return _environment; }
+ set { _environment = value; RaisePropertyChangedAuto(); EnvironmentChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private String _installerProject;
+ [Option("installer-project-file", HelpText = "Specifies the advanced installer project file to build and upload.", Required = false)]
+ public String InstallerProject
+ {
+ get { return _installerProject; }
+ set { _installerProject = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _machineVersionGuid;
+ [Option("machine-version-guid", HelpText = "Specifies the machine version id for which to upload the PPC version.", Required = true)]
+ public String MachineVersionGuid
+ {
+ get { return _machineVersionGuid; }
+ set { _machineVersionGuid = value; RaisePropertyChangedAuto(); MachineVersionGuidChanged?.Invoke(this, new EventArgs()); }
+ }
+
+ private String _tfpPath;
+ [Option("tfp", HelpText = "Specifies Tango Firmware Package file path (.tfp).", Required = true)]
+ public String TfpPath
+ {
+ get { return _tfpPath; }
+ set { _tfpPath = value; RaisePropertyChangedAuto(); }
+ }
+
+ private SynchronizationOptions _synchronization;
+ public SynchronizationOptions Synchronization
+ {
+ get { return _synchronization; }
+ set { _synchronization = value; RaisePropertyChangedAuto(); }
+ }
+
+ public PublishOptions()
+ {
+ BasePath = AppDomain.CurrentDomain.BaseDirectory + "..\\";
+ BuildConfig = "Release";
+ Synchronization = new SynchronizationOptions();
+ }
+
+ public String GetApplicationPath()
+ {
+ return Path.Combine(BasePath, BuildConfig);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishProgressEventArgs.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishProgressEventArgs.cs
new file mode 100644
index 000000000..81575203f
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishProgressEventArgs.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.PPC.Common.Publish
+{
+ public class PublishProgressEventArgs : EventArgs
+ {
+ public double Progress { get; set; }
+ public double Total { get; set; }
+ public String Message { get; set; }
+ public bool SingleLineRecommended { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/SequenceItem.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/SequenceItem.cs
new file mode 100644
index 000000000..efe80b295
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/SequenceItem.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.SQLExaminer;
+
+namespace Tango.PPC.Common.Publish
+{
+ public class SequenceItem : ExtendedObject
+ {
+ private ExaminerSequenceItemType _type;
+ public ExaminerSequenceItemType Type
+ {
+ get { return _type; }
+ set { _type = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ExaminerSequenceItemDirection _direction;
+ public ExaminerSequenceItemDirection Direction
+ {
+ get { return _direction; }
+ set { _direction = value; RaisePropertyChangedAuto(); }
+ }
+
+ private int _index;
+ public int Index
+ {
+ get { return _index; }
+ set { _index = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _name;
+ public String Name
+ {
+ get { return _name; }
+ set { _name = value; RaisePropertyChangedAuto(); }
+ }
+
+ private String _filePath;
+ public String FilePath
+ {
+ get { return _filePath; }
+ set { _filePath = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(FileName)); }
+ }
+
+ private bool _requiresSerialNumber;
+ public bool RequiresSerialNumber
+ {
+ get { return _requiresSerialNumber; }
+ set { _requiresSerialNumber = value; RaisePropertyChangedAuto(); }
+ }
+
+
+ public String FileName
+ {
+ get { return Path.GetFileName(FilePath); }
+ }
+
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/SynchronizationOptions.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/SynchronizationOptions.cs
new file mode 100644
index 000000000..4579acbe6
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/SynchronizationOptions.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.PPC.Common.Publish
+{
+ public class SynchronizationOptions
+ {
+ public ObservableCollection<SequenceItem> ProvisionSequenceItems { get; set; }
+
+ public ObservableCollection<SequenceItem> UpdateSequenceItems { get; set; }
+
+ public SynchronizationOptions()
+ {
+ ProvisionSequenceItems = new ObservableCollection<SequenceItem>();
+ UpdateSequenceItems = new ObservableCollection<SequenceItem>();
+ }
+ }
+}