summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/marlin.core/functional/GitBinaryClient.cs3
-rw-r--r--src/marlin.web/Controllers/VCSController.cs43
-rw-r--r--src/marlin.web/Models/VersionControlSource.cs2
-rw-r--r--src/marlin.web/Services/VersionControlSyncService.cs1
-rw-r--r--src/marlin.web/Views/Agents/Create.cshtml9
-rw-r--r--src/marlin.web/Views/VCS/Create.cshtml1
-rw-r--r--src/marlin.web/Views/VCS/Details.cshtml74
-rw-r--r--src/marlin.web/Views/VCS/ListSecret.cshtml16
-rw-r--r--src/marlin.web/wwwroot/css/site.css8
9 files changed, 114 insertions, 43 deletions
diff --git a/src/marlin.core/functional/GitBinaryClient.cs b/src/marlin.core/functional/GitBinaryClient.cs
index 001f2c8..3a703da 100644
--- a/src/marlin.core/functional/GitBinaryClient.cs
+++ b/src/marlin.core/functional/GitBinaryClient.cs
@@ -125,6 +125,9 @@ public class GitBinaryClient : IGitClient
if (parts.Length != 2)
continue; // ignore a malformed line rather than throw over one bad entry
+ if (parts[1].EndsWith("^{}", StringComparison.Ordinal))
+ continue; // peeled tag marker from ls-remote, not a real ref/refspec
+
result[parts[1]] = parts[0];
}
diff --git a/src/marlin.web/Controllers/VCSController.cs b/src/marlin.web/Controllers/VCSController.cs
index 8086e99..10ef59b 100644
--- a/src/marlin.web/Controllers/VCSController.cs
+++ b/src/marlin.web/Controllers/VCSController.cs
@@ -22,8 +22,6 @@ public class VCSController(ApplicationDbContext dbContext, VersionControlSyncSer
return this.View(items);
}
- public record SecretOption(Guid Id, string Label);
-
[HttpGet("details/{id}")]
public async Task<IActionResult> Details(Guid id, CancellationToken ct)
{
@@ -37,12 +35,7 @@ public class VCSController(ApplicationDbContext dbContext, VersionControlSyncSer
if (item == null)
return this.NotFound();
- var secretOptions = await dbContext.Secrets
- .Where(x => x.SourceId == id)
- .Select(x => new SecretOption(x.Id, x.Label))
- .ToListAsync(ct);
-
- return this.View((item, secretOptions));
+ return this.View(item);
}
[HttpGet("details/{sourceId}/{commitId}/blobs")]
@@ -87,9 +80,7 @@ public class VCSController(ApplicationDbContext dbContext, VersionControlSyncSer
item.UpstreamUrl = vcs.UpstreamUrl;
item.BranchFilter = vcs.BranchFilter;
- item.MainBranch = vcs.MainBranch;
item.MinPollingInterval = vcs.MinPollingInterval;
- item.AccessSecretId = vcs.AccessSecretId;
await dbContext.SaveChangesAsync(ct);
await syncService.FetchSources(ct);
@@ -97,6 +88,37 @@ public class VCSController(ApplicationDbContext dbContext, VersionControlSyncSer
return this.RedirectToAction("List");
}
+ [HttpPost("details/{sourceId}/secrets/access")]
+ public async Task<IActionResult> SetAccessSecret(Guid sourceId, Guid? secretId, CancellationToken ct)
+ {
+ var item = await dbContext.Sources
+ .FirstOrDefaultAsync(x => x.Id == sourceId, ct);
+
+ if (item == null)
+ return this.NotFound();
+
+ item.AccessSecretId = secretId;
+ await dbContext.SaveChangesAsync(ct);
+ await syncService.FetchSources(ct);
+
+ return this.RedirectToAction("ListSecret", new { sourceId });
+ }
+
+ [HttpPost("details/{sourceId}/main-branch")]
+ public async Task<IActionResult> SetMainBranch(Guid sourceId, string branchName, CancellationToken ct)
+ {
+ var item = await dbContext.Sources
+ .FirstOrDefaultAsync(x => x.Id == sourceId, ct);
+
+ if (item == null)
+ return this.NotFound();
+
+ item.MainBranch = branchName;
+ await dbContext.SaveChangesAsync(ct);
+
+ return this.RedirectToAction("Details", new { id = sourceId });
+ }
+
[HttpGet("create")]
public async Task<IActionResult> Create()
{
@@ -107,6 +129,7 @@ public class VCSController(ApplicationDbContext dbContext, VersionControlSyncSer
public async Task<IActionResult> CreatePost(VersionControlSource vcs, CancellationToken ct)
{
vcs.Id = Guid.Empty;
+ vcs.MainBranch = "";
await dbContext.AddAsync(vcs, ct);
await dbContext.SaveChangesAsync(ct);
diff --git a/src/marlin.web/Models/VersionControlSource.cs b/src/marlin.web/Models/VersionControlSource.cs
index 270df12..12d5a7a 100644
--- a/src/marlin.web/Models/VersionControlSource.cs
+++ b/src/marlin.web/Models/VersionControlSource.cs
@@ -5,7 +5,7 @@ public class VersionControlSource
public Guid Id { get; set; }
public string UpstreamUrl { get; set; }
- public string MainBranch { get; set; }
+ public string? MainBranch { get; set; }
public string BranchFilter { get; set; }
public int MinPollingInterval { get; set; }
diff --git a/src/marlin.web/Services/VersionControlSyncService.cs b/src/marlin.web/Services/VersionControlSyncService.cs
index cd75ed6..8f2046e 100644
--- a/src/marlin.web/Services/VersionControlSyncService.cs
+++ b/src/marlin.web/Services/VersionControlSyncService.cs
@@ -142,6 +142,7 @@ public class VersionControlSyncService : BackgroundService
await dbContext.SourceCommits
.Include(x => x.Branches)
.Where(x => !x.Branches.Any())
+ .Where(x => !dbContext.Jobs.Any(j => j.CommitId == x.Id))
.ExecuteDeleteAsync(ct);
}
diff --git a/src/marlin.web/Views/Agents/Create.cshtml b/src/marlin.web/Views/Agents/Create.cshtml
index 4f0f31a..e112eeb 100644
--- a/src/marlin.web/Views/Agents/Create.cshtml
+++ b/src/marlin.web/Views/Agents/Create.cshtml
@@ -1,8 +1,13 @@
@using marlin.core.models
<form method="post" asp-action="Create">
- Name: <input type="text" name="@nameof(Agent.Name)" /><br/>
- Max Concurrent Jobs: <input type="number" name="@nameof(Agent.MaxConcurrentJobs)" value="1"/><br/>
+ <dl>
+ <dt>Name</dt>
+ <dd><input type="text" name="@nameof(Agent.Name)" placeholder="myagent-1"/></dd>
+
+ <dt>Max Concurrent Jobs</dt>
+ <dd><input type="number" name="@nameof(Agent.MaxConcurrentJobs)" value="1"/></dd>
+ </dl>
<button type="submit">Create</button>
</form>
diff --git a/src/marlin.web/Views/VCS/Create.cshtml b/src/marlin.web/Views/VCS/Create.cshtml
index e04592d..5f76192 100644
--- a/src/marlin.web/Views/VCS/Create.cshtml
+++ b/src/marlin.web/Views/VCS/Create.cshtml
@@ -4,7 +4,6 @@
<form method="post" asp-action="Create">
URL: <input type="text" name="@nameof(VersionControlSource.UpstreamUrl)" /><br/>
Filter: <input type="text" name="@nameof(VersionControlSource.BranchFilter)" /><br/>
- Main Branch: <input type="text" name="@nameof(VersionControlSource.MainBranch)" /><br/>
Polling Interval: <input type="number" name="@nameof(VersionControlSource.MinPollingInterval)" /><br/>
<button type="submit">Create</button>
</form>
diff --git a/src/marlin.web/Views/VCS/Details.cshtml b/src/marlin.web/Views/VCS/Details.cshtml
index a9ef0ea..44fa91e 100644
--- a/src/marlin.web/Views/VCS/Details.cshtml
+++ b/src/marlin.web/Views/VCS/Details.cshtml
@@ -1,55 +1,73 @@
@using marlin.core
@using marlin.core.models
-@using marlin.web.Controllers
-@model (VersionControlSource Source, List<VCSController.SecretOption> SecretOptions)
+@model VersionControlSource
-<form method="post" asp-route-id="@Model.Source.Id" asp-action="Edit">
- URL: <input type="text" name="@nameof(VersionControlSource.UpstreamUrl)" value="@Model.Source.UpstreamUrl"/><br/>
- Filter: <input type="text" name="@nameof(VersionControlSource.BranchFilter)" value="@Model.Source.BranchFilter"/><br/>
- Main Branch: <input type="text" name="@nameof(VersionControlSource.MainBranch)" value="@Model.Source.MainBranch"/><br/>
- Polling Interval: <input type="number" name="@nameof(VersionControlSource.MinPollingInterval)" value="@Model.Source.MinPollingInterval"/><br/>
- Access Secret:
- <select name="@nameof(VersionControlSource.AccessSecretId)">
- <option value="">(none)</option>
- @foreach (var secret in Model.SecretOptions)
- {
- <option value="@secret.Id" selected="@(secret.Id == Model.Source.AccessSecretId)">@secret.Label</option>
- }
- </select><br/>
- <button type="submit">Save</button>
-</form>
+<div class="row">
+ <div class="col">
+ <h3>Details</h3>
+ <hr/>
+ <form method="post" asp-route-id="@Model.Id" asp-action="Edit">
+ <dl>
+ <dt>URL</dt>
+ <dd><input type="text" name="@nameof(VersionControlSource.UpstreamUrl)" value="@Model.UpstreamUrl"/></dd>
+ <dt>Filter</dt>
+ <dd><input type="text" name="@nameof(VersionControlSource.BranchFilter)" value="@Model.BranchFilter"/></dd>
+
+ <dt>Polling Interval</dt>
+ <dd><input type="number" name="@nameof(VersionControlSource.MinPollingInterval)" value="@Model.MinPollingInterval"/></dd>
+ </dl>
+
+ <button type="submit">Save</button>
+ <a asp-action="ListSecret" asp-route-sourceId="@Model.Id">Secrets</a>
+ <a asp-action="List">Back</a>
+ </form>
+ </div>
+</div>
+<br/>
+
+<h3>Branches</h3>
+<hr/>
<table>
<thead>
<tr>
- <th></th>
<th>branch</th>
<th>commit</th>
- <th>status</th>
+ <th>actions</th>
</tr>
</thead>
<tbody>
- @foreach (var branch in Model.Source.Branches)
+ @foreach (var branch in Model.Branches.OrderByDescending(b => b.Name == Model.MainBranch))
{
- <tr>
- <td>@(branch.Name == Model.Source.MainBranch ? "@" : "")</td>
- <td>@branch.Name</td>
+ <tr class="@(branch.Name == Model.MainBranch ? "highlighted" : "")">
+ <td>
+ @branch.Name
+ @if (branch.Name == Model.MainBranch)
+ {
+ <span>(primary)</span>
+ }
+ </td>
<td>@branch.Commit.Hash</td>
<td>
@if (branch.Commit.BlobsFetched)
{
<a asp-action="Blobs" asp-route-commitId="@branch.CommitId" asp-route-sourceId="@branch.SourceId">blobs</a>
}
-
+
@if (branch.Commit.WorkflowScanned)
{
<a asp-action="Workflow" asp-route-commitId="@branch.CommitId" asp-route-sourceId="@branch.SourceId">workflow</a>
}
+
+ @if (branch.Name != Model.MainBranch)
+ {
+ <form method="post" asp-action="SetMainBranch" asp-route-sourceId="@Model.Id" style="display:inline">
+ <input type="hidden" name="branchName" value="@branch.Name"/>
+ <button type="submit" class="btn btn-link p-0">make primary</button>
+ </form>
+ }
</td>
</tr>
}
</tbody>
-</table>
-
-<a asp-action="ListSecret" asp-route-sourceId="@Model.Source.Id">Secrets</a>
-<a asp-action="List">Back</a>
+</table> \ No newline at end of file
diff --git a/src/marlin.web/Views/VCS/ListSecret.cshtml b/src/marlin.web/Views/VCS/ListSecret.cshtml
index 25db7fe..84e3061 100644
--- a/src/marlin.web/Views/VCS/ListSecret.cshtml
+++ b/src/marlin.web/Views/VCS/ListSecret.cshtml
@@ -1,5 +1,19 @@
@model (VersionControlSource Source, List<ISecret> Secrets)
+<form method="post" asp-action="SetAccessSecret" asp-route-sourceId="@Model.Source.Id">
+ <label>
+ Access Secret
+ <select name="secretId">
+ <option value="">(none)</option>
+ @foreach (var secret in Model.Secrets)
+ {
+ <option value="@secret.Id" selected="@(secret.Id == Model.Source.AccessSecretId)">@secret.Label</option>
+ }
+ </select>
+ </label>
+ <button type="submit">Save</button>
+</form>
+
<a asp-action="CreateSecret" asp-route-sourceId="@Model.Source.Id">New</a>
<table>
@@ -42,4 +56,4 @@
</tbody>
</table>
-<a asp-action="Details", asp-route-id="@Model.Source.Id">back</a>
+<a asp-action="Details" asp-route-id="@Model.Source.Id">back</a>
diff --git a/src/marlin.web/wwwroot/css/site.css b/src/marlin.web/wwwroot/css/site.css
index fa66346..d5d64db 100644
--- a/src/marlin.web/wwwroot/css/site.css
+++ b/src/marlin.web/wwwroot/css/site.css
@@ -66,6 +66,14 @@ table tr:hover {
background-color: #fafafa
}
+table tr.highlighted {
+ background-color: #e1eaf6;
+}
+
+table tr.highlighted:hover {
+ background-color: #d3e9f6;
+}
+
th, td {
border: 1px solid #ccc;
text-align: left;