Пример #1
0
        public Task <Guid> EnqueueBuild(BuildQueueEntry entry)
        {
            if (entry.BuildQueueID == Guid.Empty)
            {
                entry.BuildQueueID = Guid.NewGuid();
            }

            QueueItems.Add(entry);

            return(Task.FromResult(entry.BuildQueueID));
        }
Пример #2
0
        public async Task <Guid> EnqueueBuild(BuildQueueEntry entry)
        {
            var json = Newtonsoft.Json.JsonConvert.SerializeObject(entry);

            var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"api/EnqueueBuild/{entry.ProjectID}");

            message.Content = new System.Net.Http.StringContent(json);

            var result = await _client.SendAsync(message);

            result.EnsureSuccessStatusCode();

            var responseContent = await result.Content.ReadJsonAsAsync <dynamic>();

            return(responseContent.BuildQueueID);
        }
Пример #3
0
        public async Task <Guid> EnqueueBuild(BuildQueueEntry entry)
        {
            this.EnsureOpenConnection();

            if (entry.BuildQueueID == Guid.Empty)
            {
                entry.BuildQueueID = Guid.NewGuid();
            }

            // if a build already exists in the queue for the same project with status 1 (queued)
            //      update the revision ident to the newer value
            // else if the lock is expired on a status 2 record
            //      reset the lock to null
            //      reset the status to 1
            //      update the revision ident to the newer value
            // else if the lock is not expired
            //      insert a new build queue record

            var findAgentCmd = @"
                SELECT TOP 1 A.AgentID
                FROM Project P 
                    INNER JOIN Agent A ON A.EnvironmentID = P.EnvironmentID
                WHERE P.ProjectID = @ProjectID;   
            ";

            var batchCmd = @"
                IF (EXISTS (SELECT 1 FROM BuildQueue WHERE [Status]=1 AND ProjectID=@ProjectID)) BEGIN
                    UPDATE BuildQueue
                    SET RevisionIdentifier = @RevisionIdentifier
                    WHERE ProjectID = @ProjectID
                        AND [Status] = 1;
                END ELSE IF (EXISTS (SELECT 1 FROM BuildQueue WHERE [Status]=2 AND ProjectID = @ProjectID AND [LockExpiresDateTime] < SYSDATETIMEOFFSET())) BEGIN
                    UPDATE BuildQueue
                    SET [LockExpiresDateTime] = NULL,
                        [Status] = 1,
                        [LastResultCode] = 3,
                        [FailCount] = [FailCount] + 1
                    WHERE [ProjectID] = @ProjectID
                        AND [Status] = 2;
                END ELSE BEGIN
                    INSERT INTO BuildQueue ([BuildQueueID],[ProjectID],[RevisionIdentifier],[BuildNumber],[CreateDateTime],[AssignedDateTime],[AssignedAgentID],[Status])
                    VALUES (@BuildQueueID, @ProjectID, @RevisionIdentifier, @BuildNumber, @CreateDateTime, @AssignedDateTime, @AssignedAgentID, @Status);
                END
            ";

            using (var transaction = this.Connection.BeginTransaction(IsolationLevel.Serializable))
            {
                var agentID = await this.Connection.QuerySingleOrDefaultAsync <Guid?>(findAgentCmd, param : new
                {
                    ProjectID = entry.ProjectID
                }, transaction : transaction);

                if (!agentID.HasValue)
                {
                    throw new Exception($"No agent could be found to assign for project {entry.ProjectID}.");
                }

                // Get the first agent assigned to the environment for the given project
                var batchResult = await this.Connection.ExecuteAsync(batchCmd, param : new
                {
                    entry.BuildQueueID,
                    entry.ProjectID,
                    entry.RevisionIdentifier,
                    BuildNumber      = entry.BuildNumber,
                    CreateDateTime   = DateTimeOffset.Now,
                    AssignedDateTime = DateTimeOffset.Now,
                    AssignedAgentID  = agentID,
                    Status           = 1
                }, transaction : transaction);

                transaction.Commit();

                return(entry.BuildQueueID);
            }
        }
Пример #4
0
        public void TestStartProcessCreatesEnvironmentVariables()
        {
            var writer = new Mock.MockBuildOutputWriter()
            {
                PrefixSeverity = false
            };

            var agentOptions = new BuildAgentOptions()
            {
                AgentIdentifier  = "AgentID",
                ConcurrentBuilds = 1,
                WorkingPath      = "WorkingPath"
            };

            var codeInfo = new CodeRepositoryInfo()
            {
                Author             = "Author",
                RevisionIdentifier = "RevIdent"
            };

            var buildEntry = new BuildQueueEntry()
            {
                BuildNumber = 999
            };

            var project = new BuildProjectConfiguration()
            {
                ProjectID      = Guid.NewGuid(),
                Name           = "TestProject",
                RepositoryType = "svn",
                RepositoryPath = "repo-path",
                Variables      = new Dictionary <string, string>()
                {
                    { "VarTest", "123" }
                }
            };

            using (var env = new BuildEnvironment("C:\\Build", writer))
            {
                env.AddAgentVariables(agentOptions);
                env.AddCodeInfoVariables(codeInfo);
                env.AddGlobalVariables();
                env.AddQueueEntryVariables(buildEntry);
                env.AddProjectConfigurationVariables(project);

                var resultCode = env.StartProcessAsync("cmd.exe", "/c set").Result;

                Assert.AreEqual(0, resultCode);
            }

            var vars = new Dictionary <string, string>();

            using (var reader = new System.IO.StringReader(writer.StringWriter.ToString()))
            {
                string line;
                while (true)
                {
                    line = reader.ReadLine();
                    if (line == null)
                    {
                        break;
                    }

                    var parts = line.Split(new char[] { '=' }, 2);

                    vars.Add(parts[0], parts[1]);
                }
            }

            Assert.AreEqual("true", vars["CI"]);
            Assert.AreEqual("C:\\Build", vars["CI_WORKINGPATH"]);

            Assert.AreEqual(Environment.MachineName, vars["CI_AGENTHOST"]);
            Assert.AreEqual(agentOptions.AgentIdentifier, vars["CI_AGENTIDENTIFIER"]);

            Assert.AreEqual(codeInfo.RevisionIdentifier, vars["CI_REVISIONIDENTIFIER"]);
            Assert.AreEqual(codeInfo.Author, vars["CI_REVISIONAUTHOR"]);

            Assert.IsNotNull(vars["CI_BUILDDATE"]);
            Assert.IsNotNull(vars["CI_BUILDDATETIME"]);

            Assert.AreEqual(project.NextBuildNumber, int.Parse(vars["CI_BUILDNUMBER"]));

            Assert.AreEqual(project.ProjectID.ToString(), vars["CI_PROJECTID"]);
            Assert.AreEqual(project.Name, vars["CI_PROJECTNAME"]);
            Assert.AreEqual(project.RepositoryType, vars["CI_REPOSITORYTYPE"]);
            Assert.AreEqual(project.RepositoryPath, vars["CI_REPOSITORYPATH"]);
            Assert.AreEqual(project.Variables["VarTest"], vars["CI_VARTEST"]);
        }
Пример #5
0
        public static async Task <CodeCheckResult> CheckForNeededBuild(this BuildProjectConfiguration config, ICodeRepository code, BuildQueueEntry latestBuild)
        {
            var maxFailureCount = config.MaxFailureCount;
            var force           = false;
            var codeInfo        = await code.GetInfo(config.RepositoryPath);

            string currentCommitIdentifier = codeInfo?.RevisionIdentifier;

            if (force || latestBuild == null)
            {
                return(CodeCheckResult.Force(currentCommitIdentifier));
            }
            else if (currentCommitIdentifier.Equals(latestBuild.RevisionIdentifier))
            {
                return(CodeCheckResult.Skip());
            }
            else if (latestBuild.FailCount > maxFailureCount)
            {
                return(CodeCheckResult.Skip());
            }
            else
            {
                var changedFiles = await code.GetChangedFiles(config.RepositoryPath, latestBuild?.RevisionIdentifier, currentCommitIdentifier);

                if (changedFiles.Count() <= 0)
                {
                    //reason = $"The build was skipped because no files in the latest commit matched the effective change filter.";
                    // continue to the next build
                    return(CodeCheckResult.Skip());
                }

                return(CodeCheckResult.Changed(currentCommitIdentifier));
            }
        }
Пример #6
0
 public async Task EnqueueBuild(string projectId, [FromBody] BuildQueueEntry entry)
 {
     await _queue.EnqueueBuild(entry);
 }