mirror of
https://github.com/actions/runner.git
synced 2025-12-12 15:13:30 +00:00
Adding Snapshot additional mapping tokens (#3468)
* Adding Snapshot additional mapping tokens * Lint failure fixes * Lint failure fixes - 2 * Lint failure fixes - 3 * Fixed a few nits * Lint fixes * Removed unncessary white space
This commit is contained in:
@@ -403,7 +403,7 @@ namespace GitHub.Runner.Worker
|
|||||||
var snapshotOperationProvider = HostContext.GetService<ISnapshotOperationProvider>();
|
var snapshotOperationProvider = HostContext.GetService<ISnapshotOperationProvider>();
|
||||||
jobContext.RegisterPostJobStep(new JobExtensionRunner(
|
jobContext.RegisterPostJobStep(new JobExtensionRunner(
|
||||||
runAsync: (executionContext, _) => snapshotOperationProvider.CreateSnapshotRequestAsync(executionContext, snapshotRequest),
|
runAsync: (executionContext, _) => snapshotOperationProvider.CreateSnapshotRequestAsync(executionContext, snapshotRequest),
|
||||||
condition: $"{PipelineTemplateConstants.Success}()",
|
condition: snapshotRequest.Condition,
|
||||||
displayName: $"Create custom image",
|
displayName: $"Create custom image",
|
||||||
data: null));
|
data: null));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
|||||||
public const String If = "if";
|
public const String If = "if";
|
||||||
public const String Image = "image";
|
public const String Image = "image";
|
||||||
public const String ImageName = "image-name";
|
public const String ImageName = "image-name";
|
||||||
|
public const String CustomImageVersion = "version";
|
||||||
public const String Include = "include";
|
public const String Include = "include";
|
||||||
public const String Inputs = "inputs";
|
public const String Inputs = "inputs";
|
||||||
public const String Job = "job";
|
public const String Job = "job";
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using GitHub.DistributedTask.Expressions2;
|
using GitHub.DistributedTask.Expressions2;
|
||||||
using GitHub.DistributedTask.Expressions2.Sdk;
|
using GitHub.DistributedTask.Expressions2.Sdk;
|
||||||
@@ -349,6 +350,10 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
|||||||
internal static Snapshot ConvertToJobSnapshotRequest(TemplateContext context, TemplateToken token)
|
internal static Snapshot ConvertToJobSnapshotRequest(TemplateContext context, TemplateToken token)
|
||||||
{
|
{
|
||||||
string imageName = null;
|
string imageName = null;
|
||||||
|
string version = "1.*";
|
||||||
|
string versionString = string.Empty;
|
||||||
|
var condition = $"{PipelineTemplateConstants.Success}()";
|
||||||
|
|
||||||
if (token is StringToken snapshotStringLiteral)
|
if (token is StringToken snapshotStringLiteral)
|
||||||
{
|
{
|
||||||
imageName = snapshotStringLiteral.Value;
|
imageName = snapshotStringLiteral.Value;
|
||||||
@@ -359,11 +364,19 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
|||||||
foreach (var snapshotPropertyPair in snapshotMapping)
|
foreach (var snapshotPropertyPair in snapshotMapping)
|
||||||
{
|
{
|
||||||
var propertyName = snapshotPropertyPair.Key.AssertString($"{PipelineTemplateConstants.Snapshot} key");
|
var propertyName = snapshotPropertyPair.Key.AssertString($"{PipelineTemplateConstants.Snapshot} key");
|
||||||
|
var propertyValue = snapshotPropertyPair.Value;
|
||||||
switch (propertyName.Value)
|
switch (propertyName.Value)
|
||||||
{
|
{
|
||||||
case PipelineTemplateConstants.ImageName:
|
case PipelineTemplateConstants.ImageName:
|
||||||
imageName = snapshotPropertyPair.Value.AssertString($"{PipelineTemplateConstants.Snapshot} {propertyName}").Value;
|
imageName = snapshotPropertyPair.Value.AssertString($"{PipelineTemplateConstants.Snapshot} {propertyName}").Value;
|
||||||
break;
|
break;
|
||||||
|
case PipelineTemplateConstants.If:
|
||||||
|
condition = ConvertToIfCondition(context, propertyValue, false);
|
||||||
|
break;
|
||||||
|
case PipelineTemplateConstants.CustomImageVersion:
|
||||||
|
versionString = propertyValue.AssertString($"job {PipelineTemplateConstants.Snapshot} {PipelineTemplateConstants.CustomImageVersion}").Value;
|
||||||
|
version = IsSnapshotImageVersionValid(versionString) ? versionString : null;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
propertyName.AssertUnexpectedValue($"{PipelineTemplateConstants.Snapshot} key");
|
propertyName.AssertUnexpectedValue($"{PipelineTemplateConstants.Snapshot} key");
|
||||||
break;
|
break;
|
||||||
@@ -376,7 +389,26 @@ namespace GitHub.DistributedTask.Pipelines.ObjectTemplating
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Snapshot(imageName);
|
return new Snapshot(imageName)
|
||||||
|
{
|
||||||
|
Condition = condition,
|
||||||
|
Version = version
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsSnapshotImageVersionValid(string versionString)
|
||||||
|
{
|
||||||
|
var versionSegments = versionString.Split(".");
|
||||||
|
|
||||||
|
if (versionSegments.Length != 2 ||
|
||||||
|
!versionSegments[1].Equals("*") ||
|
||||||
|
!Int32.TryParse(versionSegments[0], NumberStyles.None, CultureInfo.InvariantCulture, result: out int parsedMajor) ||
|
||||||
|
parsedMajor < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActionStep ConvertToStep(
|
private static ActionStep ConvertToStep(
|
||||||
|
|||||||
@@ -1,17 +1,27 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||||
|
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
|
||||||
|
|
||||||
namespace GitHub.DistributedTask.Pipelines
|
namespace GitHub.DistributedTask.Pipelines
|
||||||
{
|
{
|
||||||
[DataContract]
|
[DataContract]
|
||||||
public class Snapshot
|
public class Snapshot
|
||||||
{
|
{
|
||||||
public Snapshot(string imageName)
|
public Snapshot(string imageName, string condition = null, string version = null)
|
||||||
{
|
{
|
||||||
ImageName = imageName;
|
ImageName = imageName;
|
||||||
|
Condition = condition ?? $"{PipelineTemplateConstants.Success}()";
|
||||||
|
Version = version ?? "1.*";
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataMember(EmitDefaultValue = false)]
|
[DataMember(EmitDefaultValue = false)]
|
||||||
public String ImageName { get; set; }
|
public String ImageName { get; set; }
|
||||||
|
|
||||||
|
[DataMember(EmitDefaultValue = false)]
|
||||||
|
public String Condition { get; set; }
|
||||||
|
|
||||||
|
[DataMember(EmitDefaultValue = false)]
|
||||||
|
public String Version { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,11 +169,28 @@
|
|||||||
"image-name": {
|
"image-name": {
|
||||||
"type": "non-empty-string",
|
"type": "non-empty-string",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
"if": "snapshot-if",
|
||||||
|
"version": {
|
||||||
|
"type": "non-empty-string",
|
||||||
|
"required": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"snapshot-if": {
|
||||||
|
"context": [
|
||||||
|
"github",
|
||||||
|
"inputs",
|
||||||
|
"vars",
|
||||||
|
"needs",
|
||||||
|
"strategy",
|
||||||
|
"matrix"
|
||||||
|
],
|
||||||
|
"string": {}
|
||||||
|
},
|
||||||
|
|
||||||
"runs-on": {
|
"runs-on": {
|
||||||
"context": [
|
"context": [
|
||||||
"github",
|
"github",
|
||||||
|
|||||||
@@ -506,7 +506,27 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
return EnsureSnapshotPostJobStepForToken(mappingToken, snapshot);
|
return EnsureSnapshotPostJobStepForToken(mappingToken, snapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task EnsureSnapshotPostJobStepForToken(TemplateToken snapshotToken, Pipelines.Snapshot expectedSnapshot)
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public Task EnsureSnapshotPostJobStepForMappingToken_WithIf_Is_False()
|
||||||
|
{
|
||||||
|
var snapshot = new Pipelines.Snapshot("TestImageNameFromMappingToken", condition: $"{PipelineTemplateConstants.Success}() && 1==0", version: "2.*");
|
||||||
|
var imageNameValueStringToken = new StringToken(null, null, null, snapshot.ImageName);
|
||||||
|
var condition = new StringToken(null, null, null, snapshot.Condition);
|
||||||
|
var version = new StringToken(null, null, null, snapshot.Version);
|
||||||
|
|
||||||
|
var mappingToken = new MappingToken(null, null, null)
|
||||||
|
{
|
||||||
|
{ new StringToken(null,null,null, PipelineTemplateConstants.ImageName), imageNameValueStringToken },
|
||||||
|
{ new StringToken(null,null,null, PipelineTemplateConstants.If), condition },
|
||||||
|
{ new StringToken(null,null,null, PipelineTemplateConstants.CustomImageVersion), version }
|
||||||
|
};
|
||||||
|
|
||||||
|
return EnsureSnapshotPostJobStepForToken(mappingToken, snapshot, skipSnapshotStep: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EnsureSnapshotPostJobStepForToken(TemplateToken snapshotToken, Pipelines.Snapshot expectedSnapshot, bool skipSnapshotStep = false)
|
||||||
{
|
{
|
||||||
using (TestHostContext hc = CreateTestContext())
|
using (TestHostContext hc = CreateTestContext())
|
||||||
{
|
{
|
||||||
@@ -524,14 +544,28 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
|
|
||||||
Assert.Equal(1, postJobSteps.Count);
|
Assert.Equal(1, postJobSteps.Count);
|
||||||
var snapshotStep = postJobSteps.First();
|
var snapshotStep = postJobSteps.First();
|
||||||
|
_jobEc.JobSteps.Enqueue(snapshotStep);
|
||||||
|
|
||||||
|
var _stepsRunner = new StepsRunner();
|
||||||
|
_stepsRunner.Initialize(hc);
|
||||||
|
await _stepsRunner.RunAsync(_jobEc);
|
||||||
|
|
||||||
Assert.Equal("Create custom image", snapshotStep.DisplayName);
|
Assert.Equal("Create custom image", snapshotStep.DisplayName);
|
||||||
Assert.Equal($"{PipelineTemplateConstants.Success}()", snapshotStep.Condition);
|
Assert.Equal(expectedSnapshot.Condition ?? $"{PipelineTemplateConstants.Success}()", snapshotStep.Condition);
|
||||||
|
|
||||||
// Run the mock snapshot step, so we can verify it was executed with the expected snapshot object.
|
// Run the mock snapshot step, so we can verify it was executed with the expected snapshot object.
|
||||||
await snapshotStep.RunAsync();
|
// await snapshotStep.RunAsync();
|
||||||
|
if (skipSnapshotStep)
|
||||||
Assert.NotNull(_requestedSnapshot);
|
{
|
||||||
Assert.Equal(expectedSnapshot.ImageName, _requestedSnapshot.ImageName);
|
Assert.Null(_requestedSnapshot);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.NotNull(_requestedSnapshot);
|
||||||
|
Assert.Equal(expectedSnapshot.ImageName, _requestedSnapshot.ImageName);
|
||||||
|
Assert.Equal(expectedSnapshot.Condition ?? $"{PipelineTemplateConstants.Success}()", _requestedSnapshot.Condition);
|
||||||
|
Assert.Equal(expectedSnapshot.Version ?? "1.*", _requestedSnapshot.Version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user