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);
        }
        public async Task TestPushConflictAsync()
        {
            var mockGitHub = new Mock <IGitHubClient>(MockBehavior.Strict);

            var client = new BuildManifestClient(mockGitHub.Object);
            var build  = new OrchestratedBuildModel(new BuildIdentity {
                Name = "orch", BuildId = "123"
            });
            var    proj     = new GitHubProject("versions", "dotnet");
            string @ref     = "heads/master";
            string basePath = "build-info/dotnet/product/cli/master";
            string message  = "Test build upload commit";

            string fakeCommitHash    = "fakeCommitHash";
            string fakeTreeHash      = "fakeTreeHash";
            string fakeNewCommitHash = "fakeNewCommitHash";

            mockGitHub
            .Setup(c => c.GetReferenceAsync(proj, @ref))
            .ReturnsAsync(() => new GitReference
            {
                Object = new GitReferenceObject {
                    Sha = fakeCommitHash
                }
            });

            mockGitHub
            .Setup(c => c.PostTreeAsync(proj, fakeCommitHash, It.IsAny <GitObject[]>()))
            .ReturnsAsync(() => new GitTree {
                Sha = fakeTreeHash
            });

            mockGitHub
            .Setup(c => c.PostCommitAsync(proj, message, fakeTreeHash, It.IsAny <string[]>()))
            .ReturnsAsync(() => new GitCommit {
                Sha = fakeNewCommitHash
            });

            mockGitHub
            .Setup(c => c.PatchReferenceAsync(proj, @ref, fakeNewCommitHash, false))
            .Callback(() =>
            {
                // Once the exception is hit, let the next patch call work.
                mockGitHub
                .Setup(c => c.PatchReferenceAsync(proj, @ref, fakeNewCommitHash, false))
                .ReturnsAsync(() => null);
            })
            .ThrowsAsync(new NotFastForwardUpdateException("Testing non-fast-forward update."));

            await client.PushNewBuildAsync(
                new BuildManifestLocation(proj, @ref, basePath),
                build,
                null,
                message);

            mockGitHub.VerifyAll();
        }
        private async System.Threading.Tasks.Task PushChangeAsync(BuildManifestClient client)
        {
            try
            {
                var location = new BuildManifestLocation(
                    new GitHubProject(VersionsRepo, VersionsRepoOwner),
                    $"heads/{VersionsRepoBranch}",
                    VersionsRepoPath);

                IEnumerable <JoinSemaphoreGroup> joinGroups = JoinSemaphoreGroups
                                                              .Select(item => new
                {
                    ParallelPartPath  = item.ItemSpec,
                    JoinSemaphorePath = item.GetMetadata(JoinSemaphorePathMetadataName)
                })
                                                              .GroupBy(j => j.JoinSemaphorePath, j => j.ParallelPartPath)
                                                              .Select(g => new JoinSemaphoreGroup
                {
                    JoinSemaphorePath      = g.Key,
                    ParallelSemaphorePaths = g
                });

                SupplementaryUploadRequest[] supplementaryUploads =
                    PushOrchestratedBuildManifest.CreateUploadRequests(SupplementaryFiles);

                var change = new BuildManifestChange(
                    location,
                    CommitMessage,
                    OrchestratedBuildId,
                    SemaphoreNames,
                    manifest =>
                {
                    foreach (var update in ManifestUpdates ?? Enumerable.Empty <ITaskItem>())
                    {
                        ApplyUpdate(manifest, update);
                    }
                })
                {
                    SupplementaryUploads = supplementaryUploads,
                    JoinSemaphoreGroups  = joinGroups,
                };

                await client.PushChangeAsync(change);
            }
            catch (ManifestChangeOutOfDateException e)
            {
                Log.LogWarningFromException(e);
            }
        }
Esempio n. 4
0
        public override bool Execute()
        {
            GitHubAuth gitHubAuth = null;

            if (!string.IsNullOrEmpty(GitHubAuthToken))
            {
                gitHubAuth = new GitHubAuth(GitHubAuthToken, GitHubUser, GitHubEmail);
            }
            using (var gitHubClient = new GitHubClient(gitHubAuth))
            {
                var client = new BuildManifestClient(gitHubClient);

                OrchestratedBuildModel manifest = client.FetchManifestAsync(
                    new GitHubProject(VersionsRepo, VersionsRepoOwner),
                    VersionsRepoRef,
                    VersionsRepoPath)
                                                  .Result;

                OrchestratedBuild = CreateItem(manifest.Identity);

                EndpointModel[] orchestratedFeeds = manifest.Endpoints
                                                    .Where(e => e.IsOrchestratedBlobFeed)
                                                    .ToArray();

                if (orchestratedFeeds.Length != 1)
                {
                    throw new Exception(
                              "Invalid manifest. Expected 1 orchestrated blob feed, " +
                              $"found {orchestratedFeeds.Length}.");
                }

                EndpointModel feed = orchestratedFeeds[0];

                IEnumerable <ITaskItem> packageItems = feed.Artifacts.Packages.Select(CreateItem);
                IEnumerable <ITaskItem> blobItems    = feed.Artifacts.Blobs.Select(CreateItem);

                OrchestratedBlobFeed          = new[] { new TaskItem("Endpoint", feed.Attributes) };
                OrchestratedBlobFeedArtifacts = packageItems.Concat(blobItems).ToArray();

                IEnumerable <ITaskItem> buildItems = manifest.Builds.Select(CreateItem);

                OrchestratedBuildConstituents = buildItems.ToArray();
            }

            return(!Log.HasLoggedErrors);
        }
        public async Task TestPushConflictingChangeAsync()
        {
            var mockGitHub = new Mock <IGitHubClient>(MockBehavior.Strict);

            var    client           = new BuildManifestClient(mockGitHub.Object);
            var    proj             = new GitHubProject("versions", "dotnet");
            string @ref             = "heads/master";
            string basePath         = "build-info/dotnet/product/cli/master";
            string message          = "Test change manifest commit";
            string addSemaphorePath = "add-identity.semaphore";

            var fakeExistingBuild = new OrchestratedBuildModel(new BuildIdentity {
                Name = "orch", BuildId = "123"
            });
            var fakeNewExistingBuild = new OrchestratedBuildModel(new BuildIdentity {
                Name = "orch", BuildId = "456"
            });
            string fakeCommitHash = "fakeCommitHash";

            mockGitHub
            .Setup(c => c.GetReferenceAsync(proj, @ref))
            .ReturnsAsync(() => new GitReference
            {
                Object = new GitReferenceObject {
                    Sha = fakeCommitHash
                }
            });

            mockGitHub
            .Setup(c => c.GetGitHubFileContentsAsync(It.IsAny <string>(), proj, fakeCommitHash))
            .ReturnsAsync(() => fakeNewExistingBuild.ToXml().ToString());

            var pushClient = client.PushChangeAsync(
                new BuildManifestChange(
                    new BuildManifestLocation(proj, @ref, basePath),
                    message,
                    fakeExistingBuild.Identity.BuildId,
                    new[] { addSemaphorePath },
                    _ => { }
                    ));
            Func <Task> act = async() => { await pushClient; };
            await act.Should().ThrowAsync <ManifestChangeOutOfDateException>();

            mockGitHub.VerifyAll();
        }
        public override bool Execute()
        {
            if (string.IsNullOrEmpty(CommitMessage))
            {
                string semaphores = string.Join(", ", SemaphoreNames);
                string identity   = OrchestratedIdentitySummary ?? VersionsRepoPath;

                CommitMessage = $"Update {identity}: {semaphores}";
            }
            var gitHubAuth = new GitHubAuth(GitHubAuthToken, GitHubUser, GitHubEmail);

            using (var gitHubClient = new GitHubClient(gitHubAuth))
            {
                var client = new BuildManifestClient(gitHubClient);
                PushChangeAsync(client).Wait();
            }
            return(!Log.HasLoggedErrors);
        }
Esempio n. 7
0
        public static async Task <OrchestratedBuildDependencyInfo> CreateAsync(
            string simpleName,
            GitHubProject project,
            string @ref,
            string basePath,
            BuildManifestClient client)
        {
            OrchestratedBuildModel model = await client.FetchManifestAsync(
                project,
                @ref,
                basePath);

            if (model == null)
            {
                throw new ArgumentException(
                          $"Found no manifest for '{simpleName}' at " +
                          $"'{project.Segments}' '{basePath}' ref '{@ref}'");
            }

            return(new OrchestratedBuildDependencyInfo(simpleName, basePath, model));
        }
        public async Task TestPushNewBuildAsync()
        {
            var mockGitHub = new Mock <IGitHubClient>(MockBehavior.Strict);

            var client = new BuildManifestClient(mockGitHub.Object);
            var build  = new OrchestratedBuildModel(new BuildIdentity {
                Name = "orch", BuildId = "123"
            });
            var    proj     = new GitHubProject("versions", "dotnet");
            string @ref     = "heads/master";
            string basePath = "build-info/dotnet/product/cli/master";
            string message  = "Test build upload commit";

            string fakeCommitHash    = "fakeCommitHash";
            string fakeTreeHash      = "fakeTreeHash";
            string fakeNewCommitHash = "fakeNewCommitHash";

            mockGitHub
            .Setup(c => c.GetReferenceAsync(proj, @ref))
            .ReturnsAsync(() => new GitReference
            {
                Object = new GitReferenceObject {
                    Sha = fakeCommitHash
                }
            });

            mockGitHub
            .Setup(c => c.PostTreeAsync(
                       proj,
                       fakeCommitHash,
                       It.Is <GitObject[]>(
                           objects =>
                           objects.Length == 2 &&
                           objects[0].Path == $"{basePath}/{BuildManifestClient.BuildManifestXmlName}" &&
                           objects[0].Content == build.ToXml().ToString() &&
                           objects[1].Path == $"{basePath}/{SemaphoreModel.BuildSemaphorePath}" &&
                           objects[1].Content == build.Identity.BuildId + "\n")))
            .ReturnsAsync(() => new GitTree {
                Sha = fakeTreeHash
            });

            mockGitHub
            .Setup(c => c.PostCommitAsync(
                       proj,
                       message,
                       fakeTreeHash,
                       It.Is <string[]>(parents => parents.Single() == fakeCommitHash)))
            .ReturnsAsync(() => new GitCommit {
                Sha = fakeNewCommitHash
            });

            mockGitHub
            .Setup(c => c.PatchReferenceAsync(proj, @ref, fakeNewCommitHash, false))
            .ReturnsAsync(() => null);

            await client.PushNewBuildAsync(
                new BuildManifestLocation(proj, @ref, basePath),
                build,
                null,
                message);

            mockGitHub.VerifyAll();
        }
Esempio n. 9
0
        public async Task TestPushChangeSemaphoreAsync()
        {
            var mockGitHub = new Mock <IGitHubClient>(MockBehavior.Strict);

            var    client           = new BuildManifestClient(mockGitHub.Object);
            var    proj             = new GitHubProject("versions", "dotnet");
            string @ref             = "heads/master";
            string basePath         = "build-info/dotnet/product/cli/master";
            string message          = "Test change manifest commit";
            string addSemaphorePath = "add-identity.semaphore";

            var    fakeExistingBuild       = new OrchestratedBuildModel(new BuildIdentity("orch", "123"));
            string fakeExistingBuildString = fakeExistingBuild.ToXml().ToString();
            string fakeCommitHash          = "fakeCommitHash";
            string fakeTreeHash            = "fakeTreeHash";
            string fakeNewCommitHash       = "fakeNewCommitHash";

            mockGitHub
            .Setup(c => c.GetReferenceAsync(proj, @ref))
            .ReturnsAsync(() => new GitReference
            {
                Object = new GitReferenceObject {
                    Sha = fakeCommitHash
                }
            });

            mockGitHub
            .Setup(c => c.GetGitHubFileContentsAsync(
                       $"{basePath}/{BuildManifestClient.BuildManifestXmlName}",
                       proj,
                       fakeCommitHash))
            .ReturnsAsync(() => fakeExistingBuildString);

            mockGitHub
            .Setup(c => c.PostTreeAsync(
                       proj,
                       fakeCommitHash,
                       It.Is <GitObject[]>(
                           objects =>
                           objects.Length == 1 &&
                           objects[0].Path == $"{basePath}/{addSemaphorePath}" &&
                           objects[0].Content == fakeExistingBuild.Identity.BuildId + "\n")))
            .ReturnsAsync(() => new GitTree {
                Sha = fakeTreeHash
            });

            mockGitHub
            .Setup(c => c.PostCommitAsync(
                       proj,
                       message,
                       fakeTreeHash,
                       It.Is <string[]>(parents => parents.Single() == fakeCommitHash)))
            .ReturnsAsync(() => new GitCommit {
                Sha = fakeNewCommitHash
            });

            mockGitHub
            .Setup(c => c.PatchReferenceAsync(proj, @ref, fakeNewCommitHash, false))
            .ReturnsAsync(() => null);

            await client.PushChangeAsync(
                proj,
                @ref,
                basePath,
                fakeExistingBuild.Identity.BuildId,
                _ => { },
                new[] { addSemaphorePath },
                null,
                message);

            mockGitHub.VerifyAll();
        }