public static ApplicationManifestType SetGitVersion(this ApplicationManifestType appManifest, string baseVersion, IEnumerable <FabricServiceReference> fabricServiceReferences, string configuration, int maxHashLength, bool skipHash)
        {
            DateTime latest = DateTime.MinValue;
            string   version = "", diff = "";

            foreach (var spr in fabricServiceReferences)
            {
                var serviceReferencePath = Path.Combine(Path.GetDirectoryName(spr.ProjectPath), "pkg", configuration);
                var versionFile          = Path.Combine(serviceReferencePath, "Version.txt");
                var diffFile             = Path.Combine(serviceReferencePath, "Diff.txt");

                if (!Directory.Exists(serviceReferencePath) || !File.Exists(versionFile) || !File.Exists(diffFile))
                {
                    continue;
                }

                var commit = File.ReadAllText(versionFile).Split(' ');

                var serviceManifest = FabricSerializers.ServiceManifestFromFile(Path.Combine(serviceReferencePath, "ServiceManifest.xml"));
                appManifest.ServiceManifestImport
                .First(smi => smi.ServiceManifestRef.ServiceManifestName == spr.ServiceManifestName).ServiceManifestRef
                .ServiceManifestVersion = serviceManifest.Version;

                if (long.TryParse(commit[1], out var d))
                {
                    var date = new DateTime(d);
                    if (new DateTime(d) > latest)
                    {
                        version = commit[0];
                        latest  = new DateTime(d);
                    }
                }

                if (!skipHash)
                {
                    diff += File.ReadAllText(diffFile);
                }
            }

            appManifest.ApplicationTypeVersion = VersionHelper.AppendVersion(baseVersion, version, VersionHelper.Hash(diff, maxHashLength));
            return(appManifest);
        }
        public static async Task <bool> CreateDiffPackage(this IServiceFabricClient Client, string packagePath, ILogger Logger = null)
        {
            var localAppManifest = FabricSerializers.AppManifestFromFile(Path.Combine(packagePath, "ApplicationManifest.xml"));
            var appTypes         = await Client.ApplicationTypes.GetApplicationTypeInfoListAsync();

            var appManifestTasks = appTypes.Data.Where(type => type.Name == localAppManifest.ApplicationTypeName).Select(type => Client.ApplicationTypes.GetApplicationManifestAsync(type.Name, type.Version));
            await Task.WhenAll(appManifestTasks);

            var    serverAppManifests = appManifestTasks.Select(task => FabricSerializers.AppManifestFromString(task.Result.Manifest)).ToList();
            string pkgPAth            = null;

            if (serverAppManifests.Any(serverAppManifest => serverAppManifest.ApplicationTypeVersion == localAppManifest.ApplicationTypeVersion))
            {
                Logger?.LogInfo($"Application {localAppManifest.ApplicationTypeName} {localAppManifest.ApplicationTypeVersion} is already provisioned");
                return(false);
            }

            foreach (var serverAppManifest in serverAppManifests)
            {
                foreach (var serviceImport in serverAppManifest.ServiceManifestImport)
                {
                    var localService = localAppManifest.ServiceManifestImport.FirstOrDefault(s => s.ServiceManifestRef.ServiceManifestName == serviceImport.ServiceManifestRef.ServiceManifestName);
                    if (localService != null && localService.ServiceManifestRef.ServiceManifestVersion == serviceImport.ServiceManifestRef.ServiceManifestVersion)
                    {
                        Logger?.LogInfo($"Service {localAppManifest.ApplicationTypeName}.{localService.ServiceManifestRef.ServiceManifestName} {localService.ServiceManifestRef.ServiceManifestVersion} is already provisioned");
                        foreach (var dir in Directory.GetDirectories(Path.Combine(packagePath, serviceImport.ServiceManifestRef.ServiceManifestName)))
                        {
                            Symlink.DeleteIfExists(dir);
                        }
                    }
                    else
                    {
                        var serverServiceManifest    = FabricSerializers.ServiceManifestFromString((await Client.ServiceTypes.GetServiceManifestAsync(serverAppManifest.ApplicationTypeName, serverAppManifest.ApplicationTypeVersion, serviceImport.ServiceManifestRef.ServiceManifestName)).Manifest);
                        var localServiceManifestPath = Path.Combine(packagePath, serviceImport.ServiceManifestRef.ServiceManifestName, "ServiceManifest.xml");
                        if (!File.Exists(localServiceManifestPath))
                        {
                            continue;
                        }
                        var localServiceManifest = FabricSerializers.ServiceManifestFromFile(localServiceManifestPath);

                        // Logger?.LogInfo($"{serverAppManifest.ApplicationTypeName}.{localService.ServiceManifestRef.ServiceManifestName} {localService.ServiceManifestRef.ServiceManifestVersion} not found on server, checking packages");
                        if (serverServiceManifest.CodePackage != null && localServiceManifest.CodePackage != null)
                        {
                            foreach (var package in serverServiceManifest.CodePackage.Where(sp => localServiceManifest.CodePackage.Any(lp => lp.Name == sp.Name && lp.Version == sp.Version)))
                            {
                                pkgPAth = Path.Combine(packagePath, localService.ServiceManifestRef.ServiceManifestName, package.Name);
                                if (Directory.Exists(pkgPAth))
                                {
                                    Logger?.LogInfo($"Deleting {localAppManifest.ApplicationTypeName}.{localService.ServiceManifestRef.ServiceManifestName}.{package.Name} {package.Version}");
                                    Symlink.DeleteIfExists(pkgPAth);
                                }
                            }
                        }

                        if (serverServiceManifest.ConfigPackage != null && localServiceManifest.ConfigPackage != null)
                        {
                            foreach (var package in serverServiceManifest.ConfigPackage.Where(sp => localServiceManifest.ConfigPackage.Any(lp => lp.Name == sp.Name && lp.Version == sp.Version)))
                            {
                                pkgPAth = Path.Combine(packagePath, localService.ServiceManifestRef.ServiceManifestName, package.Name);
                                if (Directory.Exists(pkgPAth))
                                {
                                    Logger?.LogInfo($"Deleting {localAppManifest.ApplicationTypeName}.{localService.ServiceManifestRef.ServiceManifestName}.{package.Name} {package.Version}");
                                    Symlink.DeleteIfExists(pkgPAth);
                                }
                            }
                        }

                        if (serverServiceManifest.DataPackage != null && localServiceManifest.DataPackage != null)
                        {
                            foreach (var package in serverServiceManifest.DataPackage.Where(sp => localServiceManifest.DataPackage.Any(lp => lp.Name == sp.Name && lp.Version == sp.Version)))
                            {
                                pkgPAth = Path.Combine(packagePath, localService.ServiceManifestRef.ServiceManifestName, package.Name);
                                if (Directory.Exists(pkgPAth))
                                {
                                    Logger?.LogInfo($"Deleting {localAppManifest.ApplicationTypeName}.{localService.ServiceManifestRef.ServiceManifestName}.{package.Name} {package.Version}");
                                    Symlink.DeleteIfExists(pkgPAth);
                                }
                            }
                        }
                    }
                }
            }

            return(true);
        }