OPC # 0006: OPC Git Trunk-Based management

This commit is contained in:
amadzarak
2026-04-26 11:09:15 -04:00
parent b26cc1c0b6
commit 6396fc8cc5
4 changed files with 27 additions and 11 deletions
@@ -1,5 +1,6 @@
using ControlPlane.Core.Models;
using ControlPlane.Core.Services;
using LibGit2Sharp;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
@@ -24,9 +25,14 @@ public class ProjectBuildService(
return
[
new("Clarity.Server", BuildKind.DotnetProject, "Clarity.Server/Clarity.Server.csproj"),
new("Clarity.ServiceDefaults", BuildKind.DotnetProject, "Clarity.ServiceDefaults/Clarity.ServiceDefaults.csproj"),
new("frontend (Clarity.Server)", BuildKind.NpmProject, "frontend"),
// ── Solution-level builds (primary targets) ──────────────────────
new("Clarity Solution", BuildKind.SolutionBuild, "Clarity/Clarity.slnx"),
new("ControlPlane Solution", BuildKind.SolutionBuild, "OPC/ControlPlane.slnx"),
// ── Individual Clarity projects ───────────────────────────────────
new("Clarity.Server", BuildKind.DotnetProject, "Clarity/Clarity.Server/Clarity.Server.csproj"),
new("Clarity.ServiceDefaults", BuildKind.DotnetProject, "Clarity/Clarity.ServiceDefaults/Clarity.ServiceDefaults.csproj"),
new("frontend (Clarity.Server)", BuildKind.NpmProject, "Clarity/frontend"),
];
}
@@ -53,6 +59,16 @@ public class ProjectBuildService(
record.Log.Add("──────────────────────────────────────");
onLine($"▶ Building {def.Name}");
// Capture HEAD SHA so the build is traceable to a specific commit
try
{
using var gitRepo = new Repository(RepoRoot);
record.CommitSha = gitRepo.Head.Tip?.Sha;
if (record.CommitSha is not null)
record.Log.Add($" Commit: {record.CommitSha[..8]}");
}
catch { /* not a git repo or no commits yet */ }
try
{
var (exe, args, workDir) = def.Kind == BuildKind.NpmProject
+1 -1
View File
@@ -4,7 +4,7 @@ using System.Text.Json.Serialization;
namespace ControlPlane.Core.Models;
public enum BuildStatus { Running, Succeeded, Failed }
public enum BuildKind { DockerImage, DotnetProject, NpmProject }
public enum BuildKind { DockerImage, DotnetProject, NpmProject, SolutionBuild }
/// <summary>
/// Persisted record of a single build run — image build, dotnet build, or npm build.
@@ -64,7 +64,7 @@ function GitHistoryPanel({ relativePath }: { relativePath: string }) {
<p style={{ fontSize: '0.75rem', color: '#8f99a8', marginTop: '0.5rem' }}>No commits found for this path.</p>
)}
{commits.length > 0 && (
<HTMLTable className="bp5-html-table-condensed bp5-html-table-striped" style={{ width: '100%', marginTop: '0.5rem', fontSize: '0.72rem' }}>
<HTMLTable className="bp6-html-table-condensed bp6-html-table-striped" style={{ width: '100%', marginTop: '0.5rem', fontSize: '0.72rem' }}>
<thead>
<tr>
<th style={{ width: 60 }}>Commit</th>
@@ -250,9 +250,9 @@ export default function BuildMonitorPage() {
useEffect(() => { (async () => { await load(); })(); }, []);
// Find latest build per project
const lastBuildFor = (name: string): BuildRecord | undefined =>
history.find((b) => b.target.includes(name.split(' ')[0]) || b.target.endsWith(name));
// Find latest build per project — match exactly by relativePath (= build target)
const lastBuildFor = (project: ProjectDefinition): BuildRecord | undefined =>
history.find((b) => b.target === project.relativePath);
return (
<>
@@ -292,7 +292,7 @@ export default function BuildMonitorPage() {
<ProjectCard
key={p.name}
project={p}
lastBuild={lastBuildFor(p.name)}
lastBuild={lastBuildFor(p)}
onBuilt={load}
/>
))}
@@ -226,7 +226,7 @@ export default function PipelinesPage() {
try {
const [r, b] = await Promise.all([getReleaseHistory(), getBuildHistory()]);
setReleases(r);
setBuilds(b.filter((b) => b.kind === 'DockerImage'));
setBuilds(b.filter((b) => b.kind === 'SolutionBuild'));
} finally {
setLoading(false);
}
@@ -252,7 +252,7 @@ export default function PipelinesPage() {
</section>
<section>
<h3 style={{ margin: '0 0 0.5rem' }}>Image Build History</h3>
<h3 style={{ margin: '0 0 0.5rem' }}>Solution Build History</h3>
{loading ? <Spinner size={20} /> : <BuildHistoryTable records={builds} />}
</section>
</>