public async Task <ActionResult <object> > UpdateAssetsAsync( Guid subscriptionId, int buildId, string sourceSha, List <Asset> assets) { (InProgressPullRequest pr, bool canUpdate) = await SynchronizeInProgressPullRequestAsync(); var updateParameter = new UpdateAssetsParameters { SubscriptionId = subscriptionId, BuildId = buildId, SourceSha = sourceSha, Assets = assets }; if (pr != null && !canUpdate) { await StateManager.AddOrUpdateStateAsync( PullRequestUpdate, new List <UpdateAssetsParameters> { updateParameter }, (n, old) => { old.Add(updateParameter); return(old); }); await Reminders.TryRegisterReminderAsync( PullRequestUpdate, Array.Empty <byte>(), TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); return(ActionResult.Create <object>( null, $"Current Pull request '{pr.Url}' cannot be updated, update queued.")); } if (pr != null) { await UpdatePullRequestAsync(pr, new List <UpdateAssetsParameters> { updateParameter }); return(ActionResult.Create <object>(null, $"Pull Request '{pr.Url}' updated.")); } string prUrl = await CreatePullRequestAsync(new List <UpdateAssetsParameters> { updateParameter }); if (prUrl == null) { return(ActionResult.Create <object>(null, "Updates require no changes, no pull request created.")); } return(ActionResult.Create <object>(null, $"Pull request '{prUrl}' created.")); }
public async Task UpdateAsync(int buildId) { await SynchronizeInProgressPRAsync(); Subscription subscription = await Context.Subscriptions.FindAsync(SubscriptionId); Build build = await Context.Builds.Include(b => b.Assets) .ThenInclude(a => a.Locations) .FirstAsync(b => b.Id == buildId); string targetRepository = subscription.TargetRepository; string targetBranch = subscription.TargetBranch; long installationId = await Context.GetInstallationId(subscription.TargetRepository); IRemote darc = await DarcFactory.CreateAsync(targetRepository, installationId); List <AssetData> assets = build.Assets.Select(a => new AssetData { Name = a.Name, Version = a.Version }) .ToList(); ConditionalValue <InProgressPullRequest> maybePr = await StateManager.TryGetStateAsync <InProgressPullRequest>(PullRequest); string prUrl; if (maybePr.HasValue) { InProgressPullRequest pr = maybePr.Value; await darc.UpdatePullRequestAsync(pr.Url, build.Commit, targetBranch, assets); prUrl = pr.Url; } else { prUrl = await darc.CreatePullRequestAsync(targetRepository, targetBranch, build.Commit, assets); } var newPr = new InProgressPullRequest { Url = prUrl, BuildId = build.Id }; await StateManager.SetStateAsync(PullRequest, newPr); await Reminders.TryRegisterReminderAsync( PullRequestCheck, Array.Empty <byte>(), new TimeSpan(0, 5, 0), new TimeSpan(0, 5, 0)); await StateManager.SaveStateAsync(); }
/// <summary> /// Creates a pull request from the given updates. /// </summary> /// <param name="updates"></param> /// <returns>The pull request url when a pr was created; <see langref="null" /> if no PR is necessary</returns> private async Task <string> CreatePullRequestAsync(List <UpdateAssetsParameters> updates) { (string targetRepository, string targetBranch) = await GetTargetAsync(); IRemote darc = await GetDarc(); List <(UpdateAssetsParameters update, List <DependencyDetail> deps)> requiredUpdates = await GetRequiredUpdates(updates, darc, targetRepository, targetBranch); if (requiredUpdates.Count < 1) { return(null); } string newBranchName = $"darc-{targetBranch}-{Guid.NewGuid()}"; await darc.CreateNewBranchAsync(targetRepository, targetBranch, newBranchName); using (var description = new StringWriter()) { description.WriteLine("This pull request updates the following dependencies"); description.WriteLine(); await CommitUpdatesAsync(requiredUpdates, description, darc, targetRepository, newBranchName); string prUrl = await darc.CreatePullRequestAsync( targetRepository, new PullRequest { Title = "Update dependency files", Description = description.ToString(), BaseBranch = targetBranch, HeadBranch = newBranchName }); var inProgressPr = new InProgressPullRequest { Url = prUrl, ContainedSubscriptions = requiredUpdates.Select( u => new SubscriptionPullRequestUpdate { SubscriptionId = u.update.SubscriptionId, BuildId = u.update.BuildId }) .ToList() }; await StateManager.SetStateAsync(PullRequest, inProgressPr); await StateManager.SaveStateAsync(); await Reminders.TryRegisterReminderAsync( PullRequestCheck, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); return(prUrl); } }
/// <summary> /// Creates a pull request from the given updates. /// </summary> /// <param name="updates"></param> /// <returns>The pull request url when a pr was created; <see langref="null" /> if no PR is necessary</returns> private async Task <string> CreatePullRequestAsync(List <UpdateAssetsParameters> updates) { (string targetRepository, string targetBranch) = await GetTargetAsync(); IRemote darcRemote = await DarcRemoteFactory.GetRemoteAsync(targetRepository, Logger); List <(UpdateAssetsParameters update, List <DependencyDetail> deps)> requiredUpdates = await GetRequiredUpdates(updates, DarcRemoteFactory, targetRepository, targetBranch); if (requiredUpdates.Count < 1) { return(null); } string newBranchName = $"darc-{targetBranch}-{Guid.NewGuid()}"; await darcRemote.CreateNewBranchAsync(targetRepository, targetBranch, newBranchName); try { using (var description = new StringWriter()) { description.WriteLine("This pull request updates the following dependencies"); description.WriteLine(); await CommitUpdatesAsync(requiredUpdates, description, darcRemote, targetRepository, newBranchName); var inProgressPr = new InProgressPullRequest { // Calculate the subscriptions contained within the // update. Coherency updates do not have subscription info. ContainedSubscriptions = requiredUpdates .Where(u => !u.update.IsCoherencyUpdate) .Select( u => new SubscriptionPullRequestUpdate { SubscriptionId = u.update.SubscriptionId, BuildId = u.update.BuildId }) .ToList() }; string prUrl = await darcRemote.CreatePullRequestAsync( targetRepository, new PullRequest { Title = await ComputePullRequestTitleAsync(inProgressPr, targetBranch), Description = description.ToString(), BaseBranch = targetBranch, HeadBranch = newBranchName }); if (!string.IsNullOrEmpty(prUrl)) { inProgressPr.Url = prUrl; await StateManager.SetStateAsync(PullRequest, inProgressPr); await StateManager.SaveStateAsync(); await Reminders.TryRegisterReminderAsync( PullRequestCheck, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5)); return(prUrl); } // Something wrong happened when trying to create the PR but didn't throw an exception (probably there was no diff). // We need to delete the branch also in this case. await darcRemote.DeleteBranchAsync(targetRepository, newBranchName); return(null); } } catch { await darcRemote.DeleteBranchAsync(targetRepository, newBranchName); throw; } }
private async Task <string> UpdateAsyncImpl(int buildId) { await SynchronizeInProgressPRAsync(); Subscription subscription = await Context.Subscriptions.FindAsync(SubscriptionId); Build build = await Context.Builds.Include(b => b.Assets) .ThenInclude(a => a.Locations) .FirstAsync(b => b.Id == buildId); string targetRepository = subscription.TargetRepository; string targetBranch = subscription.TargetBranch; long installationId = await Context.GetInstallationId(subscription.TargetRepository); IRemote darc = await DarcFactory.CreateAsync(targetRepository, installationId); List <AssetData> assets = build.Assets.Select(a => new AssetData { Name = a.Name, Version = a.Version }) .ToList(); string title = GetTitle(subscription, build); string description = GetDescription(subscription, build, assets); ConditionalValue <InProgressPullRequest> maybePr = await StateManager.TryGetStateAsync <InProgressPullRequest>(PullRequest); InProgressPullRequest pr; if (maybePr.HasValue) { pr = maybePr.Value; await darc.UpdatePullRequestAsync(pr.Url, build.Commit, targetBranch, assets, title, description); } else { string prUrl = await darc.CreatePullRequestAsync( targetRepository, targetBranch, build.Commit, assets, pullRequestTitle : title, pullRequestDescription : description); if (string.IsNullOrEmpty(prUrl)) { return($"No Pull request created. Darc Reports no dependencies need to be updated."); } pr = new InProgressPullRequest { Url = prUrl }; } pr.BuildId = build.Id; await StateManager.SetStateAsync(PullRequest, pr); await Reminders.TryRegisterReminderAsync( PullRequestCheck, Array.Empty <byte>(), new TimeSpan(0, 5, 0), new TimeSpan(0, 5, 0)); await StateManager.SaveStateAsync(); return($"Pull request '{pr.Url}' updated."); }