diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 1de34e4ce3..c464aa001e 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -9,7 +9,7 @@ ] }, "microsoft.dnceng.secretmanager": { - "version": "1.1.0-beta.23314.3", + "version": "1.1.0-beta.23328.1", "commands": [ "secret-manager" ] @@ -21,7 +21,7 @@ ] }, "microsoft.dnceng.configuration.bootstrap": { - "version": "1.1.0-beta.23314.3", + "version": "1.1.0-beta.23328.1", "commands": [ "bootstrap-dnceng-configuration" ] diff --git a/Directory.Packages.props b/Directory.Packages.props index ab11039e27..bef12652ed 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,7 +24,7 @@ - + diff --git a/azure-pipeline-weekly.yml b/azure-pipeline-weekly.yml index c16f2b1d0f..ccd1cac3f9 100644 --- a/azure-pipeline-weekly.yml +++ b/azure-pipeline-weekly.yml @@ -4,7 +4,7 @@ appendCommitMessageToRunName: false trigger: none schedules: -- cron: 0 12 * * 1 +- cron: 0 6 * * 1 displayName: Weekly Monday build branches: include: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c76565e8e0..aff98d3c99 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -38,7 +38,7 @@ stages: vmImage: windows-latest steps: - checkout: self - - powershell: eng/enforce-issue.ps1 -PullRequestNumber $(System.PullRequest.PullRequestNumber) + - powershell: eng/enforce-issue.ps1 -PullRequestNumber $(System.PullRequest.PullRequestNumber) -RepositoryName $(Build.Repository.Name) displayName: Enforce GitHub issue link presence - stage: build diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 93b6f64be4..3cf2ac30ed 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,13 +115,13 @@ https://github.com/dotnet/arcade 91616785a1a6578c83f7e93d98c34a1eb83d6223 - + https://github.com/dotnet/dnceng - 7aa26710c692db98889df5a7d33be28454e7fab4 + 98e5d1f8fb3b07fc4cacf0db83e1582aa2255246 - + https://github.com/dotnet/dnceng - 7aa26710c692db98889df5a7d33be28454e7fab4 + 98e5d1f8fb3b07fc4cacf0db83e1582aa2255246 diff --git a/eng/Versions.props b/eng/Versions.props index b68dbaf4a0..be954f022a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -37,8 +37,8 @@ 1.1.0-beta.23314.1 1.1.0-beta.23314.1 1.1.0-beta.23314.1 - 1.1.0-beta.23314.3 - 1.1.0-beta.23314.3 + 1.1.0-beta.23328.1 + 1.1.0-beta.23328.1 diff --git a/eng/enforce-issue.ps1 b/eng/enforce-issue.ps1 index feef180f3b..635cab8b4c 100644 --- a/eng/enforce-issue.ps1 +++ b/eng/enforce-issue.ps1 @@ -1,13 +1,19 @@ [CmdletBinding()] param ( [Parameter(Mandatory = $True)] - $PullRequestNumber + $PullRequestNumber, + [Parameter(Mandatory = $True)] + $RepositoryName ) +function HasReleaseNotes($description) { + return $description -Match "### Release Note Description(?:\r?\n)+([^\s]+)" +} + $prDetail = Invoke-WebRequest ` - -UseBasicParsing ` - -Uri "https://api.github.com/repos/dotnet/arcade-services/pulls/$PullRequestNumber" ` -| ConvertFrom-Json + -UseBasicParsing ` + -Uri "https://api.github.com/repos/$RepositoryName/pulls/$PullRequestNumber" ` + | ConvertFrom-Json if ($prDetail.draft) { Write-Host "Draft PR does not have to have GitHub issue specified. Check passed." @@ -28,6 +34,12 @@ if (-not $hasIssue) { exit 1 } +if (HasReleaseNotes $prDetail.body) { + Write-Host "PR has release notes in the description. Check passed." + exit 0 +} + + try { $issueDetail = Invoke-WebRequest ` -UseBasicParsing ` @@ -39,16 +51,18 @@ catch { exit 1 } -$issueHasReleaseNotes = $issueDetail.body -Match "### Release Note Description(?:\r?\n)+([^\s]+)" -$issueIsAzdoMirror = $issueDetail.title -like "AzDO Issue*" -if (-not $issueHasReleaseNotes -and -not $issueIsAzdoMirror) { - Write-Host "##vso[task.LogIssue type=error;]Linked GitHub issue does not have release notes. Check failed." - Write-Host "Ensure your issue has release notes. They should be in the following format:`n`n### Release Note Description`n`n" - Write-Host "For more information, see https://dev.azure.com/dnceng/internal/_wiki/wikis/DNCEng%20Services%20Wiki/983/ReleaseNotesGuidance?anchor=mechanics" - exit 1 +if (HasReleaseNotes $issueDetail.body) { + Write-Host "PR links a GitHub issue with release notes. Check passed." + exit 0 } -elseif ($issueIsAzdoMirror) { + +$issueIsAzdoMirror = $issueDetail.title -like "AzDO Issue*" +if ($issueIsAzdoMirror) { Write-Host "##vso[task.LogIssue type=warning;]Linked GitHub issue is a mirrored Azure DevOps workitem. Please ensure the workitem has release notes in it." + exit 0 } -Write-Host "PR links a GitHub issue. Check passed." \ No newline at end of file +Write-Host "##vso[task.LogIssue type=error;]Linked GitHub issue does not have release notes. Check failed." +Write-Host "Ensure your issue has release notes. They should be in the following format:`n`n### Release Note Description`n`n" +Write-Host "For more information, see https://dev.azure.com/dnceng/internal/_wiki/wikis/DNCEng%20Services%20Wiki/983/ReleaseNotesGuidance?anchor=mechanics" +exit 1 diff --git a/src/Maestro/Maestro.DataProviders/SharedKustoQueries.cs b/src/Maestro/Maestro.DataProviders/SharedKustoQueries.cs index c34ff13a55..9d36233374 100644 --- a/src/Maestro/Maestro.DataProviders/SharedKustoQueries.cs +++ b/src/Maestro/Maestro.DataProviders/SharedKustoQueries.cs @@ -27,7 +27,7 @@ public static MultiProjectKustoQuery CreateBuildTimesQueries( Uri uri = new Uri(repository); - // Builds in AzDo are only found in the internal project + // Builds in AzDo are only found in the internal project. if (uri.Host == "dev.azure.com") { prProject = "internal"; @@ -35,11 +35,13 @@ public static MultiProjectKustoQuery CreateBuildTimesQueries( // We only care about builds that complete successfully or partially successfully // from the given repository. We summarize duration of the builds over the last specified - // number of days. There are multiple different definitions that run in parallel, so we + // number of days. + string commonQueryFilters = @"| where FinishTime > ago(_Days) + | where Result !in('failed', 'canceled')"; + + // There are multiple different definitions that run in parallel, so we // summarize on the definition id and ultimately choose the definition that took the longest. - string commonQueryText = @"| where Result != 'failed' and Result != 'canceled' - | where FinishTime > ago(_Days) - | extend duration = FinishTime - StartTime + string postFilteringOperatorsQueryText = @"| extend duration = FinishTime - StartTime | summarize average_duration = avg(duration) by DefinitionId"; // We only want the pull request time from the public ci. We exclude on target branch, @@ -47,17 +49,19 @@ public static MultiProjectKustoQuery CreateBuildTimesQueries( // apply to. string publicQueryText = $@"TimelineBuilds | project Repository, SourceBranch, TargetBranch, DefinitionId, StartTime, FinishTime, Result, Project, Reason + {commonQueryFilters} | where Project == '{prProject}' | where Repository endswith _Repository | where Reason == 'pullRequest' | where TargetBranch == _SourceBranch - {commonQueryText}"; + {postFilteringOperatorsQueryText}"; // For the official build times, we want the builds that were generated as a CI run // (either batchedCI or individualCI) for a specific branch--i.e. we want the builds // that are part of generating the product. string internalQueryText = $@"TimelineBuilds | project Repository, SourceBranch, DefinitionId, StartTime, FinishTime, Result, Project, Reason + {commonQueryFilters} | where Project == 'internal' | where Repository endswith _Repository | where Reason == 'batchedCI' or Reason == 'individualCI' or Reason == 'manual' @@ -77,7 +81,7 @@ public static MultiProjectKustoQuery CreateBuildTimesQueries( } internalQueryText += $@" - {commonQueryText}"; + {postFilteringOperatorsQueryText}"; return new MultiProjectKustoQuery(new KustoQuery(internalQueryText, parameters), new KustoQuery(publicQueryText, parameters)); } diff --git a/src/Microsoft.DotNet.Darc/Darc/Operations/GetAssetOperation.cs b/src/Microsoft.DotNet.Darc/Darc/Operations/GetAssetOperation.cs index 9667ee4ee1..acaac32594 100644 --- a/src/Microsoft.DotNet.Darc/Darc/Operations/GetAssetOperation.cs +++ b/src/Microsoft.DotNet.Darc/Darc/Operations/GetAssetOperation.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace Microsoft.DotNet.Darc.Operations; @@ -46,16 +47,31 @@ public override async Task ExecuteAsync() // Starting with the remote, get information on the asset name + version List matchingAssets = - (await remote.GetAssetsAsync(name: _options.Name, version: _options.Version)).ToList(); + (await remote.GetAssetsAsync(name: _options.Name, version: _options.Version, buildId: _options.Build)).ToList(); - string queryDescriptionString = - $"name '{_options.Name}'{(!string.IsNullOrEmpty(_options.Version) ? $" and version '{_options.Version}'" : "")}" + - $"{(targetChannel != null ? $" on channel '{targetChannel.Name}'" : "")} in the last {_options.MaxAgeInDays} days"; + var queryDescription = new StringBuilder($"name '{_options.Name}'"); + + if (!string.IsNullOrEmpty(_options.Version)) + { + queryDescription.Append($" and version '{_options.Version}'"); + } + + if (targetChannel != null) + { + queryDescription.Append($" on channel '{targetChannel.Name}'"); + } + + if (_options.Build != null) + { + queryDescription.Append($" from build '{_options.Build}'"); + } + + queryDescription.Append($" in the last {_options.MaxAgeInDays} days"); // Only print the lookup string if the output type is text. if (_options.OutputFormat == DarcOutputType.text) { - Console.WriteLine($"Looking up assets with {queryDescriptionString}"); + Console.WriteLine($"Looking up assets with {queryDescription}"); } // Walk the assets and look up the corresponding builds, potentially filtering based on channel @@ -88,7 +104,7 @@ public override async Task ExecuteAsync() if (!matchingAssetsAfterDate.Any()) { - Console.WriteLine($"No assets found with {queryDescriptionString}"); + Console.WriteLine($"No assets found with {queryDescription}"); int remaining = matchingAssets.Count - checkedAssets; if (remaining > 0) { diff --git a/src/Microsoft.DotNet.Darc/Darc/Options/GetAssetCommandLineOptions.cs b/src/Microsoft.DotNet.Darc/Darc/Options/GetAssetCommandLineOptions.cs index 945d16353e..821305e54d 100644 --- a/src/Microsoft.DotNet.Darc/Darc/Options/GetAssetCommandLineOptions.cs +++ b/src/Microsoft.DotNet.Darc/Darc/Options/GetAssetCommandLineOptions.cs @@ -3,8 +3,6 @@ using CommandLine; using Microsoft.DotNet.Darc.Operations; -using Microsoft.DotNet.DarcLib; -using System.Collections.Generic; namespace Microsoft.DotNet.Darc.Options; @@ -20,6 +18,9 @@ internal class GetAssetCommandLineOptions : CommandLineOptions [Option("channel", HelpText = "Look up the asset produced from builds applied to this channel.")] public string Channel { get; set; } + [Option("build", HelpText = "If specified, scopes the search to a specific BAR build ID")] + public int? Build { get; set; } + [Option("max-age", Default = 30, HelpText = "Show builds with a max age of this many days.")] public int MaxAgeInDays { get; set; } diff --git a/src/Microsoft.DotNet.Darc/DarcLib/Actions/Remote.cs b/src/Microsoft.DotNet.Darc/DarcLib/Actions/Remote.cs index 0061bf2557..1d480fa1bc 100644 --- a/src/Microsoft.DotNet.Darc/DarcLib/Actions/Remote.cs +++ b/src/Microsoft.DotNet.Darc/DarcLib/Actions/Remote.cs @@ -1486,9 +1486,10 @@ public async Task GetToolsDotnetVersionAsync(string repoUri, st /// Async task public async Task AddAssetLocationToDependenciesAsync(IEnumerable dependencies) { + var buildCache = new Dictionary(); + foreach (var dependency in dependencies) { - Dictionary buildCache = new Dictionary(); IEnumerable matchingAssets = await GetAssetsAsync(dependency.Name, dependency.Version); List matchingAssetsFromSameSha = new List(); diff --git a/src/Microsoft.DotNet.Darc/DarcLib/IRemote.cs b/src/Microsoft.DotNet.Darc/DarcLib/IRemote.cs index 71c97dfdf6..fdebe3d4f7 100644 --- a/src/Microsoft.DotNet.Darc/DarcLib/IRemote.cs +++ b/src/Microsoft.DotNet.Darc/DarcLib/IRemote.cs @@ -471,7 +471,11 @@ Task GetDependencyFlowGraphAsync( /// ID of build producing the asset /// Only non-shipping /// List of assets. - Task> GetAssetsAsync(string name = null, string version = null, int? buildId = null, bool? nonShipping = null); + Task> GetAssetsAsync( + string name = null, + string version = null, + int? buildId = null, + bool? nonShipping = null); /// /// Update a list of dependencies with asset locations.