feat: add cross-platform release pipeline [CI SKIP]

This commit is contained in:
justme committed 2026-10-04 14:01:26 -07:00
1 parent 26620707a0
commit deceeb19f3
27 files changed
+1036 -18

No files matched your search

@@ -252,9 +252,32 @@ public sealed class AgentEndToEndTests
await using ProbeSimulator probe = await agent.ConnectProbeAsync();
await BackendFixture.EventuallyAsync(async () => (await AgentViewAsync(agent))["probe_connected"]!.GetValue<bool>());
using HttpResponseMessage accepted = await _backend.Admin.PostAsync($"/api/admin/lines/{agent.Id}~{probe.ProbeId}/tests", BackendFixture.Json(new JsonObject { ["plan"] = "hy2_ladder", ["params"] = new JsonObject { ["size"] = 1000 } }));
Assert.True(accepted.StatusCode == System.Net.HttpStatusCode.Accepted, await accepted.Content.ReadAsStringAsync());
string testId = JsonNode.Parse(await accepted.Content.ReadAsStringAsync())!["id"]!.GetValue<string>();
HttpResponseMessage? accepted = null;
string? startFailure = null;
for (int attempt = 0; attempt < 5; attempt++)
{
accepted = await _backend.Admin.PostAsync($"/api/admin/lines/{agent.Id}~{probe.ProbeId}/tests", BackendFixture.Json(new JsonObject { ["plan"] = "hy2_ladder", ["params"] = new JsonObject { ["size"] = 1000 } }));
if (accepted.StatusCode == System.Net.HttpStatusCode.Accepted)
{
break;
}
startFailure = await accepted.Content.ReadAsStringAsync();
string? code = JsonNode.Parse(startFailure)?["code"]?.GetValue<string>();
accepted.Dispose();
accepted = null;
if (code != "probe_offline" || attempt == 4)
{
Assert.Fail($"The test request was rejected: {startFailure}");
}
await BackendFixture.EventuallyAsync(async () => (await AgentViewAsync(agent))["probe_connected"]!.GetValue<bool>(), TimeSpan.FromSeconds(15), "the probe should reconnect after a transient disconnect");
}
HttpResponseMessage acceptedResponse = accepted ?? throw new InvalidOperationException("The test request was not accepted.");
using (acceptedResponse)
{
string testId = JsonNode.Parse(await acceptedResponse.Content.ReadAsStringAsync())!["id"]!.GetValue<string>();
JsonNode test = null!;
await BackendFixture.EventuallyAsync(
@@ -273,6 +296,7 @@ public sealed class AgentEndToEndTests
await BackendFixture.EventuallyAsync(
async () => (await _backend.GetJsonAsync(_backend.Admin, $"/api/admin/raw/chunks?agent_id={agent.Id}"))["items"]!.AsArray().Count(c => c!["kind"]!.GetValue<string>() == "udp_train") == agent.App.Counters.Fragments,
because: (await _backend.GetJsonAsync(_backend.Admin, $"/api/admin/events?agent_id={agent.Id}")).ToJsonString() + $" fragments={agent.App.Counters.Fragments} discarded={agent.App.Counters.FragmentsDiscarded} pending={agent.App.Link.Outbox.PendingCount}/{agent.App.Link.Outbox.PendingBytes} dropped={agent.App.Link.Outbox.Dropped} link={agent.App.Link.IsConnected}");
}
}
[Fact]
@@ -199,3 +199,6 @@ public sealed class ApiBasicsTests
[CollectionDefinition("backend")]
public sealed class BackendCollection : ICollectionFixture<BackendFixture>;
[CollectionDefinition("probe-e2e")]
public sealed class ProbeEndToEndCollection : ICollectionFixture<BackendFixture>;
@@ -36,10 +36,13 @@ public sealed class ArchitectureTests
Path.GetFileNameWithoutExtension(path),
path,
Path.GetDirectoryName(path)!,
[.. items.Where(e => e.Name == "ProjectReference").Select(e => Path.GetFileNameWithoutExtension((string?)e.Attribute("Include") ?? ""))],
[.. items.Where(e => e.Name == "ProjectReference").Select(e => Path.GetFileNameWithoutExtension(NormalizePath((string?)e.Attribute("Include") ?? "")))],
[.. items.Where(e => e.Name == "PackageReference").Select(e => (string?)e.Attribute("Include") ?? "")]);
})];
private static string NormalizePath(string path) =>
path.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar);
private static bool IsTest(Project p) => p.Path.Contains(Path.DirectorySeparatorChar + "tests" + Path.DirectorySeparatorChar, StringComparison.Ordinal);
private static bool IsFleet(Project p) => p.Name.StartsWith("Fleet.", StringComparison.Ordinal) && !IsTest(p);
@@ -3,7 +3,7 @@ using System.Text.Json.Nodes;
namespace Monitor.Backend.Tests;
/// <summary>真实的后端 + 真实的 Agent + 真实的 Probe(都在进程内,回环网络)。</summary>
[Collection("backend")]
[Collection("probe-e2e")]
public sealed class ProbeEndToEndTests
{
private readonly BackendFixture _backend;