mirror of
https://github.com/actions/runner.git
synced 2025-12-25 10:57:32 +08:00
Resolve Actions Directly From Launch for Run Service Jobs (#2529)
Co-authored-by: Tingluo Huang <tingluohuang@github.com>
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
<NoWarn>NU1701;NU1603</NoWarn>
|
||||
<Version>$(Version)</Version>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
70
src/Sdk/WebApi/WebApi/LaunchContracts.cs
Normal file
70
src/Sdk/WebApi/WebApi/LaunchContracts.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace GitHub.Services.Launch.Contracts
|
||||
{
|
||||
[DataContract]
|
||||
public class ActionReferenceRequest
|
||||
{
|
||||
[DataMember(EmitDefaultValue = false, Name = "action")]
|
||||
public string Action { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "version")]
|
||||
public string Version { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "path")]
|
||||
public string Path { get; set; }
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
public class ActionReferenceRequestList
|
||||
{
|
||||
[DataMember(EmitDefaultValue = false, Name = "actions")]
|
||||
public IList<ActionReferenceRequest> Actions { get; set; }
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
public class ActionDownloadInfoResponse
|
||||
{
|
||||
[DataMember(EmitDefaultValue = false, Name = "authentication")]
|
||||
public ActionDownloadAuthenticationResponse Authentication { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "resolved_name")]
|
||||
public string ResolvedName { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "resolved_sha")]
|
||||
public string ResolvedSha { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "tar_url")]
|
||||
public string TarUrl { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "version")]
|
||||
public string Version { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "zip_url")]
|
||||
public string ZipUrl { get; set; }
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
public class ActionDownloadAuthenticationResponse
|
||||
{
|
||||
[DataMember(EmitDefaultValue = false, Name = "expires_at")]
|
||||
public DateTime ExpiresAt { get; set; }
|
||||
|
||||
[DataMember(EmitDefaultValue = false, Name = "token")]
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
public class ActionDownloadInfoResponseCollection
|
||||
{
|
||||
/// <summary>A mapping of action specifications to their download information.</summary>
|
||||
/// <remarks>The key is the full name of the action plus version, e.g. "actions/checkout@v2".</remarks>
|
||||
[DataMember(EmitDefaultValue = false, Name = "actions")]
|
||||
public IDictionary<string, ActionDownloadInfoResponse> Actions { get; set; }
|
||||
}
|
||||
}
|
||||
115
src/Sdk/WebApi/WebApi/LaunchHttpClient.cs
Normal file
115
src/Sdk/WebApi/WebApi/LaunchHttpClient.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Services.Launch.Contracts;
|
||||
|
||||
using Sdk.WebApi.WebApi;
|
||||
|
||||
namespace GitHub.Services.Launch.Client
|
||||
{
|
||||
public class LaunchHttpClient : RawHttpClientBase
|
||||
{
|
||||
public LaunchHttpClient(
|
||||
Uri baseUrl,
|
||||
HttpMessageHandler pipeline,
|
||||
string token,
|
||||
bool disposeHandler)
|
||||
: base(baseUrl, pipeline, disposeHandler)
|
||||
{
|
||||
m_token = token;
|
||||
m_launchServiceUrl = baseUrl;
|
||||
m_formatter = new JsonMediaTypeFormatter();
|
||||
}
|
||||
|
||||
public async Task<ActionDownloadInfoCollection> GetResolveActionsDownloadInfoAsync(Guid planId, Guid jobId, ActionReferenceList actionReferenceList, CancellationToken cancellationToken)
|
||||
{
|
||||
var GetResolveActionsDownloadInfoURLEndpoint = new Uri(m_launchServiceUrl, $"/actions/build/{planId.ToString()}/jobs/{jobId.ToString()}/runnerresolve/actions");
|
||||
return ToServerData(await GetLaunchSignedURLResponse<ActionReferenceRequestList, ActionDownloadInfoResponseCollection>(GetResolveActionsDownloadInfoURLEndpoint, ToGitHubData(actionReferenceList), cancellationToken));
|
||||
}
|
||||
|
||||
// Resolve Actions
|
||||
private async Task<T> GetLaunchSignedURLResponse<R, T>(Uri uri, R request, CancellationToken cancellationToken)
|
||||
{
|
||||
using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, uri))
|
||||
{
|
||||
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", m_token);
|
||||
requestMessage.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
||||
|
||||
using (HttpContent content = new ObjectContent<R>(request, m_formatter))
|
||||
{
|
||||
requestMessage.Content = content;
|
||||
using (var response = await SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead, cancellationToken: cancellationToken))
|
||||
{
|
||||
return await ReadJsonContentAsync<T>(response, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ActionReferenceRequestList ToGitHubData(ActionReferenceList actionReferenceList)
|
||||
{
|
||||
return new ActionReferenceRequestList
|
||||
{
|
||||
Actions = actionReferenceList.Actions?.Select(ToGitHubData).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionReferenceRequest ToGitHubData(ActionReference actionReference)
|
||||
{
|
||||
return new ActionReferenceRequest
|
||||
{
|
||||
Action = actionReference.NameWithOwner,
|
||||
Version = actionReference.Ref,
|
||||
Path = actionReference.Path
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionDownloadInfoCollection ToServerData(ActionDownloadInfoResponseCollection actionDownloadInfoResponseCollection)
|
||||
{
|
||||
return new ActionDownloadInfoCollection
|
||||
{
|
||||
Actions = actionDownloadInfoResponseCollection.Actions?.ToDictionary(kvp => kvp.Key, kvp => ToServerData(kvp.Value))
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionDownloadInfo ToServerData(ActionDownloadInfoResponse actionDownloadInfoResponse)
|
||||
{
|
||||
return new ActionDownloadInfo
|
||||
{
|
||||
Authentication = ToServerData(actionDownloadInfoResponse.Authentication),
|
||||
NameWithOwner = actionDownloadInfoResponse.Name,
|
||||
ResolvedNameWithOwner = actionDownloadInfoResponse.ResolvedName,
|
||||
ResolvedSha = actionDownloadInfoResponse.ResolvedSha,
|
||||
TarballUrl = actionDownloadInfoResponse.TarUrl,
|
||||
Ref = actionDownloadInfoResponse.Version,
|
||||
ZipballUrl = actionDownloadInfoResponse.ZipUrl,
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionDownloadAuthentication? ToServerData(ActionDownloadAuthenticationResponse? actionDownloadAuthenticationResponse)
|
||||
{
|
||||
if (actionDownloadAuthenticationResponse == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ActionDownloadAuthentication
|
||||
{
|
||||
ExpiresAt = actionDownloadAuthenticationResponse.ExpiresAt,
|
||||
Token = actionDownloadAuthenticationResponse.Token
|
||||
};
|
||||
}
|
||||
|
||||
private MediaTypeFormatter m_formatter;
|
||||
private Uri m_launchServiceUrl;
|
||||
private string m_token;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user