Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions src/Runner.Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ public static class Features
public static readonly string SendJobLevelAnnotations = "actions_send_job_level_annotations";
public static readonly string EmitCompositeMarkers = "actions_runner_emit_composite_markers";
public static readonly string BatchActionResolution = "actions_batch_action_resolution";
public static readonly string UseBearerTokenForCodeload = "actions_use_bearer_token_for_codeload";
}

// Node version migration related constants
Expand Down
23 changes: 18 additions & 5 deletions src/Runner.Worker/ActionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1367,16 +1367,29 @@ private static string GetDownloadInfoLookupKey(Pipelines.ActionStep action)
return $"{repositoryReference.Name}@{repositoryReference.Ref}";
}

private AuthenticationHeaderValue CreateAuthHeader(string token)
private AuthenticationHeaderValue CreateAuthHeader(IExecutionContext executionContext, string downloadUrl, string token)
{
if (string.IsNullOrEmpty(token))
{
return null;
}

var base64EncodingToken = Convert.ToBase64String(Encoding.UTF8.GetBytes($"x-access-token:{token}"));
HostContext.SecretMasker.AddValue(base64EncodingToken);
return new AuthenticationHeaderValue("Basic", base64EncodingToken);
if (executionContext.Global.Variables.GetBoolean(Constants.Runner.Features.UseBearerTokenForCodeload) == true &&
Uri.TryCreate(downloadUrl, UriKind.Absolute, out var parsedUrl) &&
!string.IsNullOrEmpty(parsedUrl?.Host) &&
!string.IsNullOrEmpty(parsedUrl?.PathAndQuery) &&
(parsedUrl.Host.StartsWith("codeload.", StringComparison.OrdinalIgnoreCase) || parsedUrl.PathAndQuery.StartsWith("/_codeload/", StringComparison.OrdinalIgnoreCase)))
{
Trace.Info("Using Bearer token for action archive download directly to codeload.");
return new AuthenticationHeaderValue("Bearer", token);
Comment thread
TingluoHuang marked this conversation as resolved.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in case we are talking to codeload directly, pass bearer header

}
else
{
Trace.Info("Using Basic token for action archive download.");
var base64EncodingToken = Convert.ToBase64String(Encoding.UTF8.GetBytes($"x-access-token:{token}"));
HostContext.SecretMasker.AddValue(base64EncodingToken);
return new AuthenticationHeaderValue("Basic", base64EncodingToken);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the basic header works fine with codeload URL and api.github.com URL.

}
Comment thread
TingluoHuang marked this conversation as resolved.
}
Comment thread
TingluoHuang marked this conversation as resolved.

private async Task DownloadRepositoryArchive(IExecutionContext executionContext, string downloadUrl, string downloadAuthToken, string archiveFile)
Expand All @@ -1401,7 +1414,7 @@ private async Task DownloadRepositoryArchive(IExecutionContext executionContext,
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
using (var httpClient = new HttpClient(httpClientHandler))
{
httpClient.DefaultRequestHeaders.Authorization = CreateAuthHeader(downloadAuthToken);
httpClient.DefaultRequestHeaders.Authorization = CreateAuthHeader(executionContext, downloadUrl, downloadAuthToken);

httpClient.DefaultRequestHeaders.UserAgent.AddRange(HostContext.UserAgents);
using (var response = await httpClient.GetAsync(downloadUrl))
Expand Down
Loading