Esempio n. 1
0
 public async Task <OrchestratedBuildModel> FetchManifestAsync(
     GitHubProject project,
     string @ref,
     string basePath)
 {
     return(OrchestratedBuildModel.Parse(await FetchModelXmlAsync(project, @ref, basePath)));
 }
Esempio n. 2
0
        private static async Task <IEnumerable <IDependencyInfo> > LoadBuildInfoXml()
        {
            Trace.TraceInformation($"Retrieving build info from '{Options.BuildInfoUrl}'");

            XDocument buildInfoXml;

            if (File.Exists(Options.BuildInfoUrl.LocalPath))
            {
                buildInfoXml = XDocument.Load(Options.BuildInfoUrl.LocalPath);
            }
            else
            {
                using (HttpClient client = new HttpClient())
                    using (Stream stream = await client.GetStreamAsync(Options.BuildInfoUrl))
                    {
                        buildInfoXml = XDocument.Load(stream);
                    }
            }

            OrchestratedBuildModel buildInfo = OrchestratedBuildModel.Parse(buildInfoXml.Root);

            return(new[]
            {
                CreateDependencyBuildInfo(SdkBuildInfoName, buildInfo.Builds),
                CreateDependencyBuildInfo(RuntimeBuildInfoName, buildInfo.Builds),
                CreateDependencyBuildInfo(AspNetCoreBuildInfoName, buildInfo.Builds),
            });
        }
        public override bool Execute()
        {
            string contents = System.IO.File.ReadAllText(ManifestFile);
            var    model    = OrchestratedBuildModel.Parse(XElement.Parse(contents));

            if (string.IsNullOrEmpty(CommitMessage))
            {
                CommitMessage = $"{model.Identity} orchestrated build manifest";
            }

            var gitHubAuth = new GitHubAuth(GitHubAuthToken, GitHubUser, GitHubEmail);

            using (var gitHubClient = new GitHubClient(gitHubAuth))
            {
                var client = new BuildManifestClient(gitHubClient);

                var location = new BuildManifestLocation(
                    new GitHubProject(VersionsRepo, VersionsRepoOwner),
                    $"heads/{VersionsRepoBranch}",
                    VersionsRepoPath);

                var pushTask = client.PushNewBuildAsync(
                    location,
                    model,
                    CreateUploadRequests(SupplementaryFiles),
                    CommitMessage);

                pushTask.Wait();
            }
            return(!Log.HasLoggedErrors);
        }
Esempio n. 4
0
        public void TestExampleOrchestratedBuildManifestRoundtrip()
        {
            XElement xml      = XElement.Parse(ExampleOrchestratedBuildString);
            var      model    = OrchestratedBuildModel.Parse(xml);
            XElement modelXml = model.ToXml();

            XNode.DeepEquals(xml, modelXml).Should().BeTrue("Model failed to output the parsed XML.");
        }
Esempio n. 5
0
        protected IEnumerable <IDependencyInfo> CreateDependencyInfos(
            bool remote,
            string versionsCommit)
        {
            foreach (ITaskItem info in DependencyInfo ?? Enumerable.Empty <ITaskItem>())
            {
                IDependencyInfo dependencyInfo;

                string type = info.GetMetadata("DependencyType");
                switch (type)
                {
                case "Build":
                    SetVersionsCommitOverride(info, versionsCommit);
                    dependencyInfo = CreateBuildInfoDependency(info, BuildInfoCacheDir);
                    break;

                case "Submodule":
                    dependencyInfo = SubmoduleDependencyInfo.Create(
                        GetRequiredMetadata(info, "Repository"),
                        GetRequiredMetadata(info, "Ref"),
                        GetRequiredMetadata(info, "Path"),
                        remote);
                    break;

                case "Orchestrated build":
                    SetVersionsCommitOverride(info, versionsCommit);
                    dependencyInfo = OrchestratedBuildDependencyInfo.CreateAsync(
                        info.ItemSpec,
                        new GitHubProject(
                            GetRequiredMetadata(info, "VersionsRepo"),
                            GetRequiredMetadata(info, "VersionsRepoOwner")),
                        GetRequiredMetadata(info, CurrentRefMetadataName),
                        GetRequiredMetadata(info, "BasePath"),
                        new BuildManifestClient(GitHubClient)).Result;
                    break;

                case "Orchestrated build file":
                    dependencyInfo = new OrchestratedBuildDependencyInfo(
                        info.ItemSpec,
                        OrchestratedBuildModel.Parse(
                            XElement.Parse(
                                File.ReadAllText(
                                    GetRequiredMetadata(info, "Path")))));
                    break;

                default:
                    throw new NotSupportedException(
                              $"Unsupported DependencyInfo '{info.ItemSpec}': DependencyType '{type}'.");
                }

                DependencyInfoConfigItems[dependencyInfo] = info;
                yield return(dependencyInfo);
            }
        }
        public async Task <OrchestratedBuildModel> FetchManifestAsync(
            GitHubProject project,
            string @ref,
            string basePath)
        {
            XElement contents = await FetchModelXmlAsync(project, @ref, basePath);

            if (contents == null)
            {
                return(null);
            }

            return(OrchestratedBuildModel.Parse(contents));
        }
Esempio n. 7
0
        private static async Task <IEnumerable <IDependencyInfo> > GetBuildInfoAsync()
        {
            Trace.TraceInformation($"Retrieving build info from '{Options.BuildInfoUrl}'");

            using (HttpClient client = new HttpClient())
                using (Stream stream = await client.GetStreamAsync(Options.BuildInfoUrl))
                {
                    XDocument buildInfoXml           = XDocument.Load(stream);
                    OrchestratedBuildModel buildInfo = OrchestratedBuildModel.Parse(buildInfoXml.Root);
                    BuildIdentity          sdkBuild  = buildInfo.Builds
                                                       .First(build => string.Equals(build.Name, "cli", StringComparison.OrdinalIgnoreCase));
                    BuildIdentity coreSetupBuild = buildInfo.Builds
                                                   .First(build => string.Equals(build.Name, "core-setup", StringComparison.OrdinalIgnoreCase));

                    return(new[]
                    {
                        CreateDependencyBuildInfo(SdkBuildInfoName, sdkBuild.ProductVersion),
                        CreateDependencyBuildInfo(RuntimeBuildInfoName, coreSetupBuild.ProductVersion),
                    });
                };
        }
Esempio n. 8
0
        private async Task <IDependencyInfo> GetBuildInfoAsync()
        {
            Trace.TraceInformation($"Retrieving build info from '{BuildInfoUrl}'");

            using (var client = new HttpClient())
                using (var stream = await client.GetStreamAsync(BuildInfoUrl))
                {
                    var buildInfoXml = XDocument.Load(stream);
                    var buildInfo    = OrchestratedBuildModel.Parse(buildInfoXml.Root);
                    var aspnetBuild  = buildInfo.Builds
                                       .First(build => string.Equals(build.Name, "aspnet", StringComparison.OrdinalIgnoreCase));

                    return(new BuildDependencyInfo(
                               new BuildInfo()
                    {
                        Name = RuntimeBuildInfo,
                        LatestReleaseVersion = aspnetBuild.ProductVersion,
                        LatestPackages = new Dictionary <string, string>()
                    },
                               false,
                               Enumerable.Empty <string>()));
                }
        }
        public async Task PushChangeAsync(BuildManifestChange change)
        {
            await Retry.RunAsync(async attempt =>
            {
                BuildManifestLocation location = change.Location;

                // Get the current commit. Use this throughout to ensure a clean transaction.
                GitReference remoteRef = await _github.GetReferenceAsync(
                    location.GitHubProject,
                    location.GitHubRef);

                string remoteCommit = remoteRef.Object.Sha;

                Trace.TraceInformation($"Creating update on remote commit: {remoteCommit}");

                XElement remoteModelXml = await FetchModelXmlAsync(
                    location.GitHubProject,
                    remoteCommit,
                    location.GitHubBasePath);

                OrchestratedBuildModel remoteModel = OrchestratedBuildModel.Parse(remoteModelXml);

                // This is a subsequent publish step: make sure a new build hasn't happened already.
                if (change.OrchestratedBuildId != remoteModel.Identity.BuildId)
                {
                    throw new ManifestChangeOutOfDateException(
                        change.OrchestratedBuildId,
                        remoteModel.Identity.BuildId);
                }

                OrchestratedBuildModel modifiedModel = OrchestratedBuildModel.Parse(remoteModelXml);
                change.ApplyModelChanges(modifiedModel);

                if (modifiedModel.Identity.BuildId != change.OrchestratedBuildId)
                {
                    throw new ArgumentException(
                        "Change action shouldn't modify BuildId. Changed from " +
                        $"'{change.OrchestratedBuildId}' to '{modifiedModel.Identity.BuildId}'.",
                        nameof(change));
                }

                XElement modifiedModelXml = modifiedModel.ToXml();

                string[] changedSemaphorePaths = change.SemaphorePaths.ToArray();

                // Check if any join groups are completed by this change.
                var joinCompleteCheckTasks = change.JoinSemaphoreGroups.NullAsEmpty()
                                             .Select(async g => new
                {
                    Group    = g,
                    Joinable = await IsGroupJoinableAsync(
                        location,
                        remoteCommit,
                        change.OrchestratedBuildId,
                        changedSemaphorePaths,
                        g)
                });

                var completeJoinedSemaphores = (await Task.WhenAll(joinCompleteCheckTasks))
                                               .Where(g => g.Joinable)
                                               .Select(g => g.Group.JoinSemaphorePath)
                                               .ToArray();

                IEnumerable <SupplementaryUploadRequest> semaphoreUploads = completeJoinedSemaphores
                                                                            .Concat(changedSemaphorePaths)
                                                                            .Select(p => new SupplementaryUploadRequest
                {
                    Path     = p,
                    Contents = new SemaphoreModel
                    {
                        BuildId = change.OrchestratedBuildId
                    }.ToFileContent()
                });

                IEnumerable <SupplementaryUploadRequest> uploads =
                    semaphoreUploads.Concat(change.SupplementaryUploads.NullAsEmpty());

                if (!XNode.DeepEquals(modifiedModelXml, remoteModelXml))
                {
                    uploads = uploads.Concat(new[]
                    {
                        new SupplementaryUploadRequest
                        {
                            Path     = BuildManifestXmlName,
                            Contents = modifiedModelXml.ToString()
                        }
                    });
                }

                return(await PushUploadsAsync(
                           location,
                           change.CommitMessage,
                           remoteCommit,
                           uploads));
            });
        }
        public override bool Execute()
        {
            string contents = System.IO.File.ReadAllText(ManifestFile);
            OrchestratedBuildModel model    = OrchestratedBuildModel.Parse(XElement.Parse(contents));
            EndpointModel          blobFeed = model.Endpoints.First(e => e.IsOrchestratedBlobFeed);

            string feedAssetsRoot = blobFeed.Url.Replace("/index.json", "/assets");

            string sdkProductVersion = model.Builds
                                       .FirstOrDefault(b => b.Name == "cli")
                                       ?.ProductVersion;

            string runtimeProductVersion = model.Builds
                                           .FirstOrDefault(b => b.Name == "core-setup")
                                           ?.ProductVersion;

            string aspnetProductVersion = model.Builds
                                          .FirstOrDefault(b => b.Name == "aspnet")
                                          ?.ProductVersion;

            var builder = new StringBuilder();

            builder.Append("## Product build: ");
            builder.AppendLine(model.Identity.ToString());

            if (!string.IsNullOrEmpty(SdkTableTemplateFile) && sdkProductVersion != null)
            {
                builder.AppendLine();
                builder.AppendLine(FillTemplate(
                                       SdkTableTemplateFile,
                                       feedAssetsRoot,
                                       sdkProductVersion));
            }

            if (!string.IsNullOrEmpty(DotNetRuntimeTableTemplateFile) && runtimeProductVersion != null)
            {
                builder.AppendLine();
                builder.AppendLine(FillTemplate(
                                       DotNetRuntimeTableTemplateFile,
                                       feedAssetsRoot,
                                       runtimeProductVersion));
            }

            if (!string.IsNullOrEmpty(AspNetCoreRuntimeTableTemplateFile) && aspnetProductVersion != null)
            {
                builder.AppendLine();
                builder.AppendLine(FillTemplate(
                                       AspNetCoreRuntimeTableTemplateFile,
                                       feedAssetsRoot,
                                       aspnetProductVersion));
            }

            builder.AppendLine();
            builder.AppendLine("### Built Repositories");

            foreach (BuildIdentity build in model.Builds
                     .Where(b => b.Name != "anonymous")
                     .OrderBy(b => b.Name))
            {
                builder.Append(" * ");
                builder.AppendLine(build.ToString());
            }

            System.IO.File.WriteAllText(File, builder.ToString());

            return(!Log.HasLoggedErrors);
        }
Esempio n. 11
0
        public static OrchestratedBuild Load(string xmlText, string branch)
        {
            var model = OrchestratedBuildModel.Parse(XDocument.Parse(xmlText).Root);

            var orchestratedBuild = new OrchestratedBuild
            {
                BuildNumber         = model.Identity.BuildId,
                Branch              = branch,
                OrchestratedBuildId = $"{branch}/{model.Identity.BuildId}",
                Name         = model.Identity.Name,
                IsStable     = string.IsNullOrEmpty(model.Identity.IsStable) ? false : bool.Parse(model.Identity.IsStable),
                VersionStamp = model.Identity.VersionStamp
            };

            var buildsIndex = new Dictionary <string, Build>();

            foreach (var buildModel in model.Builds.Where(b => b.Name != "anonymous"))
            {
                var build = new Build
                {
                    OrchestratedBuildId = orchestratedBuild.OrchestratedBuildId,
                    Name           = buildModel.Name,
                    BuildNumber    = buildModel.BuildId,
                    BuildId        = $"{orchestratedBuild.OrchestratedBuildId}/builds/{buildModel.Name}/{buildModel.BuildId}",
                    Branch         = buildModel.Branch,
                    ProductVersion = buildModel.ProductVersion,
                    Commit         = buildModel.Commit,
                };

                buildsIndex[build.Name] = build;
                orchestratedBuild.Builds.Add(build);
            }

            var endpointIndex = new Dictionary <string, Endpoint>();
            var packageIndex  = new Dictionary <string, Package>();
            var blobIndex     = new Dictionary <string, Blob>();

            foreach (var endpoint in model.Endpoints)
            {
                var baseUrl = endpoint.Url;
                if (baseUrl.EndsWith("/index.json"))
                {
                    baseUrl = baseUrl.Substring(0, baseUrl.Length - 11);
                }
                if (endpoint.IsOrchestratedBlobFeed)
                {
                    baseUrl += "/assets";
                }

                var ep = new Endpoint
                {
                    EndpointId = $"{orchestratedBuild.OrchestratedBuildId}/endpoints/{endpoint.Id}",
                    Id         = endpoint.Id,
                    Type       = endpoint.Type,
                    Url        = endpoint.Url
                };

                endpointIndex[ep.EndpointId] = ep;
                orchestratedBuild.Endpoints.Add(ep);

                foreach (var artifact in endpoint.Artifacts.Packages)
                {
                    if (packageIndex.TryGetValue(artifact.Id, out var existingRef))
                    {
                        existingRef.Endpoints.Add(new EndpointRef()
                        {
                            EndpointRefId = $"{orchestratedBuild.OrchestratedBuildId}/endpoints/{ep.EndpointId}/packages/{artifact.Id}",
                            EndpointId    = ep.EndpointId,
                            ArtifactUrl   = $"{baseUrl}/flatcontainer/{artifact.Id}/{artifact.Version}/{artifact.Id}.{artifact.Version}.nupkg",
                        });
                    }
                    else
                    {
                        var packageRef = new Package
                        {
                            PackageId   = $"{orchestratedBuild.OrchestratedBuildId}/packages/{artifact.Id}",
                            Id          = artifact.Id,
                            Version     = artifact.Version,
                            NonShipping = bool.Parse(artifact.Attributes.TryGetValue("NonShipping", bool.TrueString))
                        };
                        if (!string.IsNullOrEmpty(artifact.OriginBuildName) && buildsIndex.TryGetValue(artifact.OriginBuildName, out var build))
                        {
                            packageRef.OriginBuildId = build.BuildId;
                        }
                        packageIndex[artifact.Id] = packageRef;
                        orchestratedBuild.Packages.Add(packageRef);
                    }
                }

                foreach (var artifact in endpoint.Artifacts.Blobs)
                {
                    if (blobIndex.TryGetValue(artifact.Id, out var existingRef))
                    {
                        existingRef.Endpoints.Add(new EndpointRef()
                        {
                            EndpointRefId = $"{orchestratedBuild.OrchestratedBuildId}/endpoints/{ep.EndpointId}/blobs/{artifact.Id}",
                            EndpointId    = ep.EndpointId,
                            ArtifactUrl   = $"{baseUrl}/assets/{artifact.Id}",
                        });
                    }
                    else
                    {
                        var blobRef = new Blob
                        {
                            BlobId        = $"{orchestratedBuild.OrchestratedBuildId}/blobs/{artifact.Id}",
                            Id            = artifact.Id,
                            Type          = artifact.Attributes.TryGetValue("Type"),
                            ShipInstaller = artifact.Attributes.TryGetValue("ShipInstaller")
                        };
                        blobIndex[artifact.Id] = blobRef;
                        orchestratedBuild.Blobs.Add(blobRef);
                    }
                }
            }

            return(orchestratedBuild);
        }
        public async Task PushChangeAsync(
            GitHubProject project,
            string @ref,
            string basePath,
            string orchestratedBuildId,
            Action <OrchestratedBuildModel> changeModel,
            IEnumerable <string> semaphorePaths,
            IEnumerable <SupplementaryUploadRequest> supplementaryUploads,
            string message)
        {
            await Retry.RunAsync(async attempt =>
            {
                // Get the current commit. Use this throughout to ensure a clean transaction.
                string remoteCommit = (await _github.GetReferenceAsync(project, @ref)).Object.Sha;

                Trace.TraceInformation($"Creating update on remote commit: {remoteCommit}");

                // This is a subsequent publish step: check to make sure the build id matches.
                XElement remoteModelXml = await FetchModelXmlAsync(project, remoteCommit, basePath);

                OrchestratedBuildModel remoteModel = OrchestratedBuildModel.Parse(remoteModelXml);

                if (orchestratedBuildId != remoteModel.Identity.BuildId)
                {
                    throw new ManifestChangeOutOfDateException(
                        orchestratedBuildId,
                        remoteModel.Identity.BuildId);
                }

                OrchestratedBuildModel modifiedModel = OrchestratedBuildModel.Parse(remoteModelXml);
                changeModel(modifiedModel);

                if (modifiedModel.Identity.BuildId != orchestratedBuildId)
                {
                    throw new ArgumentException(
                        "Change action shouldn't modify BuildId. Changed from " +
                        $"'{orchestratedBuildId}' to '{modifiedModel.Identity.BuildId}'.",
                        nameof(changeModel));
                }

                XElement modifiedModelXml = modifiedModel.ToXml();

                IEnumerable <SupplementaryUploadRequest> uploads = semaphorePaths.NullAsEmpty()
                                                                   .Select(p => new SupplementaryUploadRequest
                {
                    Path     = p,
                    Contents = new SemaphoreModel
                    {
                        BuildId = orchestratedBuildId
                    }.ToFileContent()
                })
                                                                   .Concat(supplementaryUploads.NullAsEmpty())
                                                                   .ToArray();

                if (!XNode.DeepEquals(modifiedModelXml, remoteModelXml))
                {
                    uploads = uploads.Concat(new[]
                    {
                        new SupplementaryUploadRequest
                        {
                            Path     = BuildManifestXmlName,
                            Contents = modifiedModelXml.ToString()
                        }
                    });
                }

                return(await PushUploadsAsync(project, @ref, basePath, message, remoteCommit, uploads));
            });
        }