private void PushNewCommit(GitHubBranch branch, string commitMessage)
        {
            Command.Git("commit", "-a", "-m", commitMessage, "--author", $"{GitAuthorName} <{_auth.Email}>")
            .EnvironmentVariable("GIT_COMMITTER_NAME", GitAuthorName)
            .EnvironmentVariable("GIT_COMMITTER_EMAIL", _auth.Email)
            .Execute()
            .EnsureSuccessful();

            string remoteUrl = $"github.com/{branch.Project.Segments}.git";
            string refSpec   = $"HEAD:refs/heads/{branch.Name}";

            string logMessage = $"git push https://{remoteUrl} {refSpec}";

            Trace.TraceInformation($"EXEC {logMessage}");

            CommandResult pushResult =
                Command.Git("push", "--force", $"https://{_auth.User}:{_auth.AuthToken}@{remoteUrl}", refSpec)
                .QuietBuildReporter() // we don't want secrets showing up in our logs
                .CaptureStdErr()      // git push will write to StdErr upon success, disable that
                .CaptureStdOut()
                .Execute();

            var message = logMessage + $" exited with {pushResult.ExitCode}";

            if (pushResult.ExitCode == 0)
            {
                Trace.TraceInformation($"EXEC success: {message}");
            }
            else
            {
                Trace.TraceError($"EXEC failure: {message}");
            }

            pushResult.EnsureSuccessful(suppressOutput: true);
        }
Example #2
0
        protected static async Task AddExistingPackages(
            GitHubClient client,
            GitHubBranch branch,
            string versionsRepoPath,
            Dictionary <string, string> packages)
        {
            Dictionary <string, string> existingPackages = await GetPackagesAsync(
                client,
                branch,
                $"{versionsRepoPath}/{BuildInfo.LatestPackagesTxtFilename}");

            if (existingPackages == null)
            {
                Trace.TraceInformation(
                    "No existing Latest_Packages file found; one will be " +
                    $"created in '{versionsRepoPath}'");
            }
            else
            {
                // Add each existing package if there isn't a new package with the same id.
                foreach (var package in existingPackages)
                {
                    if (!packages.ContainsKey(package.Key))
                    {
                        packages[package.Key] = package.Value;
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Create Latest_Packages, and if versionsRepoBranch is passed, Last_Build_Packages.
        /// </summary>
        public async Task UpdateBuildInfoFilesAsync(
            IEnumerable <string> packagePaths,
            string localBaseDir,
            string versionsRepoPath,
            GitHubBranch versionsRepoBranch)
        {
            if (packagePaths == null)
            {
                throw new ArgumentNullException(nameof(packagePaths));
            }
            if (string.IsNullOrEmpty(localBaseDir))
            {
                throw new ArgumentException(nameof(localBaseDir));
            }
            if (string.IsNullOrEmpty(versionsRepoPath))
            {
                throw new ArgumentException(nameof(versionsRepoPath));
            }

            string latestPackagesDir = Path.Combine(
                localBaseDir,
                versionsRepoPath);

            Directory.CreateDirectory(latestPackagesDir);

            NupkgInfo[] packages = CreatePackageInfos(packagePaths).ToArray();

            Dictionary <string, string> packageDictionary = CreatePackageInfoDictionary(packages);

            if (versionsRepoBranch != null)
            {
                File.WriteAllText(
                    Path.Combine(latestPackagesDir, BuildInfo.LastBuildPackagesTxtFilename),
                    CreatePackageListContent(packageDictionary));

                using (var client = new GitHubClient(GitHubAuth))
                {
                    await AddExistingPackages(
                        client,
                        versionsRepoBranch,
                        versionsRepoPath,
                        packageDictionary);
                }
            }

            File.WriteAllText(
                Path.Combine(latestPackagesDir, BuildInfo.LatestTxtFilename),
                GetPrereleaseVersion(packages));

            File.WriteAllText(
                Path.Combine(latestPackagesDir, BuildInfo.LatestPackagesTxtFilename),
                CreatePackageListContent(packageDictionary));
        }
Example #4
0
        private void PushNewCommit(GitHubBranch branch, string commitMessage)
        {
            GitCommand.Commit(commitMessage, GitAuthorName, _auth.Email, all: true);

            string remoteUrl = $"github.com/{branch.Project.Segments}.git";
            string refSpec   = $"HEAD:refs/heads/{branch.Name}";

            GitCommand.Push(
                $"https://{_auth.User}:{_auth.AuthToken}@{remoteUrl}",
                $"https://{remoteUrl}",
                refSpec,
                force: true);
        }
Example #5
0
        private void PushNewCommit(GitHubBranch branch, string commitMessage, IGitHubClient client)
        {
            GitCommand.Commit(commitMessage, GitAuthorName, _auth.Email, all: true);

            string remoteUrl = client.CreateGitRemoteUrl(branch.Project);
            string refSpec   = $"HEAD:refs/heads/{branch.Name}";

            GitCommand.Push(
                $"https://{_auth.User}:{_auth.AuthToken}@{remoteUrl}",
                $"https://{remoteUrl}",
                refSpec,
                force: true);
        }
        public PullRequestCreator(
            GitHubAuth auth,
            GitHubProject origin,
            GitHubBranch upstreamBranch,
            string gitAuthorName = null,
            IUpdateBranchNamingStrategy namingStrategy = null)
        {
            _auth = auth;

            Origin = origin;
            UpstreamBranch = upstreamBranch;

            GitAuthorName = gitAuthorName ?? auth.User;
            _namingStrategy = namingStrategy ?? new SingleBranchNamingStrategy("UpdateDependencies");
        }
        public PullRequestCreator(
            GitHubAuth auth,
            GitHubProject origin,
            GitHubBranch upstreamBranch,
            string gitAuthorName = null,
            IUpdateBranchNamingStrategy namingStrategy = null)
        {
            _auth = auth;

            Origin         = origin;
            UpstreamBranch = upstreamBranch;

            GitAuthorName   = gitAuthorName ?? auth.User;
            _namingStrategy = namingStrategy ?? new SingleBranchNamingStrategy("UpdateDependencies");
        }
Example #8
0
        private static async Task <Dictionary <string, string> > GetPackagesAsync(
            GitHubClient client,
            GitHubBranch branch,
            string path)
        {
            string latestPackages = await client.GetGitHubFileContentsAsync(path, branch);

            if (latestPackages == null)
            {
                return(null);
            }

            using (var reader = new StringReader(latestPackages))
            {
                return(await BuildInfo.ReadPackageListAsync(reader));
            }
        }
        public override bool Execute()
        {
            MsBuildTraceListener[] listeners = Trace.Listeners.AddMsBuildTraceListeners(Log);
            try
            {
                IDependencyUpdater[] updaters = GetDependencyUpdaters().ToArray();
                BuildInfo[] buildInfos = GetBuildInfos().ToArray();
                var updater = new DependencyUpdater();

                DependencyUpdateResults updateResults = updater.Update(updaters, buildInfos);

                if (updateResults.ChangesDetected())
                {
                    var gitHubAuth = new GitHubAuth(GitHubAuthToken, GitHubUser, GitHubEmail);

                    var origin = new GitHubProject(ProjectRepoName, GitHubUser);

                    var upstreamBranch = new GitHubBranch(
                        ProjectRepoBranch,
                        new GitHubProject(ProjectRepoName, ProjectRepoOwner));

                    string suggestedMessage = updateResults.GetSuggestedCommitMessage();
                    string body = string.Empty;
                    if (NotifyGitHubUsers != null)
                    {
                        body += PullRequestCreator.NotificationString(NotifyGitHubUsers.Select(item => item.ItemSpec));
                    }

                    var prCreator = new PullRequestCreator(gitHubAuth, origin, upstreamBranch, GitHubAuthor);
                    prCreator.CreateOrUpdateAsync(
                        suggestedMessage,
                        suggestedMessage + $" ({ProjectRepoBranch})",
                        body,
                        forceCreate: AlwaysCreateNewPullRequest).Wait();
                }
            }
            finally
            {
                Trace.Listeners.RemoveMsBuildTraceListeners(listeners);
            }

            return true;
        }
Example #10
0
 public async Task CreateOrUpdateAsync(
     string commitMessage,
     string title,
     string description,
     GitHubBranch baseBranch,
     GitHubProject origin,
     PullRequestOptions options)
 {
     using (var client = new GitHubClient(_auth))
     {
         await CreateOrUpdateAsync(
             commitMessage,
             title,
             description,
             baseBranch,
             origin,
             options,
             client);
     }
 }
Example #11
0
        public async Task CreateOrUpdateAsync(
            string commitMessage,
            string title,
            string description,
            GitHubBranch baseBranch,
            GitHubProject origin,
            PullRequestOptions options)
        {
            options = options ?? new PullRequestOptions();

            var upstream = baseBranch.Project;

            using (var client = new GitHubClient(_auth))
            {
                GitHubBranch      originBranch        = null;
                GitHubPullRequest pullRequestToUpdate = null;

                IUpdateBranchNamingStrategy namingStrategy = options.BranchNamingStrategy
                                                             ?? new SingleBranchNamingStrategy("UpdateDependencies");

                string upgradeBranchPrefix = namingStrategy.Prefix(baseBranch.Name);

                if (!options.ForceCreate)
                {
                    pullRequestToUpdate = await client.SearchPullRequestsAsync(
                        upstream,
                        upgradeBranchPrefix,
                        _auth.User);

                    if (pullRequestToUpdate == null)
                    {
                        Trace.TraceInformation($"No existing pull request found.");
                    }
                    else
                    {
                        Trace.TraceInformation(
                            $"Pull request already exists for {upgradeBranchPrefix} in {upstream.Segments}. " +
                            $"#{pullRequestToUpdate.Number}, '{pullRequestToUpdate.Title}'");

                        GitCommit headCommit = await client.GetCommitAsync(
                            origin,
                            pullRequestToUpdate.Head.Sha);

                        string blockedReason = GetUpdateBlockedReason(
                            pullRequestToUpdate,
                            headCommit,
                            upgradeBranchPrefix,
                            origin);

                        if (blockedReason == null)
                        {
                            if (options.TrackDiscardedCommits)
                            {
                                await PostDiscardedCommitCommentAsync(
                                    baseBranch.Project,
                                    pullRequestToUpdate,
                                    headCommit,
                                    client);
                            }

                            originBranch = new GitHubBranch(
                                pullRequestToUpdate.Head.Ref,
                                origin);
                        }
                        else
                        {
                            string comment =
                                $"Couldn't update this pull request: {blockedReason}\n" +
                                $"Would have applied '{commitMessage}'";

                            await client.PostCommentAsync(upstream, pullRequestToUpdate.Number, comment);

                            return;
                        }
                    }
                }

                // No existing branch to update: push to a new one.
                if (originBranch == null)
                {
                    string newBranchName =
                        namingStrategy.Prefix(baseBranch.Name) +
                        namingStrategy.CreateFreshBranchNameSuffix(baseBranch.Name);

                    originBranch = new GitHubBranch(newBranchName, origin);
                }

                PushNewCommit(originBranch, commitMessage);

                if (pullRequestToUpdate != null)
                {
                    await client.UpdateGitHubPullRequestAsync(
                        upstream,
                        pullRequestToUpdate.Number,
                        title,
                        description,
                        maintainersCanModify : options.MaintainersCanModify);
                }
                else
                {
                    await client.PostGitHubPullRequestAsync(
                        title,
                        description,
                        originBranch,
                        baseBranch,
                        options.MaintainersCanModify);
                }
            }
        }
        protected override void TraceListenedExecute()
        {
            // Use the commit sha of versions repo master (not just "master") for stable upgrade.
            var gitHubAuth = new GitHubAuth(GitHubAuthToken, GitHubUser, GitHubEmail);
            var client = new GitHubClient(gitHubAuth);
            string masterSha = client
                .GetReferenceAsync(new GitHubProject("versions", "dotnet"), "heads/master")
                .Result.Object.Sha;

            foreach (ITaskItem item in DependencyBuildInfo)
            {
                if (!string.IsNullOrEmpty(item.GetMetadata(CurrentRefMetadataName)))
                {
                    item.SetMetadata(CurrentRefMetadataName, masterSha);
                }
                string autoUpgradeBranch = item.GetMetadata(AutoUpgradeBranchMetadataName);
                if (!string.IsNullOrEmpty(autoUpgradeBranch))
                {
                    item.SetMetadata(CurrentBranchMetadataName, autoUpgradeBranch);
                }
            }

            DependencyUpdateResults updateResults = DependencyUpdateUtils.Update(
                CreateUpdaters().ToArray(),
                CreateBuildInfoDependencies().ToArray());

            // Update CurrentRef and CurrentBranch for each applicable build info used.
            if (!string.IsNullOrEmpty(CurrentRefXmlPath))
            {
                foreach (BuildInfo info in updateResults.UsedBuildInfos)
                {
                    ITaskItem infoItem = FindDependencyBuildInfo(info.Name);

                    if (!string.IsNullOrEmpty(infoItem.GetMetadata(CurrentRefMetadataName)))
                    {
                        UpdateProperty(
                            CurrentRefXmlPath,
                            $"{info.Name}{CurrentRefMetadataName}",
                            masterSha);
                    }

                    string autoUpgradeBranch = infoItem.GetMetadata(AutoUpgradeBranchMetadataName);
                    if (!string.IsNullOrEmpty(autoUpgradeBranch))
                    {
                        UpdateProperty(
                            CurrentRefXmlPath,
                            $"{info.Name}{CurrentBranchMetadataName}",
                            autoUpgradeBranch);
                    }
                }
            }

            if (updateResults.ChangesDetected())
            {
                var origin = new GitHubProject(ProjectRepoName, GitHubUser);

                var upstreamBranch = new GitHubBranch(
                    ProjectRepoBranch,
                    new GitHubProject(ProjectRepoName, ProjectRepoOwner));

                string suggestedMessage = updateResults.GetSuggestedCommitMessage();
                string body = string.Empty;
                if (NotifyGitHubUsers != null)
                {
                    body += PullRequestCreator.NotificationString(NotifyGitHubUsers.Select(item => item.ItemSpec));
                }

                var prCreator = new PullRequestCreator(gitHubAuth, origin, upstreamBranch, GitHubAuthor);
                prCreator.CreateOrUpdateAsync(
                    suggestedMessage,
                    suggestedMessage + $" ({ProjectRepoBranch})",
                    body,
                    forceCreate: AlwaysCreateNewPullRequest).Wait();
            }
            else
            {
                Log.LogMessage("No update required: no changes detected.");
            }
        }
        protected override void TraceListenedExecute()
        {
            // Use the commit sha of versions repo master (not just "master") for stable upgrade.
            var gitHubAuth = new GitHubAuth(GitHubAuthToken, GitHubUser, GitHubEmail);
            var client = new GitHubClient(gitHubAuth);
            string masterSha = client
                .GetReferenceAsync(new GitHubProject("versions", "dotnet"), "heads/master")
                .Result.Object.Sha;

            foreach (ITaskItem item in DependencyBuildInfo)
            {
                if (!string.IsNullOrEmpty(item.GetMetadata(s_currentRef)))
                {
                    item.SetMetadata(s_currentRef, masterSha);
                }
            }

            DependencyUpdateResults updateResults = DependencyUpdateUtils.Update(
                CreateUpdaters().ToArray(),
                CreateBuildInfoDependencies().ToArray());

            if (!string.IsNullOrEmpty(CurrentRefXmlPath))
            {
                // Update the build info commit sha for each applicable build info used.
                foreach (BuildInfo info in updateResults.UsedBuildInfos)
                {
                    ITaskItem infoItem = FindDependencyBuildInfo(info.Name);
                    if (string.IsNullOrEmpty(infoItem.GetMetadata(s_currentRef)))
                    {
                        continue;
                    }

                    Regex upgrader = CreateXmlUpdateRegex($"{info.Name}{s_currentRef}", s_currentRef);

                    Action replace = FileUtils.ReplaceFileContents(
                        CurrentRefXmlPath,
                        contents =>
                        {
                            Match m = upgrader.Match(contents);
                            Group g = m.Groups[s_currentRef];

                            return contents
                                .Remove(g.Index, g.Length)
                                .Insert(g.Index, masterSha);
                        });
                    replace();
                }
            }

            if (updateResults.ChangesDetected())
            {
                var origin = new GitHubProject(ProjectRepoName, GitHubUser);

                var upstreamBranch = new GitHubBranch(
                    ProjectRepoBranch,
                    new GitHubProject(ProjectRepoName, ProjectRepoOwner));

                string suggestedMessage = updateResults.GetSuggestedCommitMessage();
                string body = string.Empty;
                if (NotifyGitHubUsers != null)
                {
                    body += PullRequestCreator.NotificationString(NotifyGitHubUsers.Select(item => item.ItemSpec));
                }

                var prCreator = new PullRequestCreator(gitHubAuth, origin, upstreamBranch, GitHubAuthor);
                prCreator.CreateOrUpdateAsync(
                    suggestedMessage,
                    suggestedMessage + $" ({ProjectRepoBranch})",
                    body,
                    forceCreate: AlwaysCreateNewPullRequest).Wait();
            }
            else
            {
                Log.LogMessage("No update required: no changes detected.");
            }
        }
        public async Task CreateOrUpdateAsync(
            string commitMessage,
            string title,
            string description,
            bool forceCreate = false)
        {
            var upstream = UpstreamBranch.Project;

            using (var client = new GitHubClient(_auth))
            {
                GitHubBranch originBranch = null;
                GitHubPullRequest pullRequestToUpdate = null;

                string upgradeBranchPrefix = _namingStrategy.Prefix(UpstreamBranch.Name);

                if (!forceCreate)
                {
                    pullRequestToUpdate = await client.SearchPullRequestsAsync(
                        upstream,
                        upgradeBranchPrefix,
                        _auth.User);

                    if (pullRequestToUpdate == null)
                    {
                        Trace.TraceInformation($"No existing pull request found.");
                    }
                    else
                    {
                        Trace.TraceInformation(
                            $"Pull request already exists for {upgradeBranchPrefix} in {upstream.Segments}. " +
                            $"#{pullRequestToUpdate.Number}, '{pullRequestToUpdate.Title}'");

                        string blockedReason = GetUpdateBlockedReason(client, pullRequestToUpdate, upgradeBranchPrefix);

                        if (blockedReason == null)
                        {
                            originBranch = new GitHubBranch(
                                pullRequestToUpdate.Head.Ref,
                                Origin);
                        }
                        else
                        {
                            string comment =
                                $"Couldn't update this pull request: {blockedReason}\n" +
                                $"Would have applied '{commitMessage}'";

                            await client.PostCommentAsync(upstream, pullRequestToUpdate.Number, comment);
                            return;
                        }
                    }
                }

                // No existing branch to update: push to a new one.
                if (originBranch == null)
                {
                    string newBranchName =
                        _namingStrategy.Prefix(UpstreamBranch.Name) +
                        _namingStrategy.CreateFreshBranchNameSuffix(UpstreamBranch.Name);

                    originBranch = new GitHubBranch(newBranchName, Origin);
                }

                PushNewCommit(originBranch, commitMessage);

                if (pullRequestToUpdate != null)
                {
                    await client.UpdateGitHubPullRequestAsync(upstream, pullRequestToUpdate.Number, title, description);
                }
                else
                {
                    await client.PostGitHubPullRequestAsync(title, description, originBranch, UpstreamBranch);
                }
            }
        }
        private void PushNewCommit(GitHubBranch branch, string commitMessage)
        {
            Command.Git("commit", "-a", "-m", commitMessage, "--author", $"{GitAuthorName} <{_auth.Email}>")
                .EnvironmentVariable("GIT_COMMITTER_NAME", GitAuthorName)
                .EnvironmentVariable("GIT_COMMITTER_EMAIL", _auth.Email)
                .Execute()
                .EnsureSuccessful();

            string remoteUrl = $"github.com/{branch.Project.Segments}.git";
            string refSpec = $"HEAD:refs/heads/{branch.Name}";

            string logMessage = $"git push https://{remoteUrl} {refSpec}";
            Trace.TraceInformation($"EXEC {logMessage}");

            CommandResult pushResult =
                Command.Git("push", "--force", $"https://{_auth.User}:{_auth.AuthToken}@{remoteUrl}", refSpec)
                    .QuietBuildReporter()  // we don't want secrets showing up in our logs
                    .CaptureStdErr() // git push will write to StdErr upon success, disable that
                    .CaptureStdOut()
                    .Execute();

            var message = logMessage + $" exited with {pushResult.ExitCode}";
            if (pushResult.ExitCode == 0)
            {
                Trace.TraceInformation($"EXEC success: {message}");
            }
            else
            {
                Trace.TraceError($"EXEC failure: {message}");
            }

            pushResult.EnsureSuccessful(suppressOutput: true);
        }
        public async Task CreateOrUpdateAsync(
            string commitMessage,
            string title,
            string description,
            bool forceCreate = false)
        {
            var upstream = UpstreamBranch.Project;

            using (var client = new GitHubClient(_auth))
            {
                GitHubBranch      originBranch        = null;
                GitHubPullRequest pullRequestToUpdate = null;

                string upgradeBranchPrefix = _namingStrategy.Prefix(UpstreamBranch.Name);

                if (!forceCreate)
                {
                    pullRequestToUpdate = await client.SearchPullRequestsAsync(
                        upstream,
                        upgradeBranchPrefix,
                        _auth.User);

                    if (pullRequestToUpdate == null)
                    {
                        Trace.TraceInformation($"No existing pull request found.");
                    }
                    else
                    {
                        Trace.TraceInformation(
                            $"Pull request already exists for {upgradeBranchPrefix} in {upstream.Segments}. " +
                            $"#{pullRequestToUpdate.Number}, '{pullRequestToUpdate.Title}'");

                        string blockedReason = GetUpdateBlockedReason(client, pullRequestToUpdate, upgradeBranchPrefix);

                        if (blockedReason == null)
                        {
                            originBranch = new GitHubBranch(
                                pullRequestToUpdate.Head.Ref,
                                Origin);
                        }
                        else
                        {
                            string comment =
                                $"Couldn't update this pull request: {blockedReason}\n" +
                                $"Would have applied '{commitMessage}'";

                            await client.PostCommentAsync(upstream, pullRequestToUpdate.Number, comment);

                            return;
                        }
                    }
                }

                // No existing branch to update: push to a new one.
                if (originBranch == null)
                {
                    string newBranchName =
                        _namingStrategy.Prefix(UpstreamBranch.Name) +
                        _namingStrategy.CreateFreshBranchNameSuffix(UpstreamBranch.Name);

                    originBranch = new GitHubBranch(newBranchName, Origin);
                }

                PushNewCommit(originBranch, commitMessage);

                if (pullRequestToUpdate != null)
                {
                    await client.UpdateGitHubPullRequestAsync(upstream, pullRequestToUpdate.Number, title, description);
                }
                else
                {
                    await client.PostGitHubPullRequestAsync(title, description, originBranch, UpstreamBranch);
                }
            }
        }