private void AddVersionedOsLegs(BuildMatrixInfo matrix, IGrouping <PlatformId, PlatformInfo> platformGrouping)
        {
            var versionGroups = platformGrouping
                                .GroupBy(platform => new
            {
                // Assumption:  Dockerfile path format <ProductVersion>/<ImageVariant>/<OsVariant>/...
                DotNetVersion = GetDotNetVersionFromPath(platform.DockerfilePathRelativeToManifest),
                OsVariant     = platform.Model.OsVersion
            });

            foreach (var versionGrouping in versionGroups)
            {
                IEnumerable <PlatformInfo> subgraphs = versionGrouping
                                                       .GetCompleteSubgraphs(platform => GetPlatformDependencies(platform, platformGrouping))
                                                       .SelectMany(subgraph => subgraph);

                BuildLegInfo leg = new BuildLegInfo()
                {
                    Name = $"{versionGrouping.Key.DotNetVersion}-{versionGrouping.Key.OsVariant}"
                };
                matrix.Legs.Add(leg);

                AddCommonVariables(platformGrouping, leg);
                leg.Variables.Add(("dotnetVersion", versionGrouping.Key.DotNetVersion));
                leg.Variables.Add(("osVariant", versionGrouping.Key.OsVariant));

                IEnumerable <string> dockerfilePaths = GetDockerfilePaths(subgraphs)
                                                       .Union(GetCustomLegGroupingDockerfilePaths(subgraphs));

                AddImageBuilderPathsVariable(dockerfilePaths.ToArray(), leg);
            }
        }
        public IEnumerable <BuildMatrixInfo> GenerateMatrixInfo()
        {
            List <BuildMatrixInfo> matrices = new List <BuildMatrixInfo>();

            // The sort order used here is arbitrary and simply helps the readability of the output.
            var platformGroups = Manifest.GetFilteredPlatforms()
                                 .GroupBy(platform => new PlatformId()
            {
                OS           = platform.Model.OS,
                OsVersion    = platform.Model.OS == OS.Linux ? null : platform.Model.OsVersion,
                Architecture = platform.Model.Architecture,
                Variant      = platform.Model.Variant
            })
                                 .OrderBy(platformGroup => platformGroup.Key.OS)
                                 .ThenByDescending(platformGroup => platformGroup.Key.OsVersion)
                                 .ThenBy(platformGroup => platformGroup.Key.Architecture)
                                 .ThenByDescending(platformGroup => platformGroup.Key.Variant);

            foreach (var platformGrouping in platformGroups)
            {
                string[] matrixNameParts =
                {
                    GetOsMatrixNamePart(platformGrouping.Key),
                    platformGrouping.Key.Architecture.GetDisplayName(platformGrouping.Key.Variant)
                };
                BuildMatrixInfo matrix = new BuildMatrixInfo()
                {
                    Name = FormatMatrixName(matrixNameParts)
                };
                matrices.Add(matrix);

                if (Options.MatrixType == MatrixType.PlatformDependencyGraph)
                {
                    AddDockerfilePathLegs(matrix, matrixNameParts, platformGrouping);
                }
                else if (Options.MatrixType == MatrixType.PlatformVersionedOs)
                {
                    AddVersionedOsLegs(matrix, platformGrouping);
                }
            }

            return(matrices);
        }
        private void AddDockerfilePathLegs(
            BuildMatrixInfo matrix, IEnumerable <string> matrixNameParts, IGrouping <PlatformId, PlatformInfo> platformGrouping)
        {
            IEnumerable <IEnumerable <PlatformInfo> > subgraphs = platformGrouping.GetCompleteSubgraphs(
                platform => GetPlatformDependencies(platform, platformGrouping));

            foreach (IEnumerable <PlatformInfo> subgraph in subgraphs)
            {
                string[] dockerfilePaths = GetDockerfilePaths(subgraph)
                                           .Union(GetCustomLegGroupingDockerfilePaths(subgraph))
                                           .ToArray();

                BuildLegInfo leg = new BuildLegInfo()
                {
                    Name = GetDockerfilePathLegName(dockerfilePaths, matrixNameParts)
                };
                matrix.Legs.Add(leg);

                AddImageBuilderPathsVariable(dockerfilePaths, leg);
                AddCommonVariables(platformGrouping, leg);
            }
        }