public void ShouldReturnCalculateCorrectPRDescriptionWhenUpdatingExistingPR() { PullRequestDescriptionBuilder pullRequestDescriptionBuilder = new PullRequestDescriptionBuilder(new NullLoggerFactory(), ""); UpdateAssetsParameters update1 = CreateUpdateAssetsParameters(false, "11111111-1111-1111-1111-111111111111"); UpdateAssetsParameters update2 = CreateUpdateAssetsParameters(false, "22222222-2222-2222-2222-222222222222"); UpdateAssetsParameters update3 = CreateUpdateAssetsParameters(false, "33333333-3333-3333-3333-333333333333"); List <DependencyUpdate> deps1 = CreateDependencyUpdates('a'); List <DependencyUpdate> deps2 = CreateDependencyUpdates('b'); List <DependencyUpdate> deps3 = CreateDependencyUpdates('c'); Build build = GivenANewBuild(true); pullRequestDescriptionBuilder.AppendBuildDescription(update1, deps1, null, build); pullRequestDescriptionBuilder.AppendBuildDescription(update2, deps2, null, build); pullRequestDescriptionBuilder.AppendBuildDescription(update3, deps3, null, build); String description = pullRequestDescriptionBuilder.ToString(); description.Should().Contain(BuildCorrectPRDescriptionWhenCoherencyUpdate(deps1, 1)); description.Should().Contain(BuildCorrectPRDescriptionWhenCoherencyUpdate(deps2, 3)); description.Should().Contain(BuildCorrectPRDescriptionWhenCoherencyUpdate(deps3, 5)); List <DependencyUpdate> deps22 = CreateDependencyUpdates('d'); pullRequestDescriptionBuilder.AppendBuildDescription(update2, deps22, null, build); description = pullRequestDescriptionBuilder.ToString(); description.Should().Contain(BuildCorrectPRDescriptionWhenCoherencyUpdate(deps1, 1)); description.Should().Contain(BuildCorrectPRDescriptionWhenCoherencyUpdate(deps3, 5)); description.Should().NotContain(BuildCorrectPRDescriptionWhenCoherencyUpdate(deps2, 3)); description.Should().Contain(BuildCorrectPRDescriptionWhenCoherencyUpdate(deps22, 7)); }
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 void ShouldReturnCalculateCorrectPRDescriptionWhenNonCoherencyUpdate() { PullRequestDescriptionBuilder pullRequestDescriptionBuilder = new PullRequestDescriptionBuilder(new NullLoggerFactory(), ""); UpdateAssetsParameters update = CreateUpdateAssetsParameters(true, "11111111-1111-1111-1111-111111111111"); List <DependencyUpdate> deps = CreateDependencyUpdates('a'); pullRequestDescriptionBuilder.AppendBuildDescription(update, deps, null, null); pullRequestDescriptionBuilder.ToString().Should().Contain(BuildCorrectPRDescriptionWhenNonCoherencyUpdate(deps)); }
/// <summary> /// Append build description to the PR description /// </summary> /// <param name="update">Update</param> /// <param name="deps">Dependencies updated</param> /// <param name="committedFiles">List of commited files</param> /// <param name="build">Build</param> /// <returns>Task</returns> /// <remarks> /// Because PRs tend to be live for short periods of time, we can put more information /// in the description than the commit message without worrying that links will go stale. /// </remarks> public void AppendBuildDescription(UpdateAssetsParameters update, List <DependencyUpdate> deps, List <GitFile> committedFiles, Build build) { var changesLinks = new List <string>(); //Find the Coherency section of the PR description if (update.IsCoherencyUpdate) { string sectionStartMarker = $"[marker]: <> (Begin:Coherency Updates)"; string sectionEndMarker = $"[marker]: <> (End:Coherency Updates)"; int sectionStartIndex = RemovePRDescriptionSection(sectionStartMarker, sectionEndMarker); var coherencySection = new StringBuilder(); coherencySection.AppendLine(sectionStartMarker); coherencySection.AppendLine("## Coherency Updates"); coherencySection.AppendLine(); coherencySection.AppendLine("The following updates ensure that dependencies with a *CoherentParentDependency*"); coherencySection.AppendLine("attribute were produced in a build used as input to the parent dependency's build."); coherencySection.AppendLine("See [Dependency Description Format](https://github.com/dotnet/arcade/blob/master/Documentation/DependencyDescriptionFormat.md#dependency-description-overview)"); coherencySection.AppendLine(); coherencySection.AppendLine(DependencyUpdateBegin); coherencySection.AppendLine(); coherencySection.AppendLine("- **Coherency Updates**:"); foreach (DependencyUpdate dep in deps) { coherencySection.AppendLine($" - **{dep.To.Name}**: from {dep.From.Version} to {dep.To.Version} (parent: {dep.To.CoherentParentDependencyName})"); } coherencySection.AppendLine(); coherencySection.AppendLine(DependencyUpdateEnd); coherencySection.AppendLine(); coherencySection.AppendLine(sectionEndMarker); _description.Insert(sectionStartIndex, coherencySection.ToString()); } else { string sourceRepository = update.SourceRepo; Guid updateSubscriptionId = update.SubscriptionId; string sectionStartMarker = $"[marker]: <> (Begin:{updateSubscriptionId})"; string sectionEndMarker = $"[marker]: <> (End:{updateSubscriptionId})"; int sectionStartIndex = RemovePRDescriptionSection(sectionStartMarker, sectionEndMarker); var subscriptionSection = new StringBuilder(); subscriptionSection.AppendLine(sectionStartMarker); subscriptionSection.AppendLine($"## From {sourceRepository}"); subscriptionSection.AppendLine($"- **Subscription**: {updateSubscriptionId}"); subscriptionSection.AppendLine($"- **Build**: {build.AzureDevOpsBuildNumber}"); subscriptionSection.AppendLine($"- **Date Produced**: {build.DateProduced.ToUniversalTime():MMMM d, yyyy h:mm:ss tt UTC}"); // This is duplicated from the files changed, but is easier to read here. subscriptionSection.AppendLine($"- **Commit**: {build.Commit}"); string branch = build.AzureDevOpsBranch ?? build.GitHubBranch; if (!string.IsNullOrEmpty(branch)) { subscriptionSection.AppendLine($"- **Branch**: {branch}"); } subscriptionSection.AppendLine(); subscriptionSection.AppendLine(DependencyUpdateBegin); subscriptionSection.AppendLine(); subscriptionSection.AppendLine($"- **Updates**:"); var shaRangeToLinkId = new Dictionary <(string from, string to), int>(); foreach (DependencyUpdate dep in deps) { if (!shaRangeToLinkId.ContainsKey((dep.From.Commit, dep.To.Commit))) { string changesUri = string.Empty; try { changesUri = GetChangesURI(dep.To.RepoUri, dep.From.Commit, dep.To.Commit); } catch (ArgumentNullException e) { _logger.LogError(e, $"Failed to create SHA comparison link for dependency {dep.To.Name} during asset update for subscription {update.SubscriptionId}"); } shaRangeToLinkId.Add((dep.From.Commit, dep.To.Commit), _startingReferenceId + changesLinks.Count); changesLinks.Add(changesUri); } subscriptionSection.AppendLine($" - **{dep.To.Name}**: [from {dep.From.Version} to {dep.To.Version}][{shaRangeToLinkId[(dep.From.Commit, dep.To.Commit)]}]");