Esempio n. 1
0
        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.");
        }