Esempio n. 1
0
        public Build()
        {
            Cake.Log.Verbosity = Verbosity.Diagnostic;

            const string solutionName     = "CodeCake";
            const string solutionFileName = solutionName + ".sln";

            var releasesDir = Cake.Directory("CodeCakeBuilder/Releases");

            Cake.CreateDirectory(releasesDir);

            var projects = Cake.ParseSolution(solutionFileName)
                           .Projects
                           .Where(p => !(p is SolutionFolder) &&
                                  p.Name != "CodeCakeBuilder");

            // We do not publish .Tests projects for this solution.
            var projectsToPublish = projects.Where(p => !p.Path.Segments.Contains("Tests"));

            // The SimpleRepositoryInfo should be computed once and only once.
            SimpleRepositoryInfo gitInfo = Cake.GetSimpleRepositoryInfo();
            // This default global info will be replaced by Check-Repository task.
            // It is allocated here to ease debugging and/or manual work on complex build script.
            CheckRepositoryInfo globalInfo = new CheckRepositoryInfo {
                Version = gitInfo.SafeNuGetVersion
            };

            Setup(context =>
            {
                context.Information("Executed BEFORE the first task.");
            });

            Teardown(context =>
            {
                context.Information("Executed AFTER the last task.");
            });

            TaskSetup(setupContext =>
            {
                setupContext.Information($"TaskSetup for Task: {setupContext.Task.Name}");
            });

            TaskTeardown(teardownContext =>
            {
                teardownContext.Information($"TaskTeardown for Task: {teardownContext.Task.Name}");
            });

            Task("Check-Repository")
            .Does(() =>
            {
                globalInfo = StandardCheckRepository(projectsToPublish, gitInfo);
                if (globalInfo.ShouldStop)
                {
                    Cake.TerminateWithSuccess("All packages from this commit are already available. Build skipped.");
                }
            });

            Task("Clean")
            .Does(() =>
            {
                Cake.CleanDirectories(projects.Select(p => p.Path.GetDirectory().Combine("bin")));
                Cake.CleanDirectories(releasesDir);
            });

            // Use N as the first answser: this test takes a looong time (why?)
            // In -autointeraction mode, this will be skipped (unless explicitly asked from the command line).
            Task("AutoTests")
            .WithCriteria(() => Cake.InteractiveMode() == InteractiveMode.NoInteraction ||
                          Cake.ReadInteractiveOption("RunAutoTests", "Run Auto Tests (for Dynamic paths)?", 'N', 'Y') == 'Y')
            .Does(() =>
            {
                void ShouldFindAutoTestFolderFromDynamicPaths(bool shouldFind)
                {
                    string[] paths = Cake.Environment.GetEnvironmentVariable("PATH").Split(new char[] { Cake.Environment.Platform.IsUnix() ? ':' : ';' }, StringSplitOptions.RemoveEmptyEntries);
                    // Cake does not normalize the paths to System.IO.Path.DirectorySeparatorChar. We do it here.
                    string af       = Cake.Environment.WorkingDirectory.FullPath + "/CodeCakeBuilder/AutoTests".Replace('\\', '/');
                    bool autoFolder = paths.Select(p => p.Replace('\\', '/')).Contains(af);
                    if (autoFolder != shouldFind)
                    {
                        throw new Exception(shouldFind ? "AutoTests folder should be found." : "AutoTests folder should not be found.");
                    }
                }

                void ShouldFindTestTxtFileFromDynamicPaths(bool shouldFind)
                {
                    string[] paths             = Cake.Environment.GetEnvironmentVariable("PATH").Split(new char[] { Cake.Environment.Platform.IsUnix() ? ':' : ';' }, StringSplitOptions.RemoveEmptyEntries);
                    bool findTestTxtFileInPath = paths.Select(p => System.IO.Path.Combine(p, "Test.txt")).Any(f => System.IO.File.Exists(f));
                    if (findTestTxtFileInPath != shouldFind)
                    {
                        throw new Exception(shouldFind ? "Should find Text.txt file." : "Should not find Test.txt file.");
                    }
                }

                if (System.IO.Directory.Exists("CodeCakeBuilder/AutoTests"))
                {
                    Cake.DeleteDirectory("CodeCakeBuilder/AutoTests", new DeleteDirectorySettings()
                    {
                        Recursive = true, Force = true
                    });
                }
                ShouldFindAutoTestFolderFromDynamicPaths(false);
                ShouldFindTestTxtFileFromDynamicPaths(false);
                Cake.CreateDirectory("CodeCakeBuilder/AutoTests/TestDynamic0");
                ShouldFindAutoTestFolderFromDynamicPaths(true);
                ShouldFindTestTxtFileFromDynamicPaths(false);
                System.IO.File.WriteAllText("CodeCakeBuilder/AutoTests/TestDynamic0/Test.txt", "c");
                ShouldFindAutoTestFolderFromDynamicPaths(true);
                ShouldFindTestTxtFileFromDynamicPaths(true);
                Cake.DeleteDirectory("CodeCakeBuilder/AutoTests/TestDynamic0", new DeleteDirectorySettings()
                {
                    Recursive = true, Force = true
                });
                Cake.CreateDirectory("CodeCakeBuilder/AutoTests/Sub/TestDynamicB");
                ShouldFindAutoTestFolderFromDynamicPaths(true);
                ShouldFindTestTxtFileFromDynamicPaths(false);
                System.IO.File.WriteAllText("CodeCakeBuilder/AutoTests/Sub/TestDynamicB/Test.txt", "c");
                ShouldFindTestTxtFileFromDynamicPaths(true);
                Cake.DeleteDirectory("CodeCakeBuilder/AutoTests", new DeleteDirectorySettings()
                {
                    Recursive = true, Force = true
                });
                ShouldFindTestTxtFileFromDynamicPaths(false);
                ShouldFindAutoTestFolderFromDynamicPaths(false);
            });

            Task("Build")
            .IsDependentOn("Clean")
            .IsDependentOn("Check-Repository")
            .IsDependentOn("AutoTests")
            .Does(() =>
            {
                StandardSolutionBuild(solutionFileName, gitInfo, globalInfo.BuildConfiguration);
            });

            Task("Create-NuGet-Packages")
            .WithCriteria(() => gitInfo.IsValid)
            .IsDependentOn("Build")
            .Does(() =>
            {
                StandardCreateNuGetPackages(releasesDir, projectsToPublish, gitInfo, globalInfo.BuildConfiguration);
            });

            Task("Push-NuGet-Packages")
            .IsDependentOn("Create-NuGet-Packages")
            .WithCriteria(() => gitInfo.IsValid)
            .Does(() =>
            {
                StandardPushNuGetPackages(globalInfo, releasesDir);
            });

            Task("Default").IsDependentOn("Push-NuGet-Packages");
        }
Esempio n. 2
0
        public Build()
        {
            const string solutionName     = "CK-Core";
            const string solutionFileName = solutionName + ".sln";

            var releasesDir = Cake.Directory("CodeCakeBuilder/Releases");
            SimpleRepositoryInfo gitInfo = null;
            // Configuration is either "Debug" or "Release".
            string configuration = null;

            // We do not publish .Tests projects for this solution.
            var projectsToPublish = Cake.ParseSolution(solutionFileName)
                                    .Projects
                                    .Where(p => p.Name != "CodeCakeBuilder" &&
                                           !p.Path.Segments.Contains("Tests"));

            Task("Check-Repository")
            .Does(() =>
            {
                gitInfo = Cake.GetSimpleRepositoryInfo();

                if (!gitInfo.IsValid)
                {
                    if (Cake.IsInteractiveMode() &&
                        Cake.ReadInteractiveOption("Repository is not ready to be published. Proceed anyway?", 'Y', 'N') == 'Y')
                    {
                        Cake.Warning("GitInfo is not valid, but you choose to continue...");
                    }
                    else
                    {
                        throw new Exception("Repository is not ready to be published.");
                    }
                }
                configuration = gitInfo.IsValidRelease && gitInfo.PreReleaseName.Length == 0 ? "Release" : "Debug";

                Cake.Information("Publishing {0} projects with version={1} and configuration={2}: {3}",
                                 projectsToPublish.Count(),
                                 gitInfo.SemVer,
                                 configuration,
                                 projectsToPublish.Select(p => p.Name).Concatenate());
            });

            Task("Restore-NuGet-Packages")
            .Does(() =>
            {
                Cake.NuGetRestore(solutionFileName);
            });

            Task("Clean")
            .IsDependentOn("Check-Repository")
            .Does(() =>
            {
                Cake.CleanDirectories("**/bin/" + configuration, d => !d.Path.Segments.Contains("CodeCakeBuilder"));
                Cake.CleanDirectories("**/obj/" + configuration, d => !d.Path.Segments.Contains("CodeCakeBuilder"));
                Cake.CleanDirectories(releasesDir);
                Cake.DeleteFiles("Tests/**/TestResult.xml");
            });

            Task("Build")
            .IsDependentOn("Clean")
            .IsDependentOn("Restore-NuGet-Packages")
            .IsDependentOn("Check-Repository")
            .Does(() =>
            {
                using (var tempSln = Cake.CreateTemporarySolutionFile(solutionFileName))
                {
                    tempSln.ExcludeProjectsFromBuild("CodeCakeBuilder");
                    Cake.MSBuild(tempSln.FullPath, settings =>
                    {
                        settings.Configuration = configuration;
                        settings.Verbosity     = Verbosity.Minimal;
                        // Always generates Xml documentation. Relies on this definition in the csproj files:
                        //
                        // <PropertyGroup Condition=" $(GenerateDocumentation) != '' ">
                        //   <DocumentationFile>bin\$(Configuration)\$(AssemblyName).xml</DocumentationFile>
                        // </PropertyGroup>
                        //
                        settings.Properties.Add("GenerateDocumentation", new[] { "true" });
                    });
                }
            });

            Task("Unit-Testing")
            .IsDependentOn("Build")
            .Does(() =>
            {
                Cake.CreateDirectory(releasesDir);
                var testDlls = Cake.ParseSolution(solutionFileName)
                               .Projects
                               .Where(p => p.Name.EndsWith(".Tests"))
                               .Select(p => p.Path.GetDirectory().CombineWithFilePath("bin/" + configuration + "/" + p.Name + ".dll"));
                Cake.Information("Testing: {0}", string.Join(", ", testDlls.Select(p => p.GetFilename().ToString())));

                Cake.NUnit(testDlls, new NUnitSettings()
                {
                    Framework  = "v4.5",
                    OutputFile = releasesDir.Path + "/TestResult.txt"
                });
            });

            Task("Create-NuGet-Packages")
            .IsDependentOn("Unit-Testing")
            .WithCriteria(() => gitInfo.IsValid)
            .Does(() =>
            {
                Cake.CreateDirectory(releasesDir);
                var settings = new NuGetPackSettings()
                {
                    Version         = gitInfo.NuGetVersion,
                    BasePath        = Cake.Environment.WorkingDirectory,
                    OutputDirectory = releasesDir
                };
                Cake.CopyFiles("CodeCakeBuilder/NuSpec/*.nuspec", releasesDir);
                foreach (var nuspec in Cake.GetFiles(releasesDir.Path + "/*.nuspec"))
                {
                    TransformText(nuspec, configuration, gitInfo);
                    Cake.NuGetPack(nuspec, settings);
                }
                Cake.DeleteFiles(releasesDir.Path + "/*.nuspec");
            });


            Task("Push-NuGet-Packages")
            .IsDependentOn("Create-NuGet-Packages")
            .WithCriteria(() => gitInfo.IsValid)
            .Does(() =>
            {
                IEnumerable <FilePath> nugetPackages = Cake.GetFiles(releasesDir.Path + "/*.nupkg");
                if (Cake.IsInteractiveMode())
                {
                    var localFeed = Cake.FindDirectoryAbove("LocalFeed");
                    if (localFeed != null)
                    {
                        Cake.Information("LocalFeed directory found: {0}", localFeed);
                        if (Cake.ReadInteractiveOption("Do you want to publish to LocalFeed?", 'Y', 'N') == 'Y')
                        {
                            Cake.CopyFiles(nugetPackages, localFeed);
                        }
                    }
                }
                if (gitInfo.IsValidRelease)
                {
                    if (gitInfo.PreReleaseName == "" ||
                        gitInfo.PreReleaseName == "prerelease" ||
                        gitInfo.PreReleaseName == "rc")
                    {
                        PushNuGetPackages("NUGET_API_KEY", "https://www.nuget.org/api/v2/package", nugetPackages);
                    }
                    else
                    {
                        // An alpha, beta, delta, epsilon, gamma, kappa goes to invenietis-preview.
                        PushNuGetPackages("MYGET_PREVIEW_API_KEY", "https://www.myget.org/F/invenietis-preview/api/v2/package", nugetPackages);
                    }
                }
                else
                {
                    Debug.Assert(gitInfo.IsValidCIBuild);
                    PushNuGetPackages("MYGET_CI_API_KEY", "https://www.myget.org/F/invenietis-ci/api/v2/package", nugetPackages);
                }
            });

            Task("Build-DocFX")
            .IsDependentOn("Check-Repository")
            .WithCriteria(() => gitInfo.IsValid)
            .Does(() =>
            {
                var settingsFile     = Cake.File("DocFX/docfx.json");
                var settingsFileCopy = Cake.File("DocFX/docfx.json.old");
                try
                {
                    // Create a copy restored in finally{}
                    Cake.Information($"Backing up {settingsFile} to {settingsFileCopy}");
                    Cake.CopyFile(settingsFile, settingsFileCopy);

                    // Edit the settings file
                    // TODO: A proper visitor & rewriter; target properties are:
                    //   o.build.globalMetadata._appVersion
                    //   o.build.globalMetadata._appShortVersion
                    Cake.Information($"Writing {settingsFile}");
                    Cake.Information($"* _appVersion: {gitInfo.SemVer}");
                    Cake.Information($"* _appShortVersion: {gitInfo.NuGetVersion}");
                    File.WriteAllText(
                        settingsFile,
                        File.ReadAllText(settingsFile)
                        .Replace("%%VERSION%%", gitInfo.SemVer)
                        .Replace("%%SHORTVERSION%%", gitInfo.NuGetVersion)
                        );

                    // Build DocFX project
                    var docFxProjectFile = Cake.File("DocFX/DocFX.csproj");

                    Cake.Information($"Building {docFxProjectFile}");

                    Cake.MSBuild(docFxProjectFile, settings =>
                    {
                        settings.Configuration = configuration;
                        settings.Verbosity     = Verbosity.Minimal;
                    });

                    // Pack output
                    var outDir = Cake.Directory("DocFX/_site");      // Configured in DocFX/docfx.json
                    var outZip = releasesDir.Path.CombineWithFilePath($@"{solutionName}.{gitInfo.SemVer}.DocFX.zip");

                    Cake.Information($"Packing {outDir} to {outZip}");
                    Cake.Zip(outDir, outZip);
                }
                finally
                {
                    // Delete existing file and restore file copy
                    if (Cake.FileExists(settingsFileCopy))
                    {
                        Cake.Information($"Restoring {settingsFile}");
                        if (Cake.FileExists(settingsFile))
                        {
                            Cake.DeleteFile(settingsFile);
                        }
                        Cake.MoveFile(settingsFileCopy, settingsFile);
                    }
                }
            });

            // The Default task for this script can be set here.
            Task("Default")
            .IsDependentOn("Push-NuGet-Packages");
        }
Esempio n. 3
0
        public Build()
        {
            const string solutionName     = "Yodii-Script";
            const string solutionFileName = solutionName + ".sln";

            var releasesDir = Cake.Directory("CodeCakeBuilder/Releases");

            var projects = Cake.ParseSolution(solutionFileName)
                           .Projects
                           .Where(p => !(p is SolutionFolder) &&
                                  p.Name != "CodeCakeBuilder");

            // We do not publish .Tests projects for this solution.
            var projectsToPublish = projects
                                    .Where(p => !p.Path.Segments.Contains("Tests"));

            // The SimpleRepositoryInfo should be computed once and only once.
            SimpleRepositoryInfo gitInfo = Cake.GetSimpleRepositoryInfo();
            // This default global info will be replaced by Check-Repository task.
            // It is allocated here to ease debugging and/or manual work on complex build script.
            CheckRepositoryInfo globalInfo = new CheckRepositoryInfo(gitInfo, projectsToPublish);

            Task("Check-Repository")
            .Does(() =>
            {
                globalInfo = StandardCheckRepository(projectsToPublish, gitInfo);
                if (globalInfo.ShouldStop)
                {
                    Cake.TerminateWithSuccess("All packages from this commit are already available. Build skipped.");
                }
            });

            Task("Clean")
            .Does(() =>
            {
                Cake.CleanDirectories(projects.Select(p => p.Path.GetDirectory().Combine("bin")));
                Cake.CleanDirectories(releasesDir);
            });

            Task("Build")
            .IsDependentOn("Clean")
            .IsDependentOn("Check-Repository")
            .Does(() =>
            {
                StandardSolutionBuild(solutionFileName, gitInfo, globalInfo.BuildConfiguration);
            });

            Task("Unit-Testing")
            .IsDependentOn("Build")
            .WithCriteria(() => Cake.InteractiveMode() == InteractiveMode.NoInteraction ||
                          Cake.ReadInteractiveOption("RunUnitTests", "Run Unit Tests?", 'Y', 'N') == 'Y')
            .Does(() =>
            {
                StandardUnitTests(globalInfo, projects.Where(p => p.Name.EndsWith(".Tests")));
            });

            Task("Create-NuGet-Packages")
            .WithCriteria(() => gitInfo.IsValid)
            .IsDependentOn("Unit-Testing")
            .Does(() =>
            {
                StandardCreateNuGetPackages(releasesDir, projectsToPublish, gitInfo, globalInfo.BuildConfiguration);
            });


            Task("Push-NuGet-Packages")
            .IsDependentOn("Create-NuGet-Packages")
            .WithCriteria(() => gitInfo.IsValid)
            .Does(() =>
            {
                StandardPushNuGetPackages(globalInfo, releasesDir);
            });

            // The Default task for this script can be set here.
            Task("Default")
            .IsDependentOn("Push-NuGet-Packages");
        }
Esempio n. 4
0
        public Build()
        {
            Cake.Log.Verbosity = Verbosity.Diagnostic;

            const string solutionName              = "CK-DB";
            const string solutionFileName          = solutionName + ".sln";
            const string integrationSolution       = "IntegrationTests/IntegrationTests.sln";
            const string integrationTestsDirectory = "IntegrationTests/Tests/AllPackages.Tests";
            const string integrationTestsCSProj    = integrationTestsDirectory + "/AllPackages.Tests.csproj";

            var releasesDir = Cake.Directory("CodeCakeBuilder/Releases");

            var projects = Cake.ParseSolution(solutionFileName)
                           .Projects
                           .Where(p => !(p is SolutionFolder) &&
                                  !p.Path.Segments.Contains("IntegrationTests") &&
                                  p.Name != "CodeCakeBuilder");

            var integrationProjects = Cake.ParseSolution(integrationSolution)
                                      .Projects
                                      .Where(p => !(p is SolutionFolder));

            // We publish .Tests projects for this solution.
            var projectsToPublish = projects;

            // The SimpleRepositoryInfo should be computed once and only once.
            SimpleRepositoryInfo gitInfo = Cake.GetSimpleRepositoryInfo();
            // This default global info will be replaced by Check-Repository task.
            // It is allocated here to ease debugging and/or manual work on complex build script.
            CheckRepositoryInfo globalInfo = new CheckRepositoryInfo {
                Version = gitInfo.SafeNuGetVersion
            };

            var vCKDatabase = XDocument.Load("Common/DependencyVersions.props")
                              .Root
                              .Elements("PropertyGroup")
                              .Elements("CKDatabaseVersion")
                              .Single()
                              .Value;

            Cake.Information($"Using CK-Database version {vCKDatabase}.");
            string ckSetupNet461Path = System.IO.Path.GetFullPath(System.IO.Path.Combine(releasesDir, "CKSetup-Net461"));

            Task("Check-Repository")
            .Does(() =>
            {
                globalInfo = StandardCheckRepository(projectsToPublish, gitInfo);
                if (globalInfo.ShouldStop)
                {
                    Cake.TerminateWithSuccess("All packages from this commit are already available. Build skipped.");
                }
            });

            Task("Clean")
            .Does(() =>
            {
                Cake.CleanDirectories(projects.Select(p => p.Path.GetDirectory().Combine("bin")));
                Cake.CleanDirectories(releasesDir);
                Cake.DeleteFiles("Tests/**/TestResult*.xml");
            });

            Task("Build")
            .IsDependentOn("Check-Repository")
            .IsDependentOn("Clean")
            .Does(() =>
            {
                StandardSolutionBuild(solutionFileName, gitInfo, globalInfo.BuildConfiguration);
            });

            Task("Unit-Testing")
            .IsDependentOn("Build")
            .WithCriteria(() => Cake.InteractiveMode() == InteractiveMode.NoInteraction ||
                          Cake.ReadInteractiveOption("RunUnitTests", "Run Unit Tests?", 'Y', 'N') == 'Y')
            .Does(() =>
            {
                var testProjects = projects.Where(p => p.Name.EndsWith(".Tests"));
                StandardUnitTests(globalInfo.BuildConfiguration, testProjects);
            });

            Task("Create-NuGet-Packages")
            .IsDependentOn("Unit-Testing")
            .Does(() =>
            {
                StandardCreateNuGetPackages(releasesDir, projectsToPublish, gitInfo, globalInfo.BuildConfiguration);
            });

            Task("Compile-IntegrationTests")
            .IsDependentOn("Create-NuGet-Packages")
            .Does(() =>
            {
                //if( !gitInfo.IsValid )
                //{
                //    string nugetV3Cache = Environment.ExpandEnvironmentVariables( @"%USERPROFILE%/.nuget/packages" );
                //    Cake.CleanDirectories( nugetV3Cache + @"/**/" + CSemVer.SVersion.ZeroVersion );
                //}

                //string version = gitInfo.IsValid
                //                  ? gitInfo.SafeNuGetVersion
                //                  : CSemVer.SVersion.ZeroVersion.ToString();

                //Cake.DotNetCoreBuild( integrationSolution, new DotNetCoreBuildSettings()
                //{
                //    ArgumentCustomization = c => c.Append( $@"/p:CKDBVersion=""{version}""" )
                //} );
                //Cake.DotNetCorePublish( integrationTestsCSProj, new DotNetCorePublishSettings()
                //{
                //    ArgumentCustomization = c => c.Append( $@"/p:CKDBVersion=""{version}""" ).Append( " /p:IsPackable=true" ),
                //    Framework = "netcoreapp2.0"
                //} );
            });

            Task("Download-CKSetup-Net461-From-Store-and-Unzip-it")
            .Does(() =>
            {
                //var tempFile = Cake.DownloadFile( "http://cksetup.invenietis.net/dl-zip/CKSetup/Net461" );
                //Cake.Unzip( tempFile, ckSetupNet461Path );
            });

            Task("Run-CKSetup-On-IntegrationTests-AllPackages-Net461-With-CKSetup-Net461")
            .IsDependentOn("Compile-IntegrationTests")
            .IsDependentOn("Download-CKSetup-Net461-From-Store-and-Unzip-it")
            .Does(() =>
            {
                //var binPath = System.IO.Path.GetFullPath( integrationTestsDirectory + $"/bin/{globalInfo.BuildConfiguration}/net461" );
                //string dbCon = GetConnectionStringForIntegrationTestsAllPackages();

                //string configFile = System.IO.Path.Combine( releasesDir, "CKSetup-IntegrationTests-AllPackages-Net461.xml" );
                //Cake.TransformTextFile( "CodeCakeBuilder/CKSetup-IntegrationTests-AllPackages.xml", "{", "}" )
                //      .WithToken( "binPath", binPath )
                //      .WithToken( "connectionString", dbCon )
                //      .Save( configFile );

                //var cmdLine = $@"{ckSetupNet461Path}\CKSetup.exe run ""{configFile}"" -v Monitor ";
                //if( globalInfo.LocalFeedPath != null && globalInfo.LocalFeedPath.EndsWith( "LocalFeed\\Blank" ) )
                //{
                //    cmdLine += $"--store \"{System.IO.Path.Combine( globalInfo.LocalFeedPath, "CKSetupStore" )}\"";
                //}
                //int result = Cake.RunCmd( cmdLine );
                //if( result != 0 ) throw new Exception( "CKSetup.exe failed." );
            });

            Task("Run-IntegrationTests")
            .IsDependentOn("Compile-IntegrationTests")
            .WithCriteria(() => Cake.InteractiveMode() == InteractiveMode.NoInteraction ||
                          Cake.ReadInteractiveOption("Run integration tests?", 'Y', 'N') == 'Y')
            .Does(() =>
            {
                // There should be a bad database test name here.
                // Skip it for now...
                //
                // Running AllPackages.Tests executes a CKSetup on MultiBinPaths with the
                // 3 applications (FacadeApp) on the CKDB_TEST_MultiBinPaths database.
                // The task "Run-Facade-App-Tests" below executes the 3 tests apps which
                // use the burned connection string of the generated StObjMap.
                //
                //var integrationTests = integrationProjects.Where( p => p.Name == "AllPackages.Tests" );

                //var testDlls = integrationTests
                //                .Select( p => System.IO.Path.Combine(
                //                                    p.Path.GetDirectory().ToString(), "bin", globalInfo.BuildConfiguration, "net461", p.Name + ".dll" ) );
                //Cake.Information( $"Testing: {string.Join( ", ", testDlls )}" );
                //Cake.NUnit( testDlls, new NUnitSettings() { Framework = "v4.5" } );
            });

            Task("Run-Facade-App-Tests")
            .IsDependentOn("Run-IntegrationTests")
            .WithCriteria(() => Cake.InteractiveMode() == InteractiveMode.NoInteraction ||
                          Cake.ReadInteractiveOption("Run Facade application tests?", 'Y', 'N') == 'Y')
            .Does(() =>
            {
                //var facadeTests = integrationProjects.Where( p => p.Name.StartsWith( "FacadeApp" ) );

                //var testNet461Dlls = facadeTests
                //                .Select( p => System.IO.Path.Combine(
                //                                    p.Path.GetDirectory().ToString(), "bin", globalInfo.BuildConfiguration, "net461", p.Name + ".dll" ) );
                //Cake.Information( $"Testing: {string.Join( ", ", testNet461Dlls )}" );
                //Cake.NUnit( testNet461Dlls, new NUnitSettings() { Framework = "v4.5" } );
            });

            Task("Push-NuGet-Packages")
            .IsDependentOn("Create-NuGet-Packages")
            .IsDependentOn("Run-CKSetup-On-IntegrationTests-AllPackages-Net461-With-CKSetup-Net461")
            .IsDependentOn("Run-IntegrationTests")
            .IsDependentOn("Run-Facade-App-Tests")
            .WithCriteria(() => gitInfo.IsValid)
            .Does(() =>
            {
                StandardPushNuGetPackages(globalInfo, releasesDir);
            });

            Task("Default").IsDependentOn("Push-NuGet-Packages");
        }
        /// <summary>
        /// Creates a new <see cref="StandardGlobalInfo"/> initialized by the
        /// current environment.
        /// </summary>
        /// <param name="gitInfo">The git info.</param>
        /// <returns>A new info object.</returns>
        StandardGlobalInfo CreateStandardGlobalInfo(SimpleRepositoryInfo gitInfo)
        {
            var result = new StandardGlobalInfo(Cake, gitInfo);

            // By default:
            if (!gitInfo.IsValid)
            {
                if (Cake.InteractiveMode() != InteractiveMode.NoInteraction &&
                    Cake.ReadInteractiveOption("PublishDirtyRepo", "Repository is not ready to be published. Proceed anyway?", 'Y', 'N') == 'Y')
                {
                    Cake.Warning("GitInfo is not valid, but you choose to continue...");
                    result.IgnoreNoArtifactsToProduce = true;
                }
                else
                {
                    // On Appveyor, we let the build run: this gracefully handles Pull Requests.
                    if (Cake.AppVeyor().IsRunningOnAppVeyor)
                    {
                        result.IgnoreNoArtifactsToProduce = true;
                    }
                    else
                    {
                        Cake.TerminateWithError("Repository is not ready to be published.");
                    }
                }
                // When the gitInfo is not valid, we do not try to push any packages, even if the build continues
                // (either because the user choose to continue or if we are on the CI server).
                // We don't need to worry about feeds here.
            }
            else
            {
                // gitInfo is valid: it is either ci or a release build.
                var v = gitInfo.Info.FinalSemVersion;
                // If a /LocalFeed/ directory exists above, we publish the packages in it.
                var localFeedRoot = Cake.FindDirectoryAbove("LocalFeed");
                if (localFeedRoot != null)
                {
                    if (v.AsCSVersion == null)
                    {
                        if (v.Prerelease.EndsWith(".local"))
                        {
                            // Local releases must not be pushed on any remote and are copied to LocalFeed/Local
                            // feed (if LocalFeed/ directory above exists).
                            result.IsLocalCIRelease = true;
                            result.LocalFeedPath    = System.IO.Path.Combine(localFeedRoot, "Local");
                        }
                        else
                        {
                            // CI build versions are routed to LocalFeed/CI
                            result.LocalFeedPath = System.IO.Path.Combine(localFeedRoot, "CI");
                        }
                    }
                    else
                    {
                        // Release or prerelease go to LocalFeed/Release
                        result.LocalFeedPath = System.IO.Path.Combine(localFeedRoot, "Release");
                    }
                    System.IO.Directory.CreateDirectory(result.LocalFeedPath);
                }
                else
                {
                    result.IsLocalCIRelease = v.Prerelease.EndsWith(".local");
                }

                // Creating the right remote feed.
                if (!result.IsLocalCIRelease &&
                    (Cake.InteractiveMode() == InteractiveMode.NoInteraction ||
                     Cake.ReadInteractiveOption("PushToRemote", "Push to Remote feeds?", 'Y', 'N') == 'Y'))
                {
                    result.PushToRemote = true;
                }
            }
            return(result);
        }
Esempio n. 6
0
        public Build()
        {
            var releasesDir = Cake.Directory("CodeCakeBuilder/Releases");

            string configuration         = null;
            SimpleRepositoryInfo gitInfo = null;
            var    solution          = Cake.ParseSolution("CK-DB.sln");
            var    CKDBProjectNames  = new HashSet <string>(solution.Projects.Where(p => p.Name.StartsWith("CK.")).Select(pub => pub.Name));
            string CKDatabaseVersion = null;
            Dictionary <string, string> DependentPackages            = null;
            Dictionary <string, string> IntegrationDependentPackages = null;

            Task("Check-Dependencies")
            .Does(() =>
            {
                var allPackages = solution.Projects
                                  .Where(p => p.Name.StartsWith("CK."))
                                  .Select(p => new
                {
                    Project       = p,
                    PackageConfig = p.Path.GetDirectory().CombineWithFilePath("packages.config").FullPath
                })
                                  .Where(p => System.IO.File.Exists(p.PackageConfig))
                                  .SelectMany(p => XDocument.Load(p.PackageConfig)
                                              .Root
                                              .Elements("package")
                                              .Select(e => { e.AddAnnotation(p.Project); return(e); }))
                                  .ToList();
                var byPackage = allPackages
                                .GroupBy(e => e.Attribute("id").Value,
                                         e => new
                {
                    ProjectName = e.Annotation <SolutionProject>().Name,
                    Version     = e.Attribute("version").Value
                });
                var multiVersions = byPackage.Where(g => g.GroupBy(x => x.Version).Count() > 1);
                if (multiVersions.Any())
                {
                    var conflicts = multiVersions.Select(e => Environment.NewLine + " - " + e.Key + ":" + Environment.NewLine + "    - " + string.Join(Environment.NewLine + "    - ", e.GroupBy(x => x.Version).Select(x => x.Key + " in " + string.Join(", ", x.Select(xN => xN.ProjectName)))));
                    Cake.TerminateWithError($"Dependency versions differ for:{Environment.NewLine}{string.Join( Environment.NewLine, conflicts )}");
                }
                CKDatabaseVersion = byPackage.Single(e => e.Key == "CK.StObj.Model").First().Version;
                // Use Tests/CK.DB.Actor.Tests/packages.config for packages' versions that are not the CK-DB ones.
                XDocument aclPackagesConfig = XDocument.Load("Tests/CK.DB.Actor.Tests/packages.config");
                var pp            = aclPackagesConfig.Root.Descendants("package").Where(e => !CKDBProjectNames.Contains((string)e.Attribute("id")));
                DependentPackages = pp.ToDictionary(e => (string)e.Attribute("id"), e => (string)e.Attribute("version"));
            });

            Task("Check-Repository")
            .IsDependentOn("Check-Dependencies")
            .Does(() =>
            {
                gitInfo = Cake.GetSimpleRepositoryInfo();
                if (!gitInfo.IsValid)
                {
                    if (Cake.IsInteractiveMode() &&
                        Cake.ReadInteractiveOption("Repository is not ready to be published. Proceed anyway?", 'Y', 'N') == 'Y')
                    {
                        Cake.Warning("GitInfo is not valid, but you choose to continue...");
                    }
                    else
                    {
                        throw new Exception("Repository is not ready to be published.");
                    }
                }
                IntegrationDependentPackages = new Dictionary <string, string>(DependentPackages);
                foreach (var n in CKDBProjectNames)
                {
                    IntegrationDependentPackages.Add(n, gitInfo.NuGetVersion);
                }
                configuration = gitInfo.IsValidRelease && gitInfo.PreReleaseName.Length == 0 ? "Release" : "Debug";
                Cake.Information("Publishing {0} in {1}.", gitInfo.SemVer, configuration);
            });

            Task("Clean")
            .IsDependentOn("Check-Repository")
            .Does(() =>
            {
                Cake.CleanDirectories("**/bin/" + configuration, d => !d.Path.Segments.Contains("CodeCakeBuilder"));
                Cake.CleanDirectories("**/obj/" + configuration, d => !d.Path.Segments.Contains("CodeCakeBuilder"));
                Cake.CleanDirectories(releasesDir);
            });

            Task("Restore-NuGet-Packages")
            .Does(() =>
            {
                Cake.NuGetRestore("CK-DB.sln");
            });


            Task("Build")
            .IsDependentOn("Clean")
            .IsDependentOn("Restore-NuGet-Packages")
            .IsDependentOn("Check-Repository")
            .Does(() =>
            {
                using (var tempSln = Cake.CreateTemporarySolutionFile("CK-DB.sln"))
                {
                    tempSln.ExcludeProjectsFromBuild("CodeCakeBuilder");
                    Cake.MSBuild(tempSln.FullPath, settings =>
                    {
                        settings.Configuration = configuration;
                        settings.Verbosity     = Verbosity.Minimal;
                        // Always generates Xml documentation. Relies on this definition in the csproj files:
                        //
                        // <PropertyGroup Condition=" $(GenerateDocumentation) != '' ">
                        //   <DocumentationFile>bin\$(Configuration)\$(AssemblyName).xml</DocumentationFile>
                        // </PropertyGroup>
                        //
                        settings.Properties.Add("GenerateDocumentation", new[] { "true" });
                    });
                }
            });

            Task("Unit-Testing")
            .IsDependentOn("Build")
            .WithCriteria(() => gitInfo.IsValidRelease)
            .Does(() =>
            {
                var testDlls = solution.Projects
                               .Where(p => p.Name.EndsWith(".Tests"))
                               .Select(p => p.Path.GetDirectory().CombineWithFilePath("bin/" + configuration + "/" + p.Name + ".dll"));
                Cake.Information("Testing: {0}", string.Join(", ", testDlls.Select(p => p.GetFilename().ToString())));
                Cake.NUnit(testDlls, new NUnitSettings()
                {
                    Framework = "v4.5"
                });
            });

            Task("Create-NuGet-Packages")
            .IsDependentOn("Unit-Testing")
            .Does(() =>
            {
                Cake.CreateDirectory(releasesDir);
                var settings = new NuGetPackSettings()
                {
                    Version         = gitInfo.NuGetVersion,
                    BasePath        = Cake.Environment.WorkingDirectory,
                    OutputDirectory = releasesDir
                };
                Cake.CopyFiles("CodeCakeBuilder/NuSpec/*.nuspec", releasesDir);
                foreach (var nuspec in Cake.GetFiles(releasesDir.Path + "/*.nuspec"))
                {
                    TransformText(nuspec, configuration, gitInfo, CKDatabaseVersion);
                    Cake.NuGetPack(nuspec, settings);
                }
                Cake.DeleteFiles(releasesDir.Path + "/*.nuspec");
            });

            Task("Run-IntegrationTests")
            .IsDependentOn("Create-NuGet-Packages")
            .WithCriteria(() => gitInfo.IsValid)
            .WithCriteria(() => !Cake.IsInteractiveMode() ||
                          Cake.ReadInteractiveOption("Run integration tests?", 'Y', 'N') == 'Y')
            .Does(() =>
            {
                var integrationSolution = "IntegrationTests/IntegrationTests.sln";
                var integration         = Cake.ParseSolution(integrationSolution);
                var projects            = integration.Projects
                                          .Where(p => p.Name != "CodeCakeBuilder")
                                          .Select(p => new
                {
                    CSProj     = p.Path.FullPath,
                    ConfigFile = p.Path.GetDirectory().CombineWithFilePath("packages.config").FullPath
                })
                                          .Where(p => System.IO.File.Exists(p.ConfigFile));
                // Cleans all the existing IntegrationTests/packages.
                // The CodeCakeBuilder restore will get them (from Release for CK-DB packages).
                Cake.CleanDirectory("IntegrationTests/packages");

                foreach (var config in projects.Select(p => p.ConfigFile))
                {
                    XDocument doc = XDocument.Load(config);
                    int countRef  = 0;
                    foreach (var p in doc.Root.Elements("package"))
                    {
                        string packageName = p.Attribute("id").Value;
                        if (IntegrationDependentPackages.ContainsKey(packageName))
                        {
                            string depVersion = IntegrationDependentPackages[packageName];
                            if (p.Attribute("version").Value != depVersion)
                            {
                                p.SetAttributeValue("version", depVersion);
                                ++countRef;
                            }
                        }
                    }
                    if (countRef > 0)
                    {
                        Cake.Information($"Updated {countRef} in file {config}.");
                        doc.Save(config);
                    }
                }
                foreach (var csproj in projects.Select(p => p.CSProj))
                {
                    XDocument doc  = XDocument.Load(csproj);
                    int countRef   = 0;
                    var projection = doc.Root.Descendants(msBuild + "Reference")
                                     .Select(e => new
                    {
                        Reference       = e,
                        IncludeAttr     = e.Attribute("Include"),
                        HintPathElement = e.Element(msBuild + "HintPath"),
                    });
                    var filtered = projection.Where(e => e.HintPathElement != null &&
                                                    e.IncludeAttr != null &&
                                                    e.HintPathElement.Value.StartsWith(@"..\packages\"));
                    var final = filtered.Select(e => new
                    {
                        E           = e,
                        ProjectName = new AssemblyName(e.IncludeAttr.Value).Name
                    })
                                .Where(e => IntegrationDependentPackages.ContainsKey(e.ProjectName));

                    foreach (var p in final)
                    {
                        var version   = IntegrationDependentPackages[p.ProjectName];
                        var path      = p.E.HintPathElement.Value.Split('\\');
                        var newFolder = p.ProjectName + '.' + version;
                        if (path[2] != newFolder)
                        {
                            path[2] = newFolder;
                            p.E.HintPathElement.Value = string.Join("\\", path);
                            ++countRef;
                        }
                    }
                    if (countRef > 0)
                    {
                        Cake.Information($"Updated {countRef} references in file {csproj}.");
                        doc.Save(csproj);
                    }
                }

                Cake.NuGetRestore(integrationSolution);
                Cake.MSBuild("IntegrationTests/CodeCakeBuilder/CodeCakeBuilder.csproj", settings =>
                {
                    settings.Configuration = configuration;
                    settings.Verbosity     = Verbosity.Minimal;
                });
                if (Cake.StartProcess($"IntegrationTests/CodeCakeBuilder/bin/{configuration}/CodeCakeBuilder.exe", "-" + InteractiveAliases.NoInteractionArgument) != 0)
                {
                    Cake.TerminateWithError("Error in IntegrationTests.");
                }
            });


            Task("Push-NuGet-Packages")
            .IsDependentOn("Create-NuGet-Packages")
            .IsDependentOn("Run-IntegrationTests")
            .WithCriteria(() => gitInfo.IsValid)
            .Does(() =>
            {
                IEnumerable <FilePath> nugetPackages = Cake.GetFiles(releasesDir.Path + "/*.nupkg");
                if (Cake.IsInteractiveMode())
                {
                    var localFeed = Cake.FindDirectoryAbove("LocalFeed");
                    if (localFeed != null)
                    {
                        Cake.Information("LocalFeed directory found: {0}", localFeed);
                        if (Cake.ReadInteractiveOption("Do you want to publish to LocalFeed?", 'Y', 'N') == 'Y')
                        {
                            Cake.CopyFiles(nugetPackages, localFeed);
                        }
                    }
                }
                if (gitInfo.IsValidRelease)
                {
                    if (gitInfo.PreReleaseName == "" ||
                        gitInfo.PreReleaseName == "rc" ||
                        gitInfo.PreReleaseName == "prerelease")
                    {
                        PushNuGetPackages("NUGET_API_KEY", "https://www.nuget.org/api/v2/package", nugetPackages);
                    }
                    else
                    {
                        // An alpha, beta, delta, epsilon, gamma, kappa goes to invenietis-preview.
                        PushNuGetPackages("MYGET_PREVIEW_API_KEY", "https://www.myget.org/F/invenietis-preview/api/v2/package", nugetPackages);
                    }
                }
                else
                {
                    Debug.Assert(gitInfo.IsValidCIBuild);
                    PushNuGetPackages("MYGET_CI_API_KEY", "https://www.myget.org/F/invenietis-ci/api/v2/package", nugetPackages);
                }
            });

            Task("Default").IsDependentOn("Push-NuGet-Packages");
        }
Esempio n. 7
0
        static int Main(string[] args)
        {
            try
            {
                var app = new CommandLineApplication();
                app.Name        = "sgv";
                app.Description = "SimpleGitVersion commands.";
                app.HelpOption("-?|-h|--help");
                app.VersionOption("--version", GetVersion, GetInformationalVersion);
                var optVerbose = app.Option("-v|--verbose", "Verbose output", CommandOptionType.NoValue);

                app.Command("info", c =>
                {
                    c.Description     = "Display SimpleGitVersion information from Git repository.";
                    var optionProject = c.Option("-p|--project <PATH>", "Path to a project, solution or any path under the solution directory, default is current directory", CommandOptionType.SingleValue);
                    c.HelpOption("-?|-h|--help");

                    c.OnExecute(() =>
                    {
                        ConsoleLoggerAdapter logger = new ConsoleLoggerAdapter(true);
                        string path = optionProject.Value() ?? Directory.GetCurrentDirectory();
                        SimpleRepositoryInfo info = SimpleRepositoryInfo.LoadFromPath(logger, path, (log, hasRepoXml, options) =>
                        {
                            options.IgnoreDirtyWorkingFolder = true;
                        });
                        return(0);
                    });
                });

                app.Command("prebuild", c =>
                {
                    c.Description     = "Creates or updates Properties/SGVVersionInfo.cs files from Git repository.";
                    var optionProject = c.Option("-p|--project <PATH>", "Path to project, default is current directory", CommandOptionType.SingleValue);
                    c.HelpOption("-?|-h|--help");

                    c.OnExecute(() =>
                    {
                        ConsoleLoggerAdapter logger = new ConsoleLoggerAdapter(optVerbose.HasValue());
                        string path = optionProject.Value() ?? Directory.GetCurrentDirectory();
                        var ctx     = new DNXSolution(path, logger);
                        if (ctx.IsValid)
                        {
                            var project = ctx.FindFromPath(path);
                            if (project != null)
                            {
                                project.CreateOrUpdateSGVVersionInfoFile();
                            }
                            else
                            {
                                logger.Warn("Project not found.");
                            }
                        }
                        return(0);
                    });
                });

                app.Command("update", c =>
                {
                    c.Description     = "Updates version properties in project.json files based on Git repository.";
                    var optionProject = c.Option("-p|--project <PATH>", "Path to project, default is current directory", CommandOptionType.SingleValue);
                    c.HelpOption("-?|-h|--help");

                    c.OnExecute(() =>
                    {
                        ConsoleLoggerAdapter logger = new ConsoleLoggerAdapter(optVerbose.HasValue());
                        string path = optionProject.Value() ?? Directory.GetCurrentDirectory();
                        var ctx     = new DNXSolution(path, logger);
                        if (ctx.IsValid)
                        {
                            ctx.UpdateProjectFiles();
                        }
                        return(0);
                    });
                });

                app.Command("restore", c =>
                {
                    c.Description     = "Restores project.json files that differ only by version properties for this solution.";
                    var optionProject = c.Option("-p|--project <PATH>", "Path to project, default is current directory", CommandOptionType.SingleValue);
                    c.HelpOption("-?|-h|--help");

                    c.OnExecute(() =>
                    {
                        ConsoleLoggerAdapter logger = new ConsoleLoggerAdapter(optVerbose.HasValue());
                        string path = optionProject.Value() ?? Directory.GetCurrentDirectory();
                        var ctx     = new DNXSolution(path, logger);
                        if (ctx.IsValid)
                        {
                            ctx.RestoreProjectFilesFromGitThatDifferOnlyByVersion();
                        }
                        return(0);
                    });
                });

                // Show help information if no subcommand/option was specified.
                app.OnExecute(() =>
                {
                    app.ShowHelp();
                    return(2);
                });

                return(app.Execute(args));
            }
            catch (Exception exception)
            {
                Console.WriteLine("Error: {0}", exception.Message);
                return(1);
            }
        }