diff --git a/.gitignore b/.gitignore
index f834920dd1..9aed881a4b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,8 @@ _ReSharper.*
*.pidb
*.vspx
*.psess
+*.binlog
+*.log
packages
target
artifacts
diff --git a/build/RepositoryBuild.targets b/build/RepositoryBuild.targets
index 7a329f6dca..bef1c6b508 100644
--- a/build/RepositoryBuild.targets
+++ b/build/RepositoryBuild.targets
@@ -17,15 +17,29 @@
false
+
+
+
+
+
+
+
+ Properties="BuildGroup=%(BatchedRepository.BuildGroup);BuildNumber=$(BuildNumber);IsFinalBuild=$(IsFinalBuild);Configuration=$(Configuration)" />
-
+
$(RepositoryBuildArguments) /p:BuildNumber=$(BuildNumber) /p:Configuration=$(Configuration) /p:CommitHash=$(CommitHash)
@@ -68,16 +82,4 @@
-
-
-
-
-
-
-
-
-
diff --git a/build/repo.targets b/build/repo.targets
index 7d105c3107..ad9f7d7c7f 100644
--- a/build/repo.targets
+++ b/build/repo.targets
@@ -106,7 +106,7 @@
+ DependsOnTargets="_PrepareRepositories;_CreateRepositoriesListWithCommits;ComputeGraph;_BuildRepositories" />
-
-
-
-
-
-
-
-
$(BuildDir)$(_RepositoryListFileName)
diff --git a/build/tasks/AnalyzeBuildGraph.cs b/build/tasks/AnalyzeBuildGraph.cs
index c4f587cc75..2e9de07dd8 100644
--- a/build/tasks/AnalyzeBuildGraph.cs
+++ b/build/tasks/AnalyzeBuildGraph.cs
@@ -136,8 +136,8 @@ namespace RepoTasks
inconsistentVersions.Add(new VersionMismatch
{
- Solution = sln,
- Project = proj,
+ Solution = solution,
+ Project = project,
PackageId = dependency.Key,
ActualVersion = dependency.Value.Version,
ExpectedVersion = package.PackageInfo.Version,
diff --git a/build/tasks/GenerateLineup.cs b/build/tasks/GenerateLineup.cs
index 544284e409..1acbd7c577 100644
--- a/build/tasks/GenerateLineup.cs
+++ b/build/tasks/GenerateLineup.cs
@@ -25,6 +25,9 @@ namespace RepoTasks
// Can be set to filter the lists of packages when produce a list for a specific repository
public string Repository { get; set; }
+ // Items to add to the RestoreAdditionalProjectSources list in project
+ public ITaskItem[] RestoreAdditionalSources { get; set; }
+
public bool UseFloatingVersions { get; set; }
public string BuildNumber { get; set; }
@@ -40,25 +43,25 @@ namespace RepoTasks
}
var items = new XElement("ItemGroup");
- var root = new XElement("Project", items);
+ var props = new XElement("PropertyGroup");
+ var root = new XElement("Project", props, items);
var doc = new XDocument(root);
+ if (RestoreAdditionalSources.Length > 0)
+ {
+ var sources = RestoreAdditionalSources.Aggregate("$(RestoreAdditionalProjectSources)", (sum, piece) => sum + ";" + piece.ItemSpec);
+ props.Add(new XElement("RestoreAdditionalProjectSources", sources));
+ }
+
var packages = new List();
- foreach (var item in Artifacts)
+ foreach (var pkg in Artifacts.Select(ArtifactInfo.Parse)
+ .OfType()
+ .Where(p => !p.IsSymbolsArtifact
+ && (string.IsNullOrEmpty(Repository)
+ || !Repository.Equals(p.RepoName, StringComparison.OrdinalIgnoreCase))))
{
- var info = ArtifactInfo.Parse(item);
- switch (info)
- {
- case ArtifactInfo.Package pkg when (!pkg.IsSymbolsArtifact):
- // TODO filter this list based on topological sort info
- if (string.IsNullOrEmpty(Repository)
- || !Repository.Equals(pkg.RepoName, StringComparison.OrdinalIgnoreCase))
- {
- packages.Add(pkg.PackageInfo);
- }
- break;
- }
+ packages.Add(pkg.PackageInfo);
}
foreach (var pkg in packages.OrderBy(i => i.Id))
diff --git a/build/tasks/PinVersions.cs b/build/tasks/PinVersions.cs
deleted file mode 100644
index b98c878173..0000000000
--- a/build/tasks/PinVersions.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Linq;
-using Microsoft.Build.Framework;
-using RepoTasks.VersionPinning;
-
-namespace RepoTasks
-{
- public class PinVersions : Microsoft.Build.Utilities.Task
- {
- [Required]
- public string BuildRepositoryRoot { get; set; }
-
- [Required]
- public ITaskItem[] PackageSources { get; set; }
-
- public string GraphSpecsRoot { get; set; }
-
- public override bool Execute()
- {
- if (PackageSources?.Length == 0)
- {
- Log.LogError($"Missing PackageSources. At least one item source must be specified.");
- return false;
- }
-
- var graphSpecProvider = !string.IsNullOrEmpty(GraphSpecsRoot)
- ? new DependencyGraphSpecProvider(GraphSpecsRoot)
- : DependencyGraphSpecProvider.Default;
-
- using (graphSpecProvider)
- {
- var pinVersionUtility = new PinVersionUtility(
- BuildRepositoryRoot,
- PackageSources.Select(i => i.ItemSpec).ToList(),
- graphSpecProvider,
- Log);
- pinVersionUtility.Execute();
- }
-
- return true;
- }
- }
-}
diff --git a/build/tasks/VersionPinning/DependencyGraphSpecProvider.cs b/build/tasks/VersionPinning/DependencyGraphSpecProvider.cs
deleted file mode 100644
index 1a5e2af362..0000000000
--- a/build/tasks/VersionPinning/DependencyGraphSpecProvider.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using NuGet.ProjectModel;
-
-namespace RepoTasks.VersionPinning
-{
- public class DependencyGraphSpecProvider : IDisposable
- {
- private readonly string _packageSpecDirectory;
- private readonly bool _deleteSpecDirectoryOnDispose;
- private readonly string _dotnetPath;
-
- public DependencyGraphSpecProvider(string packageSpecDirectory)
- : this(packageSpecDirectory, deleteSpecDirectoryOnDispose: false)
- {
- }
-
- private DependencyGraphSpecProvider(string packageSpecDirectory, bool deleteSpecDirectoryOnDispose)
- {
- _packageSpecDirectory = packageSpecDirectory;
- _deleteSpecDirectoryOnDispose = deleteSpecDirectoryOnDispose;
- _dotnetPath = Process.GetCurrentProcess().MainModule.FileName;
- }
-
- public static DependencyGraphSpecProvider Default { get; } =
- new DependencyGraphSpecProvider(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()), deleteSpecDirectoryOnDispose: true);
-
- public DependencyGraphSpec GetDependencyGraphSpec(string repositoryName, string solutionPath)
- {
- var outputFile = Path.Combine(_packageSpecDirectory, repositoryName, Path.GetFileName(solutionPath) + ".json");
-
- if (!File.Exists(outputFile))
- {
- RunMSBuild(solutionPath, outputFile);
- }
-
- return DependencyGraphSpec.Load(outputFile);
- }
-
- private void RunMSBuild(string solutionPath, string outputFile)
- {
- var psi = new ProcessStartInfo(_dotnetPath);
-
- var arguments = new List
- {
- "msbuild",
- $"\"{solutionPath}\"",
- "/t:GenerateRestoreGraphFile",
- "/nologo",
- "/v:q",
- "/p:BuildProjectReferences=false",
- $"/p:RestoreGraphOutputPath=\"{outputFile}\"",
- "/p:KoreBuildRestoreTargetsImported=true",
- };
-
- psi.Arguments = string.Join(" ", arguments);
- psi.RedirectStandardOutput = true;
-
- var process = new Process
- {
- StartInfo = psi,
- EnableRaisingEvents = true,
- };
- process.OutputDataReceived += (sender, args) =>
- {
- if (!string.IsNullOrEmpty(args.Data))
- {
- Console.WriteLine(args.Data);
- }
- };
-
- using (process)
- {
- process.Start();
- process.BeginOutputReadLine();
-
- process.WaitForExit(60 * 5000);
- if (process.ExitCode != 0)
- {
- throw new Exception($"{psi.FileName} {psi.Arguments} failed. Exit code {process.ExitCode}.");
- }
- }
- }
-
- public void Dispose()
- {
- if (_deleteSpecDirectoryOnDispose)
- {
- Directory.Delete(_packageSpecDirectory, recursive: true);
- }
- }
- }
-}
diff --git a/build/tasks/VersionPinning/PinVersionUtility.cs b/build/tasks/VersionPinning/PinVersionUtility.cs
deleted file mode 100644
index c94e19fc62..0000000000
--- a/build/tasks/VersionPinning/PinVersionUtility.cs
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using Microsoft.Build.Framework;
-using Microsoft.Build.Utilities;
-using NuGet.Common;
-using NuGet.Frameworks;
-using NuGet.LibraryModel;
-using NuGet.ProjectModel;
-using NuGet.Protocol;
-using NuGet.Protocol.Core.Types;
-using NuGet.Versioning;
-
-namespace RepoTasks.VersionPinning
-{
- internal class PinVersionUtility
- {
- private readonly string _repositoryRoot;
- private readonly FindPackageByIdResource[] _findPackageResources;
- private readonly ConcurrentDictionary> _exactMatches = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase);
- private readonly DependencyGraphSpecProvider _provider;
- private readonly SourceCacheContext _sourceCacheContext;
- private readonly TaskLoggingHelper _logger;
-
- public PinVersionUtility(
- string repositoryRoot,
- List pinSources,
- DependencyGraphSpecProvider provider,
- TaskLoggingHelper logger)
- {
- _repositoryRoot = repositoryRoot;
- _findPackageResources = new FindPackageByIdResource[pinSources.Count];
- for (var i = 0; i < pinSources.Count; i++)
- {
- var repository = FactoryExtensionsV3.GetCoreV3(Repository.Factory, pinSources[i].Trim());
- _findPackageResources[i] = repository.GetResource();
- }
- _provider = provider;
- _sourceCacheContext = new SourceCacheContext();
- _logger = logger;
- }
-
- public void Execute()
- {
- _logger.LogMessage(MessageImportance.High, $"Pinning package references for projects in {_repositoryRoot}");
-
- var solutionPinMetadata = GetProjectPinVersionMetadata();
- foreach (var cliToolReference in solutionPinMetadata.CLIToolReferences)
- {
- _logger.LogMessage(MessageImportance.Normal, $"Pinning CLI Tool {cliToolReference.Item1.Name}({cliToolReference.Item1.VersionRange} to {cliToolReference.Item2} for all projects in {_repositoryRoot}.");
- }
-
- foreach (var item in solutionPinMetadata.PinVersionLookup)
- {
- var projectPinMetadata = item.Value;
- var specProject = projectPinMetadata.PackageSpec;
-
- if (!(projectPinMetadata.Packages.Any() || solutionPinMetadata.CLIToolReferences.Any()))
- {
- _logger.LogMessage(MessageImportance.Normal, $"No package or tool references to pin for {specProject.FilePath}.");
- continue;
- }
-
- var projectFileInfo = new FileInfo(specProject.FilePath);
- var pinnedReferencesFile = Path.Combine(
- specProject.RestoreMetadata.OutputPath,
- projectFileInfo.Name + ".pinnedversions.targets");
-
- Directory.CreateDirectory(Path.GetDirectoryName(pinnedReferencesFile));
-
- if (projectPinMetadata.Packages.Any())
- {
- _logger.LogMessage(MessageImportance.Normal, $"Pinning package versions for {specProject.FilePath}.");
- }
-
- var pinnedReferences = new XElement("ItemGroup", new XAttribute("Condition", "'$(PolicyDesignTimeBuild)' != 'true' AND !Exists('$(MSBuildThisFileDirectory)$(MSBuildProjectFile).nugetpolicy.g.targets')"));
- foreach (var packageReference in projectPinMetadata.Packages)
- {
- (var tfm, var libraryRange, var exactVersion) = packageReference;
- _logger.LogMessage(MessageImportance.Normal, $"Pinning reference {libraryRange.Name}({libraryRange.VersionRange} to {exactVersion}.");
- var metadata = new List
- {
- new XAttribute("Update", libraryRange.Name),
- new XAttribute("Version", exactVersion.ToNormalizedString()),
- };
-
- if (tfm != NuGetFramework.AnyFramework)
- {
- metadata.Add(new XAttribute("Condition", $"'$(TargetFramework)'=='{tfm.GetShortFolderName()}'"));
- }
-
- pinnedReferences.Add(new XElement("PackageReference", metadata));
- }
-
- // CLI Tool references are specified at solution level.
- foreach (var toolReference in solutionPinMetadata.CLIToolReferences)
- {
- (var libraryRange, var exactVersion) = toolReference;
- var metadata = new List
- {
- new XAttribute("Update", libraryRange.Name),
- new XAttribute("Version", exactVersion.ToNormalizedString()),
- };
-
- pinnedReferences.Add(new XElement("DotNetCliToolReference", metadata));
- }
-
- var pinnedVersionRoot = new XElement("Project", pinnedReferences);
- File.WriteAllText(pinnedReferencesFile, pinnedVersionRoot.ToString());
- }
- }
-
- private SolutionPinVersionMetadata GetProjectPinVersionMetadata()
- {
- var repositoryDirectoryInfo = new DirectoryInfo(_repositoryRoot);
- var projects = new Dictionary(StringComparer.OrdinalIgnoreCase);
- var cliToolReferences = new List<(LibraryRange, NuGetVersion)>();
-
- foreach (var slnFile in repositoryDirectoryInfo.EnumerateFiles("*.sln"))
- {
- var graphSpec = _provider.GetDependencyGraphSpec(repositoryDirectoryInfo.Name, slnFile.FullName);
- foreach (var specProject in graphSpec.Projects)
- {
- if (!projects.TryGetValue(specProject.FilePath, out var pinMetadata))
- {
- pinMetadata = new ProjectPinVersionMetadata(specProject);
- projects[specProject.FilePath] = pinMetadata;
- }
-
- var allDependencies = specProject.Dependencies.Select(dependency => new { Dependency = dependency, FrameworkName = NuGetFramework.AnyFramework })
- .Concat(specProject.TargetFrameworks.SelectMany(tfm => tfm.Dependencies.Select(dependency => new { Dependency = dependency, tfm.FrameworkName })))
- .Where(d => d.Dependency.LibraryRange.TypeConstraintAllows(LibraryDependencyTarget.Package));
-
- foreach (var dependency in allDependencies)
- {
- var reference = dependency.Dependency;
- var versionRange = reference.LibraryRange.VersionRange;
- if (!versionRange.IsFloating)
- {
- continue;
- }
-
- var exactVersion = GetExactVersion(reference.Name, versionRange);
- if (exactVersion == null)
- {
- continue;
- }
-
- var projectStyle = specProject.RestoreMetadata.ProjectStyle;
- if (projectStyle == ProjectStyle.PackageReference)
- {
- pinMetadata.Packages.Add((dependency.FrameworkName, reference.LibraryRange, exactVersion));
- }
- else if (projectStyle == ProjectStyle.DotnetCliTool)
- {
- cliToolReferences.Add((reference.LibraryRange, exactVersion));
- }
- else
- {
- throw new NotSupportedException($"Unknown project style '{projectStyle}'.");
- }
- }
- }
- }
-
- return new SolutionPinVersionMetadata(projects, cliToolReferences);
- }
-
- private NuGetVersion GetExactVersion(string name, VersionRange range)
- {
- if (range.MinVersion == null)
- {
- throw new Exception($"Unsupported version range {range}.");
- }
-
- if (!_exactMatches.TryGetValue(name, out var versionTask))
- {
- versionTask = _exactMatches.GetOrAdd(name, GetExactVersionAsync(name, range.MinVersion));
- }
-
- return versionTask.Result;
- }
-
- private async Task GetExactVersionAsync(string name, NuGetVersion floatingVersion)
- {
- foreach (var findPackageResource in _findPackageResources)
- {
- var packageVersions = await findPackageResource.GetAllVersionsAsync(name, _sourceCacheContext, NullLogger.Instance, default(CancellationToken));
-
- var matchingVersions = packageVersions.Where(v => v.Version == floatingVersion.Version).ToList();
- switch (matchingVersions.Count)
- {
- case 0:
- continue;
- case 1:
- return matchingVersions[0];
- default:
- throw new Exception($"More than one version for {name} found that matches the specified version constraint: {string.Join(" ", matchingVersions)}.");
- }
- }
-
- return null;
- }
-
- private struct SolutionPinVersionMetadata
- {
- public SolutionPinVersionMetadata(
- IDictionary pinVersionLookup,
- List<(LibraryRange, NuGetVersion)> cliToolReferences)
- {
- PinVersionLookup = pinVersionLookup;
- CLIToolReferences = cliToolReferences;
- }
-
- public IDictionary PinVersionLookup { get; }
-
- public List<(LibraryRange, NuGetVersion)> CLIToolReferences { get; }
- }
-
- private struct ProjectPinVersionMetadata
- {
- public ProjectPinVersionMetadata(PackageSpec packageSpec)
- {
- PackageSpec = packageSpec;
- Packages = new List<(NuGetFramework, LibraryRange, NuGetVersion)>();
- }
-
- public PackageSpec PackageSpec { get; }
-
- public List<(NuGetFramework, LibraryRange, NuGetVersion)> Packages { get; }
- }
- }
-}