public Task <Guid> EnqueueBuild(BuildQueueEntry entry) { if (entry.BuildQueueID == Guid.Empty) { entry.BuildQueueID = Guid.NewGuid(); } QueueItems.Add(entry); return(Task.FromResult(entry.BuildQueueID)); }
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); }
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); } }
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"]); }
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)); } }
public async Task EnqueueBuild(string projectId, [FromBody] BuildQueueEntry entry) { await _queue.EnqueueBuild(entry); }