summaryrefslogtreecommitdiff
path: root/src/marlin.web/Controllers
diff options
context:
space:
mode:
authorMelodi <62381002+Melodi17@users.noreply.github.com>2026-09-03 23:06:05 +1000
committerMelodi <62381002+Melodi17@users.noreply.github.com>2026-09-03 23:06:05 +1000
commit7c33b3f334cf91918add7af08866f2ea37ed9c3f (patch)
tree8095a2d65e87a808fac62b47e315a4875cc86b73 /src/marlin.web/Controllers
chore: initial commit
Diffstat (limited to 'src/marlin.web/Controllers')
-rw-r--r--src/marlin.web/Controllers/DispatchController.cs10
-rw-r--r--src/marlin.web/Controllers/HomeController.cs28
-rw-r--r--src/marlin.web/Controllers/JobsController.cs65
-rw-r--r--src/marlin.web/Controllers/VCSController.cs68
4 files changed, 171 insertions, 0 deletions
diff --git a/src/marlin.web/Controllers/DispatchController.cs b/src/marlin.web/Controllers/DispatchController.cs
new file mode 100644
index 0000000..6b2285c
--- /dev/null
+++ b/src/marlin.web/Controllers/DispatchController.cs
@@ -0,0 +1,10 @@
+namespace marlin.web.Controllers;
+
+using Microsoft.AspNetCore.Mvc;
+
+[Route("api/dispatch")]
+[ApiController]
+public class DispatchController : ControllerBase
+{
+
+} \ No newline at end of file
diff --git a/src/marlin.web/Controllers/HomeController.cs b/src/marlin.web/Controllers/HomeController.cs
new file mode 100644
index 0000000..243f66d
--- /dev/null
+++ b/src/marlin.web/Controllers/HomeController.cs
@@ -0,0 +1,28 @@
+using System.Diagnostics;
+using Microsoft.AspNetCore.Mvc;
+using marlin.web.Models;
+
+namespace marlin.web.Controllers;
+
+public class HomeController : Controller
+{
+ public IActionResult Index()
+ {
+ return View();
+ }
+
+ public IActionResult Privacy()
+ {
+ return View();
+ }
+
+ [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
+ public IActionResult Error()
+ {
+ return View(
+ new ErrorViewModel
+ {
+ RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
+ });
+ }
+} \ No newline at end of file
diff --git a/src/marlin.web/Controllers/JobsController.cs b/src/marlin.web/Controllers/JobsController.cs
new file mode 100644
index 0000000..1cfdadb
--- /dev/null
+++ b/src/marlin.web/Controllers/JobsController.cs
@@ -0,0 +1,65 @@
+namespace marlin.web.Controllers;
+
+using core.models;
+using Data;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Util;
+
+[Route("jobs")]
+public class JobsController(ApplicationDbContext dbContext) : Controller
+{
+
+ // list jobs (pending, active, cancelled, success, failed), filter to vcs, filter to recipe
+ public record JobListFilter(JobStatus? Status = null, Guid? Vcs = null, string? Ref = null, string? Recipe = null);
+
+ [HttpGet("list")]
+ public async Task<IActionResult> List([FromQuery] JobListFilter filter, CancellationToken ct)
+ {
+ var results = await dbContext.Jobs
+ .WhereIf(filter.Status != null, x => x.Status == filter.Status)
+ .WhereIf(filter.Vcs != null, x => x.SourceId == filter.Vcs)
+ .WhereIf(filter.Ref != null, x => x.Ref == filter.Ref)
+ .WhereIf(filter.Recipe != null, x => x.Recipe == filter.Recipe)
+ .OrderByDescending(x => x.CreatedAt)
+
+ .Include(x => x.Source)
+ .Include(x => x.Agent)
+ .ToListAsync(ct);
+
+ return this.View(results);
+ }
+
+ [HttpGet("spawn")]
+ public async Task<IActionResult> Spawn()
+ {
+ return this.View();
+ }
+
+ public record JobSpawnRequest(Guid Vcs, string Ref, string Commit, string Recipe);
+
+ [HttpPost("spawn")]
+ public async Task<IActionResult> SpawnPost(JobSpawnRequest request, CancellationToken ct)
+ {
+ Job job = new()
+ {
+ SourceId = request.Vcs,
+ Ref = request.Ref,
+ Commit = request.Commit,
+ Recipe = request.Recipe,
+
+ CreatedAt = DateTime.UtcNow,
+ CreatedReason = "user created",
+ Status = JobStatus.Pending
+ };
+
+ await dbContext.Jobs.AddAsync(job, ct);
+ await dbContext.SaveChangesAsync(ct);
+
+ return this.RedirectToAction("Details", new { id = job.Id });
+ }
+
+ // cancel job
+
+ // details job (recipe, status, agent, target, plan, log, artifacts)
+} \ No newline at end of file
diff --git a/src/marlin.web/Controllers/VCSController.cs b/src/marlin.web/Controllers/VCSController.cs
new file mode 100644
index 0000000..86f655b
--- /dev/null
+++ b/src/marlin.web/Controllers/VCSController.cs
@@ -0,0 +1,68 @@
+namespace marlin.web.Controllers;
+
+using core;
+using core.models;
+using Data;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+
+[Route("vcs")]
+public class VCSController(ApplicationDbContext dbContext) : Controller
+{
+ [HttpGet("list")]
+ public async Task<IActionResult> List(CancellationToken ct)
+ {
+ var items = await dbContext.Sources
+ .ToListAsync(ct);
+
+ return this.View(items);
+ }
+
+ [HttpGet("details/{id}")]
+ public async Task<IActionResult> Details(Guid id, CancellationToken ct)
+ {
+ var item = await dbContext.Sources
+ .FirstOrDefaultAsync(x => x.Id == id, ct);
+
+ if (item == null)
+ return this.NotFound();
+
+ return this.View(item);
+ }
+
+ [HttpPost("edit/{id}")]
+ public async Task<IActionResult> Edit(Guid id, VersionControlSource vcs, CancellationToken ct)
+ {
+ var item = await dbContext.Sources
+ .FirstOrDefaultAsync(x => x.Id == id, ct);
+
+ if (item == null)
+ return this.NotFound();
+
+ item.UpstreamUrl = vcs.UpstreamUrl;
+ item.BranchFilter = vcs.BranchFilter;
+ item.MainBranch = vcs.MainBranch;
+ item.MinPollingInterval = vcs.MinPollingInterval;
+
+ await dbContext.SaveChangesAsync(ct);
+
+ return this.RedirectToAction("List");
+ }
+
+ [HttpGet("create")]
+ public async Task<IActionResult> Create()
+ {
+ return this.View();
+ }
+
+ [HttpPost("create")]
+ public async Task<IActionResult> CreatePost(VersionControlSource vcs, CancellationToken ct)
+ {
+ vcs.Id = Guid.Empty;
+
+ await dbContext.AddAsync(vcs, ct);
+ await dbContext.SaveChangesAsync(ct);
+
+ return this.RedirectToAction("Details", new { id = vcs.Id });
+ }
+} \ No newline at end of file