public async Task <GitFileContentContainer> UpdateDependencyFiles( IEnumerable <DependencyDetail> itemsToUpdate, string repoUri, string branch) { XmlDocument versionDetails = await ReadVersionDetailsXmlAsync(repoUri, branch); XmlDocument versionProps = await ReadVersionPropsAsync(repoUri, branch); JObject globalJson = await ReadGlobalJsonAsync(repoUri, branch); foreach (DependencyDetail itemToUpdate in itemsToUpdate) { // Use a case-insensitive update. XmlNodeList versionList = versionDetails.SelectNodes($"//Dependency[translate(@Name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'," + $"'abcdefghijklmnopqrstuvwxyz')='{itemToUpdate.Name.ToLower()}']"); if (versionList.Count != 1) { if (versionList.Count == 0) { throw new DependencyException($"No dependencies named '{itemToUpdate.Name}' found."); } else { throw new DarcException("The use of the same asset, even with a different version, is currently not " + "supported."); } } XmlNode nodeToUpdate = versionList.Item(0); nodeToUpdate.Attributes["Version"].Value = itemToUpdate.Version; nodeToUpdate.Attributes["Name"].Value = itemToUpdate.Name; nodeToUpdate.SelectSingleNode("Sha").InnerText = itemToUpdate.Commit; nodeToUpdate.SelectSingleNode("Uri").InnerText = itemToUpdate.RepoUri; UpdateVersionFiles(versionProps, globalJson, itemToUpdate); } var fileContainer = new GitFileContentContainer { GlobalJson = new GitFile(VersionFiles.GlobalJson, globalJson), VersionDetailsXml = new GitFile(VersionFiles.VersionDetailsXml, versionDetails), VersionProps = new GitFile(VersionFiles.VersionProps, versionProps) }; return(fileContainer); }
public async Task <GitFileContentContainer> UpdateDependencyFiles(IEnumerable <DependencyDetail> itemsToUpdate, string repoUri, string branch) { XmlDocument versionDetails = await ReadVersionDetailsXmlAsync(repoUri, branch); XmlDocument versionProps = await ReadVersionPropsAsync(repoUri, branch); JObject globalJson = await ReadGlobalJsonAsync(repoUri, branch); foreach (DependencyDetail itemToUpdate in itemsToUpdate) { XmlNodeList versionList = versionDetails.SelectNodes($"//Dependency[@Name='{itemToUpdate.Name}']"); if (versionList.Count != 1) { if (versionList.Count == 0) { _logger.LogError($"No dependencies named '{itemToUpdate.Name}' found."); } else { _logger.LogError("The use of the same asset, even with a different version, is currently not supported."); } return(null); } XmlNode nodeToUpdate = versionDetails.DocumentElement.SelectSingleNode($"//Dependency[@Name='{itemToUpdate.Name}']"); nodeToUpdate.Attributes["Version"].Value = itemToUpdate.Version; nodeToUpdate.SelectSingleNode("Sha").InnerText = itemToUpdate.Commit; nodeToUpdate.SelectSingleNode("Uri").InnerText = itemToUpdate.RepoUri; UpdateVersionFiles(versionProps, globalJson, itemToUpdate); } GitFileContentContainer fileContainer = new GitFileContentContainer { GlobalJson = new GitFile(VersionFilePath.GlobalJson, globalJson), VersionDetailsXml = new GitFile(VersionFilePath.VersionDetailsXml, versionDetails), VersionProps = new GitFile(VersionFilePath.VersionProps, versionProps) }; return(fileContainer); }
private async Task CommitFilesForPullRequestAsync(string repoUri, string branch, string assetsProducedInCommit, IEnumerable <DependencyDetail> itemsToUpdate, string pullRequestBaseBranch = null) { CheckForValidGitClient(); GitFileContentContainer fileContainer = await _fileManager.UpdateDependencyFiles(itemsToUpdate, repoUri, branch); List <GitFile> filesToCommit = fileContainer.GetFilesToCommitMap(pullRequestBaseBranch); // If there is an arcade asset that we need to update we try to update the script files as well DependencyDetail arcadeItem = itemsToUpdate.Where(i => i.Name.ToLower().Contains("arcade")).FirstOrDefault(); if (arcadeItem != null && repoUri != arcadeItem.RepoUri) { List <GitFile> engCommonsFiles = await GetScriptFilesAsync(arcadeItem.RepoUri, assetsProducedInCommit); filesToCommit.AddRange(engCommonsFiles); } await _gitClient.PushFilesAsync(filesToCommit, repoUri, pullRequestBaseBranch, "Updating version files"); }
public async Task CommitUpdatesAsync( string repoUri, string branch, List <DependencyDetail> itemsToUpdate, string message) { CheckForValidGitClient(); GitFileContentContainer fileContainer = await _fileManager.UpdateDependencyFiles(itemsToUpdate, repoUri, branch); List <GitFile> filesToCommit = fileContainer.GetFilesToCommit(); // If we are updating the arcade sdk we need to update the eng/common files as well DependencyDetail arcadeItem = itemsToUpdate.FirstOrDefault( i => string.Equals(i.Name, "Microsoft.DotNet.Arcade.Sdk", StringComparison.OrdinalIgnoreCase)); if (arcadeItem != null && repoUri != arcadeItem.RepoUri) { // Files in arcade repository List <GitFile> engCommonFiles = await GetCommonScriptFilesAsync(arcadeItem.RepoUri, arcadeItem.Commit); filesToCommit.AddRange(engCommonFiles); // Files in the target repo string latestCommit = await _gitClient.GetLastCommitShaAsync(_gitClient.GetOwnerAndRepoFromRepoUri(repoUri), branch); List <GitFile> targetEngCommonFiles = await GetCommonScriptFilesAsync(repoUri, latestCommit); foreach (GitFile file in targetEngCommonFiles) { if (!engCommonFiles.Where(f => f.FilePath == file.FilePath).Any()) { file.Operation = GitFileOperation.Delete; filesToCommit.Add(file); } } } await _gitClient.PushFilesAsync(filesToCommit, repoUri, branch, message); }
public async Task CommitUpdatesAsync( string repoUri, string branch, List <DependencyDetail> itemsToUpdate, string message) { CheckForValidGitClient(); GitFileContentContainer fileContainer = await _fileManager.UpdateDependencyFiles(itemsToUpdate, repoUri, branch); List <GitFile> filesToCommit = new List <GitFile>(); // If we are updating the arcade sdk we need to update the eng/common files and the dotnet versions as well DependencyDetail arcadeItem = itemsToUpdate.FirstOrDefault( i => string.Equals(i.Name, "Microsoft.DotNet.Arcade.Sdk", StringComparison.OrdinalIgnoreCase)); if (arcadeItem != null && repoUri != arcadeItem.RepoUri) { // Files in arcade repository. All Arcade items have a GitHub repo URI by default so we need to change the // URI from we are getting the eng/common files. If in an AzDO context we change the URI to that of // dotnet-arcade in dnceng string arcadeRepoUri = arcadeItem.RepoUri; if (Uri.TryCreate(repoUri, UriKind.Absolute, out Uri parsedUri)) { if (parsedUri.Host == "dev.azure.com" || parsedUri.Host.EndsWith("visualstudio.com")) { arcadeRepoUri = "https://dev.azure.com/dnceng/internal/_git/dotnet-arcade"; } } SemanticVersion arcadeDotnetVersion = await GetToolsDotnetVersionAsync(arcadeRepoUri, arcadeItem.Commit); if (arcadeDotnetVersion != null) { fileContainer.GlobalJson = UpdateDotnetVersionGlobalJson(arcadeDotnetVersion, fileContainer.GlobalJson); } List <GitFile> engCommonFiles = await GetCommonScriptFilesAsync(arcadeRepoUri, arcadeItem.Commit); filesToCommit.AddRange(engCommonFiles); // Files in the target repo string latestCommit = await _gitClient.GetLastCommitShaAsync(repoUri, branch); List <GitFile> targetEngCommonFiles = await GetCommonScriptFilesAsync(repoUri, latestCommit); foreach (GitFile file in targetEngCommonFiles) { if (!engCommonFiles.Where(f => f.FilePath == file.FilePath).Any()) { file.Operation = GitFileOperation.Delete; filesToCommit.Add(file); } } } filesToCommit.AddRange(fileContainer.GetFilesToCommit()); await _gitClient.CommitFilesAsync(filesToCommit, repoUri, branch, message); }
public async Task <GitFileContentContainer> UpdateDependencyFiles( IEnumerable <DependencyDetail> itemsToUpdate, string repoUri, string branch) { XmlDocument versionDetails = await ReadVersionDetailsXmlAsync(repoUri, branch); XmlDocument versionProps = await ReadVersionPropsAsync(repoUri, branch); JObject globalJson = await ReadGlobalJsonAsync(repoUri, branch); foreach (DependencyDetail itemToUpdate in itemsToUpdate) { if (string.IsNullOrEmpty(itemToUpdate.Version) || string.IsNullOrEmpty(itemToUpdate.Name) || string.IsNullOrEmpty(itemToUpdate.Commit) || string.IsNullOrEmpty(itemToUpdate.RepoUri)) { throw new DarcException("Either the name, version, commit or repo uri of a dependency in " + $"repo '{repoUri}' and branch '{branch}' was empty."); } // Double check that the dependency is not pinned if (itemToUpdate.Pinned) { throw new DarcException($"An attempt to update pinned dependency '{itemToUpdate.Name}' was made"); } // Use a case-insensitive update. XmlNodeList versionList = versionDetails.SelectNodes($"//{VersionFiles.DependencyElementName}[translate(@Name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'," + $"'abcdefghijklmnopqrstuvwxyz')='{itemToUpdate.Name.ToLower()}']"); if (versionList.Count != 1) { if (versionList.Count == 0) { throw new DependencyException($"No dependencies named '{itemToUpdate.Name}' found."); } else { throw new DarcException("The use of the same asset, even with a different version, is currently not " + "supported."); } } XmlNode nodeToUpdate = versionList.Item(0); SetAttribute(versionDetails, nodeToUpdate, VersionFiles.VersionAttributeName, itemToUpdate.Version); SetAttribute(versionDetails, nodeToUpdate, VersionFiles.NameAttributeName, itemToUpdate.Name); SetElement(versionDetails, nodeToUpdate, VersionFiles.ShaElementName, itemToUpdate.Commit); SetElement(versionDetails, nodeToUpdate, VersionFiles.UriElementName, itemToUpdate.RepoUri); UpdateVersionFiles(versionProps, globalJson, itemToUpdate); } var fileContainer = new GitFileContentContainer { GlobalJson = new GitFile(VersionFiles.GlobalJson, globalJson), VersionDetailsXml = new GitFile(VersionFiles.VersionDetailsXml, versionDetails), VersionProps = new GitFile(VersionFiles.VersionProps, versionProps) }; return(fileContainer); }
public async Task <GitFileContentContainer> UpdateDependencyFiles( IEnumerable <DependencyDetail> itemsToUpdate, string repoUri, string branch, IEnumerable <DependencyDetail> oldDependencies = null) { XmlDocument versionDetails = await ReadVersionDetailsXmlAsync(repoUri, branch); XmlDocument versionProps = await ReadVersionPropsAsync(repoUri, branch); JObject globalJson = await ReadGlobalJsonAsync(repoUri, branch); XmlDocument nugetConfig = await ReadNugetConfigAsync(repoUri, branch); foreach (DependencyDetail itemToUpdate in itemsToUpdate) { if (string.IsNullOrEmpty(itemToUpdate.Version) || string.IsNullOrEmpty(itemToUpdate.Name) || string.IsNullOrEmpty(itemToUpdate.Commit) || string.IsNullOrEmpty(itemToUpdate.RepoUri)) { throw new DarcException("Either the name, version, commit or repo uri of a dependency in " + $"repo '{repoUri}' and branch '{branch}' was empty."); } // Double check that the dependency is not pinned if (itemToUpdate.Pinned) { throw new DarcException($"An attempt to update pinned dependency '{itemToUpdate.Name}' was made"); } // Use a case-insensitive update. XmlNodeList versionList = versionDetails.SelectNodes($"//{VersionFiles.DependencyElementName}[translate(@Name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'," + $"'abcdefghijklmnopqrstuvwxyz')='{itemToUpdate.Name.ToLower()}']"); if (versionList.Count != 1) { if (versionList.Count == 0) { throw new DependencyException($"No dependencies named '{itemToUpdate.Name}' found."); } else { throw new DarcException($"The use of the same asset '{itemToUpdate.Name}', even with a different version, is currently not " + "supported."); } } XmlNode nodeToUpdate = versionList.Item(0); SetAttribute(versionDetails, nodeToUpdate, VersionFiles.VersionAttributeName, itemToUpdate.Version); SetAttribute(versionDetails, nodeToUpdate, VersionFiles.NameAttributeName, itemToUpdate.Name); SetElement(versionDetails, nodeToUpdate, VersionFiles.ShaElementName, itemToUpdate.Commit); SetElement(versionDetails, nodeToUpdate, VersionFiles.UriElementName, itemToUpdate.RepoUri); UpdateVersionFiles(versionProps, globalJson, itemToUpdate); } // Combine the two sets of dependencies. If an asset is present in the itemsToUpdate, // prefer that one over the old dependencies Dictionary <string, HashSet <string> > itemsToUpdateLocations = GetAssetLocationMapping(itemsToUpdate); if (oldDependencies != null) { foreach (DependencyDetail dependency in oldDependencies) { if (!itemsToUpdateLocations.ContainsKey(dependency.Name) && dependency.Locations != null) { itemsToUpdateLocations.Add(dependency.Name, new HashSet <string>(dependency.Locations)); } } } // At this point we only care about the Maestro managed locations for the assets. // Flatten the dictionary into a set that has all the managed feeds HashSet <string> managedFeeds = FlattenLocations(itemsToUpdateLocations, IsMaestroManagedFeed); var updatedNugetConfig = UpdatePackageSources(nugetConfig, managedFeeds); var fileContainer = new GitFileContentContainer { GlobalJson = new GitFile(VersionFiles.GlobalJson, globalJson), VersionDetailsXml = new GitFile(VersionFiles.VersionDetailsXml, versionDetails), VersionProps = new GitFile(VersionFiles.VersionProps, versionProps), NugetConfig = new GitFile(VersionFiles.NugetConfig, updatedNugetConfig) }; return(fileContainer); }