@@ -74,7 +74,7 @@ public void IsNodeVersionUpgraded(string inputVersion, string expectedVersion)
7474 }
7575 }
7676
77-
77+
7878
7979 [ Fact ]
8080 [ Trait ( "Level" , "L0" ) ]
@@ -116,5 +116,259 @@ public void Node24ExplicitlyRequested_HonoredByDefault()
116116 Assert . Equal ( "node24" , handler . Data . NodeVersion ) ;
117117 }
118118 }
119+
120+ [ Fact ]
121+ [ Trait ( "Level" , "L0" ) ]
122+ [ Trait ( "Category" , "Worker" ) ]
123+ public void Node20Action_TrackedWhenWarnFlagEnabled ( )
124+ {
125+ using ( TestHostContext hc = CreateTestContext ( ) )
126+ {
127+ // Arrange.
128+ var hf = new HandlerFactory ( ) ;
129+ hf . Initialize ( hc ) ;
130+
131+ var variables = new Dictionary < string , VariableValue >
132+ {
133+ { Constants . Runner . NodeMigration . WarnOnNode20Flag , new VariableValue ( "true" ) }
134+ } ;
135+ Variables serverVariables = new ( hc , variables ) ;
136+ var deprecatedActions = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
137+
138+ _ec . Setup ( x => x . Global ) . Returns ( new GlobalContext ( )
139+ {
140+ Variables = serverVariables ,
141+ EnvironmentVariables = new Dictionary < string , string > ( ) ,
142+ DeprecatedNode20Actions = deprecatedActions
143+ } ) ;
144+
145+ var actionRef = new RepositoryPathReference
146+ {
147+ Name = "actions/checkout" ,
148+ Ref = "v4"
149+ } ;
150+
151+ // Act.
152+ var data = new NodeJSActionExecutionData ( ) ;
153+ data . NodeVersion = "node20" ;
154+ hf . Create (
155+ _ec . Object ,
156+ actionRef ,
157+ new Mock < IStepHost > ( ) . Object ,
158+ data ,
159+ new Dictionary < string , string > ( ) ,
160+ new Dictionary < string , string > ( ) ,
161+ new Variables ( hc , new Dictionary < string , VariableValue > ( ) ) ,
162+ "" ,
163+ new List < JobExtensionRunner > ( )
164+ ) ;
165+
166+ // Assert.
167+ Assert . Contains ( "actions/checkout@v4" , deprecatedActions ) ;
168+ }
169+ }
170+
171+ [ Fact ]
172+ [ Trait ( "Level" , "L0" ) ]
173+ [ Trait ( "Category" , "Worker" ) ]
174+ public void Node20Action_NotTrackedWhenWarnFlagDisabled ( )
175+ {
176+ using ( TestHostContext hc = CreateTestContext ( ) )
177+ {
178+ // Arrange.
179+ var hf = new HandlerFactory ( ) ;
180+ hf . Initialize ( hc ) ;
181+
182+ var variables = new Dictionary < string , VariableValue > ( ) ;
183+ Variables serverVariables = new ( hc , variables ) ;
184+ var deprecatedActions = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
185+
186+ _ec . Setup ( x => x . Global ) . Returns ( new GlobalContext ( )
187+ {
188+ Variables = serverVariables ,
189+ EnvironmentVariables = new Dictionary < string , string > ( ) ,
190+ DeprecatedNode20Actions = deprecatedActions
191+ } ) ;
192+
193+ var actionRef = new RepositoryPathReference
194+ {
195+ Name = "actions/checkout" ,
196+ Ref = "v4"
197+ } ;
198+
199+ // Act.
200+ var data = new NodeJSActionExecutionData ( ) ;
201+ data . NodeVersion = "node20" ;
202+ hf . Create (
203+ _ec . Object ,
204+ actionRef ,
205+ new Mock < IStepHost > ( ) . Object ,
206+ data ,
207+ new Dictionary < string , string > ( ) ,
208+ new Dictionary < string , string > ( ) ,
209+ new Variables ( hc , new Dictionary < string , VariableValue > ( ) ) ,
210+ "" ,
211+ new List < JobExtensionRunner > ( )
212+ ) ;
213+
214+ // Assert - should not track when flag is disabled
215+ Assert . Empty ( deprecatedActions ) ;
216+ }
217+ }
218+
219+ [ Fact ]
220+ [ Trait ( "Level" , "L0" ) ]
221+ [ Trait ( "Category" , "Worker" ) ]
222+ public void Node24Action_NotTrackedEvenWhenWarnFlagEnabled ( )
223+ {
224+ using ( TestHostContext hc = CreateTestContext ( ) )
225+ {
226+ // Arrange.
227+ var hf = new HandlerFactory ( ) ;
228+ hf . Initialize ( hc ) ;
229+
230+ var variables = new Dictionary < string , VariableValue >
231+ {
232+ { Constants . Runner . NodeMigration . WarnOnNode20Flag , new VariableValue ( "true" ) }
233+ } ;
234+ Variables serverVariables = new ( hc , variables ) ;
235+ var deprecatedActions = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
236+
237+ _ec . Setup ( x => x . Global ) . Returns ( new GlobalContext ( )
238+ {
239+ Variables = serverVariables ,
240+ EnvironmentVariables = new Dictionary < string , string > ( ) ,
241+ DeprecatedNode20Actions = deprecatedActions
242+ } ) ;
243+
244+ var actionRef = new RepositoryPathReference
245+ {
246+ Name = "actions/checkout" ,
247+ Ref = "v5"
248+ } ;
249+
250+ // Act.
251+ var data = new NodeJSActionExecutionData ( ) ;
252+ data . NodeVersion = "node24" ;
253+ hf . Create (
254+ _ec . Object ,
255+ actionRef ,
256+ new Mock < IStepHost > ( ) . Object ,
257+ data ,
258+ new Dictionary < string , string > ( ) ,
259+ new Dictionary < string , string > ( ) ,
260+ new Variables ( hc , new Dictionary < string , VariableValue > ( ) ) ,
261+ "" ,
262+ new List < JobExtensionRunner > ( )
263+ ) ;
264+
265+ // Assert - node24 actions should not be tracked
266+ Assert . Empty ( deprecatedActions ) ;
267+ }
268+ }
269+
270+ [ Fact ]
271+ [ Trait ( "Level" , "L0" ) ]
272+ [ Trait ( "Category" , "Worker" ) ]
273+ public void Node12Action_TrackedAsDeprecatedWhenWarnFlagEnabled ( )
274+ {
275+ using ( TestHostContext hc = CreateTestContext ( ) )
276+ {
277+ // Arrange.
278+ var hf = new HandlerFactory ( ) ;
279+ hf . Initialize ( hc ) ;
280+
281+ var variables = new Dictionary < string , VariableValue >
282+ {
283+ { Constants . Runner . NodeMigration . WarnOnNode20Flag , new VariableValue ( "true" ) }
284+ } ;
285+ Variables serverVariables = new ( hc , variables ) ;
286+ var deprecatedActions = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
287+
288+ _ec . Setup ( x => x . Global ) . Returns ( new GlobalContext ( )
289+ {
290+ Variables = serverVariables ,
291+ EnvironmentVariables = new Dictionary < string , string > ( ) ,
292+ DeprecatedNode20Actions = deprecatedActions
293+ } ) ;
294+
295+ var actionRef = new RepositoryPathReference
296+ {
297+ Name = "some-org/old-action" ,
298+ Ref = "v1"
299+ } ;
300+
301+ // Act - node12 gets migrated to node20, then should be tracked
302+ var data = new NodeJSActionExecutionData ( ) ;
303+ data . NodeVersion = "node12" ;
304+ hf . Create (
305+ _ec . Object ,
306+ actionRef ,
307+ new Mock < IStepHost > ( ) . Object ,
308+ data ,
309+ new Dictionary < string , string > ( ) ,
310+ new Dictionary < string , string > ( ) ,
311+ new Variables ( hc , new Dictionary < string , VariableValue > ( ) ) ,
312+ "" ,
313+ new List < JobExtensionRunner > ( )
314+ ) ;
315+
316+ // Assert - node12 gets migrated to node20 and should be tracked
317+ Assert . Contains ( "some-org/old-action@v1" , deprecatedActions ) ;
318+ }
319+ }
320+
321+ [ Fact ]
322+ [ Trait ( "Level" , "L0" ) ]
323+ [ Trait ( "Category" , "Worker" ) ]
324+ public void LocalNode20Action_TrackedWhenWarnFlagEnabled ( )
325+ {
326+ using ( TestHostContext hc = CreateTestContext ( ) )
327+ {
328+ // Arrange.
329+ var hf = new HandlerFactory ( ) ;
330+ hf . Initialize ( hc ) ;
331+
332+ var variables = new Dictionary < string , VariableValue >
333+ {
334+ { Constants . Runner . NodeMigration . WarnOnNode20Flag , new VariableValue ( "true" ) }
335+ } ;
336+ Variables serverVariables = new ( hc , variables ) ;
337+ var deprecatedActions = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
338+
339+ _ec . Setup ( x => x . Global ) . Returns ( new GlobalContext ( )
340+ {
341+ Variables = serverVariables ,
342+ EnvironmentVariables = new Dictionary < string , string > ( ) ,
343+ DeprecatedNode20Actions = deprecatedActions
344+ } ) ;
345+
346+ // Local action: Name is empty, Path is the local path
347+ var actionRef = new RepositoryPathReference
348+ {
349+ Name = "" ,
350+ Path = "./.github/actions/my-action" ,
351+ RepositoryType = "self"
352+ } ;
353+
354+ // Act.
355+ var data = new NodeJSActionExecutionData ( ) ;
356+ data . NodeVersion = "node20" ;
357+ hf . Create (
358+ _ec . Object ,
359+ actionRef ,
360+ new Mock < IStepHost > ( ) . Object ,
361+ data ,
362+ new Dictionary < string , string > ( ) ,
363+ new Dictionary < string , string > ( ) ,
364+ new Variables ( hc , new Dictionary < string , VariableValue > ( ) ) ,
365+ "" ,
366+ new List < JobExtensionRunner > ( )
367+ ) ;
368+
369+ // Assert - local action should be tracked with its path
370+ Assert . Contains ( "./.github/actions/my-action" , deprecatedActions ) ;
371+ }
372+ }
119373 }
120374}
0 commit comments