diff --git a/Alchegos.Gitea.Webhook.csproj b/Alchegos.Gitea.Webhook.csproj
index b89cedd..ee6b80a 100644
--- a/Alchegos.Gitea.Webhook.csproj
+++ b/Alchegos.Gitea.Webhook.csproj
@@ -12,15 +12,12 @@
.dockerignore
-
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/AlchegosEventDispatcher.cs b/AlchegosEventDispatcher.cs
new file mode 100644
index 0000000..b920816
--- /dev/null
+++ b/AlchegosEventDispatcher.cs
@@ -0,0 +1,6 @@
+namespace Alchegos.Gitea.Webhook;
+
+public class AlchegosEventDispatcher
+{
+
+}
\ No newline at end of file
diff --git a/GiteaEventDispatcher.cs b/GiteaEventDispatcher.cs
new file mode 100644
index 0000000..7b78038
--- /dev/null
+++ b/GiteaEventDispatcher.cs
@@ -0,0 +1,25 @@
+using System.Text.Json.Nodes;
+using Alchegos.Core.Services.RabbitMQ;
+using Alchegos.Gitea.Webhook.Handlers;
+
+namespace Alchegos.Gitea.Webhook;
+
+public class GiteaEventDispatcher
+{
+ private Dictionary Handlers { get; set; } = new (StringComparer.OrdinalIgnoreCase)
+ {
+ {"push", new PushEventHandler()},
+ {"issues", new IssuesEventHandler()},
+ {"issue_comment", new IssueCommentEventHandler()},
+ {"pull_request", new PullRequestEventHandler()}
+ };
+
+
+ public async Task DispatchAsync(string eventType, JsonNode payload, IRabbitPublisher publisher)
+ {
+ if (Handlers.TryGetValue(eventType, out var handler))
+ {
+ await handler.HandleAsync(payload, publisher);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Handlers/IAlchegosEventHandler.cs b/Handlers/IAlchegosEventHandler.cs
new file mode 100644
index 0000000..3442df1
--- /dev/null
+++ b/Handlers/IAlchegosEventHandler.cs
@@ -0,0 +1,6 @@
+namespace Alchegos.Gitea.Webhook.Handlers;
+
+public interface IAlchegosEventHandler : IWebhookEventHandler
+{
+
+}
\ No newline at end of file
diff --git a/Handlers/IGiteaEventHandler.cs b/Handlers/IGiteaEventHandler.cs
new file mode 100644
index 0000000..3eec880
--- /dev/null
+++ b/Handlers/IGiteaEventHandler.cs
@@ -0,0 +1,6 @@
+namespace Alchegos.Gitea.Webhook.Handlers;
+
+public interface IGiteaEventHandler: IWebhookEventHandler
+{
+
+}
\ No newline at end of file
diff --git a/Handlers/IWebhookEventHandler.cs b/Handlers/IWebhookEventHandler.cs
new file mode 100644
index 0000000..a8bcce9
--- /dev/null
+++ b/Handlers/IWebhookEventHandler.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Nodes;
+using Alchegos.Core.Services.RabbitMQ;
+
+namespace Alchegos.Gitea.Webhook.Handlers;
+
+public interface IWebhookEventHandler
+{
+ Task HandleAsync(JsonNode payload, IRabbitPublisher publisher);
+}
\ No newline at end of file
diff --git a/Handlers/IssueCommentEventHandler.cs b/Handlers/IssueCommentEventHandler.cs
new file mode 100644
index 0000000..827acb5
--- /dev/null
+++ b/Handlers/IssueCommentEventHandler.cs
@@ -0,0 +1,24 @@
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using Alchegos.Core.Services.RabbitMQ;
+
+namespace Alchegos.Gitea.Webhook.Handlers;
+
+public class IssueCommentEventHandler : IGiteaEventHandler
+{
+ public async Task HandleAsync(JsonNode payload, IRabbitPublisher publisher)
+ {
+ if (payload["action"]?.ToString() != "created")
+ return;
+
+ var message = new Dictionary
+ {
+ {"repo_url", payload["repository"]?["url"]?.ToString()},
+ {"repo_owner", payload["repository"]?["owner"]?["login"]?.ToString()},
+ {"repo_name", payload["repository"]?["name"]?.ToString()},
+ {"issue_id", payload["issue"]?["id"]?.ToString()},
+ {"comment_id", payload["comment"]?["id"]?.ToString()},
+ };
+ await publisher.PublishAsync("alchegos", "issue_commented", JsonSerializer.Serialize(message));
+ }
+}
diff --git a/Handlers/IssuesEventHandler.cs b/Handlers/IssuesEventHandler.cs
new file mode 100644
index 0000000..da55969
--- /dev/null
+++ b/Handlers/IssuesEventHandler.cs
@@ -0,0 +1,50 @@
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using Alchegos.Core.Services.RabbitMQ;
+
+namespace Alchegos.Gitea.Webhook.Handlers;
+
+public class IssuesEventHandler : IGiteaEventHandler
+{
+ public async Task HandleAsync(JsonNode payload, IRabbitPublisher publisher)
+ {
+ string action = payload["action"]?.ToString() ?? "";
+ string repo_url = payload["repository"]?["url"]?.ToString();
+ string repo_owner = payload["repository"]?["owner"]?["login"]?.ToString();
+ string repo_name = payload["repository"]?["name"]?.ToString();
+ string issue_url = payload["issue"]?["url"]?.ToString();
+ string issue_id = payload["issue"]?["id"]?.ToString();
+
+ var labels = payload["issue"]?["labels"]?.AsArray() ?? new JsonArray();
+
+ var routingKeys = new Dictionary
+ {
+ {"status/ready", "ready_to_develop"},
+ {"status/completed", "task_completed"}
+ };
+
+ if (action is "opened" or "label_updated")
+ {
+ foreach (var label in labels)
+ {
+ string labelName = label["name"]?.ToString().Trim() ?? label.ToString().Trim();
+ if (routingKeys.TryGetValue(labelName, out string routingKey))
+ {
+ var message = new Dictionary
+ {
+ { "repo_url", repo_url },
+ { "repo_owner", repo_owner },
+ { "repo_name", repo_name },
+ { "issue_url", issue_url },
+ { "issue_id", issue_id },
+ };
+ await publisher.PublishAsync(
+ exchange: "alchegos",
+ routingKey: routingKey,
+ message: JsonSerializer.Serialize(message));
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/Handlers/ProjectPlanEventHandler.cs b/Handlers/ProjectPlanEventHandler.cs
new file mode 100644
index 0000000..adcf791
--- /dev/null
+++ b/Handlers/ProjectPlanEventHandler.cs
@@ -0,0 +1,32 @@
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using Alchegos.Core.Services.RabbitMQ;
+
+namespace Alchegos.Gitea.Webhook.Handlers;
+
+public class ProjectPlanEventHandler : IGiteaEventHandler
+{
+ public async Task HandleAsync(JsonNode payload, IRabbitPublisher publisher)
+ {
+ string projectName = payload["title"]?.ToString();
+ string action = payload["action"]?.ToString();
+ string plan = payload["content"]?.ToString();
+
+ Dictionary routingKeys = new Dictionary
+ {
+ {"create", "new_project_plan_created"},
+ {"update", "project_plan_updated"},
+ };
+
+ Dictionary message = new()
+ {
+ { "project_name", projectName },
+ { "project_plan", plan }
+ };
+ await publisher.PublishAsync(
+ exchange: "alchegos",
+ routingKey: routingKeys.GetValueOrDefault(action, ""),
+ message: JsonSerializer.Serialize(message)
+ );
+ }
+}
\ No newline at end of file
diff --git a/Handlers/PullRequestEventHandler.cs b/Handlers/PullRequestEventHandler.cs
new file mode 100644
index 0000000..c79d952
--- /dev/null
+++ b/Handlers/PullRequestEventHandler.cs
@@ -0,0 +1,49 @@
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using Alchegos.Core.Services.RabbitMQ;
+
+namespace Alchegos.Gitea.Webhook.Handlers;
+
+public class PullRequestEventHandler : IGiteaEventHandler
+{
+ public async Task HandleAsync(JsonNode payload, IRabbitPublisher publisher)
+ {
+ string action = payload["action"]?.ToString() ?? "";
+ string repo_url = payload["repository"]?["url"]?.ToString();
+ string repo_owner = payload["repository"]?["owner"]?["login"]?.ToString();
+ string repo_name = payload["repository"]?["name"]?.ToString();
+ string branch = payload["pull_request"]?["head"]?["ref"]?.ToString();
+
+ JsonArray labels = payload["pull_request"]?["labels"]?.AsArray() ?? new JsonArray();
+
+ Dictionary routingKeys = new Dictionary
+ {
+ {"status/pending_review", "pull_request_pending_review"},
+ {"status/pending_test", "pull_request_pending_test"}
+ };
+
+ if (action is "opened" or "label_updated")
+ {
+ foreach (JsonNode label in labels)
+ {
+ string labelName = label["name"]?.ToString().Trim() ?? label.ToString().Trim();
+ if (routingKeys.TryGetValue(labelName, out string routingKey))
+ {
+ Dictionary message = new Dictionary
+ {
+ {"repo_url", repo_url},
+ {"repo_owner", repo_owner},
+ {"repo_name", repo_name},
+ {"branch", branch}
+ };
+ await publisher.PublishAsync(
+ exchange: "alchegos",
+ routingKey: routingKey,
+ message: JsonSerializer.Serialize(message)
+ );
+ break;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Handlers/PushEventHandler.cs b/Handlers/PushEventHandler.cs
new file mode 100644
index 0000000..92631de
--- /dev/null
+++ b/Handlers/PushEventHandler.cs
@@ -0,0 +1,34 @@
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using Alchegos.Core.Services.RabbitMQ;
+
+namespace Alchegos.Gitea.Webhook.Handlers;
+
+public class PushEventHandler : IGiteaEventHandler
+{
+ public async Task HandleAsync(JsonNode payload, IRabbitPublisher publisher)
+ {
+ string branch = payload["ref"]?.ToString()?.Replace("refs/heads/", "") ?? "";
+ if (branch == "main")
+ return;
+
+ JsonArray commits = payload["commits"]?.AsArray() ?? new JsonArray();
+ foreach (var commit in commits)
+ {
+ if (commit["message"]?.ToString()?.Trim() == "init")
+ {
+ Dictionary message = new Dictionary
+ {
+ {"repo_url", payload["repository"]?["url"]?.ToString()},
+ {"repo_owner", payload["repository"]?["owner"]?["login"]?.ToString()},
+ {"repo_name", payload["repository"]?["name"]?.ToString()}
+ };
+ await publisher.PublishAsync(
+ exchange: "alchegos",
+ routingKey:"project_initialized",
+ message: JsonSerializer.Serialize(message));
+ break;
+ }
+ }
+ }
+}
diff --git a/Models/GiteaWebhookPayload.cs b/Models/GiteaWebhookPayload.cs
deleted file mode 100644
index 1d66fa9..0000000
--- a/Models/GiteaWebhookPayload.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-namespace Alchegos.Gitea.Webhook.Models;
-using System.Text.Json.Serialization;
-
-public class GiteaWebhookPayload
-{
- [JsonPropertyName("repository")]
- public Repository? Repository { get; set; }
-
- [JsonPropertyName("pusher")]
- public User? Pusher { get; set; }
-
- [JsonPropertyName("commits")]
- public List? Commits { get; set; }
-
- [JsonPropertyName("head_commit")]
- public CommitInfo? HeadCommit { get; set; }
-
-}
-
-public class Repository
-{
- [JsonPropertyName("name")]
- public string? Name { get; set; }
-}
-
-public class User
-{
- [JsonPropertyName("username")]
- public string? UserName { get; set; }
-}
-
-public class CommitInfo
-{
- [JsonPropertyName("id")]
- public string? Id { get; set; }
-
- [JsonPropertyName("message")]
- public string? Message { get; set; }
-}
diff --git a/Program.cs b/Program.cs
index c98edd5..efc018a 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,9 +1,11 @@
+using System.Text.Json.Nodes;
using Alchegos.Core;
using Alchegos.Core.Services.RabbitMQ;
+using Alchegos.Gitea.Webhook;
GlobalRegistry.Instance.Start();
-var builder = WebApplication.CreateBuilder(args);
+WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Services.Configure(
@@ -14,26 +16,23 @@ builder.Services.AddSingleton();
builder.Services.AddSingleton();
builder.Services.AddSingleton();
-var app = builder.Build();
-var logger = app.Services.GetRequiredService>();
+builder.Services.AddSingleton();
+WebApplication app = builder.Build();
+ILogger logger = app.Services.GetRequiredService>();
logger.LogInformation("Starting web hook /webhook/gitea");
-app.MapPost("/webhook/gitea", async (HttpRequest request, HttpResponse response, IRabbitPublisher publisher) =>
+app.MapPost("/webhook/gitea",
+ async (
+ HttpRequest request,
+ HttpResponse response,
+ IRabbitPublisher publisher,
+ GiteaEventDispatcher dispatcher
+ ) =>
{
- logger.LogInformation("Received gitea webhook request");
- using var reader = new StreamReader(request.Body);
- var jsonBody = await reader.ReadToEndAsync();
-
- var giteaEvent = request.Headers["X-Gitea-Event"].ToString() ?? "unknown";
-
- logger.LogInformation($"Received gitea webhook post: {giteaEvent}");
- logger.LogInformation($" {jsonBody}");
-
- await publisher.PublishAsync(
- exchange: "gitea.webhook.exchange",
- routingKey: giteaEvent,
- message: jsonBody
- );
- response.StatusCode = 200;
- await response.WriteAsync(jsonBody);
+ string jsonBody = await new StreamReader(request.Body).ReadToEndAsync();
+ string giteaEvent = request.Headers["X-Gitea-Event"].ToString() ?? "unknown";
+ JsonNode payload = JsonNode.Parse(jsonBody);
+ if(payload is not null)
+ await dispatcher.DispatchAsync(giteaEvent, payload, publisher);
+ return Results.Ok();
});
app.Run();
\ No newline at end of file