Skip to content

Commit

Permalink
Resolve action download info (#515)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericsciple authored Jun 9, 2020
1 parent 1aea046 commit 5815819
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 81 deletions.
10 changes: 10 additions & 0 deletions src/Runner.Common/JobServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public interface IJobServer : IRunnerService
Task<List<TimelineRecord>> UpdateTimelineRecordsAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, IEnumerable<TimelineRecord> records, CancellationToken cancellationToken);
Task RaisePlanEventAsync<T>(Guid scopeIdentifier, string hubName, Guid planId, T eventData, CancellationToken cancellationToken) where T : JobEvent;
Task<Timeline> GetTimelineAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, CancellationToken cancellationToken);
Task<ActionDownloadInfoCollection> ResolveActionDownloadInfoAsync(Guid scopeIdentifier, string hubName, Guid planId, ActionReferenceList actions, CancellationToken cancellationToken);
}

public sealed class JobServer : RunnerService, IJobServer
Expand Down Expand Up @@ -113,5 +114,14 @@ public Task<Timeline> GetTimelineAsync(Guid scopeIdentifier, string hubName, Gui
CheckConnection();
return _taskClient.GetTimelineAsync(scopeIdentifier, hubName, planId, timelineId, includeRecords: true, cancellationToken: cancellationToken);
}

//-----------------------------------------------------------------
// Action download info
//-----------------------------------------------------------------
public Task<ActionDownloadInfoCollection> ResolveActionDownloadInfoAsync(Guid scopeIdentifier, string hubName, Guid planId, ActionReferenceList actions, CancellationToken cancellationToken)
{
CheckConnection();
return _taskClient.ResolveActionDownloadInfoAsync(scopeIdentifier, hubName, planId, actions, cancellationToken: cancellationToken);
}
}
}
167 changes: 87 additions & 80 deletions src/Runner.Worker/ActionManager.cs

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion src/Runner.Worker/ExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public interface IExecutionContext : IRunnerService
TaskResult? CommandResult { get; set; }
CancellationToken CancellationToken { get; }
List<ServiceEndpoint> Endpoints { get; }
TaskOrchestrationPlanReference Plan { get; }

PlanFeatures Features { get; }
Variables Variables { get; }
Expand Down Expand Up @@ -141,6 +142,7 @@ public sealed class ExecutionContext : RunnerService, IExecutionContext
public Task ForceCompleted => _forceCompleted.Task;
public CancellationToken CancellationToken => _cancellationTokenSource.Token;
public List<ServiceEndpoint> Endpoints { get; private set; }
public TaskOrchestrationPlanReference Plan { get; private set; }
public Variables Variables { get; private set; }
public Dictionary<string, string> IntraActionState { get; private set; }
public IDictionary<String, IDictionary<String, String>> JobDefaults { get; private set; }
Expand Down Expand Up @@ -275,6 +277,7 @@ public IExecutionContext CreateChild(Guid recordId, string displayName, string r
child.Features = Features;
child.Variables = Variables;
child.Endpoints = Endpoints;
child.Plan = Plan;
if (intraActionState == null)
{
child.IntraActionState = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Expand Down Expand Up @@ -576,7 +579,8 @@ public void InitializeJob(Pipelines.AgentJobRequestMessage message, Cancellation

_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);

// Features
// Plan
Plan = message.Plan;
Features = PlanUtil.GetFeatures(message.Plan);

// Endpoints
Expand Down
32 changes: 32 additions & 0 deletions src/Sdk/DTGenerated/Generated/TaskHttpClientBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,5 +317,37 @@ public virtual Task<Timeline> GetTimelineAsync(
userState: userState,
cancellationToken: cancellationToken);
}

/// <summary>
/// [Preview API] Resolves information required to download actions (URL, token) defined in an orchestration.
/// </summary>
/// <param name="scopeIdentifier">The project GUID to scope the request</param>
/// <param name="hubName">The name of the server hub: "build" for the Build server or "rm" for the Release Management server</param>
/// <param name="planId"></param>
/// <param name="actionReferenceList"></param>
/// <param name="userState"></param>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
public virtual Task<ActionDownloadInfoCollection> ResolveActionDownloadInfoAsync(
Guid scopeIdentifier,
string hubName,
Guid planId,
ActionReferenceList actionReferenceList,
object userState = null,
CancellationToken cancellationToken = default)
{
HttpMethod httpMethod = new HttpMethod("POST");
Guid locationId = new Guid("27d7f831-88c1-4719-8ca1-6a061dad90eb");
object routeValues = new { scopeIdentifier = scopeIdentifier, hubName = hubName, planId = planId };
HttpContent content = new ObjectContent<ActionReferenceList>(actionReferenceList, new VssJsonMediaTypeFormatter(true));

return SendAsync<ActionDownloadInfoCollection>(
httpMethod,
locationId,
routeValues: routeValues,
version: new ApiResourceVersion(6.0, 1),
userState: userState,
cancellationToken: cancellationToken,
content: content);
}
}
}
40 changes: 40 additions & 0 deletions src/Sdk/DTWebApi/WebApi/ActionDownloadInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.Runtime.Serialization;

namespace GitHub.DistributedTask.WebApi
{
[DataContract]
public class ActionDownloadInfo
{
[DataMember(EmitDefaultValue = false)]
public ActionDownloadAuthentication Authentication { get; set; }

[DataMember(EmitDefaultValue = false)]
public string NameWithOwner { get; set; }

[DataMember(EmitDefaultValue = false)]
public string ResolvedNameWithOwner { get; set; }

[DataMember(EmitDefaultValue = false)]
public string ResolvedSha { get; set; }

[DataMember(EmitDefaultValue = false)]
public string TarballUrl { get; set; }

[DataMember(EmitDefaultValue = false)]
public string Ref { get; set; }

[DataMember(EmitDefaultValue = false)]
public string ZipballUrl { get; set; }
}

[DataContract]
public class ActionDownloadAuthentication
{
[DataMember(EmitDefaultValue = false)]
public DateTime ExpiresAt { get; set; }

[DataMember(EmitDefaultValue = false)]
public string Token { get; set; }
}
}
16 changes: 16 additions & 0 deletions src/Sdk/DTWebApi/WebApi/ActionDownloadInfoCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace GitHub.DistributedTask.WebApi
{
[DataContract]
public class ActionDownloadInfoCollection
{
[DataMember]
public IDictionary<string, ActionDownloadInfo> Actions
{
get;
set;
}
}
}
22 changes: 22 additions & 0 deletions src/Sdk/DTWebApi/WebApi/ActionReference.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Runtime.Serialization;

namespace GitHub.DistributedTask.WebApi
{
[DataContract]
public class ActionReference
{
[DataMember]
public string NameWithOwner
{
get;
set;
}

[DataMember]
public string Ref
{
get;
set;
}
}
}
16 changes: 16 additions & 0 deletions src/Sdk/DTWebApi/WebApi/ActionReferenceList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace GitHub.DistributedTask.WebApi
{
[DataContract]
public class ActionReferenceList
{
[DataMember]
public IList<ActionReference> Actions
{
get;
set;
}
}
}
22 changes: 22 additions & 0 deletions src/Test/L0/Worker/ActionManagerL0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public sealed class ActionManagerL0
private Mock<IConfigurationStore> _configurationStore;
private Mock<IDockerCommandManager> _dockerManager;
private Mock<IExecutionContext> _ec;
private Mock<IJobServer> _jobServer;
private Mock<IRunnerPluginManager> _pluginManager;
private TestHostContext _hc;
private ActionManager _actionManager;
Expand Down Expand Up @@ -3583,6 +3584,7 @@ private void Setup([CallerMemberName] string name = "", bool newActionMetadata =
_ec.Setup(x => x.Variables).Returns(new Variables(_hc, variables));
_ec.Setup(x => x.ExpressionValues).Returns(new DictionaryContextData());
_ec.Setup(x => x.ExpressionFunctions).Returns(new List<IFunctionInfo>());
_ec.Setup(x => x.Plan).Returns(new TaskOrchestrationPlanReference());
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>())).Callback((string tag, string message) => { _hc.GetTrace().Info($"[{tag}]{message}"); });
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>())).Callback((Issue issue, string message) => { _hc.GetTrace().Info($"[{issue.Type}]{issue.Message ?? message}"); });
_ec.Setup(x => x.GetGitHubContext("workspace")).Returns(Path.Combine(_workFolder, "actions", "actions"));
Expand All @@ -3593,13 +3595,33 @@ private void Setup([CallerMemberName] string name = "", bool newActionMetadata =

_dockerManager.Setup(x => x.DockerBuild(_ec.Object, It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(0));

_jobServer = new Mock<IJobServer>();
_jobServer.Setup(x => x.ResolveActionDownloadInfoAsync(It.IsAny<Guid>(), It.IsAny<string>(), It.IsAny<Guid>(), It.IsAny<ActionReferenceList>(), It.IsAny<CancellationToken>()))
.Returns((Guid scopeIdentifier, string hubName, Guid planId, ActionReferenceList actions, CancellationToken cancellationToken) =>
{
var result = new ActionDownloadInfoCollection { Actions = new Dictionary<string, ActionDownloadInfo>() };
foreach (var action in actions.Actions)
{
var key = $"{action.NameWithOwner}@{action.Ref}";
result.Actions[key] = new ActionDownloadInfo
{
NameWithOwner = action.NameWithOwner,
Ref = action.Ref,
TarballUrl = $"<GITHUB_API_URL>/repos/{action.NameWithOwner}/tarball/{action.Ref}",
ZipballUrl = $"<GITHUB_API_URL>/repos/{action.NameWithOwner}/zipball/{action.Ref}",
};
}
return Task.FromResult(result);
});

_pluginManager = new Mock<IRunnerPluginManager>();
_pluginManager.Setup(x => x.GetPluginAction(It.IsAny<string>())).Returns(new RunnerPluginActionInfo() { PluginTypeName = "plugin.class, plugin", PostPluginTypeName = "plugin.cleanup, plugin" });

var actionManifest = new ActionManifestManager();
actionManifest.Initialize(_hc);

_hc.SetSingleton<IDockerCommandManager>(_dockerManager.Object);
_hc.SetSingleton<IJobServer>(_jobServer.Object);
_hc.SetSingleton<IRunnerPluginManager>(_pluginManager.Object);
_hc.SetSingleton<IActionManifestManager>(actionManifest);
_hc.SetSingleton<IHttpClientHandlerFactory>(new HttpClientHandlerFactory());
Expand Down

0 comments on commit 5815819

Please sign in to comment.