Skip to content

Commit dde84e9

Browse files
authored
Merge branch 'main' into dependabot/nuget/src/Sdk/main/multi-9d7b3e2497
2 parents 208d164 + b06c585 commit dde84e9

11 files changed

Lines changed: 301 additions & 17 deletions

File tree

src/Misc/expressionFunc/hashFiles/package-lock.json

Lines changed: 77 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Misc/expressionFunc/hashFiles/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"author": "GitHub Actions",
3333
"license": "MIT",
3434
"dependencies": {
35-
"@actions/glob": "^0.6.1"
35+
"@actions/glob": "^0.7.0"
3636
},
3737
"devDependencies": {
3838
"@stylistic/eslint-plugin": "^5.10.0",

src/Runner.Worker/ActionManager.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,11 @@ private async Task BuildActionContainerAsync(IExecutionContext executionContext,
880880
return new Dictionary<string, WebApi.ActionDownloadInfo>();
881881
}
882882

883+
// Pass lockfile dependencies to Launch when present, so it can
884+
// perform ref-scoped policy matching with the original refs.
885+
var deps = executionContext.Global.ActionsDependencies;
886+
IList<string> dependencies = (deps != null && deps.Count > 0) ? deps : null;
887+
883888
// Resolve download info
884889
var launchServer = HostContext.GetService<ILaunchServer>();
885890
var jobServer = HostContext.GetService<IJobServer>();
@@ -891,7 +896,7 @@ private async Task BuildActionContainerAsync(IExecutionContext executionContext,
891896
if (MessageUtil.IsRunServiceJob(executionContext.Global.Variables.Get(Constants.Variables.System.JobRequestType)))
892897
{
893898
var displayHelpfulActionsDownloadErrors = executionContext.Global.Variables.GetBoolean(Constants.Runner.Features.DisplayHelpfulActionsDownloadErrors) ?? false;
894-
actionDownloadInfos = await launchServer.ResolveActionsDownloadInfoAsync(executionContext.Global.Plan.PlanId, executionContext.Root.Id, new WebApi.ActionReferenceList { Actions = actionReferences }, executionContext.CancellationToken, displayHelpfulActionsDownloadErrors);
899+
actionDownloadInfos = await launchServer.ResolveActionsDownloadInfoAsync(executionContext.Global.Plan.PlanId, executionContext.Root.Id, new WebApi.ActionReferenceList { Actions = actionReferences, Dependencies = dependencies }, executionContext.CancellationToken, displayHelpfulActionsDownloadErrors);
895900
}
896901
else
897902
{

src/Runner.Worker/ExecutionContext.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,9 @@ public void InitializeJob(Pipelines.AgentJobRequestMessage message, Cancellation
875875
// File table
876876
Global.FileTable = new List<String>(message.FileTable ?? new string[0]);
877877

878+
// Workflow dependencies (lockfile pins)
879+
Global.ActionsDependencies = message.ActionsDependencies;
880+
878881
// What type of job request is running (i.e. Run Service vs. pipelines)
879882
Global.Variables.Set(Constants.Variables.System.JobRequestType, message.MessageType);
880883

src/Runner.Worker/GlobalContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@ public sealed class GlobalContext
3838
public HashSet<string> DeprecatedNode20Actions { get; set; }
3939
public HashSet<string> UpgradedToNode24Actions { get; set; }
4040
public HashSet<string> Arm32Node20Actions { get; set; }
41+
public IList<String> ActionsDependencies { get; set; }
4142
}
4243
}

src/Sdk/DTPipelines/Pipelines/AgentJobRequestMessage.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,21 @@ public DebuggerTunnelInfo DebuggerTunnel
267267
set;
268268
}
269269

270+
/// <summary>
271+
/// Gets the workflow-level action dependencies (lockfile entries)
272+
/// </summary>
273+
public IList<String> ActionsDependencies
274+
{
275+
get
276+
{
277+
if (m_actionsDependencies == null)
278+
{
279+
m_actionsDependencies = new List<String>();
280+
}
281+
return m_actionsDependencies;
282+
}
283+
}
284+
270285
/// <summary>
271286
/// Gets the collection of variables associated with the current context.
272287
/// </summary>
@@ -441,6 +456,11 @@ private void OnSerializing(StreamingContext context)
441456
m_variables = null;
442457
}
443458

459+
if (m_actionsDependencies?.Count == 0)
460+
{
461+
m_actionsDependencies = null;
462+
}
463+
444464
// todo: remove after feature-flag DistributedTask.EvaluateContainerOnRunner is enabled everywhere
445465
if (!string.IsNullOrEmpty(m_jobContainerResourceAlias))
446466
{
@@ -466,6 +486,9 @@ private void OnSerializing(StreamingContext context)
466486
[DataMember(Name = "Variables", EmitDefaultValue = false)]
467487
private IDictionary<String, VariableValue> m_variables;
468488

489+
[DataMember(Name = "dependencies", EmitDefaultValue = false)]
490+
private List<String> m_actionsDependencies;
491+
469492
// todo: remove after feature-flag DistributedTask.EvaluateContainerOnRunner is enabled everywhere
470493
[DataMember(Name = "JobSidecarContainers", EmitDefaultValue = false)]
471494
private IDictionary<String, String> m_jobSidecarContainers;

src/Sdk/DTWebApi/WebApi/ActionReferenceList.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,12 @@ public IList<ActionReference> Actions
1212
get;
1313
set;
1414
}
15+
16+
[DataMember(EmitDefaultValue = false)]
17+
public IList<string> Dependencies
18+
{
19+
get;
20+
set;
21+
}
1522
}
1623
}

src/Sdk/WebApi/WebApi/LaunchContracts.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public class ActionReferenceRequestList
2222
{
2323
[DataMember(EmitDefaultValue = false, Name = "actions")]
2424
public IList<ActionReferenceRequest> Actions { get; set; }
25+
26+
[DataMember(EmitDefaultValue = false, Name = "actions_dependencies")]
27+
public IList<string> ActionsDependencies { get; set; }
2528
}
2629

2730
[DataContract]

src/Sdk/WebApi/WebApi/LaunchHttpClient.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ private static ActionReferenceRequestList ToGitHubData(ActionReferenceList actio
9797
{
9898
return new ActionReferenceRequestList
9999
{
100-
Actions = actionReferenceList.Actions?.Select(ToGitHubData).ToList()
100+
Actions = actionReferenceList.Actions?.Select(ToGitHubData).ToList(),
101+
ActionsDependencies = actionReferenceList.Dependencies
101102
};
102103
}
103104

src/Test/L0/Sdk/RSWebApi/AgentJobRequestMessageL0.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,48 @@ public void VerifyDebuggerTunnelDeserialization_WithoutTunnel()
119119
Assert.Null(recoveredMessage.DebuggerTunnel);
120120
}
121121

122+
[Fact]
123+
[Trait("Level", "L0")]
124+
[Trait("Category", "Common")]
125+
public void VerifyActionsDependenciesDeserialization_WithDependencies()
126+
{
127+
// Arrange
128+
var serializer = new DataContractJsonSerializer(typeof(AgentJobRequestMessage));
129+
string json = DoubleQuotify("{'dependencies': ['actions/checkout@v4:sha256-abc123', 'actions/setup-node@v4:sha256-def456']}");
130+
131+
// Act
132+
using var stream = new MemoryStream();
133+
stream.Write(Encoding.UTF8.GetBytes(json));
134+
stream.Position = 0;
135+
var recoveredMessage = serializer.ReadObject(stream) as AgentJobRequestMessage;
136+
137+
// Assert
138+
Assert.NotNull(recoveredMessage);
139+
Assert.Equal(2, recoveredMessage.ActionsDependencies.Count);
140+
Assert.Equal("actions/checkout@v4:sha256-abc123", recoveredMessage.ActionsDependencies[0]);
141+
Assert.Equal("actions/setup-node@v4:sha256-def456", recoveredMessage.ActionsDependencies[1]);
142+
}
143+
144+
[Fact]
145+
[Trait("Level", "L0")]
146+
[Trait("Category", "Common")]
147+
public void VerifyActionsDependenciesDeserialization_DefaultsToEmpty()
148+
{
149+
// Arrange
150+
var serializer = new DataContractJsonSerializer(typeof(AgentJobRequestMessage));
151+
string json = DoubleQuotify("{'messageType': 'PipelineAgentJobRequest'}");
152+
153+
// Act
154+
using var stream = new MemoryStream();
155+
stream.Write(Encoding.UTF8.GetBytes(json));
156+
stream.Position = 0;
157+
var recoveredMessage = serializer.ReadObject(stream) as AgentJobRequestMessage;
158+
159+
// Assert
160+
Assert.NotNull(recoveredMessage);
161+
Assert.Empty(recoveredMessage.ActionsDependencies);
162+
}
163+
122164
private static string DoubleQuotify(string text)
123165
{
124166
return text.Replace('\'', '"');

0 commit comments

Comments
 (0)