Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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");
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #7
0
        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);
        }