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); }
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; } } } }
/// <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)); }
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); }
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"); }
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; }
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); } }
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); } } }