fix(worker): kept worktree in a company repo opens a PR, unexpected ADO/git errors never fail a task start
This commit is contained in:
@@ -45,8 +45,6 @@ public sealed class WorktreeRepository
|
||||
.SetProperty(w => w.MergeCommit, mergeCommit), ct);
|
||||
}
|
||||
|
||||
/// <summary>Records a successful auto-rebase: the branch's fork point moves to the rebased-onto
|
||||
/// commit and its head moves to the new tip <c>git rebase</c> produced.</summary>
|
||||
/// <summary>Stores the draft PR an approve in a company repo created or reused.</summary>
|
||||
public async Task SetPullRequestUrlAsync(string taskId, string url, CancellationToken ct = default)
|
||||
{
|
||||
@@ -55,6 +53,8 @@ public sealed class WorktreeRepository
|
||||
.ExecuteUpdateAsync(s => s.SetProperty(w => w.PullRequestUrl, url), ct);
|
||||
}
|
||||
|
||||
/// <summary>Records a successful auto-rebase: the branch's fork point moves to the rebased-onto
|
||||
/// commit and its head moves to the new tip <c>git rebase</c> produced.</summary>
|
||||
public async Task SetRebasedAsync(string taskId, string baseCommit, string headCommit, CancellationToken ct = default)
|
||||
{
|
||||
await _context.Worktrees
|
||||
|
||||
@@ -121,7 +121,7 @@ public sealed class AzureDevOpsClient
|
||||
private static string StripHeads(string branch) =>
|
||||
branch.StartsWith("refs/heads/", StringComparison.Ordinal) ? branch["refs/heads/".Length..] : branch;
|
||||
|
||||
private async Task<JsonNode> SendAsync(
|
||||
private async Task<JsonObject> SendAsync(
|
||||
AzdoRepo repo, HttpMethod method, string path, string? query, string? body, CancellationToken ct)
|
||||
{
|
||||
var pat = Pat;
|
||||
@@ -153,7 +153,11 @@ public sealed class AzureDevOpsClient
|
||||
throw new AzureDevOpsException("Azure DevOps 203: PAT abgelaufen oder ohne Scope Code (Read & Write).");
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
try { return JsonNode.Parse(payload) ?? new JsonObject(); }
|
||||
try
|
||||
{
|
||||
return JsonNode.Parse(payload) as JsonObject
|
||||
?? throw new AzureDevOpsException($"Unerwartete Antwort von Azure DevOps bei {method} {path}.");
|
||||
}
|
||||
catch (JsonException ex) { throw new AzureDevOpsException($"Unerwartete Antwort von Azure DevOps: {ex.Message}"); }
|
||||
}
|
||||
|
||||
@@ -174,9 +178,10 @@ public sealed class AzureDevOpsClient
|
||||
{
|
||||
try
|
||||
{
|
||||
if (JsonNode.Parse(payload)?["message"]?.GetValue<string>() is { Length: > 0 } msg) return msg;
|
||||
if (JsonNode.Parse(payload) is JsonObject o && o["message"]?.GetValue<string>() is { Length: > 0 } msg) return msg;
|
||||
}
|
||||
catch (JsonException) { }
|
||||
// InvalidOperationException: "message" exists but is not a string.
|
||||
catch (Exception ex) when (ex is JsonException or InvalidOperationException) { }
|
||||
return payload.Length <= 500 ? payload : payload[..500];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,8 @@ public sealed class PullRequestPublisher
|
||||
var description = BuildDescription(task, ticketId, await ResolveProjectIdAsync(ticketId, ct), verifyCommand);
|
||||
(url, created) = await _azdo.EnsureDraftPullRequestAsync(repo, wt.BranchName, target, title, description, ct);
|
||||
}
|
||||
catch (AzureDevOpsException ex)
|
||||
// InvalidOperationException: a field of the ADO answer has an unexpected JSON type.
|
||||
catch (Exception ex) when (ex is AzureDevOpsException or InvalidOperationException)
|
||||
{
|
||||
return Blocked($"gepusht, PR fehlgeschlagen: {ex.Message}");
|
||||
}
|
||||
|
||||
@@ -1054,7 +1054,8 @@ public sealed class TaskMergeService
|
||||
}
|
||||
}
|
||||
|
||||
if (wt is { State: WorktreeState.Active } && _pullRequests is not null
|
||||
// Kept (parked or reverted) goes the PR way too: a local merge has no place in a company repo.
|
||||
if (wt is { State: WorktreeState.Active or WorktreeState.Kept } && _pullRequests is not null
|
||||
&& !string.IsNullOrWhiteSpace(list.WorkingDir)
|
||||
&& await _pullRequests.IsCompanyRepoAsync(list.WorkingDir, ct))
|
||||
return await ApproveCompanyAsync(task, list, wt, verifyCommand, ct, progress);
|
||||
@@ -1164,9 +1165,18 @@ public sealed class TaskMergeService
|
||||
if (failed is not null) return failed;
|
||||
}
|
||||
|
||||
return await ProgressReporter.RunAsync(
|
||||
var result = await ProgressReporter.RunAsync(
|
||||
_pullRequests.PublishAsync(task, list, wt, ranVerify ? verifyCommand : null, ct),
|
||||
ProgressReportInterval, progress, "push + draft PR running");
|
||||
|
||||
// A branch with an open PR is under review again, whatever parked it before.
|
||||
if (wt.State == WorktreeState.Kept && result.PullRequestUrl is not null)
|
||||
{
|
||||
using (var ctx = _dbFactory.CreateDbContext())
|
||||
await new WorktreeRepository(ctx).SetStateAsync(task.Id, WorktreeState.Active, ct);
|
||||
await _broadcaster.WorktreeUpdated(task.Id);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -282,8 +282,17 @@ public sealed class WorktreeManager
|
||||
.Select(c => c.BaseBranch)
|
||||
.FirstOrDefaultAsync(ct)).NullIfBlank();
|
||||
|
||||
if (isCompany && await FetchCompanyBaseAsync(workingDir, baseBranch, ct) is { } fetched)
|
||||
return fetched;
|
||||
if (isCompany)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (await FetchCompanyBaseAsync(workingDir, baseBranch, ct) is { } fetched) return fetched;
|
||||
}
|
||||
catch (Exception ex) when (ex is not OperationCanceledException)
|
||||
{
|
||||
_logger.LogWarning(ex, "Fetching the company base in {working_dir} failed, continuing with the local branch", workingDir);
|
||||
}
|
||||
}
|
||||
|
||||
return baseBranch is null
|
||||
? await _git.RevParseHeadAsync(workingDir, ct)
|
||||
@@ -304,7 +313,7 @@ public sealed class WorktreeManager
|
||||
if (basis is null && _azdo is not null && pat is not null && AzureDevOpsClient.ParseRemote(remote) is { } repo)
|
||||
{
|
||||
try { basis = await _azdo.GetDefaultBranchAsync(repo, ct); }
|
||||
catch (AzureDevOpsException ex) { _logger.LogWarning("Default branch from Azure DevOps unavailable: {reason}", ex.Message); }
|
||||
catch (Exception ex) when (ex is AzureDevOpsException or InvalidOperationException) { _logger.LogWarning("Default branch from Azure DevOps unavailable: {reason}", ex.Message); }
|
||||
}
|
||||
basis ??= await _git.GetRemoteHeadBranchAsync(workingDir, ct);
|
||||
if (basis is null)
|
||||
|
||||
Reference in New Issue
Block a user