* Added OpenAI to the PipelineAgent
This commit is contained in:
@@ -50,6 +50,9 @@ steps:
|
||||
depends_on: [restore]
|
||||
ai-agent-gate:
|
||||
image: mcr.microsoft.com/dotnet/sdk:latest
|
||||
environment:
|
||||
OPENAI_API_KEY:
|
||||
from_secret: openai_api_key
|
||||
commands:
|
||||
- |
|
||||
set -euf
|
||||
|
||||
@@ -7,4 +7,8 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenAI" Version="2.8.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using System.Xml.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Xml.Linq;
|
||||
using OpenAI;
|
||||
using OpenAI.Chat;
|
||||
|
||||
if (args.Length == 0)
|
||||
{
|
||||
@@ -25,41 +28,75 @@ try
|
||||
.Descendants(ns + "UnitTestResult")
|
||||
.Where(x => (string?)x.Attribute("outcome") == "Failed")
|
||||
.ToList();
|
||||
|
||||
|
||||
var total = doc
|
||||
.Descendants(ns + "UnitTestResult")
|
||||
.Count();
|
||||
|
||||
Console.WriteLine($"AI‑Gate: total tests = {total}, failed = {failed.Count}");
|
||||
|
||||
if (failed.Count == 0)
|
||||
var failuresForModel = failed.Select(f => new
|
||||
{
|
||||
Console.WriteLine("AI‑Gate: All tests passed – proceeding.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Console.WriteLine("AI‑Gate: Listing up to 5 failing tests:");
|
||||
foreach (var f in failed.Take(5))
|
||||
{
|
||||
var name = (string?)f.Attribute("testName") ?? "<no name>";
|
||||
var message = f
|
||||
TestName = (string?)f.Attribute("testName") ?? "<no name>",
|
||||
Message = f
|
||||
.Element(ns + "Output")?
|
||||
.Element(ns + "ErrorInfo")?
|
||||
.Element(ns + "Message")?
|
||||
.Value;
|
||||
.Value
|
||||
}).ToList();
|
||||
|
||||
Console.WriteLine($" - {name}");
|
||||
if (!string.IsNullOrWhiteSpace(message))
|
||||
Console.WriteLine($" {message.Trim()}");
|
||||
var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
|
||||
if (string.IsNullOrWhiteSpace(apiKey))
|
||||
{
|
||||
Console.WriteLine("AI‑Gate: OPENAI_API_KEY not set, blocking by default.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console.WriteLine("AI‑Gate: Blocking pipeline because there are failing tests.");
|
||||
return 1;
|
||||
var client = new OpenAIClient(apiKey);
|
||||
|
||||
var systemPrompt = """
|
||||
Jesteś asystentem DevOps oceniającym wyniki testów .NET.
|
||||
Na podstawie listy błędów:
|
||||
|
||||
- sklasyfikuj każdy błąd jako: CriticalBug, InfraOrConfig, FlakyTest
|
||||
- zwróć JEDEN obiekt JSON w formacie:
|
||||
{
|
||||
"decision": "block" | "allow" | "allow-with-warning",
|
||||
"reason": "krótkie wyjaśnienie po polsku"
|
||||
}
|
||||
|
||||
Decyzja:
|
||||
- "block" gdy jest choć jeden CriticalBug.
|
||||
- "allow-with-warning" gdy są tylko InfraOrConfig lub FlakyTest, ale wygląda to na coś, co trzeba sprawdzić.
|
||||
- "allow" gdy wszystko wskazuje na drobne lub znane flaky testy.
|
||||
Nie dodawaj żadnego tekstu poza JSON.
|
||||
""";
|
||||
|
||||
var userContent = JsonSerializer.Serialize(failuresForModel);
|
||||
|
||||
var chat = client.GetChatClient("gpt-4.1-mini");
|
||||
|
||||
var response = await chat.CompleteChatAsync(new SystemChatMessage(systemPrompt),
|
||||
new UserChatMessage($"Błędy testów:\n{userContent}"));
|
||||
|
||||
var json = response.Value.Content[0].Text;
|
||||
Console.WriteLine("AI‑Gate LLM raw response:");
|
||||
Console.WriteLine(json);
|
||||
|
||||
var decisionDoc = JsonDocument.Parse(json);
|
||||
var decision = decisionDoc.RootElement.GetProperty("decision").GetString();
|
||||
var reason = decisionDoc.RootElement.GetProperty("reason").GetString();
|
||||
|
||||
Console.WriteLine($"AI‑Gate decision: {decision}");
|
||||
Console.WriteLine($"Reason: {reason}");
|
||||
|
||||
return decision switch
|
||||
{
|
||||
"allow" => 0,
|
||||
"allow-with-warning" => 0,
|
||||
_ => 1
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"AI‑Gate: error while reading TRX: {ex.Message}");
|
||||
// Bezpieczniej zablokować pipeline, niż przepuścić w ciemno
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user