static int Main(string[] args) { var optParams = ParseCommands.ParseOptions(args); if (optParams == null) { return(-1); } var targetDir = optParams["target"]; var package = new ReleasePackage(optParams["input"]); var targetFile = Path.Combine(targetDir, package.SuggestedReleaseFileName); string fullRelease; try { fullRelease = package.CreateReleasePackage(targetFile, optParams["pkgdir"] != "" ? optParams["pkgdir"] : null, input => (new Markdown()).Transform(input)); } catch (Exception ex) { Console.Error.WriteLine(); Console.Error.WriteLine("Unexpected exception occurred creating package:"); Console.Error.WriteLine(ex); Console.Error.WriteLine(); Console.Error.WriteLine(); return(-4); } Console.WriteLine("{0};", fullRelease); var releaseFile = Path.Combine(targetDir, "RELEASES"); if (File.Exists(releaseFile)) { var releasesText = File.ReadAllText(releaseFile, Encoding.UTF8); var releaseEntries = ReleaseEntry.ParseReleaseFile(releasesText); var previousFullRelease = ReleaseEntry.GetPreviousRelease(releaseEntries, package, targetDir); if (previousFullRelease != null && File.Exists(previousFullRelease.ReleasePackageFile)) { var deltaFile = Path.Combine(targetDir, package.SuggestedReleaseFileName.Replace("full", "delta")); Console.WriteLine("{0}; {1}", previousFullRelease.InputPackageFile, deltaFile); if (File.Exists(deltaFile)) { File.Delete(deltaFile); } var deltaBuilder = new DeltaPackageBuilder(); deltaBuilder.CreateDeltaPackage(previousFullRelease, package, deltaFile); } } ReleaseEntry.BuildReleasesFile(targetDir); return(0); }
private static void ReleasifyElectron(string package, string targetDir = null, string baseUrl = null) { // check that package is valid new ZipPackage(package).GetType(); if (baseUrl != null) { if (!Utility.IsHttpUrl(baseUrl)) { throw new Exception($"Invalid --baseUrl '{baseUrl}'. A base URL must start with http or https and be a valid URI."); } if (!baseUrl.EndsWith("/")) { baseUrl += "/"; } } targetDir = targetDir ?? Path.Combine(".", "Releases"); var di = new DirectoryInfo(targetDir); var releaseFilePath = Path.Combine(di.FullName, "RELEASES"); var previousReleases = new List <ReleaseEntry>(); if (File.Exists(releaseFilePath)) { previousReleases.AddRange(ReleaseEntry.ParseReleaseFile(File.ReadAllText(releaseFilePath, Encoding.UTF8))); } var processed = new List <string>(); var rp = new ReleasePackage(package, true); processed.Add(package); var prev = ReleaseEntry.GetPreviousRelease(previousReleases, rp, targetDir); if (prev != null) { var deltaBuilder = new DeltaPackageBuilder(); var dp = deltaBuilder.CreateDeltaPackage(prev, rp, Path.Combine(di.FullName, rp.SuggestedReleaseFileName.Replace("full", "delta"))); processed.Insert(0, dp.InputPackageFile); } var newReleaseEntries = processed .Select(packageFilename => ReleaseEntry.GenerateFromFile(packageFilename, baseUrl)) .ToList(); var distinctPreviousReleases = previousReleases .Where(x => !newReleaseEntries.Select(e => e.Version).Contains(x.Version)); var releaseEntries = distinctPreviousReleases.Concat(newReleaseEntries).ToList(); ReleaseEntry.WriteReleaseFile(releaseEntries, releaseFilePath); var newestFullRelease = releaseEntries.MaxBy(x => x.Version).First(x => !x.IsDelta); Console.Out.WriteLine(ReleaseEntry.GenerateFromFile(Path.Combine(di.FullName, newestFullRelease.Filename)).EntryAsString); }
public void WhenCurrentReleaseMatchesLastReleaseReturnNull() { var package = new ReleasePackage("Espera-1.7.6-beta.nupkg"); var releaseEntries = new[] { ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.6-beta.nupkg")) }; Assert.Null(ReleaseEntry.GetPreviousRelease( releaseEntries, package, @"C:\temp\somefolder")); }
public void WhenMultipleReleasesFoundInOtherOrderReturnPreviousVersion() { var expected = new Version("1.7.6"); var input = new ReleasePackage("Espera-1.7.7-beta.nupkg"); var releaseEntries = new[] { ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.5-beta.nupkg")), ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.6-beta.nupkg")) }; var actual = ReleaseEntry.GetPreviousRelease( releaseEntries, input, @"C:\temp\"); Assert.Equal(expected, actual.Version); }
public void WhenMultipleReleaseMatchesReturnEarlierResult() { var expected = new Version("1.7.5"); var package = new ReleasePackage("Espera-1.7.6-beta.nupkg"); var releaseEntries = new[] { ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.6-beta.nupkg")), ReleaseEntry.ParseReleaseEntry(MockReleaseEntry("Espera-1.7.5-beta.nupkg")) }; var actual = ReleaseEntry.GetPreviousRelease( releaseEntries, package, @"C:\temp\"); Assert.Equal(expected, actual.Version); }
public void Releasify(string package, string targetDir = null, string packagesDir = null, string bootstrapperExe = null, string backgroundGif = null, string signingOpts = null, string baseUrl = null, string setupIcon = null, bool generateMsi = true) { if (baseUrl != null) { if (!Utility.IsHttpUrl(baseUrl)) { throw new Exception(string.Format("Invalid --baseUrl '{0}'. A base URL must start with http or https and be a valid URI.", baseUrl)); } if (!baseUrl.EndsWith("/")) { baseUrl += "/"; } } targetDir = targetDir ?? Path.Combine(".", "Releases"); packagesDir = packagesDir ?? "."; bootstrapperExe = bootstrapperExe ?? Path.Combine(".", "Setup.exe"); if (!Directory.Exists(targetDir)) { Directory.CreateDirectory(targetDir); } if (!File.Exists(bootstrapperExe)) { bootstrapperExe = Path.Combine( Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Setup.exe"); } this.Log().Info("Bootstrapper EXE found at:" + bootstrapperExe); var di = new DirectoryInfo(targetDir); File.Copy(package, Path.Combine(di.FullName, Path.GetFileName(package)), true); var allNuGetFiles = di.EnumerateFiles() .Where(x => x.Name.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase)); var toProcess = allNuGetFiles.Where(x => !x.Name.Contains("-delta") && !x.Name.Contains("-full")); var processed = new List <string>(); var releaseFilePath = Path.Combine(di.FullName, "RELEASES"); var previousReleases = new List <ReleaseEntry>(); if (File.Exists(releaseFilePath)) { previousReleases.AddRange(ReleaseEntry.ParseReleaseFile(File.ReadAllText(releaseFilePath, Encoding.UTF8))); } foreach (var file in toProcess) { this.Log().Info("Creating release package: " + file.FullName); var rp = new ReleasePackage(file.FullName); rp.CreateReleasePackage(Path.Combine(di.FullName, rp.SuggestedReleaseFileName), packagesDir, contentsPostProcessHook: pkgPath => { new DirectoryInfo(pkgPath).GetAllFilesRecursively() .Where(x => x.Name.ToLowerInvariant().EndsWith(".exe")) .Where(x => !x.Name.ToLowerInvariant().Contains("squirrel.exe")) .Where(x => Utility.ExecutableUsesWin32Subsystem(x.FullName)) .ForEachAsync(x => createExecutableStubForExe(x.FullName)) .Wait(); if (signingOpts == null) { return; } new DirectoryInfo(pkgPath).GetAllFilesRecursively() .Where(x => Utility.FileIsLikelyPEImage(x.Name)) .ForEachAsync(async x => { if (isPEFileSigned(x.FullName)) { this.Log().Info("{0} is already signed, skipping", x.FullName); return; } this.Log().Info("About to sign {0}", x.FullName); await signPEFile(x.FullName, signingOpts); }) .Wait(); }); processed.Add(rp.ReleasePackageFile); var prev = ReleaseEntry.GetPreviousRelease(previousReleases, rp, targetDir); if (prev != null) { var deltaBuilder = new DeltaPackageBuilder(null); var dp = deltaBuilder.CreateDeltaPackage(prev, rp, Path.Combine(di.FullName, rp.SuggestedReleaseFileName.Replace("full", "delta"))); processed.Insert(0, dp.InputPackageFile); } } foreach (var file in toProcess) { File.Delete(file.FullName); } var newReleaseEntries = processed .Select(packageFilename => ReleaseEntry.GenerateFromFile(packageFilename, baseUrl)) .ToList(); var distinctPreviousReleases = previousReleases .Where(x => !newReleaseEntries.Select(e => e.Version).Contains(x.Version)); var releaseEntries = distinctPreviousReleases.Concat(newReleaseEntries).ToList(); ReleaseEntry.WriteReleaseFile(releaseEntries, releaseFilePath); var targetSetupExe = Path.Combine(di.FullName, "Setup.exe"); var newestFullRelease = releaseEntries.MaxBy(x => x.Version).Where(x => !x.IsDelta).First(); File.Copy(bootstrapperExe, targetSetupExe, true); var zipPath = createSetupEmbeddedZip(Path.Combine(di.FullName, newestFullRelease.Filename), di.FullName, backgroundGif, signingOpts).Result; var writeZipToSetup = findExecutable("WriteZipToSetup.exe"); try { var result = Utility.InvokeProcessAsync(writeZipToSetup, String.Format("\"{0}\" \"{1}\"", targetSetupExe, zipPath), CancellationToken.None).Result; if (result.Item1 != 0) { throw new Exception("Failed to write Zip to Setup.exe!\n\n" + result.Item2); } } catch (Exception ex) { this.Log().ErrorException("Failed to update Setup.exe with new Zip file", ex); } finally { File.Delete(zipPath); } Utility.Retry(() => setPEVersionInfoAndIcon(targetSetupExe, new ZipPackage(package), setupIcon).Wait()); if (signingOpts != null) { signPEFile(targetSetupExe, signingOpts).Wait(); } if (generateMsi) { createMsiPackage(targetSetupExe, new ZipPackage(package)).Wait(); if (signingOpts != null) { signPEFile(targetSetupExe.Replace(".exe", ".msi"), signingOpts).Wait(); } } }
public void Releasify(string package, string targetDir = null, string packagesDir = null, string bootstrapperExe = null, string backgroundGif = null, string signingOpts = null, string baseUrl = null, string setupIcon = null) { if (baseUrl != null) { if (!Utility.IsHttpUrl(baseUrl)) { throw new Exception(string.Format("Invalid --baseUrl '{0}'. A base URL must start with http or https and be a valid URI.", baseUrl)); } if (!baseUrl.EndsWith("/")) { baseUrl += "/"; } } targetDir = targetDir ?? ".\\Releases"; packagesDir = packagesDir ?? "."; bootstrapperExe = bootstrapperExe ?? ".\\Setup.exe"; if (!Directory.Exists(targetDir)) { Directory.CreateDirectory(targetDir); } if (!File.Exists(bootstrapperExe)) { bootstrapperExe = Path.Combine( Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Setup.exe"); } this.Log().Info("Bootstrapper EXE found at:" + bootstrapperExe); var di = new DirectoryInfo(targetDir); File.Copy(package, Path.Combine(di.FullName, Path.GetFileName(package)), true); var allNuGetFiles = di.EnumerateFiles() .Where(x => x.Name.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase)); var toProcess = allNuGetFiles.Where(x => !x.Name.Contains("-delta") && !x.Name.Contains("-full")); var processed = new List <string>(); var releaseFilePath = Path.Combine(di.FullName, "RELEASES"); var previousReleases = Enumerable.Empty <ReleaseEntry>(); if (File.Exists(releaseFilePath)) { previousReleases = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releaseFilePath, Encoding.UTF8)); } foreach (var file in toProcess) { this.Log().Info("Creating release package: " + file.FullName); var rp = new ReleasePackage(file.FullName); rp.CreateReleasePackage(Path.Combine(di.FullName, rp.SuggestedReleaseFileName), packagesDir, contentsPostProcessHook: pkgPath => { if (signingOpts == null) { return; } new DirectoryInfo(pkgPath).GetAllFilesRecursively() .Where(x => x.Name.ToLowerInvariant().EndsWith(".exe")) .ForEachAsync(x => signPEFile(x.FullName, signingOpts)) .Wait(); }); processed.Add(rp.ReleasePackageFile); var prev = ReleaseEntry.GetPreviousRelease(previousReleases, rp, targetDir); if (prev != null) { var deltaBuilder = new DeltaPackageBuilder(); var dp = deltaBuilder.CreateDeltaPackage(prev, rp, Path.Combine(di.FullName, rp.SuggestedReleaseFileName.Replace("full", "delta"))); processed.Insert(0, dp.InputPackageFile); } } foreach (var file in toProcess) { File.Delete(file.FullName); } var releaseEntries = previousReleases.Concat(processed.Select(packageFilename => ReleaseEntry.GenerateFromFile(packageFilename, baseUrl))); ReleaseEntry.WriteReleaseFile(releaseEntries, releaseFilePath); var targetSetupExe = Path.Combine(di.FullName, "Setup.exe"); var newestFullRelease = releaseEntries.MaxBy(x => x.Version).Where(x => !x.IsDelta).First(); File.Copy(bootstrapperExe, targetSetupExe, true); var zipPath = createSetupEmbeddedZip(Path.Combine(di.FullName, newestFullRelease.Filename), di.FullName, backgroundGif, signingOpts).Result; try { var zip = File.ReadAllBytes(zipPath); IntPtr handle = NativeMethods.BeginUpdateResource(targetSetupExe, false); if (handle == IntPtr.Zero) { throw new Win32Exception(); } if (!NativeMethods.UpdateResource(handle, "DATA", new IntPtr(131), 0x0409, zip, zip.Length)) { throw new Win32Exception(); } if (!NativeMethods.EndUpdateResource(handle, false)) { throw new Win32Exception(); } } catch (Exception ex) { this.Log().ErrorException("Failed to update Setup.exe with new Zip file", ex); } finally { File.Delete(zipPath); } Utility.Retry(() => setPEVersionInfoAndIcon(targetSetupExe, new ZipPackage(package), setupIcon).Wait()); if (signingOpts != null) { signPEFile(targetSetupExe, signingOpts).Wait(); } }
public void GetLatestReleaseWithEmptyCollectionReturnsNull() { Assert.Null(ReleaseEntry.GetPreviousRelease( Enumerable.Empty <ReleaseEntry>(), null, null)); }
public void GetLatestReleaseWithNullCollectionReturnsNull() { Assert.Null(ReleaseEntry.GetPreviousRelease( null, null, null)); }
public void Releasify(string package, string targetDir = null, string packagesDir = null, string bootstrapperExe = null) { targetDir = targetDir ?? ".\\Releases"; packagesDir = packagesDir ?? "."; bootstrapperExe = bootstrapperExe ?? ".\\Setup.exe"; if (!Directory.Exists(targetDir)) { Directory.CreateDirectory(targetDir); } if (!File.Exists(bootstrapperExe)) { bootstrapperExe = Path.Combine( Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Setup.exe"); } this.Log().Info("Bootstrapper EXE found at:" + bootstrapperExe); var di = new DirectoryInfo(targetDir); File.Copy(package, Path.Combine(di.FullName, Path.GetFileName(package)), true); var allNuGetFiles = di.EnumerateFiles() .Where(x => x.Name.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase)); var toProcess = allNuGetFiles.Where(x => !x.Name.Contains("-delta") && !x.Name.Contains("-full")); var releaseFilePath = Path.Combine(di.FullName, "RELEASES"); var previousReleases = Enumerable.Empty <ReleaseEntry>(); if (File.Exists(releaseFilePath)) { previousReleases = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releaseFilePath, Encoding.UTF8)); } foreach (var file in toProcess) { this.Log().Info("Creating release package: " + file.FullName); var rp = new ReleasePackage(file.FullName); rp.CreateReleasePackage(Path.Combine(di.FullName, rp.SuggestedReleaseFileName), packagesDir); var prev = ReleaseEntry.GetPreviousRelease(previousReleases, rp, targetDir); if (prev != null) { var deltaBuilder = new DeltaPackageBuilder(); deltaBuilder.CreateDeltaPackage(prev, rp, Path.Combine(di.FullName, rp.SuggestedReleaseFileName.Replace("full", "delta"))); } } foreach (var file in toProcess) { File.Delete(file.FullName); } var releaseEntries = allNuGetFiles.Select(x => ReleaseEntry.GenerateFromFile(x.FullName)); ReleaseEntry.WriteReleaseFile(releaseEntries, releaseFilePath); var targetSetupExe = Path.Combine(di.FullName, "Setup.exe"); var newestFullRelease = releaseEntries.MaxBy(x => x.Version).Where(x => !x.IsDelta).First(); File.Copy(bootstrapperExe, targetSetupExe, true); var zipPath = createSetupEmbeddedZip(Path.Combine(di.FullName, newestFullRelease.Filename), di.FullName); try { var zip = File.ReadAllBytes(zipPath); IntPtr handle = NativeMethods.BeginUpdateResource(targetSetupExe, false); if (handle == IntPtr.Zero) { throw new Win32Exception(); } if (!NativeMethods.UpdateResource(handle, "DATA", new IntPtr(131), 0x0409, zip, zip.Length)) { throw new Win32Exception(); } if (!NativeMethods.EndUpdateResource(handle, false)) { throw new Win32Exception(); } } catch (Exception ex) { this.Log().ErrorException("Failed to update Setup.exe with new Zip file", ex); } finally { File.Delete(zipPath); } }