Пример #1
0
 protected AbstractGitTransactionTest()
 {
     RemoteRepositoryPath = Path.Combine(m_TempDirectory.Directory.Location, "Remote");
     
     RepositoryInitHelper.InitializeRepository(RemoteRepositoryPath);
     
     m_RemoteRepository = new Repository(RemoteRepositoryPath);
     m_RemoteRepository.CreateBranch(s_Branch2, m_RemoteRepository.Commits.Single());
     m_RemoteRepository.CreateBranch(s_Branch3, m_RemoteRepository.Commits.Single());
 }
Пример #2
0
        public override void CreateBranch(string branch)
        {
            try
            {
                _repo.CreateBranch(branch);
                _repo.Checkout(branch);

                RequeryUnsyncedCommits();
            }
            catch (LibGit2SharpException ex)
            {
                throw new SourceControlException(SourceControlText.GitNewBranchFailed, ex);
            }
        }
Пример #3
0
        private async Task PullSrcRepo(string branch)
        {
            Logger.Info($"Pulling branch {branch} from source repo...");

            var options = new PullOptions
            {
                FetchOptions = new FetchOptions {
                    CredentialsProvider = GitCredentials
                }
            };
            await Task.Run(() =>
            {
                using var repo = new GitRepository("srcRepo");

                if (repo.Branches[branch] == null)
                {
                    var remoteBranch = repo.Branches[$"origin/{branch}"];
                    var newBranch    = repo.CreateBranch(branch, remoteBranch.Tip);
                    repo.Branches.Update(newBranch, b => b.TrackedBranch = remoteBranch.CanonicalName);
                }

                Commands.Checkout(repo, repo.Branches[branch]);
                Commands.Pull(repo, _defaultSignature, options);
            });
        }
Пример #4
0
        public string SetupBranch(string p_BranchNamePrefix,
                                  string p_RemoteName)
        {
            string guid = DateTime.Now.ToString("yyyyMMdd_HHmmss");

            m_BranchName = $"{p_BranchNamePrefix}_{guid}";
            s_Logger.Info($"Branch: {m_BranchName}");

            Branch localBranch;

            if (m_Repository.Branches[m_BranchName] == null)
            {
                localBranch = m_Repository.CreateBranch(m_BranchName);
            }
            else
            {
                //todo will not checkout due to a conflict if there are files there already
                localBranch = m_Repository.Branches[m_BranchName];
            }

            Commands.Checkout(m_Repository, localBranch);
            Remote remote = m_Repository.Network.Remotes[p_RemoteName];

            m_Repository.Branches.Update(localBranch, b => b.Remote = remote.Name, b => b.UpstreamBranch = localBranch.CanonicalName);
            return(m_BranchName);
        }
        public void PullAndRebaseAndPush(PullRequest pr)
        {
            string reppath = Path.Combine(_account.TempRepPath, pr.Base.Repository.Name);

            using (var repo = new Repository(reppath))
            {
                var branchMaster  = repo.Branches["master"];
                var masterCommits = branchMaster.Commits.First();
                var orgin         = repo.Network.Remotes["orgin"];

                var branchname = pr.Head.Ref;
                repo.Branches.Remove(branchname);

                Branch orginBranch = repo.Branches[$"refs/remotes/origin/{branchname}"];

                Branch localBranch = repo.CreateBranch(branchname, orginBranch.Tip);
                localBranch = Commands.Checkout(repo, localBranch);

                if (!localBranch.Commits.Contains(masterCommits))
                {
                    Console.WriteLine(branchname);
                    var rebaseOptions = new RebaseOptions();
                    var rb            = repo.Rebase.Start(localBranch, branchMaster, null, _identity, rebaseOptions);
                    if (rb.Status != RebaseStatus.Complete)
                    {
                        repo.Rebase.Abort();
                        return;
                    }
                    Commands.Checkout(repo, branchname);
                    repo.Network.Push(orgin, $"+refs/heads/{branchname}:refs/heads/{branchname}", _pushOptions);
                }
            }
        }
Пример #6
0
        public bool Checkout(Api.Git.Repository repository, string branchName)
        {
            using (var repo = new LibGit2Sharp.Repository(repository.Path))
            {
                string realBranchName = branchName;
                Branch branch;

                // Check if local branch exists
                if (repo.Branches.Any(b => b.FriendlyName == branchName))
                {
                    branch = Commands.Checkout(repo, branchName);
                }
                else
                {
                    // Create local branch to remote branch tip and set its upstream branch to remote
                    var upstreamBranch = repo.Branches.FirstOrDefault(b => b.FriendlyName.EndsWith(branchName));
                    branch = repo.CreateBranch(branchName, upstreamBranch.Tip);
                    this.SetUpstream(repository, branchName, upstreamBranch.FriendlyName);

                    branch = Commands.Checkout(repo, branchName);
                }


                return(branch.FriendlyName == branchName);
            }
        }
Пример #7
0
        public bool Checkout(Api.Git.Repository repository, string branchName)
        {
            using (var repo = new LibGit2Sharp.Repository(repository.Path))
            {
                Branch branch;

                // Check if local branch exists
                if (repo.Branches.Any(b => b.FriendlyName == branchName))
                {
                    branch = Commands.Checkout(repo, branchName);
                }
                else
                {
                    // Create local branch to remote branch tip and set its upstream branch to remote
                    var upstreamBranch = repo.Branches.FirstOrDefault(b => string.Equals(b.UpstreamBranchCanonicalName, "refs/heads/" + branchName, StringComparison.OrdinalIgnoreCase));

                    if (upstreamBranch is null)
                    {
                        return(false);
                    }

                    _ = repo.CreateBranch(branchName, upstreamBranch.Tip);
                    this.SetUpstream(repository, branchName, upstreamBranch.FriendlyName);

                    branch = Commands.Checkout(repo, branchName);
                }

                return(branch.FriendlyName == branchName);
            }
        }
Пример #8
0
        public string SetupBranch(string p_BranchNamePrefix,
                                  string p_RemoteName)
        {
            //todo Create logic for branch name
            string ticketName = "INNO-001";
            string guid       = "alpha1234";

            m_BranchName = $"{p_BranchNamePrefix}{ticketName}_{guid}";
            s_Logger.Info($"Branch: {m_BranchName}");

            Branch localBranch;

            if (m_Repository.Branches[m_BranchName] == null)
            {
                localBranch = m_Repository.CreateBranch(m_BranchName);
            }
            else
            {
                //todo will not checkout due to a conflict if there are files there already
                localBranch = m_Repository.Branches[m_BranchName];
            }

            Commands.Checkout(m_Repository, localBranch);
            var remote = m_Repository.Network.Remotes[p_RemoteName];

            m_Repository.Branches.Update(localBranch,
                                         b => b.Remote         = remote.Name,
                                         b => b.UpstreamBranch = localBranch.CanonicalName);
            return(m_BranchName);
        }
Пример #9
0
        public void FetchWithoutConflict(string remoteUrl, string branchName)
        {
            var tracer = _tracerFactory.GetTracer();

            try
            {
                using (var repo = new LibGit2Sharp.Repository(RepositoryPath))
                {
                    var trackedBranchName = string.Format("{0}/{1}", _remoteAlias, branchName);
                    var refSpec           = string.Format("+refs/heads/{0}:refs/remotes/{1}", branchName, trackedBranchName);

                    // Configure the remote
                    var remote = repo.Network.Remotes.Add(_remoteAlias, remoteUrl, refSpec);

                    // This will only retrieve the "master"
                    repo.Network.Fetch(remote);

                    // Optionally set up the branch tracking configuration
                    var trackedBranch = repo.Branches[trackedBranchName];
                    if (trackedBranch == null)
                    {
                        throw new BranchNotFoundException(branchName, null);
                    }
                    var branch = repo.Branches[branchName] ?? repo.CreateBranch(branchName, trackedBranch.Tip);
                    repo.Branches.Update(branch,
                                         b => b.TrackedBranch = trackedBranch.CanonicalName);

                    //Update the raw ref to point the head of branchName to the latest fetched branch
                    UpdateRawRef(string.Format("refs/heads/{0}", branchName), trackedBranchName);

                    // Now checkout out our branch, which points to the right place
                    Update(branchName);
                }
            }
            catch (LibGit2SharpException exception)
            {
                tracer.TraceWarning("LibGit2SharpRepository fetch failed with {0}", exception);

                // LibGit2Sharp doesn't support SSH yet. Use GitExeRepository
                // LibGit2Sharp only supports smart Http protocol
                if (exception.Message.Equals("Unsupported URL protocol") ||
                    exception.Message.Equals("Received unexpected content-type"))
                {
                    tracer.TraceWarning("LibGit2SharpRepository fallback to git.exe");

                    _legacyGitExeRepository.FetchWithoutConflict(remoteUrl, branchName);
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                using (var repo = new LibGit2Sharp.Repository(RepositoryPath))
                {
                    repo.Network.Remotes.Remove(_remoteAlias);
                }
            }
        }
        public GitBasedFileSystemSnapshotTest()
        {
            RepositoryInitHelper.InitializeRepository(m_TempDirectory.Location);

            using (var repo = new Repository(m_TempDirectory.Location))
            {
                repo.CreateBranch(new BranchName("branch", "name"), repo.Commits.Single());
            }

        }
        public GitBasedFileSystemHistoryTest()
        { 
            RepositoryInitHelper.InitializeRepository(m_TempDirectory.Location);

            m_Repository = new Repository(m_TempDirectory.Location);
            var branchName = new BranchName("", "branch1");
            m_Repository.CreateBranch(branchName, m_Repository.GetAllCommits().Single());

            m_Instance = new GitBasedFileSystemHistory(m_Repository, branchName);

        }
Пример #12
0
 public override void CreateBranch(string branch)
 {
     try
     {
         _repo.CreateBranch(branch);
         _repo.Checkout(branch);
     }
     catch (LibGit2SharpException ex)
     {
         throw new SourceControlException("Branch creation failed.", ex);
     }
 }
        public void CheckoutBaseBranch(string branchName)
        {
            var localBranch = _repository.Branches[branchName];

            if (localBranch == null)
            {
                // Probably a remote branch
                Branch trackedBranch = _repository.Branches[$"origin/{branchName}"];

                if (trackedBranch == null)
                {
                    throw new Exception($"Branch {branchName} not found locally or on origin.");
                }

                localBranch = _repository.CreateBranch(branchName, trackedBranch.Tip);
                _repository.Branches.Update(localBranch, b => b.UpstreamBranch = $"refs/heads/{branchName}");
            }

            Commands.Checkout(_repository, _repository.Branches[branchName]);
            _baseBranch    = localBranch;
            _changesBranch = localBranch;
        }
Пример #14
0
        private string CreateBranchForNewChanges(NewChanges newChanges, string prBranch)
        {
            string OriginalSha;
            var    targetRepo = newChanges.TargetRepository;
            var    branchName =
                $"mirror-merge-{(long)DateTime.Now.Subtract(new DateTime(2000, 1, 1, 0, 0, 0)).TotalMinutes}";

            s_logger.Info($"Creating branch {prBranch} in {targetRepo} to merge changes into {prBranch}");
            using (var repo = new Repository(targetRepo.Path))
            {
                var branch = repo.CreateBranch(branchName);
                s_logger.Info("Checking out PR branch");
                Commands.Checkout(repo, branch);
                OriginalSha = branch.Tip.ToString();
            }

            foreach (var source in newChanges.changes.Keys)
            {
                var sourceRepository = targetRepo.Configuration.Repos.Where(t => t.Name == source).First();
                using (var repo = new Repository(sourceRepository.Path))
                {
                    foreach (var change in newChanges.changes[sourceRepository.Name])
                    {
                        var commit = repo.Lookup <Commit>(change);
                        if (!IsMirrorCommit(commit.Message, targetRepo.Configuration.MirrorSignatureUser) &&
                            commit.Parents.Count() == 1
                            )
                        {
                            s_logger.Info($"Applying {change}");
                            var patch = FormatPatch(sourceRepository, change);
                            if (string.IsNullOrWhiteSpace(patch))
                            {
                                continue;
                            }
                            s_logger.Debug($"Patch:\n{patch}");
                            ApplyPatch(sourceRepository, newChanges.TargetRepository, patch, commit);
                        }
                    }
                }
            }
            using (var repo = new Repository(targetRepo.Path))
            {
                if (repo.Head.Tip.ToString() == OriginalSha)
                {
                    s_logger.Info($"No new commits To add into this branch");
                    return(null);
                }
            }

            return(branchName);
        }
Пример #15
0
 public void Init(DeclarationOfExistence doe)
 {
     if (!_directory.Exists)
     {
         _directory.Create();
     }
     if (!_directory.GetFiles().Any() && !_directory.GetDirectories().Any())
     {
         // Directory is empty
         Repository.Init(_directory.FullName, isBare: true);
         using (var repo = new Repository(_directory.FullName))
         {
             InitCoreTags(repo);
             Commit doeCommit = CreateDeclarationOfExistence(repo, doe);
             repo.CreateBranch(CONTROL_BRANCH, doeCommit);
             repo.CreateBranch(CONTENT_BRANCH, doeCommit);
         }
     }
     else
     {
         throw new BastionException(string.Format("{0} has already been initialized", _directory.FullName));
     }
 }
Пример #16
0
        /// <summary>
        /// Ensure that the repository exists on disk and its origin remote points to the correct url
        /// </summary>
        /// <param name="repo"></param>
        private void EnsureRepository(List <RepositoryInfo> repos)
        {
            foreach (var repo in repos)
            {
                var repoPath = repo.Path;
                s_logger.Info($"Verifying repository {repo} at {repo.Path}");
                if (!Directory.Exists(repoPath) || !Repository.IsValid(repoPath))
                {
                    if (Directory.Exists(repoPath))
                    {
                        Directory.Delete(repoPath, true);
                    }

                    s_logger.Info($"Cloning the repo from {repo.CloneUrl}");
                    Repository.Clone(repo.CloneUrl, repoPath);
                }
                using (var repository = new Repository(repoPath))
                {
                    var remote = repository.Network.Remotes["origin"];
                    if (remote == null)
                    {
                        repository.Network.Remotes.Add("origin", repo.CloneUrl);
                    }
                    else if (remote.Url != repo.CloneUrl)
                    {
                        repository.Network.Remotes.Update("origin", u => u.Url = repo.CloneUrl);
                    }
                    var master = repository.Branches["master"] ?? repository.CreateBranch("master");
                    repository.Branches.Update(master, b => b.Remote = "origin", b => b.UpstreamBranch = "refs/heads/master");

                    remote = repository.Network.Remotes["upstream"];
                    if (remote == null)
                    {
                        repository.Network.Remotes.Add("upstream", @"https://github.com/" + repo.UpstreamOwner + @"/" + repo.Name + ".git");
                    }
                }
            }
        }
Пример #17
0
        /// <summary>
        /// Initializes a new bare repository at the specified location, adds a repository info file to the root directory
        /// and tags the initial commit with he value of <see cref="InitialCommitTagName"/>
        /// </summary>
        public static void InitializeRepository(string location)
        {            
            // initialize a bare repository
            Repository.Init(location, true);

            var directoryCreator = new LocalItemCreator();

            // clone the repository, add initial commit and push the changes back to the actual repository
            using (var tempDirectory = directoryCreator.CreateTemporaryDirectory())
            {
                var clonedRepoPath = Repository.Clone(location, tempDirectory.Directory.Location);

                var repositoryInfoFile = new RepositoryInfoFile(tempDirectory.Directory);

                // add a empty file to the repository
                directoryCreator.CreateFile(repositoryInfoFile, tempDirectory.Directory.Location);

                // commit and push the file to the bare repository we created
                using (var clonedRepo = new Repository(clonedRepoPath))
                {
                    var signature = SignatureHelper.NewSignature();

                    clonedRepo.Stage(repositoryInfoFile.Name);
                    clonedRepo.Commit("Initial Commit", signature, signature, new CommitOptions());                    

                    clonedRepo.Network.Push(clonedRepo.Network.Remotes["origin"], @"refs/heads/master");                    
                }
            }

            //create the configuration branch pointing to the initial commit
            using (var repository = new Repository(location))
            {
                repository.CreateBranch(ConfigurationBranchName.ToString(), repository.GetAllCommits().Single());
                repository.Tags.Add(InitialCommitTagName, repository.GetAllCommits().Single());
            }
        }
Пример #18
0
        /// <summary>
        /// Adds the standard .NET targets to the build.
        /// </summary>
        /// <param name="build">The build to which to add targets.</param>
        /// <param name="settings">The build settings.</param>
        public static void AddDotNetTargets(this BuildApp build, DotNetBuildSettings?settings = null)
        {
            settings ??= new DotNetBuildSettings();

            var buildOptions        = settings.BuildOptions ?? (settings.BuildOptions = new DotNetBuildOptions());
            var configurationOption = buildOptions.ConfigurationOption ?? (buildOptions.ConfigurationOption =
                                                                               build.AddOption("-c|--configuration <name>", "The configuration to build (default Release)", "Release"));
            var platformOption = buildOptions.PlatformOption ?? (buildOptions.PlatformOption =
                                                                     build.AddOption("-p|--platform <name>", "The solution platform to build"));
            var versionSuffixOption = buildOptions.VersionSuffixOption ?? (buildOptions.VersionSuffixOption =
                                                                               build.AddOption("--version-suffix <suffix>", "Generates a prerelease package"));
            var nugetOutputOption = buildOptions.NuGetOutputOption ?? (buildOptions.NuGetOutputOption =
                                                                           build.AddOption("--nuget-output <path>", "Directory for generated package (default release)", "release"));
            var triggerOption = buildOptions.TriggerOption ?? (buildOptions.TriggerOption =
                                                                   build.AddOption("--trigger <name>", "The git branch or tag that triggered the build"));
            var buildNumberOption = buildOptions.BuildNumberOption ?? (buildOptions.BuildNumberOption =
                                                                           build.AddOption("--build-number <number>", "The automated build number"));
            var noTestFlag = buildOptions.NoTestFlag ?? (buildOptions.NoTestFlag =
                                                             build.AddFlag("--no-test", "Skip the unit tests"));

            var solutionName    = settings.SolutionName;
            var nugetSource     = settings.NuGetSource ?? "https://api.nuget.org/v3/index.json";
            var msbuildSettings = settings.MSBuildSettings;

            var dotNetTools           = settings.DotNetTools ?? new DotNetTools(Path.Combine("tools", "bin"));
            var xmlDocMarkdownVersion = settings.DocsSettings?.ToolVersion ?? "2.0.1";

            var    packagePaths          = new List <string>();
            string?trigger               = null;
            var    ignoreIfAlreadyPushed = false;

            build.Target("clean")
            .Describe("Deletes all build output")
            .Does(() =>
            {
                var findDirectoriesToDelete = settings.CleanSettings?.FindDirectoriesToDelete ?? (() => FindDirectories("{src,tests}/**/{bin,obj}", "tools/XmlDocTarget/{bin,obj}"));
                foreach (var directoryToDelete in findDirectoriesToDelete())
                {
                    deleteDirectory(directoryToDelete);
                }

                var extraProperties = getExtraProperties("clean");
                if (msbuildSettings == null)
                {
                    RunDotNet(new[] { "clean", solutionName, "-c", configurationOption.Value, getPlatformArg(), "--verbosity", "normal", getMaxCpuCountArg() }.Concat(extraProperties));
                }
                else
                {
                    runMSBuild(new[] { solutionName, "-t:Clean", $"-p:Configuration={configurationOption.Value}", getPlatformArg(), "-v:normal", getMaxCpuCountArg() }.Concat(extraProperties));
                }
            });

            build.Target("restore")
            .Describe("Restores NuGet packages")
            .Does(() =>
            {
                var extraProperties = getExtraProperties("restore");
                if (msbuildSettings == null)
                {
                    RunDotNet(new[] { "restore", solutionName, getPlatformArg(), "--verbosity", "normal", getMaxCpuCountArg() }.Concat(extraProperties));
                }
                else
                {
                    runMSBuild(new[] { solutionName, "-t:Restore", $"-p:Configuration={configurationOption.Value}", getPlatformArg(), "-v:normal", getMaxCpuCountArg() }.Concat(extraProperties));
                }
            });

            build.Target("build")
            .DependsOn("restore")
            .Describe("Builds the solution")
            .Does(() =>
            {
                var buildNumberArg = buildNumberOption.Value == null ? null : $"-p:BuildNumber={buildNumberOption.Value}";

                var extraProperties = getExtraProperties("build");
                if (msbuildSettings == null)
                {
                    RunDotNet(new[] { "build", solutionName, "-c", configurationOption.Value, getPlatformArg(), buildNumberArg, "--no-restore", "--verbosity", "normal", getMaxCpuCountArg() }.Concat(extraProperties));
                }
                else
                {
                    runMSBuild(new[] { solutionName, $"-p:Configuration={configurationOption.Value}", getPlatformArg(), buildNumberArg, "-v:normal", getMaxCpuCountArg() }.Concat(extraProperties));
                }
            });

            build.Target("test")
            .DependsOn("build")
            .Describe("Runs the unit tests")
            .Does(() =>
            {
                if (noTestFlag.Value)
                {
                    Console.WriteLine("Skipping unit tests due to --no-test.");
                }
                else
                {
                    var extraProperties    = getExtraProperties("test").ToList();
                    var findTestAssemblies = settings.TestSettings?.FindTestAssemblies;
                    if (findTestAssemblies != null)
                    {
                        foreach (var testAssembly in findTestAssemblies())
                        {
                            if (settings.TestSettings?.RunTests != null)
                            {
                                settings.TestSettings.RunTests(testAssembly);
                            }
                            else
                            {
                                RunDotNet(new AppRunnerSettings {
                                    Arguments = new[] { "vstest", Path.GetFileName(testAssembly) }.Concat(extraProperties), WorkingDirectory = Path.GetDirectoryName(testAssembly)
                                });
                            }
                        }
                    }
                    else
                    {
                        var testProjects = new List <string?>();

                        var findTestProjects = settings.TestSettings?.FindProjects;
                        if (findTestProjects != null)
                        {
                            testProjects.AddRange(findTestProjects());
                        }
                        else
                        {
                            testProjects.Add(solutionName);
                        }

                        foreach (var testProject in testProjects)
                        {
                            if (settings.TestSettings?.RunTests != null)
                            {
                                settings.TestSettings.RunTests(testProject);
                            }
                            else
                            {
                                RunDotNet(new[] { "test", testProject, "-c", configurationOption.Value, getPlatformArg(), "--no-build", getMaxCpuCountArg() }.Concat(extraProperties));
                            }
                        }
                    }
                }
            });

            build.Target("package")
            .DependsOn("clean", "test")
            .Describe("Builds NuGet packages")
            .Does(() =>
            {
                trigger = triggerOption.Value;

                if (trigger == "detect")
                {
                    using var repository = new Repository(".");
                    var headSha          = repository.Head.Tip.Sha;
                    var autoTrigger      = GetBestTriggerFromTags(repository.Tags.Where(x => x.Target.Sha == headSha).Select(x => x.FriendlyName).ToList());
                    if (autoTrigger != null)
                    {
                        trigger = autoTrigger;
                        ignoreIfAlreadyPushed = true;
                        Console.WriteLine($"Detected trigger: {trigger}");
                    }
                }

                var versionSuffix = versionSuffixOption.Value;
                if (versionSuffix == null && trigger != null)
                {
                    versionSuffix = GetVersionFromTrigger(trigger) is string triggerVersion ? SplitVersion(triggerVersion).Suffix : null;
                }

                var nugetOutputPath = Path.GetFullPath(nugetOutputOption.Value);
                var tempOutputPath  = Path.Combine(nugetOutputPath, $"temp_{Guid.NewGuid():N}");

                var packageProjects = new List <string?>();

                var findPackageProjects = settings.PackageSettings?.FindProjects;
                if (findPackageProjects != null)
                {
                    packageProjects.AddRange(findPackageProjects());
                }
                else
                {
                    packageProjects.Add(solutionName);
                }

                var extraProperties = getExtraProperties("package").ToList();
                foreach (var packageProject in packageProjects)
                {
                    if (msbuildSettings == null)
                    {
                        RunDotNet(new[]
                        {
                            "pack", packageProject,
                            "-c", configurationOption.Value,
                            getPlatformArg(),
                            "--no-build",
                            "--output", tempOutputPath,
                            versionSuffix != null ? "--version-suffix" : null, versionSuffix,
                            getMaxCpuCountArg()
                        }.Concat(extraProperties));
                    }
                    else
                    {
                        runMSBuild(new[]
                        {
                            packageProject, "-t:Pack",
                            $"-p:Configuration={configurationOption.Value}",
                            getPlatformArg(),
                            "-p:NoBuild=true",
                            $"-p:PackageOutputPath={tempOutputPath}",
                            versionSuffix != null ? $"-p:VersionSuffix={versionSuffix}" : null,
                            "-v:normal",
                            getMaxCpuCountArg()
                        }.Concat(extraProperties));
                    }
                }

                var tempPackagePaths = FindFilesFrom(tempOutputPath, "*.nupkg");
                foreach (var tempPackagePath in tempPackagePaths)
                {
                    var packagePath = Path.Combine(nugetOutputPath, Path.GetFileName(tempPackagePath) ?? throw new InvalidOperationException());
                    if (File.Exists(packagePath))
                    {
                        File.Delete(packagePath);
                    }
                    File.Move(tempPackagePath, packagePath);
                    packagePaths.Add(packagePath);
                }
                deleteDirectory(tempOutputPath);

                if (packagePaths.Count == 0)
                {
                    throw new ApplicationException("No NuGet packages created.");
                }
            });

            build.Target("publish")
            .Describe("Publishes NuGet packages and documentation")
            .DependsOn("package")
            .Does(() =>
            {
                if (packagePaths.Count == 0)
                {
                    throw new ApplicationException("No NuGet packages found.");
                }

                if (trigger == null)
                {
                    throw new ApplicationException("--trigger option required.");
                }

                var triggerParts          = trigger.Split('-');
                var publishTrigger        = triggerParts.Length >= 2 && triggerParts[0] == "publish" ? triggerParts[1] : null;
                var shouldPublishPackages = publishTrigger == "package" || publishTrigger == "packages" || publishTrigger == "all";
                var shouldPublishDocs     = publishTrigger == "docs" || publishTrigger == "all";

                var triggerVersion = GetVersionFromTrigger(trigger);
                if (triggerVersion != null)
                {
                    var mismatches = packagePaths.Where(x => GetPackageInfo(x).Version != triggerVersion).ToList();
                    if (mismatches.Count != 0)
                    {
                        throw new ApplicationException($"Trigger '{trigger}' doesn't match package version: {string.Join(", ", mismatches.Select(Path.GetFileName))}");
                    }

                    shouldPublishPackages = true;
                    shouldPublishDocs     = triggerVersion.IndexOf('-') == -1;
                }

                if (shouldPublishPackages || shouldPublishDocs)
                {
                    var docsSettings      = settings.DocsSettings;
                    var shouldPushDocs    = false;
                    string?cloneDirectory = null;
                    string?repoDirectory  = null;
                    string?gitBranchName  = null;

                    Credentials provideCredentials(string url, string usernameFromUrl, SupportedCredentialTypes types) =>
                    new UsernamePasswordCredentials
                    {
                        Username = docsSettings?.GitLogin?.Username ?? throw new ApplicationException("GitLogin has a null Username."),
                        Password = docsSettings?.GitLogin?.Password ?? throw new ApplicationException("GitLogin has a null Password."),
                    };

                    if (shouldPublishDocs && docsSettings != null)
                    {
                        if (docsSettings.GitLogin == null || docsSettings.GitAuthor == null)
                        {
                            throw new ApplicationException("GitLogin and GitAuthor must be set on DocsSettings.");
                        }

                        var gitRepositoryUrl = docsSettings.GitRepositoryUrl;
                        gitBranchName        = docsSettings.GitBranchName;

                        if (gitRepositoryUrl != null)
                        {
                            cloneDirectory = "docs_repo_" + Path.GetRandomFileName();
                            Repository.Clone(sourceUrl: gitRepositoryUrl, workdirPath: cloneDirectory,
                                             options: new CloneOptions {
                                BranchName = gitBranchName, CredentialsProvider = provideCredentials
                            });
                            repoDirectory = cloneDirectory;
                        }
                        else
                        {
                            repoDirectory = ".";
                        }

                        using var repository = new Repository(repoDirectory);
                        if (gitRepositoryUrl != null)
                        {
                            if (gitBranchName == null)
                            {
                                gitBranchName = repository.Head.FriendlyName;
                            }
                        }
                        else if (gitBranchName != null)
                        {
                            if (gitBranchName != repository.Head.FriendlyName)
                            {
                                var branch = repository.Branches[gitBranchName] ?? repository.CreateBranch(gitBranchName);
                                Commands.Checkout(repository, branch);
                            }
                        }
                        else
                        {
                            var branch = repository.Branches.FirstOrDefault(x => x.IsCurrentRepositoryHead);
                            if (branch == null)
                            {
                                var autoBranchName = Environment.GetEnvironmentVariable("APPVEYOR_REPO_BRANCH");
                                if (autoBranchName != null)
                                {
                                    branch = repository.Branches[autoBranchName] ?? repository.CreateBranch(autoBranchName);
                                }
                                else
                                {
                                    branch = repository.Branches.FirstOrDefault(x => x.Tip.Sha == repository.Head.Tip.Sha);
                                }
                                if (branch != null)
                                {
                                    Commands.Checkout(repository, branch);
                                }
                            }
                            if (branch == null)
                            {
                                throw new ArgumentException("Could not determine repository branch for publishing docs.");
                            }
                            gitBranchName = branch.FriendlyName;
                        }

                        var projectHasDocs = docsSettings.ProjectHasDocs ?? (_ => true);
                        foreach (var projectName in packagePaths.Select(x => GetPackageInfo(x).Name).Where(projectHasDocs))
                        {
                            string findAssembly(string name) =>
                            FindFiles($"tools/XmlDocTarget/bin/**/{name}.dll").OrderByDescending(File.GetLastWriteTime).FirstOrDefault() ??
                            FindFiles($"src/{name}/bin/**/{name}.dll").OrderByDescending(File.GetLastWriteTime).FirstOrDefault();

                            var assemblyPaths = new List <string>();
                            if (docsSettings.FindAssemblies != null)
                            {
                                assemblyPaths.AddRange(docsSettings.FindAssemblies(projectName));
                            }
                            else
                            {
                                var assemblyPath = (docsSettings.FindAssembly ?? findAssembly)(projectName);
                                if (assemblyPath != null)
                                {
                                    assemblyPaths.Add(assemblyPath);
                                }
                            }

                            if (assemblyPaths.Count != 0)
                            {
                                foreach (var assemblyPath in assemblyPaths)
                                {
                                    RunApp(dotNetTools.GetToolPath($"xmldocmd/{xmlDocMarkdownVersion}"), assemblyPath,
                                           Path.Combine(repoDirectory, docsSettings.TargetDirectory ?? "docs"),
                                           "--source", $"{docsSettings.SourceCodeUrl}/{projectName}", "--newline", "lf", "--clean");
                                }
                            }
                            else
                            {
                                Console.WriteLine($"Documentation not generated for {projectName}; assembly not found.");
                            }
                        }

                        shouldPushDocs = repository.RetrieveStatus().IsDirty;
                    }

                    if (shouldPublishPackages)
                    {
                        var nugetApiKey = settings.NuGetApiKey;
                        if (string.IsNullOrEmpty(nugetApiKey))
                        {
                            throw new ApplicationException("NuGetApiKey required to publish.");
                        }

                        if (ignoreIfAlreadyPushed)
                        {
                            var nugetSettings            = NuGet.Configuration.Settings.LoadDefaultSettings(root: null);
                            var packageSourceProvider    = new PackageSourceProvider(nugetSettings);
                            var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, NuGet.Protocol.Core.Types.Repository.Provider.GetCoreV3());
                            using var sourceCacheContext = new SourceCacheContext();
                            var nugetRepositories        = sourceRepositoryProvider.GetRepositories()
                                                           .Select(x => x.GetResourceAsync <DependencyInfoResource>().GetAwaiter().GetResult())
                                                           .ToList();

                            foreach (var packagePath in packagePaths.ToList())
                            {
                                var packageInfo = GetPackageInfo(packagePath);
                                var package     = new PackageIdentity(packageInfo.Name, NuGetVersion.Parse(packageInfo.Version));

                                foreach (var nugetRepository in nugetRepositories)
                                {
                                    var dependencyInfo = nugetRepository.ResolvePackage(package, NuGetFramework.AnyFramework,
                                                                                        sourceCacheContext, NullLogger.Instance, CancellationToken.None).GetAwaiter().GetResult();
                                    if (dependencyInfo != null)
                                    {
                                        Console.WriteLine($"Package already pushed: {packageInfo.Name} {packageInfo.Version}");
                                        packagePaths.Remove(packagePath);
                                        break;
                                    }
                                }
                            }
                        }

                        foreach (var packagePath in packagePaths)
                        {
                            RunDotNet("nuget", "push", packagePath, "--source", nugetSource, "--api-key", nugetApiKey);
                        }
                    }

                    if (shouldPushDocs)
                    {
                        using var repository = new Repository(repoDirectory);
                        Console.WriteLine("Publishing documentation changes.");
                        Commands.Stage(repository, "*");
                        var author = new Signature(docsSettings !.GitAuthor !.Name, docsSettings !.GitAuthor !.Email, DateTimeOffset.Now);
                        repository.Commit("Documentation updated.", author, author, new CommitOptions());
                        repository.Network.Push(repository.Network.Remotes["origin"],
                                                $"refs/heads/{gitBranchName}", new PushOptions {
                            CredentialsProvider = provideCredentials
                        });
                    }

                    if (cloneDirectory != null)
                    {
                        // delete the cloned directory
                        foreach (var fileInfo in FindFiles(cloneDirectory, "**").Select(x => new FileInfo(x)).Where(x => x.IsReadOnly))
                        {
                            fileInfo.IsReadOnly = false;
                        }
                        deleteDirectory(cloneDirectory);
                    }
                }
                else
                {
                    Console.WriteLine("To publish to NuGet, push this tag: v" + GetPackageInfo(packagePaths[0]).Version);
                }
            });

            string?getPlatformArg()
            {
                var platformValue = platformOption?.Value ?? settings?.SolutionPlatform;

                return(platformValue == null ? null : $"-p:Platform={platformValue}");
            }

            string?getMaxCpuCountArg()
            {
                if (settings !.MaxCpuCount != null)
                {
                    return($"-maxcpucount:{settings.MaxCpuCount}");
                }
Пример #19
0
        public void GetGitVersion()
        {
            commitChangesToReadme(repo, "Hej", "Added Readme");

            verifyVersion(repo, 0, 0, 1, "beta.1");

            commitChangesToGitVersionFile(repo, "1.0.0", "Added .gitversion file with version = 1.0.0");

            verifyVersion(repo, 1, 0, 0, "beta.1");


            var featureBranch = repo.CreateBranch("feature");

            Commands.Checkout(repo, featureBranch);
            commitChangesToReadme(repo, "Hej2", "Changed Readme on feature branch");

            verifyVersion(repo, 1, 0, 0, "alpha.1.1", featureBranch.FriendlyName);

            Commands.Checkout(repo, "master");
            repo.Merge(featureBranch, me, noFastForward);

            verifyVersion(repo, 1, 0, 0, "beta.2");

            commitChangesToReadme(repo, "Version 2", "Bumped version to 2.0");
            commitChangesToGitVersionFile(repo, "2.0.0", "Updated version to 2.0.0 in .gitversion file");

            verifyVersion(repo, 2, 0, 0, "beta.1");


            repo.CreateBranch("release2x");
            Commands.Checkout(repo, "release2x");

            verifyVersion(repo, 2, 0, 0, "rc");

            Commands.Checkout(repo, "master");

            verifyVersion(repo, 2, 0, 0, "beta.1");

            Commands.Checkout(repo, "release2x");
            repo.ApplyTag("v2.0.0", me, "Official 2.0.0 release");

            verifyVersion(repo, 2, 0, 0, null);

            Commands.Checkout(repo, "master");
            commitChangesToGitVersionFile(repo, "2.1.0", "Bumped version to 2.1");
            verifyVersion(repo, 2, 1, 0, "beta.1");
            featureBranch = repo.CreateBranch("feature2");
            Commands.Checkout(repo, featureBranch);
            commitChangesToReadme(repo, "Version 2.1 something", "Changed readme");
            verifyVersion(repo, 2, 1, 0, "alpha.1.1", featureBranch.FriendlyName);
            Commands.Checkout(repo, "master");
            repo.Merge(featureBranch, me, noFastForward);
            verifyVersion(repo, 2, 1, 0, "beta.2");
            Commands.Checkout(repo, "release2x");
            repo.Merge("master", me, noFastForward);


            // At this point we have created the following git history:
            // *   Merge branch 'master' into 'rc2x'
            // |\
            // | *   (master) Merge branch 'feature2'
            // | |\
            // | | * (feature2) Changed readme
            // | |/
            // | *   (tag: v2.1) Bumped version to 2.1
            // |/
            // *     (tag: v2.0, release2x) Bumped version to 2.0
            var commit210rc = repo.Head.Tip;

            verifyVersion(repo, 2, 1, 0, "rc.1");

            var hotfixBranch = repo.CreateBranch("hotfix");

            Commands.Checkout(repo, hotfixBranch);
            commitChangesToReadme(repo, "Version 2.1 hotfix", "Changed readme on hotfix branch.");
            Commands.Checkout(repo, "release2x");
            repo.Merge(hotfixBranch, me, noFastForward);

            // At this point we have created the following git history:
            // *   (rc2x) Merge branch 'hotfix' into 'rc2x'
            // |\
            // | *   (hotfix) Changed readme on hotfix branch.
            // |/
            // *   Merge branch 'master' into 'rc2x'
            // |\
            // | *   (master) Merge branch 'feature2'
            // | |\
            // | | * (feature2) Changed readme
            // | |/
            // | *   (tag: v2.1) Bumped version to 2.1
            // |/
            // *     (tag: v2.0, release2x) Bumped version to 2.0
            new GitVersionAction()
            {
                PrintLog = "10", RepoPath = repo.Info.WorkingDirectory
            }.Execute(new System.Threading.CancellationToken());
            verifyVersion(repo, 2, 1, 0, "rc.2");

            // Now we will try to go back to a previous commit (not the HEAD):
            // This is what GitLab CI does, so important for us to support

            //Commands.Checkout(repo, shortHash211alpha);
            //verifyVersion(2, 1, 0, "alpha.1.1", shortHash211alpha + ".hotfix");   // TODO: This fails and we should try to improve. See TODO in GitVersionCalulator

            Commands.Checkout(repo, commit210rc);
            verifyVersion(repo, commit210rc, 2, 1, 0, "rc.1");
        }
 private static void SetupMasterBranch(Repository repository, string masterName, Signature author)
 {
     //We know we have a master branch , so check to see if the gitflow master is different and if it is
     Branch branch;
     if (masterName != "master" && !repository.TryGetBranch(masterName, out branch))
     {
         repository.CreateBranch(masterName);
     }
 }
Пример #21
0
        public void Commit_pushes_newly_created_branches()
        {
            var branchName = "newBranch";

            var transaction = CreateTransaction();
            transaction.Begin();

            using (var repository = new Repository(transaction.LocalPath))
            {
                repository.CreateBranch(branchName, repository.Commits.Single());
            }

            AddFile(transaction, branchName, "file1");
            
            transaction.Commit();

            Assert.True(m_RemoteRepository.Branches.Any(x => x.FriendlyName == branchName));
            Assert.Equal(2, m_RemoteRepository.GetAllCommits().Count());
        }
Пример #22
0
        private static async Task WriteContributorsToRepo(string username, string password)
        {
            var nameOfThankyouBranch        = "thankyou";
            var contributorsHeader          = _parsedOptions.acknowledgementSection;
            var fileHoldingContributorsInfo = _parsedOptions.fileInRepoForAcknowledgement;
            var githubRepoOwner             = _parsedOptions.githubRepoOwner;
            var githubRepoName = _parsedOptions.githubRepoName;

            string tempPathGitFolder = CreateTempFolderForTheRepo();

            // Login to GitHub with Octokit
            var githubClient = new GitHubClient(new ProductHeaderValue(username));

            githubClient.Credentials = new Octokit.Credentials(password);

            var githubRepo = await githubClient.Repository.Get(githubRepoOwner, githubRepoName);

            var gitCredentialsHandler = new CredentialsHandler(
                (url, usernameFromUrl, types) =>
                new UsernamePasswordCredentials()
            {
                Username = username,
                Password = password
            });

            var cloneOptions = new CloneOptions();

            cloneOptions.CredentialsProvider = gitCredentialsHandler;
            LibGit2Sharp.Repository.Clone(githubRepo.CloneUrl, tempPathGitFolder, cloneOptions);

            using (var repo = new LibGit2Sharp.Repository(tempPathGitFolder))
            {
                var remote        = repo.Network.Remotes["origin"];
                var defaultBranch = repo.Branches.FirstOrDefault(b => b.IsCurrentRepositoryHead == true);
                var refSpecs      = remote.FetchRefSpecs.Select(x => x.Specification);

                var remoteThankYouBranch = repo.Branches.FirstOrDefault(b => b.FriendlyName == repo.Network.Remotes.FirstOrDefault()?.Name + "/" + nameOfThankyouBranch);

                if (remoteThankYouBranch != null)
                {
                    Commands.Checkout(repo, remoteThankYouBranch);
                }

                if (repo.Head.FriendlyName != nameOfThankyouBranch)
                {
                    var newThankyouBranch = repo.CreateBranch(nameOfThankyouBranch);
                    repo.Branches.Update(newThankyouBranch,
                                         b => b.UpstreamBranch = newThankyouBranch.CanonicalName,
                                         b => b.Remote         = repo.Network.Remotes.First().Name);
                    Commands.Checkout(repo, newThankyouBranch);
                }


                var pathToReadme = Path.Combine(tempPathGitFolder, fileHoldingContributorsInfo);

                // Change the file and save it
                var inputLines = await File.ReadAllLinesAsync(pathToReadme);

                var outputLines = MarkdownProcessor.AddContributorsToMarkdownFile(inputLines, _contributorsToday);
                await File.WriteAllLinesAsync(pathToReadme, outputLines);

                var status = repo.RetrieveStatus(fileHoldingContributorsInfo);
                if (status == FileStatus.ModifiedInWorkdir)
                {
                    try
                    {
                        // Commit the file to the repo, on a non-master branch
                        repo.Index.Add(fileHoldingContributorsInfo);
                        repo.Index.Write();

                        var gitAuthorName  = _parsedOptions.gitAuthorName;
                        var gitAuthorEmail = _parsedOptions.gitAuthorEmail;

                        // Create the committer's signature and commit
                        var author    = new LibGit2Sharp.Signature(gitAuthorName, gitAuthorEmail, DateTime.Now);
                        var committer = author;

                        // Commit to the repository
                        var commit = repo.Commit("A new list of awesome contributors", author, committer);

                        //Push the commit to origin
                        LibGit2Sharp.PushOptions options = new LibGit2Sharp.PushOptions();
                        options.CredentialsProvider = gitCredentialsHandler;
                        repo.Network.Push(repo.Head, options);

                        // Check if there is already a PR exist for the same branch
                        var prsOfRepo = await githubClient.PullRequest.GetAllForRepository(githubRepoOwner, githubRepoName, new PullRequestRequest { State = ItemStateFilter.Open });

                        var currentPR = prsOfRepo.FirstOrDefault(x => x.Head.Label == $"{githubRepoOwner}:{nameOfThankyouBranch}");

                        if (currentPR == null)
                        {
                            //  Create a PR on the repo for the branch "thank you"
                            await githubClient.PullRequest.Create(username, githubRepoName, new NewPullRequest("Give credit for people on Twitch chat", nameOfThankyouBranch, defaultBranch.FriendlyName));
                        }
                        else
                        {
                            _logger.LogWarning($"Pull Rrequest is already created. Check PR {currentPR.Id}");
                        }
                    }
                    catch (Exception ex)
                    {
                        // This exception might be caused by an already existing PR for this branch. In this case it's ok, otherwise we will just log it.
                        _logger.LogError(ex, $"Ops, We couldn't create the PR. But here is the list of contributors you were trying to add {string.Join(", ", _contributorsToday.Select(c => c.Name))}");
                    }
                }
                else
                {
                    _logger.LogInformation("There was no changes on the README file, this means that either there was no contributors, or all today's contributors are duplicates.");
                }
            }
        }
Пример #23
0
        private static async Task WriteContributorsToRepo(string username, string password)
        {
            var nameOfThankyouBranch = "thankyou";
            var repoUrl                     = _parsedOptions.gitRepositoryUrl;
            var contributorsHeader          = _parsedOptions.acknowledgementSection;
            var fileHoldingContributorsInfo = _parsedOptions.fileInRepoForAcknowledgement;

            string tempPathGitFolder = CreateTempFolderForTheRepo();

            var gitCredentialsHandler = new CredentialsHandler(
                (url, usernameFromUrl, types) =>
                new UsernamePasswordCredentials()
            {
                Username = username,
                Password = password
            });

            var cloneOptions = new CloneOptions();

            cloneOptions.CredentialsProvider = gitCredentialsHandler;
            LibGit2Sharp.Repository.Clone(repoUrl, tempPathGitFolder, cloneOptions);

            using (var repo = new LibGit2Sharp.Repository(tempPathGitFolder))
            {
                var remote        = repo.Network.Remotes["origin"];
                var defaultBranch = repo.Branches.FirstOrDefault(b => b.IsCurrentRepositoryHead == true);
                var refSpecs      = remote.FetchRefSpecs.Select(x => x.Specification);

                var remoteThankYouBranch = repo.Branches.FirstOrDefault(b => b.FriendlyName == repo.Network.Remotes.FirstOrDefault()?.Name + "/" + nameOfThankyouBranch);

                if (remoteThankYouBranch != null)
                {
                    Commands.Checkout(repo, remoteThankYouBranch);
                }

                if (repo.Head.FriendlyName != nameOfThankyouBranch)
                {
                    var newThankyouBranch = repo.CreateBranch(nameOfThankyouBranch);
                    repo.Branches.Update(newThankyouBranch,
                                         b => b.UpstreamBranch = newThankyouBranch.CanonicalName,
                                         b => b.Remote         = repo.Network.Remotes.First().Name);
                    Commands.Checkout(repo, newThankyouBranch);
                }


                var pathToReadme = Path.Combine(tempPathGitFolder, fileHoldingContributorsInfo);

                // Change the file and save it
                var inputLines = await File.ReadAllLinesAsync(pathToReadme);

                var outputLines = MarkdownProcessor.AddContributorsToMarkdownFile(inputLines, _contributorsToday);
                await File.WriteAllLinesAsync(pathToReadme, outputLines);

                var status = repo.RetrieveStatus(fileHoldingContributorsInfo);
                if (status == FileStatus.ModifiedInWorkdir)
                {
                    // Commit the file to the repo, on a non-master branch
                    repo.Index.Add(fileHoldingContributorsInfo);
                    repo.Index.Write();

                    var gitAuthorName  = _parsedOptions.gitAuthorName;
                    var gitAuthorEmail = _parsedOptions.gitAuthorEmail;

                    // Create the committer's signature and commit
                    var author    = new LibGit2Sharp.Signature(gitAuthorName, gitAuthorEmail, DateTime.Now);
                    var committer = author;

                    // Commit to the repository
                    var commit = repo.Commit("A new list of awesome contributors", author, committer);

                    //Push the commit to origin
                    LibGit2Sharp.PushOptions options = new LibGit2Sharp.PushOptions();
                    options.CredentialsProvider = gitCredentialsHandler;
                    repo.Network.Push(repo.Head, options);

                    // Login to GitHub with Octokit
                    var githubClient = new GitHubClient(new ProductHeaderValue(username));
                    githubClient.Credentials = new Octokit.Credentials(password);

                    try
                    {
                        //  Create a PR on the repo for the branch "thank you"
                        await githubClient.PullRequest.Create(username, "thankyou", new NewPullRequest("Give credit for people on Twitch chat", nameOfThankyouBranch, defaultBranch.FriendlyName));
                    }
                    catch (Exception ex)
                    {
                        // It's alright, the PR is already there. No harm is done.
                    }
                }
            }
        }
        private static void ResetBuildBranchToTag(Repository repository, ILogger logger, VersionLabel versionLabel, Tag versionLabelTag)
        {
            var buildBranch =
                (from branch in repository.Branches
                 where branch.FriendlyName == BuildBranchName
                 select branch).SingleOrDefault();
            if (buildBranch == null)
            {
                logger.Log($"The branch '{BuildBranchName}' doesn't exist: creating it and resetting it to '{versionLabel.Raw}'");

                // If the build branch doesn't exist, create it and check it out
                buildBranch = repository.CreateBranch(BuildBranchName, versionLabelTag.Target as Commit);
                repository.Checkout(buildBranch, new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force });
            }
            else
            {
                logger.Log($"The branch '{BuildBranchName}' already exists: checking it out and resetting it to '{versionLabel.Raw}'");

                // If the build branch exists, check it out and do an hard reset
                repository.Checkout(buildBranch, new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force });
                repository.Reset(ResetMode.Hard, versionLabelTag.Target as Commit);
            }
        }
Пример #25
0
        public void CanReuseLocalRepository_returns_false_if_the_repository_contains_unpublished_branches()
        {
            var transaction1 = CreateTransaction();
            transaction1.Begin();
            using (var repository = new Repository(transaction1.LocalPath))
            {
                repository.CreateBranch("newBranch", repository.GetAllCommits().Single());
            }

            //do not commit the changes from the transaction (leaves the local directory intact (with a new commit))        

            var cachingTransaction = CreateCachingTransaction(transaction1.LocalPath);
            Assert.False(cachingTransaction.CanReuseLocalRepository());
        }
Пример #26
0
        public void Commit_fails_to_create_a_new_branch_if_the_same_branch_was_created_by_another_transaction()
        {
            const string branchName = "newBranch";
            
            var transaction1 = CreateTransaction();
            var transaction2 = CreateTransaction();

            transaction1.Begin();
            transaction2.Begin();

            using (var localRepository1 = new Repository(transaction1.LocalPath))
            {
                localRepository1.CreateBranch(branchName, localRepository1.Commits.Single());
            }

            AddFile(transaction1, branchName, "file1");

            using (var localRepository2 = new Repository(transaction2.LocalPath))
            {
                localRepository2.CreateBranch(branchName, localRepository2.Commits.Single());
            }

            transaction1.Commit();
            Assert.Throws<TransactionFailedException>(() => transaction2.Commit());
        }
Пример #27
0
        private static async Task WriteContributorsToRepo(string username, string password)
        {
            var nameOfThankyouBranch = "thankyou";
            var repoUrl                     = _parsedOptions.repositoryUrl;
            var contributorsHeader          = _parsedOptions.acknowledgementSection;
            var fileHoldingContributorsInfo = _parsedOptions.fileInRepoForAcknowledgement;

            var cloneOptions          = new CloneOptions();
            var gitCredentialsHandler = new CredentialsHandler(
                (url, usernameFromUrl, types) =>
                new UsernamePasswordCredentials()
            {
                Username = username,
                Password = password
            });

            cloneOptions.CredentialsProvider = gitCredentialsHandler;
            var tempPath        = Path.GetTempPath();
            var tempPathForRepo = Path.Combine(tempPath, "Jaan");

            if (Directory.Exists(tempPathForRepo))
            {
                Directory.Delete(tempPathForRepo, true); //TODO: Don't remove and re-clone, clone only if doesn't exist
            }
            var tempPathGitFolder = Path.Combine(tempPath, "Jaan");

            if (!Directory.Exists(tempPathGitFolder))
            {
                var directoryInfo = Directory.CreateDirectory(tempPathGitFolder);
            }
            LibGit2Sharp.Repository.Clone(repoUrl, tempPathGitFolder, cloneOptions); //TODO: if the repo clone is already here, should we delete and reclone? or should we assume correct repo here.
            using (var repo = new LibGit2Sharp.Repository(tempPathGitFolder))
            {
                var remote        = repo.Network.Remotes["origin"];
                var defaultBranch = repo.Branches.FirstOrDefault(b => b.IsCurrentRepositoryHead == true);
                var refSpecs      = remote.FetchRefSpecs.Select(x => x.Specification);

                var remoteThankYouBranch = repo.Branches.FirstOrDefault(b => b.FriendlyName == repo.Network.Remotes.FirstOrDefault()?.Name + "/" + nameOfThankyouBranch);

                if (remoteThankYouBranch != null)
                {
                    Commands.Checkout(repo, remoteThankYouBranch);
                }

                if (repo.Head.FriendlyName != nameOfThankyouBranch)
                {
                    var newThankyouBranch = repo.CreateBranch(nameOfThankyouBranch);
                    repo.Branches.Update(newThankyouBranch,
                                         b => b.UpstreamBranch = newThankyouBranch.CanonicalName,
                                         b => b.Remote         = repo.Network.Remotes.First().Name);
                    Commands.Checkout(repo, newThankyouBranch);
                }


                var pathToReadme = Path.Combine(tempPathGitFolder, fileHoldingContributorsInfo);
                // Change the file and save it
                using (StreamWriter sw = File.AppendText(pathToReadme))
                {
                    foreach (var contributor in _contributorsToday)
                    {
                        sw.WriteLine(contributor);
                    }
                }

                // Commit the file to the repo, on a non-master branch
                repo.Index.Add(fileHoldingContributorsInfo);
                repo.Index.Write();

                // Create the committer's signature and commit
                var author    = new LibGit2Sharp.Signature(_parsedOptions.gitAuthorName, _parsedOptions.gitAuthorEmail, DateTime.Now);
                var committer = author;

                // Commit to the repository
                var commit = repo.Commit("A new list of awesome contributors", author, committer);

                //Push the commit to origin
                LibGit2Sharp.PushOptions options = new LibGit2Sharp.PushOptions();
                options.CredentialsProvider = gitCredentialsHandler;
                repo.Network.Push(repo.Head, options);

                // Login to GitHub with Octokit
                var githubClient = new GitHubClient(new ProductHeaderValue(username));
                githubClient.Credentials = new Octokit.Credentials(password);

                try
                {
                    //  Create a PR on the repo for the branch "thank you"
                    await githubClient.PullRequest.Create(username, "thankyou", new NewPullRequest("Give credit for people on Twitch chat", nameOfThankyouBranch, defaultBranch.FriendlyName));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
        }
Пример #28
0
        public void Commit_succeeds_if_two_transactions_created_the_same_branch_pointing_to_the_same_commit()
        {
            const string branchName = "newBranch";
            
            var transaction1 = CreateTransaction();
            var transaction2 = CreateTransaction();

            transaction1.Begin();
            transaction2.Begin();

            // transaction 1: create branch
            using (var localRepository1 = new Repository(transaction1.LocalPath))
            {
                localRepository1.CreateBranch(branchName, localRepository1.Commits.Single());
            }

            // transaction 2: create branch
            using (var localRepository2 = new Repository(transaction2.LocalPath))
            {
                localRepository2.CreateBranch(branchName, localRepository2.Commits.Single());
            }

            // commit both transactions
            transaction1.Commit();
            transaction2.Commit();

            Assert.True(m_RemoteRepository.Branches.Any(x => x.FriendlyName == branchName));
        }
Пример #29
0
 public Branch CreateBranch(string branch, string baseBranchName)
 {
     using (var repo = new Repository(_settings.Workspace))
     {
         var baseBranch = repo.Lookup<Commit>(baseBranchName);
         return repo.CreateBranch(branch, baseBranch);
     }
 }
Пример #30
0
        public void NewPost(Post post)
        {
            using (var repo = new Repository(_directory.FullName))
            {
                var json = JsonConvert.SerializeObject(post);
                var sig = new Signature(post.Author.Name, post.Author.Identifier, post.Timestamp);

                // Create post structure
                var votesDir = repo.ObjectDatabase.CreateTree(new TreeDefinition());
                var repliesDir = repo.ObjectDatabase.CreateTree(new TreeDefinition());
                var postRoot = new TreeDefinition();
                postRoot.Add(VOTES_DIR, votesDir);
                postRoot.Add(REPLIES_DIR, repliesDir);

                var commit = CommitToBranch(repo, CONTENT_BRANCH, json, sig, repo.ObjectDatabase.CreateTree(postRoot));
                // Create a named branch for all future content on this post
                repo.CreateBranch(commit.Sha, commit);
            }
        }
Пример #31
0
        public override int Execute(UpdateSettings settings, ILookup <string, string> remaining)
        {
            // Get the user.
            var client = new GitHubClient(new ProductHeaderValue("Cake-Addin-Updater"))
            {
                Credentials = new Octokit.Credentials(settings.Token)
            };

            // Validate the provided version.
            if (!System.Version.TryParse(settings.Version, out var _))
            {
                _log.Error("The provided version is not valid.");
                return(1);
            }

            // Get the root.
            var root = settings.WorkingDirectory ?? new DirectoryPath(".");

            root = root.MakeAbsolute(_environment);

            // Get the user.
            var user      = client.User.Get(settings.User).Result;
            var userEmail = GetUserEmail(client);

            // Get the repository parts.
            var info = GetRepositoryInfo(settings);

            // Does the directory contains anything?
            var path = CreateRepositoryDirectory(root, info);

            if (_filesystem.Directory.GetFiles(path, "*.*", SearchScope.Current).Any() ||
                _filesystem.Directory.GetDirectories(path, "*.*", SearchScope.Current).Any())
            {
                _log.Error($"Repository '{path}' already exist on disk.");
                _log.Write("Remove it and try again.");
                return(1);
            }

            // Fork the repository.
            var repository = ForkRepository(client, info);

            if (string.IsNullOrWhiteSpace(repository?.Name))
            {
                _log.Error("Could not fork repository.");
                return(1);
            }

            // Get the default branch.
            var defaultBranch = repository.DefaultBranch;

            if (string.IsNullOrWhiteSpace(defaultBranch))
            {
                _log.Error("Could not get default branch for repository.");
                return(1);
            }

            // Clone the repository at the specified path.
            _log.Write("Cloning repository...");
            GitRepository.Clone($"https://github.com/{settings.User}/{repository.Name}", path.FullPath, new CloneOptions
            {
                Checkout = true
            });

            using (var gitRepository = new GitRepository(path.FullPath))
            {
                // Create a new branch in the repository.
                _log.Write("Creating branch...");
                gitRepository.CreateBranch($"feature/cake-{settings.Version}");
                _log.Write("Checking out branch...");
                GitCommands.Checkout(gitRepository, $"feature/cake-{settings.Version}");

                // Update all package references in project.
                var processed = _processor.Process(root, path, settings.Version);
                if (processed == 0)
                {
                    _log.Error("Nothing was updated. Probably a newer repository.");
                    return(1);
                }

                // Commit?
                if (settings.Commit)
                {
                    _log.Write("Staging changes...");
                    GitCommands.Stage(gitRepository, "*");

                    var status = gitRepository.RetrieveStatus();
                    if (status.Any())
                    {
                        _log.Write("Committing changes...");
                        var author = new GitSignature(user.Name, userEmail, DateTime.Now);
                        gitRepository.Commit($"Updated to Cake {settings.Version}.", author, author);

                        // Push?
                        if (settings.Push)
                        {
                            // Build everything first.
                            if (!BuildProject(path))
                            {
                                return(1);
                            }

                            // Push the commit.
                            if (!Push(settings, path))
                            {
                                return(1);
                            }

                            // Create a pull request?
                            if (settings.OpenPullRequest)
                            {
                                CreatePullRequest(client, settings, info);
                            }
                        }
                    }
                    else
                    {
                        _log.Error("No changes in repository. Already updated?");
                    }
                }
            }

            return(0);
        }
Пример #32
0
        public void FetchWithoutConflict(string remoteUrl, string branchName)
        {
            var tracer = _tracerFactory.GetTracer();

            try
            {
                using (var repo = new LibGit2Sharp.Repository(RepositoryPath))
                {
                    var trackedBranchName = string.Format("{0}/{1}", _remoteAlias, branchName);
                    var refSpec           = string.Format("+refs/heads/{0}:refs/remotes/{1}", branchName, trackedBranchName);

                    LibGit2Sharp.Remote remote = null;
                    using (tracer.Step("LibGit2SharpRepository Add Remote"))
                    {
                        // only add if matching remote does not exist
                        // to address strange LibGit2SharpRepository remove and add remote issue (remote already exists!)
                        remote = repo.Network.Remotes[_remoteAlias];
                        if (remote != null &&
                            string.Equals(remote.Url, remoteUrl, StringComparison.OrdinalIgnoreCase) &&
                            remote.FetchRefSpecs.Any(rf => string.Equals(rf.Specification, refSpec, StringComparison.OrdinalIgnoreCase)))
                        {
                            tracer.Trace("Git remote exists");
                        }
                        else
                        {
                            // Remove it if it already exists (does not throw if it doesn't)
                            repo.Network.Remotes.Remove(_remoteAlias);

                            // Configure the remote
                            remote = repo.Network.Remotes.Add(_remoteAlias, remoteUrl, refSpec);

                            tracer.Trace("Git remote added");
                        }
                    }

                    using (tracer.Step("LibGit2SharpRepository Fetch"))
                    {
                        // This will only retrieve the "master"
                        repo.Network.Fetch(remote);
                    }

                    using (tracer.Step("LibGit2SharpRepository Update"))
                    {
                        // Are we fetching a tag?
                        if (branchName.Trim().StartsWith("refs/tags/", StringComparison.OrdinalIgnoreCase))
                        {
                            var trackedTag = repo.Tags[branchName];
                            if (trackedTag == null)
                            {
                                throw new BranchNotFoundException(branchName, null);
                            }

                            // Update the raw ref to point to the tag
                            UpdateRawRef(branchName, branchName);

                            // Now checkout out the tag, which points to the right place
                            Update(branchName);
                        }
                        else
                        {
                            // Optionally set up the branch tracking configuration
                            var trackedBranch = repo.Branches[trackedBranchName];
                            if (trackedBranch == null)
                            {
                                throw new BranchNotFoundException(branchName, null);
                            }

                            var branch = repo.Branches[branchName] ?? repo.CreateBranch(branchName, trackedBranch.Tip);
                            repo.Branches.Update(branch,
                                                 b => b.TrackedBranch = trackedBranch.CanonicalName);

                            // Update the raw ref to point the head of branchName to the latest fetched branch
                            UpdateRawRef(string.Format("refs/heads/{0}", branchName), trackedBranchName);

                            // Now checkout out our branch, which points to the right place
                            Update(branchName);
                        }
                    }
                }
            }
            catch (LibGit2SharpException exception)
            {
                // LibGit2Sharp doesn't support SSH yet. Use GitExeRepository
                // LibGit2Sharp only supports smart Http protocol
                if (exception.Message.Equals("Unsupported URL protocol") ||
                    exception.Message.Equals("Received unexpected content-type"))
                {
                    tracer.TraceWarning("LibGit2SharpRepository fallback to git.exe due to {0}", exception.Message);

                    _legacyGitExeRepository.FetchWithoutConflict(remoteUrl, branchName);
                }
                else
                {
                    throw;
                }
            }
        }
        public void When_The_Main_Branch_Has_More_Commits_Than_A_Ref_Branch_It_Should_Not_Be_Deletable()
        {
            /* Setup */
            // First commit
            File.WriteAllText(Path.Combine(_repoPath, "file1.txt"), "File1's content...");
            _repo.Stage("file1.txt");
            _repo.Commit("First commit...");

            // Checkout new branch
            _repo.CreateBranch("newBranch");
            _repo.Checkout("newBranch");

            // Second commit
            File.WriteAllText(Path.Combine(_repoPath, "file2.txt"), "File2's content...");
            _repo.Stage("file2.txt");
            _repo.Commit("Second commit...");

            // Prepare for comparison
            var mainBranch = _repo.Branches["newBranch"];
            var refBranch  = _repo.Branches["master"];

            /* Test */
            var result = _selector.CompareBranches(new Gitcomparer.Core.Model.Branch(mainBranch), new Gitcomparer.Core.Model.Branch(refBranch));

            /* Assert */
            Assert.That(result.MainBranch.Name, Is.EqualTo(mainBranch.Name));
            Assert.That(result.RefBranch.Name, Is.EqualTo(refBranch.Name));
            Assert.That(result.Status, Is.EqualTo(ResultStatus.No));
        }
Пример #34
0
        protected virtual void HandleFixedVersioning_Commit(Dependency dependency, Repository otherRepository)
        {
            var dependencyCommit = otherRepository.Lookup(dependency.Commit) as Commit;
            if (dependencyCommit == null)
                throw new InvalidOperationException($"Dependency {dependency}: Commit '{dependency.Commit}' is invalid");

            var buildBranch =
                (from branch in otherRepository.Branches
                where branch.FriendlyName == VersionResolver.BuildBranchName
                select branch).SingleOrDefault();

            if (buildBranch == null)
            {
                Log($"Dependency {dependency}: fixed versioning: '{VersionResolver.BuildBranchName}' branch not found => creating it at Commit = '{dependency.Commit}'...");
                otherRepository.CreateBranch(VersionResolver.BuildBranchName, dependency.Commit);
            }
            else
            {
                Log($"Dependency {dependency}: fixed versioning: '{VersionResolver.BuildBranchName}' branch found => checking it out and hard resetting it to Commit = '{dependency.Commit}'...");
                otherRepository.Checkout(buildBranch, new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force });
                otherRepository.Reset(ResetMode.Hard, dependencyCommit);
            }
        }
Пример #35
0
        public void Begin_creates_new_local_branches_for_branches_created_in_the_remote_repository()
        {
            const string branchName = "newTestBranch";

            var transaction1 = CreateTransaction();
            var transaction2 = CreateTransaction();

            transaction1.Begin();
            transaction2.Begin();

            // in transaction1 create a branch and push it to the remote directory
            using (var repository = new Repository(transaction1.LocalPath))
            {
                repository.CreateBranch(branchName, repository.Commits.Single());
            }            

            transaction1.Commit();

            var transaction3 = CreateCachingTransaction(transaction2.LocalPath);
            transaction3.Begin();

            using (var repository = new Repository(transaction3.LocalPath))
            {
                Assert.True(repository.Branches[branchName] != null);
            }                
        }
Пример #36
0
        /// <summary>
        /// Creates local tracking branches for all remote branches
        /// </summary>
        protected void CreateLocalBranches()
        {
            using (var repository = new Repository(LocalPath))
            {
                // for every remote branch, create a local branch if it does not already exist
                foreach (var remoteBranch in repository.Branches.GetRemoteBranches())
                {
                    var branchName = remoteBranch.FriendlyName.Replace($"{s_Origin}/", "");

                    var localBranch = repository.Branches[branchName] ?? repository.CreateBranch(branchName, remoteBranch.Tip);

                    // set up the local branch to track the remote branch
                    repository.Branches.Update(localBranch, b => b.TrackedBranch = remoteBranch.CanonicalName);
                }
            }
        }
Пример #37
0
        public Task <bool> Commit(string localRepository, string baseBranch, string branch, string commitMessage, string author, string email)
        {
            try
            {
                var repo      = new Repository(localRepository);
                var signature = new LibGit2Sharp.Signature(author, email, DateTimeOffset.UtcNow);

                // if we're working on empty repository, create master branch
                if (repo.Branches == null || repo.Branches.Count() == 0)
                {
                    var readmeFile = Path.Combine(localRepository, "README.md");

                    if (!File.Exists(readmeFile))
                    {
                        File.WriteAllText(Path.Combine(localRepository, "README.md"), "# Catapult-generated");
                    }

                    Commands.Stage(repo, "README.md");

                    if (File.Exists(Path.Combine(localRepository, ".gitignore")))
                    {
                        Commands.Stage(repo, ".gitignore");
                    }

                    repo.Commit("Initial commit", signature, signature);
                    var masterBranch = repo.Branches[baseBranch];

                    var remote = repo.Network.Remotes["origin"];
                    repo.Branches.Update(masterBranch,
                                         b => b.Remote         = remote.Name,
                                         b => b.UpstreamBranch = masterBranch.CanonicalName);

                    _logger.LogInformation("Repository has been initialized");
                }

                // checkout base branch
                var branchObj = repo.Branches[baseBranch] != null ? repo.Branches[baseBranch] : repo.Branches[$"origin/{baseBranch}"];

                if (branch == null)
                {
                    _logger.LogError($"Base branch {baseBranch} was not found");
                    return(Task.FromResult(false));
                }

                if (repo.Head.Commits.FirstOrDefault() != branchObj.Commits.FirstOrDefault())
                {
                    Commands.Checkout(repo, branchObj);
                }

                if (repo.Branches[branch] == null)
                {
                    var newBranch = repo.CreateBranch(branch);

                    var remote = repo.Network.Remotes["origin"];
                    repo.Branches.Update(newBranch,
                                         b => b.Remote         = remote.Name,
                                         b => b.UpstreamBranch = newBranch.CanonicalName);

                    _logger.LogInformation("Branch {branch} has been created.", branch);
                }

                Commands.Checkout(repo, repo.Branches[branch]);
                Commands.Stage(repo, "*");
                var commit = repo.Commit(commitMessage, signature, signature);

                return(Task.FromResult(commit != null));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);

                return(Task.FromResult(false));
            }
        }
Пример #38
0
        /// <summary>
        /// Adds the standard .NET targets to the build.
        /// </summary>
        /// <param name="build">The build to which to add targets.</param>
        /// <param name="settings">The build settings.</param>
        public static void AddDotNetTargets(this BuildApp build, DotNetBuildSettings?settings = null)
        {
            settings ??= new DotNetBuildSettings();

            var buildOptions        = settings.BuildOptions ?? (settings.BuildOptions = new DotNetBuildOptions());
            var configurationOption = buildOptions.ConfigurationOption ?? (buildOptions.ConfigurationOption =
                                                                               build.AddOption("-c|--configuration <name>", "The configuration to build (default Release)", "Release"));
            var platformOption = buildOptions.PlatformOption ?? (buildOptions.PlatformOption =
                                                                     build.AddOption("-p|--platform <name>", "The solution platform to build"));
            var verbosityOption = buildOptions.VerbosityOption ?? (buildOptions.VerbosityOption =
                                                                       build.AddOption("-v|--verbosity <level>", "The build verbosity (q[uiet], m[inimal], n[ormal], d[etailed])"));
            var versionSuffixOption = buildOptions.VersionSuffixOption ?? (buildOptions.VersionSuffixOption =
                                                                               build.AddOption("--version-suffix <suffix>", "Generates a prerelease package"));
            var nugetOutputOption = buildOptions.NuGetOutputOption ?? (buildOptions.NuGetOutputOption =
                                                                           build.AddOption("--nuget-output <path>", "Directory for generated package (default release)", "release"));
            var triggerOption = buildOptions.TriggerOption ?? (buildOptions.TriggerOption =
                                                                   build.AddOption("--trigger <name>", "The git branch or tag that triggered the build"));
            var buildNumberOption = buildOptions.BuildNumberOption ?? (buildOptions.BuildNumberOption =
                                                                           build.AddOption("--build-number <number>", "The automated build number"));
            var noTestFlag = buildOptions.NoTestFlag ?? (buildOptions.NoTestFlag =
                                                             build.AddFlag("--no-test", "Skip the unit tests"));

            var solutionName    = settings.SolutionName;
            var nugetSource     = settings.NuGetSource ?? "https://api.nuget.org/v3/index.json";
            var msbuildSettings = settings.MSBuildSettings;

            var    packagePaths          = new List <string>();
            string?trigger               = null;
            var    ignoreIfAlreadyPushed = false;

            build.Target("clean")
            .Describe("Deletes all build output")
            .Does(() =>
            {
                var findDirectoriesToDelete = settings.CleanSettings?.FindDirectoriesToDelete ??
                                              (() => FindDirectories("{src,tests,tools}/**/{bin,obj}").Except(FindDirectories("tools/bin")).ToList());
                foreach (var directoryToDelete in findDirectoriesToDelete())
                {
                    DeleteDirectory(directoryToDelete);
                }

                var verbosity       = GetVerbosity();
                var extraProperties = GetExtraProperties("clean");
                if (msbuildSettings == null)
                {
                    RunDotNet(new[] { "clean", solutionName, "-c", configurationOption.Value, GetPlatformArg(), "--verbosity", verbosity, GetMaxCpuCountArg() }.Concat(extraProperties));
                }
                else
                {
                    MSBuild(new[] { solutionName, "-t:Clean", $"-p:Configuration={configurationOption.Value}", GetPlatformArg(), $"-v:{verbosity}", GetMaxCpuCountArg() }.Concat(extraProperties));
                }
            });

            build.Target("restore")
            .Describe("Restores NuGet packages")
            .Does(() =>
            {
                var verbosity       = GetVerbosity();
                var extraProperties = GetExtraProperties("restore");
                if (msbuildSettings == null)
                {
                    RunDotNet(new[] { "restore", solutionName, GetPlatformArg(), "--verbosity", verbosity, GetMaxCpuCountArg() }.Concat(extraProperties));
                }
                else
                {
                    MSBuild(new[] { solutionName, "-t:Restore", $"-p:Configuration={configurationOption.Value}", GetPlatformArg(), $"-v:{verbosity}", GetMaxCpuCountArg() }.Concat(extraProperties));
                }

                if (DotNetLocalTool.Any())
                {
                    RunDotNet("tool", "restore");
                }
            });

            build.Target("build")
            .DependsOn("restore")
            .Describe("Builds the solution")
            .Does(() =>
            {
                var buildNumberArg = GetBuildNumberArg();

                var verbosity       = GetVerbosity();
                var extraProperties = GetExtraProperties("build");
                if (msbuildSettings == null)
                {
                    RunDotNet(new[] { "build", solutionName, "-c", configurationOption.Value, GetPlatformArg(), buildNumberArg, "--no-restore", "--verbosity", verbosity, GetMaxCpuCountArg() }.Concat(extraProperties));
                }
                else
                {
                    MSBuild(new[] { solutionName, $"-p:Configuration={configurationOption.Value}", GetPlatformArg(), buildNumberArg, $"-v:{verbosity}", GetMaxCpuCountArg() }.Concat(extraProperties));
                }
            });

            build.Target("test")
            .DependsOn("build")
            .Describe("Runs the unit tests")
            .Does(() =>
            {
                if (noTestFlag.Value)
                {
                    Console.WriteLine("Skipping unit tests due to --no-test.");
                }
                else
                {
                    var extraProperties    = GetExtraProperties("test").ToList();
                    var findTestAssemblies = settings.TestSettings?.FindTestAssemblies;
                    if (findTestAssemblies != null)
                    {
                        foreach (var testAssembly in findTestAssemblies())
                        {
                            if (settings.TestSettings?.RunTests != null)
                            {
                                settings.TestSettings.RunTests(testAssembly);
                            }
                            else
                            {
                                RunDotNet(new AppRunnerSettings {
                                    Arguments = new[] { "vstest", Path.GetFileName(testAssembly) }.Concat(extraProperties), WorkingDirectory = Path.GetDirectoryName(testAssembly)
                                });
                            }
                        }
                    }
                    else
                    {
                        var testProjects = new List <string?>();

                        var findTestProjects = settings.TestSettings?.FindProjects;
                        if (findTestProjects != null)
                        {
                            testProjects.AddRange(findTestProjects());
                        }
                        else
                        {
                            testProjects.Add(solutionName);
                        }

                        foreach (var testProject in testProjects)
                        {
                            if (settings.TestSettings?.RunTests != null)
                            {
                                settings.TestSettings.RunTests(testProject);
                            }
                            else
                            {
                                RunDotNet(new[] { "test", testProject, "-c", configurationOption.Value, GetPlatformArg(), "--no-build", GetMaxCpuCountArg() }.Concat(extraProperties));
                            }
                        }
                    }
                }
            });

            build.Target("package")
            .DependsOn("clean", "test")
            .Describe("Builds NuGet packages")
            .Does(() =>
            {
                trigger = triggerOption.Value;

                if (trigger == "detect")
                {
                    using var repository = new Repository(".");
                    var headSha          = repository.Head.Tip.Sha;
                    var autoTrigger      = GetBestTriggerFromTags(repository.Tags.Where(x => x.Target.Sha == headSha).Select(x => x.FriendlyName).ToList());
                    if (autoTrigger != null)
                    {
                        trigger = autoTrigger;
                        ignoreIfAlreadyPushed = true;
                        Console.WriteLine($"Detected trigger: {trigger}");
                    }
                }

                var versionSuffix = versionSuffixOption.Value;
                if (versionSuffix == null && trigger != null)
                {
                    versionSuffix = GetVersionFromTrigger(trigger) is string triggerVersion ? SplitVersion(triggerVersion).Suffix : null;
                }

                var nugetOutputPath = Path.GetFullPath(nugetOutputOption.Value !);
                var tempOutputPath  = Path.Combine(nugetOutputPath, Path.GetRandomFileName());

                var packageProjects = new List <string?>();

                var findPackageProjects = settings.PackageSettings?.FindProjects;
                if (findPackageProjects != null)
                {
                    packageProjects.AddRange(findPackageProjects());
                }
                else
                {
                    packageProjects.Add(solutionName);
                }

                var extraProperties = GetExtraProperties("package").ToList();
                foreach (var packageProject in packageProjects)
                {
                    if (msbuildSettings == null)
                    {
                        RunDotNet(new[]
                        {
                            "pack", packageProject,
                            "-c", configurationOption.Value,
                            GetPlatformArg(),
                            "--no-build",
                            "--output", tempOutputPath,
                            versionSuffix != null ? "--version-suffix" : null, versionSuffix,
                            GetMaxCpuCountArg(),
                        }.Concat(extraProperties));
                    }
                    else
                    {
                        MSBuild(new[]
                        {
                            packageProject, "-t:Pack",
                            $"-p:Configuration={configurationOption.Value}",
                            GetPlatformArg(),
                            "-p:NoBuild=true",
                            $"-p:PackageOutputPath={tempOutputPath}",
                            versionSuffix != null ? $"-p:VersionSuffix={versionSuffix}" : null,
                            $"-v:{GetVerbosity()}",
                            GetMaxCpuCountArg(),
                        }.Concat(extraProperties));
                    }
                }

                var tempPackagePaths = FindFilesFrom(tempOutputPath, "*.nupkg");
                foreach (var tempPackagePath in tempPackagePaths)
                {
                    var packagePath = Path.Combine(nugetOutputPath, Path.GetFileName(tempPackagePath) ?? throw new InvalidOperationException());
                    if (File.Exists(packagePath))
                    {
                        File.Delete(packagePath);
                    }
                    File.Move(tempPackagePath, packagePath);
                    packagePaths.Add(packagePath);
                    Console.WriteLine($"NuGet package: {packagePath}");
                }
                DeleteDirectory(tempOutputPath);

                if (packagePaths.Count == 0)
                {
                    throw new BuildException("No NuGet packages created.");
                }
            });

            build.Target("publish")
            .Describe("Publishes NuGet packages and documentation")
            .DependsOn("package")
            .Does(() =>
            {
                if (packagePaths.Count == 0)
                {
                    throw new BuildException("No NuGet packages found.");
                }

                if (trigger is null)
                {
                    if (packagePaths.Any(x => GetPackageInfo(x).Version == "0.0.0"))
                    {
                        Console.WriteLine("Not publishing package with version 0.0.0. Change package version to publish.");
                        return;
                    }

                    trigger = "publish-all";
                }

                var triggerParts          = trigger.Split('-');
                var publishTrigger        = triggerParts.Length >= 2 && triggerParts[0] == "publish" ? triggerParts[1] : null;
                var shouldPublishPackages = publishTrigger == "package" || publishTrigger == "packages" || publishTrigger == "all";
                var shouldPublishDocs     = publishTrigger == "docs" || publishTrigger == "all";
                var shouldSkipDuplicates  = publishTrigger == "all";

                var triggerVersion = GetVersionFromTrigger(trigger);
                if (triggerVersion != null)
                {
                    var mismatches = packagePaths.Where(x => GetPackageInfo(x).Version != triggerVersion).ToList();
                    if (mismatches.Count != 0)
                    {
                        throw new BuildException($"Trigger '{trigger}' doesn't match package version: {string.Join(", ", mismatches.Select(Path.GetFileName))}");
                    }

                    shouldPublishPackages = true;
                    shouldPublishDocs     = triggerVersion.IndexOf('-') == -1;
                }

                if (shouldPublishPackages || shouldPublishDocs)
                {
                    var docsSettings      = settings.DocsSettings;
                    var shouldPushDocs    = false;
                    string?cloneDirectory = null;
                    string?repoDirectory  = null;
                    string?gitBranchName  = null;

                    if (shouldPublishDocs && docsSettings != null)
                    {
                        if (docsSettings.GitLogin == null || docsSettings.GitAuthor == null)
                        {
                            throw new BuildException("GitLogin and GitAuthor must be set on DocsSettings.");
                        }

                        var gitRepositoryUrl = docsSettings.GitRepositoryUrl;
                        gitBranchName        = docsSettings.GitBranchName;

                        if (gitRepositoryUrl != null)
                        {
                            cloneDirectory = "docs_repo_" + Path.GetRandomFileName();
                            Repository.Clone(sourceUrl: gitRepositoryUrl, workdirPath: cloneDirectory,
                                             options: new CloneOptions {
                                BranchName = gitBranchName, CredentialsProvider = ProvideCredentials
                            });
                            repoDirectory = cloneDirectory;
                        }
                        else
                        {
                            repoDirectory = ".";
                        }

                        using var repository = new Repository(repoDirectory);
                        if (gitRepositoryUrl != null)
                        {
                            gitBranchName ??= repository.Head.FriendlyName;
                        }
                        else if (gitBranchName != null)
                        {
                            if (gitBranchName != repository.Head.FriendlyName)
                            {
                                var branch = repository.Branches[gitBranchName] ?? repository.CreateBranch(gitBranchName);
                                Commands.Checkout(repository, branch);
                            }
                        }
                        else
                        {
                            var branch = repository.Branches.FirstOrDefault(x => x.IsCurrentRepositoryHead);
                            if (branch == null)
                            {
                                var autoBranchName = Environment.GetEnvironmentVariable("APPVEYOR_REPO_BRANCH");

                                if (autoBranchName == null)
                                {
                                    var gitRef          = Environment.GetEnvironmentVariable("GITHUB_REF");
                                    const string prefix = "refs/heads/";
                                    if (gitRef != null && gitRef.StartsWith(prefix, StringComparison.Ordinal))
                                    {
                                        autoBranchName = gitRef.Substring(prefix.Length);
                                    }
                                }

                                if (autoBranchName != null)
                                {
                                    branch = repository.Branches[autoBranchName] ?? repository.CreateBranch(autoBranchName);
                                }
                                else
                                {
                                    branch = repository.Branches.FirstOrDefault(x => x.Tip.Sha == repository.Head.Tip.Sha);
                                }

                                if (branch != null)
                                {
                                    Commands.Checkout(repository, branch);
                                }
                            }
                            if (branch == null)
                            {
                                throw new BuildException("Could not determine repository branch for publishing docs.");
                            }
                            gitBranchName = branch.FriendlyName;
                        }

                        var docsPath = Path.Combine(repoDirectory, docsSettings.TargetDirectory ?? "docs");

                        string?xmlDocGenPath = null;
                        var xmlDocGenProject = FindFiles("tools/XmlDocGen/XmlDocGen.csproj").FirstOrDefault();
                        if (xmlDocGenProject != null)
                        {
                            RunDotNet("publish", xmlDocGenProject, "--output", Path.Combine("tools", "bin", "XmlDocGen"), "--nologo", "--verbosity", "quiet");
                            xmlDocGenPath = Path.Combine("tools", "bin", "XmlDocGen", "XmlDocGen.dll");
                        }

                        var projectHasDocs = docsSettings.ProjectHasDocs ?? (_ => true);
                        foreach (var projectName in packagePaths.Select(x => GetPackageInfo(x).Name).Where(projectHasDocs))
                        {
                            if (xmlDocGenPath != null)
                            {
                                RunDotNet(new[] { xmlDocGenPath }.Concat(GetXmlDocArgs(projectName)));
                            }
                            else
                            {
                                var assemblyPaths = new List <string>();
                                if (docsSettings.FindAssemblies != null)
                                {
                                    assemblyPaths.AddRange(docsSettings.FindAssemblies(projectName));
                                }
                                else
                                {
                                    var assemblyPath = (docsSettings.FindAssembly ?? FindAssembly)(projectName);
                                    if (assemblyPath != null)
                                    {
                                        assemblyPaths.Add(assemblyPath);
                                    }
                                }

                                if (assemblyPaths.Count != 0)
                                {
                                    if (DotNetLocalTool.TryCreate("xmldocmd") is DotNetLocalTool xmldocmd)
                                    {
                                        foreach (var assemblyPath in assemblyPaths)
                                        {
                                            xmldocmd.Run(GetXmlDocArgs(assemblyPath));
                                        }
                                    }
                                    else
                                    {
                                        var dotNetTools           = settings.DotNetTools ?? new DotNetTools(Path.Combine("tools", "bin"));
                                        var xmlDocMarkdownVersion = settings.DocsSettings?.ToolVersion ?? "2.0.1";

                                        foreach (var assemblyPath in assemblyPaths)
                                        {
                                            RunApp(dotNetTools.GetToolPath($"xmldocmd/{xmlDocMarkdownVersion}"), GetXmlDocArgs(assemblyPath));
                                        }
                                    }
                                }
                                else
                                {
                                    Console.WriteLine($"Documentation not generated for {projectName}; assembly not found.");
                                }
Пример #39
0
        public void FetchWithoutConflict(string remoteUrl, string branchName)
        {
            var tracer = _tracerFactory.GetTracer();
            try
            {
                using (var repo = new LibGit2Sharp.Repository(RepositoryPath))
                {
                    var trackedBranchName = string.Format("{0}/{1}", _remoteAlias, branchName);
                    var refSpec = string.Format("+refs/heads/{0}:refs/remotes/{1}", branchName, trackedBranchName);

                    // Configure the remote
                    var remote = repo.Network.Remotes.Add(_remoteAlias, remoteUrl, refSpec);

                    // This will only retrieve the "master"
                    repo.Network.Fetch(remote);

                    // Optionally set up the branch tracking configuration
                    var trackedBranch = repo.Branches[trackedBranchName];
                    if (trackedBranch == null)
                    {
                        throw new BranchNotFoundException(branchName, null);
                    }
                    var branch = repo.Branches[branchName] ?? repo.CreateBranch(branchName, trackedBranch.Tip);
                    repo.Branches.Update(branch,
                        b => b.TrackedBranch = trackedBranch.CanonicalName);

                    //Update the raw ref to point the head of branchName to the latest fetched branch
                    UpdateRawRef(string.Format("refs/heads/{0}", branchName), trackedBranchName);

                    // Now checkout out our branch, which points to the right place
                    Update(branchName);
                }
            }
            catch (LibGit2SharpException exception)
            {
                tracer.TraceWarning("LibGit2SharpRepository fetch failed with {0}", exception);

                // LibGit2Sharp doesn't support SSH yet. Use GitExeRepository
                // LibGit2Sharp only supports smart Http protocol
                if (exception.Message.Equals("Unsupported URL protocol") ||
                    exception.Message.Equals("Received unexpected content-type"))
                {
                    tracer.TraceWarning("LibGit2SharpRepository fallback to git.exe");

                    _legacyGitExeRepository.FetchWithoutConflict(remoteUrl, branchName);
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                using (var repo = new LibGit2Sharp.Repository(RepositoryPath))
                {
                    repo.Network.Remotes.Remove(_remoteAlias);
                }
            }
        }
Пример #40
0
 /// <summary>
 /// Creates a new branch with branchName.
 /// </summary>
 /// <param name="repositoryPath"></param>
 /// <param name="branchName"></param>
 /// <returns>CommandStatus</returns>
 private ECommandStatus Branch(string repositoryPath, string branchName, bool delete, bool isRemote)
 {
     try
     {
         using (var repo = new Repository(repositoryPath))
         {
             var localBranch = repo.Branches[branchName];
             if (localBranch == null)
             {
                 if (delete)
                 {
                     return ECommandStatus.BranchNotFound;
                 }
                 else
                 {
                     Branch branch = repo.CreateBranch(branchName);
                     return ECommandStatus.OK;
                 }
             }
             else
             {
                 if (delete)
                 {
                     repo.Branches.Remove(branchName, isRemote);
                     return ECommandStatus.OK;
                 }
                 else
                 {
                     return ECommandStatus.BranchAlreadyExists;
                 }
             }
         }
     }
     catch (Exception ex)
     {
         System.Diagnostics.Debug.WriteLine(ex.Message);
         return ECommandStatus.FAIL;
     }
 }