public void RemoveUselessFiles() { var f = new Futile(Console.Out); var q = new FsQuery(this.f.ParentPath, new string[] { "/.git", "^/Releases", "^/Tests/Builder" }); //delete /Tests/binaries (*.pdb, *.xml, *.dll) //delete /Core/obj folder //Deleate all bin,obj,imageacache,uploads, and results folders under /Samples, /Tests, and /Plugins f.DelFiles(q.files("^/(Tests|Plugins|Samples)/*/(bin|obj|imagecache|uploads|results)/*", "^/Core/obj/*", "^/Core.Mvc/obj/*")); f.DelFiles(q.files("^/Samples/MvcSample/App_Data/*")); //delete .xml and .pdb files for third-party libs f.DelFiles(q.files("^/dlls/*/(Aforge|LitS3|Ionic)*.(pdb|xml)$")); //delete Thumbs.db //delete */.DS_Store f.DelFiles(q.files("/Thumbs.db$", "/.DS_Store$")); q = null; }
public void Run() { MakeConsoleNicer(); //PrepareForPackaging(); //using (RestorePoint rp = new RestorePoint(q.files(new Pattern("^/Samples/*/*.(cs|vb)proj$")))) { // //Replace all project references temporarily // foreach (string pf in q.files(new Pattern("^/Samples/[^/]+/*.(cs|vb)proj$"))) { // new ProjectFileEditor(pf).ReplaceAllProjectReferencesWithDllReferences("..\\..\\dlls\\release"); // } //} say("Project root: " + f.ParentPath); nl(); //The base name for creating zip packags. string packageBase = v.get("PackageName"); // // [assembly: PackageName("Resizer")] //List the file version number [assembly: AssemblyFileVersion("3.0.5.*")] string fileVer = list("FileVersion", v.get("AssemblyFileVersion").TrimEnd('.', '*')); //List the assembly version number. AssemblyVersion("3.0.5.*")] string assemblyVer = list("AssemblyVersion", v.get("AssemblyVersion").TrimEnd('.', '*')); //List the information version number. (used in zip package names) [assembly: AssemblyInformationalVersion("3-alpha-5")] string infoVer = list("InfoVersion", v.get("AssemblyInformationalVersion").TrimEnd('.', '*')); //List the Nuget package version number. New builds need to have a 4th number specified. string nugetVer = list("NugetVersion", v.get("NugetVersion").TrimEnd('.', '*')); //a. Ask if version numbers need to be modified if (ask("Change version numbers?")) { //b. Ask for file version number [assembly: AssemblyFileVersion("3.0.5.*")] fileVer = change("FileVersion", v.get("AssemblyFileVersion").TrimEnd('.', '*')); //c. Ask for assembly version number. AssemblyVersion("3.0.5.*")] assemblyVer = change("AssemblyVersion", v.get("AssemblyVersion").TrimEnd('.', '*')); //d: Ask for information version number. (used in zip package names) [assembly: AssemblyInformationalVersion("3-alpha-5")] infoVer = change("InfoVersion", v.get("AssemblyInformationalVersion").TrimEnd('.', '*')); //e. Ask for Nuget package version number. New builds need to have a 4th number specified. nugetVer = change("NugetVersion", v.get("NugetVersion").TrimEnd('.', '*')); } //b. Ask about hotfix - for hotfixes, we embed warnings and stuff so they don't get used in production. bool isHotfix = ask("Is this a hotfix? Press Y to tag the assembiles and packages as such."); //Build the hotfix name string packageHotfix = isHotfix ? ("-hotfix-" + DateTime.Now.ToString("htt").ToLower()) : ""; //Get the download server from SharedAssemblyInfo.cs if specified string downloadServer = v.get("DownloadServer"); if (downloadServer == null) { downloadServer = "http://downloads.imageresizing.net/"; } //f. For each package, specify options: choose 'c' (create and/or overwrite), 'u' (upload), 'p' (make private). //Should inform if the file already exists. nl(); say("For each zip package, specify all operations to perform, then press enter."); say("'c' - Create package (overwrite if exists), 'u' (upload to S3), 's' (skip), 'p' (make private)"); bool isBuilding = false; StringBuilder downloadPaths = new StringBuilder(); foreach (PackageDescriptor desc in packages) { desc.Path = getReleasePath(packageBase, infoVer, desc.Kind, packageHotfix); if (desc.Exists) { say("\n" + Path.GetFileName(desc.Path) + " already exists"); } string opts = ""; Console.Write(desc.Kind + " (" + opts + "):"); opts = Console.ReadLine().Trim(); desc.Options = opts; if (desc.Build) { isBuilding = true; } if (desc.Upload) { downloadPaths.AppendLine(downloadServer + Path.GetFileName(desc.Path)); } } if (downloadPaths.Length > 0) { say("Once complete, your files will be available at"); say(downloadPaths.ToString()); if (ask("Copy these to the clipboard?")) { System.Windows.Clipboard.SetText(downloadPaths.ToString()); } } //Get all the .nuspec packages on in the /nuget directory. IList <NPackageDescriptor> npackages = NPackageDescriptor.GetPackagesIn(Path.Combine(f.ParentPath, "nuget")); bool isMakingNugetPackage = false; if (ask("Create or upload NuGet packages?")) { foreach (NPackageDescriptor desc in npackages) { desc.VariableSubstitutions = GetNugetVariables(); desc.VariableSubstitutions["version"] = nugetVer; desc.Version = nugetVer; desc.OutputDirectory = Path.Combine(Path.Combine(f.ParentPath, "Releases", "nuget-packages")); if (!Directory.Exists(desc.OutputDirectory)) { Directory.CreateDirectory(desc.OutputDirectory); } say(Path.GetFileName(desc.PackagePath) + (desc.PackageExists ? " exists" : " not found"), desc.PackageExists ? ConsoleColor.Green : ConsoleColor.Gray); say(Path.GetFileName(desc.SymbolPackagePath) + (desc.SymbolPackageExists ? " exists" : " not found"), desc.SymbolPackageExists ? ConsoleColor.Green : (desc.PackageExists ? ConsoleColor.Red : ConsoleColor.Gray)); } say("What should we do with these packages? Enter multiple options like 'ou' "); say("r (create missing packages), c (overwrite all packages), u (upload all packages to nuget.org), i (enter interactive mode - choose per package), s (skip)"); string selection = Console.ReadLine().Trim().ToLowerInvariant(); bool interactive = selection.IndexOf('i') > -1; if (interactive) { selection = selection.Replace("i", ""); } //Set the default for every package foreach (NPackageDescriptor desc in npackages) { desc.Options = selection; } //Let the user pick per package if (interactive) { foreach (NPackageDescriptor desc in npackages) { Console.Write(desc.BaseName + " (" + desc.Options + "):"); desc.Options = Console.ReadLine().Trim().ToLowerInvariant(); } } isMakingNugetPackage = npackages.Any(desc => desc.Build); } var cs = new CredentialStore(); if (downloadPaths.Length > 0) { cs.Need("S3ID", "Amazon S3 AccessKey ID"); cs.Need("S3KEY", "Amazon S3 SecretAccessKey"); } if (isMakingNugetPackage) { cs.Need("NugetKey", "NuGet API Key"); } cs.AcquireCredentials(); nuget.apiKey = cs.Get("NugetKey", null); string s3ID = cs.Get("S3ID", null); string s3Key = cs.Get("S3KEY", null); s3 = new TransferUtility(s3ID, s3Key, Amazon.RegionEndpoint.USEast1); if (!isBuilding && isMakingNugetPackage) { isBuilding = ask("You're creating 1 or more NuGet packages. Rebuild software?"); } if (isBuilding) { //1 (moved execution to 8a) bool cleanAll = ask("Clean All?"); //2 - Set version numbers (with *, if missing) string originalContents = v.Contents; //Save for checking changes. v.set("AssemblyFileVersion", v.join(fileVer, "*")); v.set("AssemblyVersion", v.join(assemblyVer, "*")); v.set("AssemblyInformationalVersion", infoVer); v.set("NugetVersion", nugetVer); v.set("Commit", "git-commit-guid-here"); v.Save(); //Save contents for reverting later string fileContents = v.Contents; //Generate hard revision number for building (so all dlls use the same number) short revision = (short)(DateTime.UtcNow.TimeOfDay.Milliseconds % short.MaxValue); //the part under 32767. Can actually go up to, 65534, but what's the point. string exactVersion = v.join(fileVer, revision.ToString()); string fullInfoVer = infoVer + (isHotfix ? ("-temp-hotfix-" + DateTime.Now.ToString("MMM-d-yyyy-htt").ToLower()) : ""); string tag = "resizer" + v.join(infoVer, revision.ToString()) + (isHotfix ? "-hotfix": ""); //3 - Prompt to commit and tag bool versionsChanged = !fileContents.Equals(originalContents); string question = versionsChanged ? "SharedAssemblyInfo.cs was modified. Commit it (and any other changes) to the repository, then hit 'y'." : "Are all changes commited? Hit 'y' to continue. The SHA-1 of HEAD will be embedded in the DLLs."; while (!ask(question)) { } if (ask("Tag HEAD with '" + tag + "'?")) { g.Tag(tag); } //[assembly: Commit("git-commit-guid-here")] //4 - Embed git commit value string gitCommit = g.CanExecute ? g.GetHeadHash() : "git-could-not-run-during-build"; v.set("Commit", gitCommit); //4b - change to hard version number for building v.set("AssemblyFileVersion", exactVersion); v.set("AssemblyVersion", exactVersion); //Add hotfix suffix for hotfixes v.set("AssemblyInformationalVersion", fullInfoVer); v.Save(); //Prepare searchersq PrepareForPackaging(); bool success = false; //Allows use to temporarily edit all the sample project files using (RestorePoint rp = new RestorePoint(q.files(new Pattern("^/Plugins/*/*.(cs|vb)proj$"), new Pattern("^/Contrib/*/*.(cs|vb)proj$")))) { //Replace all project references temporarily foreach (string pf in rp.Paths) { new ProjectFileEditor(pf).RemoveStrongNameRefs(); } //8a Clean projects if specified if (cleanAll) { CleanAll(); } //6 - if (c) was specified for any package, build all. success = BuildAll(true); //isMakingNugetPackage); } //7 - Revert file to state at commit (remove 'full' version numbers and 'commit' value) v.Contents = fileContents; q.Rescan(); //Rescan filesystem to prevent errors building the archive (since we delete stuff in CleanAll()) v.Save(); if (!success) { return; //If the build didn't go ok, pause and exit } //8b - run cleanup routine RemoveUselessFiles(); //Allows use to temporarily edit all the sample project files using (RestorePoint rp = new RestorePoint(q.files(new Pattern("^/Samples/*/*.(cs|vb)proj$")))) { //Replace all project references temporarily foreach (string pf in q.files(new Pattern("^/Samples/[^/]+/*.(cs|vb)proj$"))) { new ProjectFileEditor(pf).ReplaceAllProjectReferencesWithDllReferences("..\\..\\dlls\\release").RemoveStrongNameRefs(); } //9 - Pacakge all selected zip configurations foreach (PackageDescriptor pd in packages) { if (pd.Skip || !pd.Build) { continue; } if (pd.Exists && pd.Build) { File.Delete(pd.Path); say("Deleted " + pd.Path); } pd.Builder(pd); //Copy to a 'tozip' version for e-mailing //File.Copy(pd.Path, pd.Path.Replace(".zip", ".tozip"), true); } } } //10 - Pacakge all nuget configurations foreach (NPackageDescriptor pd in npackages) { if (pd.Skip) { continue; } if (pd.Build) { nuget.Pack(pd); } } //11 - Upload all selected zip configurations foreach (PackageDescriptor pd in packages) { if (pd.Skip) { continue; } if (pd.Upload) { if (!pd.Exists) { say("Can't upload, file missing: " + pd.Path); continue; } var request = new TransferUtilityUploadRequest(); request.CannedACL = pd.Private ? Amazon.S3.S3CannedACL.Private : Amazon.S3.S3CannedACL.PublicRead; request.BucketName = bucketName; request.Timeout = TimeSpan.FromHours(2); request.ContentType = "application/zip"; request.Key = Path.GetFileName(pd.Path); request.FilePath = pd.Path; say("Uploading " + Path.GetFileName(pd.Path) + " to " + bucketName + " with CannedAcl:" + request.CannedACL.ToString()); bool retry = false; do { //Upload try { s3.Upload(request); } catch (Exception ex) { say("Upload failed: " + ex.Message); retry = ask("Retry upload?"); } } while (retry); say("Finished uploading " + Path.GetFileName(pd.Path)); } } //2 - Upload all nuget configurations foreach (NPackageDescriptor pd in npackages) { if (pd.Skip || !pd.Upload) { continue; } nuget.Push(pd); } //12 - Generate template for release notes article say("Everything is done."); }