Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions TUnit.Engine/Reporters/Html/GitHubArtifactUploader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,20 @@ internal static class GitHubArtifactUploader
// Step 1: CreateArtifact (deduplicate name on 409 conflict)
var createUrl = $"{origin}/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact";
string? signedUploadUrl = null;
string? acceptedArtifactName = null;
var nameWithoutExt = Path.GetFileNameWithoutExtension(fileName);
var ext = Path.GetExtension(fileName);

for (var nameAttempt = 0; nameAttempt < 3 && signedUploadUrl is null; nameAttempt++)
{
var artifactName = nameAttempt == 0
? fileName
: $"{Path.GetFileNameWithoutExtension(fileName)}-{nameAttempt + 1}{Path.GetExtension(fileName)}";
var artifactName = nameAttempt switch
{
0 => fileName,
// On first conflict, append the job backend ID to uniquely identify this matrix job
1 => $"{nameWithoutExt}-{GetShortJobId(workflowJobRunBackendId)}{ext}",
// On further conflicts, add an extra numeric suffix
_ => $"{nameWithoutExt}-{GetShortJobId(workflowJobRunBackendId)}-{nameAttempt}{ext}",
};

var createBody = BuildCreateArtifactJson(workflowRunBackendId, workflowJobRunBackendId, artifactName);

Expand All @@ -66,6 +74,11 @@ internal static class GitHubArtifactUploader
using var doc = JsonDocument.Parse(json);
return doc.RootElement.GetProperty("signed_upload_url").GetString();
}, cancellationToken);

if (signedUploadUrl is not null)
{
acceptedArtifactName = artifactName;
}
}

if (signedUploadUrl is null)
Expand Down Expand Up @@ -105,7 +118,7 @@ internal static class GitHubArtifactUploader

// Step 3: FinalizeArtifact
var finalizeUrl = $"{origin}/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact";
var finalizeBody = BuildFinalizeArtifactJson(workflowRunBackendId, workflowJobRunBackendId, fileName, fileBytes.Length, sha256Hash);
var finalizeBody = BuildFinalizeArtifactJson(workflowRunBackendId, workflowJobRunBackendId, acceptedArtifactName!, fileBytes.Length, sha256Hash);

var artifactId = await RetryAsync(async () =>
{
Expand All @@ -127,6 +140,13 @@ internal static class GitHubArtifactUploader
return artifactId;
}

private static string GetShortJobId(string jobRunBackendId)
{
return jobRunBackendId.Length > 8
? jobRunBackendId[..8]
: jobRunBackendId;
}

private static string BuildCreateArtifactJson(string runId, string jobId, string fileName)
{
using var ms = new MemoryStream();
Expand Down
Loading