Compare commits

...

5 Commits

Author SHA1 Message Date
Tingluo Huang
745b90a8b2 Revert "Update Base64 Encoders to deal with suffixes (#284)" (#330)
This reverts commit c45aebc9ab.
2020-02-12 14:26:30 -05:00
Tingluo Huang
0db908da8d Use authenticate endpoint for testing runner connection. (#311)
* use authenticate endpoint for testing runner connection.

* PR feedback.
2020-02-05 16:56:38 -05:00
Thomas Boop
68de3a94be Remove Temporary Build Step (#316)
* Remove Temporary Build Step

* Updated dev.sh to set path for find
2020-02-04 12:59:49 -05:00
Tingluo Huang
a0a590fb48 setup/evaluate env context after setup steps context. (#309) 2020-01-30 22:14:14 -05:00
Christopher Johnson
87a232c477 Fix windows directions in release notes (#307) 2020-01-29 12:58:09 -05:00
10 changed files with 141 additions and 124 deletions

View File

@@ -43,14 +43,6 @@ jobs:
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
# Set Path workaround for https://github.com/actions/virtual-environments/issues/263
- run: |
echo "::add-path::C:\Program Files\Git\mingw64\bin"
echo "::add-path::C:\Program Files\Git\usr\bin"
echo "::add-path::C:\Program Files\Git\bin"
if: matrix.os == 'windows-latest'
name: "Temp step to Set Path for Windows"
# Build runner layout # Build runner layout
- name: Build & Layout Release - name: Build & Layout Release
run: | run: |

View File

@@ -24,7 +24,7 @@
- Treat warnings as errors during compile (#249) - Treat warnings as errors during compile (#249)
## Windows x64 ## Windows x64
We recommend configuring the runner under "<DRIVE>:\actions-runner". This will help avoid issues related to service identity folder permissions and long file path restrictions on Windows We recommend configuring the runner in a root folder of the Windows drive (e.g. "C:\actions-runner"). This will help avoid issues related to service identity folder permissions and long file path restrictions on Windows
``` ```
// Create a folder under the drive root // Create a folder under the drive root
mkdir \actions-runner ; cd \actions-runner mkdir \actions-runner ; cd \actions-runner
@@ -32,7 +32,7 @@ mkdir \actions-runner ; cd \actions-runner
Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-win-x64-<RUNNER_VERSION>.zip -OutFile actions-runner-win-x64-<RUNNER_VERSION>.zip Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-win-x64-<RUNNER_VERSION>.zip -OutFile actions-runner-win-x64-<RUNNER_VERSION>.zip
// Extract the installer // Extract the installer
Add-Type -AssemblyName System.IO.Compression.FileSystem ; Add-Type -AssemblyName System.IO.Compression.FileSystem ;
[System.IO.Compression.ZipFile]::ExtractToDirectory("$HOME\Downloads\actions-runner-win-x64-<RUNNER_VERSION>.zip", "$PWD") [System.IO.Compression.ZipFile]::ExtractToDirectory("$PWD\actions-runner-win-x64-<RUNNER_VERSION>.zip", "$PWD")
``` ```
## OSX ## OSX

View File

@@ -83,7 +83,6 @@ namespace GitHub.Runner.Common
_loadContext.Unloading += LoadContext_Unloading; _loadContext.Unloading += LoadContext_Unloading;
this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscape); this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscape);
this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscapeTrimmed);
this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscapeShift1); this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscapeShift1);
this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscapeShift2); this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscapeShift2);
this.SecretMasker.AddValueEncoder(ValueEncoders.ExpressionStringEscape); this.SecretMasker.AddValueEncoder(ValueEncoders.ExpressionStringEscape);

View File

@@ -277,12 +277,15 @@ namespace GitHub.Runner.Listener.Configuration
throw new NotSupportedException("Message queue listen OAuth token."); throw new NotSupportedException("Message queue listen OAuth token.");
} }
// Testing agent connection, detect any protential connection issue, like local clock skew that cause OAuth token expired. // Testing agent connection, detect any potential connection issue, like local clock skew that cause OAuth token expired.
var credMgr = HostContext.GetService<ICredentialManager>(); var credMgr = HostContext.GetService<ICredentialManager>();
VssCredentials credential = credMgr.LoadCredentials(); VssCredentials credential = credMgr.LoadCredentials();
try try
{ {
await _runnerServer.ConnectAsync(new Uri(runnerSettings.ServerUrl), credential); await _runnerServer.ConnectAsync(new Uri(runnerSettings.ServerUrl), credential);
// ConnectAsync() hits _apis/connectionData which is an anonymous endpoint
// Need to hit an authenticate endpoint to trigger OAuth token exchange.
await _runnerServer.GetAgentPoolsAsync();
_term.WriteSuccessMessage("Runner connection is good"); _term.WriteSuccessMessage("Runner connection is good");
} }
catch (VssOAuthTokenRequestException ex) when (ex.Message.Contains("Current server time is")) catch (VssOAuthTokenRequestException ex) when (ex.Message.Contains("Current server time is"))

View File

@@ -76,38 +76,38 @@ namespace GitHub.Runner.Worker
// Start // Start
step.ExecutionContext.Start(); step.ExecutionContext.Start();
// Populate env context for each step
Trace.Info("Initialize Env context for step");
#if OS_WINDOWS
var envContext = new DictionaryContextData();
#else
var envContext = new CaseSensitiveDictionaryContextData();
#endif
step.ExecutionContext.ExpressionValues["env"] = envContext;
foreach (var pair in step.ExecutionContext.EnvironmentVariables)
{
envContext[pair.Key] = new StringContextData(pair.Value ?? string.Empty);
}
if (step is IActionRunner actionStep)
{
// Set GITHUB_ACTION
step.ExecutionContext.SetGitHubContext("action", actionStep.Action.Name);
// Evaluate and merge action's env block to env context
var templateTrace = step.ExecutionContext.ToTemplateTraceWriter();
var schema = new PipelineTemplateSchemaFactory().CreateSchema();
var templateEvaluator = new PipelineTemplateEvaluator(templateTrace, schema);
var actionEnvironment = templateEvaluator.EvaluateStepEnvironment(actionStep.Action.Environment, step.ExecutionContext.ExpressionValues, VarUtil.EnvironmentVariableKeyComparer);
foreach (var env in actionEnvironment)
{
envContext[env.Key] = new StringContextData(env.Value ?? string.Empty);
}
}
// Initialize scope // Initialize scope
if (InitializeScope(step, scopeInputs)) if (InitializeScope(step, scopeInputs))
{ {
// Populate env context for each step
Trace.Info("Initialize Env context for step");
#if OS_WINDOWS
var envContext = new DictionaryContextData();
#else
var envContext = new CaseSensitiveDictionaryContextData();
#endif
step.ExecutionContext.ExpressionValues["env"] = envContext;
foreach (var pair in step.ExecutionContext.EnvironmentVariables)
{
envContext[pair.Key] = new StringContextData(pair.Value ?? string.Empty);
}
if (step is IActionRunner actionStep)
{
// Set GITHUB_ACTION
step.ExecutionContext.SetGitHubContext("action", actionStep.Action.Name);
// Evaluate and merge action's env block to env context
var templateTrace = step.ExecutionContext.ToTemplateTraceWriter();
var schema = new PipelineTemplateSchemaFactory().CreateSchema();
var templateEvaluator = new PipelineTemplateEvaluator(templateTrace, schema);
var actionEnvironment = templateEvaluator.EvaluateStepEnvironment(actionStep.Action.Environment, step.ExecutionContext.ExpressionValues, VarUtil.EnvironmentVariableKeyComparer);
foreach (var env in actionEnvironment)
{
envContext[env.Key] = new StringContextData(env.Value ?? string.Empty);
}
}
var expressionManager = HostContext.GetService<IExpressionManager>(); var expressionManager = HostContext.GetService<IExpressionManager>();
try try
{ {

View File

@@ -16,11 +16,6 @@ namespace GitHub.DistributedTask.Logging
{ {
return Convert.ToBase64String(Encoding.UTF8.GetBytes(value)); return Convert.ToBase64String(Encoding.UTF8.GetBytes(value));
} }
public static String Base64StringEscapeTrimmed(String value)
{
return TrimBase64End(Convert.ToBase64String(Encoding.UTF8.GetBytes(value)));
}
// Base64 is 6 bits -> char // Base64 is 6 bits -> char
// A byte is 8 bits // A byte is 8 bits
@@ -72,15 +67,15 @@ namespace GitHub.DistributedTask.Logging
{ {
var shiftArray = new byte[bytes.Length - shift]; var shiftArray = new byte[bytes.Length - shift];
Array.Copy(bytes, shift, shiftArray, 0, bytes.Length - shift); Array.Copy(bytes, shift, shiftArray, 0, bytes.Length - shift);
return TrimBase64End(Convert.ToBase64String(shiftArray)); return Convert.ToBase64String(shiftArray);
} }
else else
{ {
return TrimBase64End(Convert.ToBase64String(bytes)); return Convert.ToBase64String(bytes);
} }
} }
public static String UriDataEscape( private static String UriDataEscape(
String value, String value,
Int32 maxSegmentSize) Int32 maxSegmentSize)
{ {
@@ -108,26 +103,5 @@ namespace GitHub.DistributedTask.Logging
return result.ToString(); return result.ToString();
} }
private static String TrimBase64End(String value)
{
if (String.IsNullOrEmpty(value))
{
return String.Empty;
}
if (value.EndsWith('='))
{
var trimmed = value.TrimEnd('=');
if (trimmed.Length > 1)
{
// If a base64 string ends in '=' it indicates that the base 64 character is only using 2 or 4 of the six bytes and will change if another character is added
// For example 'ab' is 'YWI=' in base 64
// 'abc' is 'YWJj'
// We need to detect YW, not YWI so we trim the last character ('I')
return trimmed.Substring(0, trimmed.Length - 1);
}
}
return value;
}
} }
} }

View File

@@ -93,21 +93,12 @@ namespace GitHub.Runner.Common.Tests
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Pass%20word%20123%21123")); Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Pass%20word%20123%21123"));
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Pass&lt;word&gt;123!123")); Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Pass&lt;word&gt;123!123"));
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Pass''word''123!123")); Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Pass''word''123!123"));
Assert.Equal("OlBh***Q==", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($":Password123!")))); Assert.Equal("OlBh***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($":Password123!"))));
Assert.Equal("YTpQ***E=", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"a:Password123!")))); Assert.Equal("YTpQ***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"a:Password123!"))));
Assert.Equal("YWI6***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"ab:Password123!")))); Assert.Equal("YWI6***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"ab:Password123!"))));
Assert.Equal("YWJjOlBh***Q==", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abc:Password123!")))); Assert.Equal("YWJjOlBh***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abc:Password123!"))));
Assert.Equal("YWJjZDpQ***E=", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abcd:Password123!")))); Assert.Equal("YWJjZDpQ***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abcd:Password123!"))));
Assert.Equal("YWJjZGU6***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abcde:Password123!")))); Assert.Equal("YWJjZGU6***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abcde:Password123!"))));
Assert.Equal("***Og==", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"Password123!:"))));
Assert.Equal("***OmE=", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"Password123!:a"))));
Assert.Equal("***OmFi", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"Password123!:ab"))));
Assert.Equal("***OmFiYw==", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"Password123!:abc"))));
Assert.Equal("***OmFiY2Q=", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"Password123!:abcd"))));
Assert.Equal("***OmFiY2Rl", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"Password123!:abcde"))));
Assert.Equal("OlBh***To=", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($":Password123!:"))));
Assert.Equal("YTpQ***E6YQ==", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"a:Password123!:a"))));
Assert.Equal("YWJjOlBh***Tph", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abc:Password123!:a"))));
} }
finally finally
{ {

View File

@@ -175,8 +175,8 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
Assert.True(s.PoolId.Equals(_expectedPoolId)); Assert.True(s.PoolId.Equals(_expectedPoolId));
Assert.True(s.WorkFolder.Equals(_expectedWorkFolder)); Assert.True(s.WorkFolder.Equals(_expectedWorkFolder));
// validate GetAgentPoolsAsync gets called once with automation pool type // validate GetAgentPoolsAsync gets called twice with automation pool type
_runnerServer.Verify(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.Is<TaskAgentPoolType>(p => p == TaskAgentPoolType.Automation)), Times.Once); _runnerServer.Verify(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.Is<TaskAgentPoolType>(p => p == TaskAgentPoolType.Automation)), Times.Exactly(2));
_runnerServer.Verify(x => x.AddAgentAsync(It.IsAny<int>(), It.Is<TaskAgent>(a => a.Labels.Contains("self-hosted") && a.Labels.Contains(VarUtil.OS) && a.Labels.Contains(VarUtil.OSArchitecture))), Times.Once); _runnerServer.Verify(x => x.AddAgentAsync(It.IsAny<int>(), It.Is<TaskAgent>(a => a.Labels.Contains("self-hosted") && a.Labels.Contains(VarUtil.OS) && a.Labels.Contains(VarUtil.OSArchitecture))), Times.Once);
} }

View File

@@ -70,9 +70,9 @@ namespace GitHub.Runner.Common.Tests.Worker
// Arrange. // Arrange.
var variableSets = new[] var variableSets = new[]
{ {
new[] { CreateStep(TaskResult.Succeeded, "success()"), CreateStep(TaskResult.Succeeded, "success()") }, new[] { CreateStep(hc, TaskResult.Succeeded, "success()"), CreateStep(hc, TaskResult.Succeeded, "success()") },
new[] { CreateStep(TaskResult.Succeeded, "success()"), CreateStep(TaskResult.Succeeded, "success() || failure()") }, new[] { CreateStep(hc, TaskResult.Succeeded, "success()"), CreateStep(hc, TaskResult.Succeeded, "success() || failure()") },
new[] { CreateStep(TaskResult.Succeeded, "success()"), CreateStep(TaskResult.Succeeded, "always()") } new[] { CreateStep(hc, TaskResult.Succeeded, "success()"), CreateStep(hc, TaskResult.Succeeded, "always()") }
}; };
foreach (var variableSet in variableSets) foreach (var variableSet in variableSets)
{ {
@@ -102,12 +102,12 @@ namespace GitHub.Runner.Common.Tests.Worker
// Arrange. // Arrange.
var variableSets = new[] var variableSets = new[]
{ {
new[] { CreateStep(TaskResult.Failed, "success()", true), CreateStep(TaskResult.Succeeded, "success()") }, new[] { CreateStep(hc, TaskResult.Failed, "success()", true), CreateStep(hc, TaskResult.Succeeded, "success()") },
new[] { CreateStep(TaskResult.Failed, "success()", true), CreateStep(TaskResult.Succeeded, "success() || failure()") }, new[] { CreateStep(hc, TaskResult.Failed, "success()", true), CreateStep(hc, TaskResult.Succeeded, "success() || failure()") },
new[] { CreateStep(TaskResult.Failed, "success()", true), CreateStep(TaskResult.Succeeded, "always()") }, new[] { CreateStep(hc, TaskResult.Failed, "success()", true), CreateStep(hc, TaskResult.Succeeded, "always()") },
new[] { CreateStep(TaskResult.Failed, "success()", true), CreateStep(TaskResult.Failed, "success()", true) }, new[] { CreateStep(hc, TaskResult.Failed, "success()", true), CreateStep(hc, TaskResult.Failed, "success()", true) },
new[] { CreateStep(TaskResult.Failed, "success()", true), CreateStep(TaskResult.Failed, "success() || failure()", true) }, new[] { CreateStep(hc, TaskResult.Failed, "success()", true), CreateStep(hc, TaskResult.Failed, "success() || failure()", true) },
new[] { CreateStep(TaskResult.Failed, "success()", true), CreateStep(TaskResult.Failed, "always()", true) } new[] { CreateStep(hc, TaskResult.Failed, "success()", true), CreateStep(hc, TaskResult.Failed, "always()", true) }
}; };
foreach (var variableSet in variableSets) foreach (var variableSet in variableSets)
{ {
@@ -139,12 +139,12 @@ namespace GitHub.Runner.Common.Tests.Worker
{ {
new new
{ {
Steps = new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "success()") }, Steps = new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "success()") },
Expected = false, Expected = false,
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "success() || failure()") }, Steps = new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "success() || failure()") },
Expected = true, Expected = true,
}, },
}; };
@@ -178,27 +178,27 @@ namespace GitHub.Runner.Common.Tests.Worker
{ {
new new
{ {
Steps = new[] { CreateStep(TaskResult.Succeeded, "success()"), CreateStep(TaskResult.Succeeded, "always()") }, Steps = new[] { CreateStep(hc, TaskResult.Succeeded, "success()"), CreateStep(hc, TaskResult.Succeeded, "always()") },
Expected = TaskResult.Succeeded, Expected = TaskResult.Succeeded,
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "always()") }, Steps = new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "always()") },
Expected = TaskResult.Failed, Expected = TaskResult.Failed,
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "always()") }, Steps = new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "always()") },
Expected = TaskResult.Failed, Expected = TaskResult.Failed,
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Succeeded, "success()"), CreateStep(TaskResult.Failed, "always()") }, Steps = new[] { CreateStep(hc, TaskResult.Succeeded, "success()"), CreateStep(hc, TaskResult.Failed, "always()") },
Expected = TaskResult.Failed, Expected = TaskResult.Failed,
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Succeeded, "success()"), CreateStep(TaskResult.Failed, "always()", true) }, Steps = new[] { CreateStep(hc, TaskResult.Succeeded, "success()"), CreateStep(hc, TaskResult.Failed, "always()", true) },
Expected = TaskResult.Succeeded, Expected = TaskResult.Succeeded,
}, },
}; };
@@ -232,47 +232,47 @@ namespace GitHub.Runner.Common.Tests.Worker
{ {
new new
{ {
Steps = new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "success()") }, Steps = new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "success()") },
Expected = TaskResult.Failed Expected = TaskResult.Failed
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "success() || failure()") }, Steps = new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "success() || failure()") },
Expected = TaskResult.Failed Expected = TaskResult.Failed
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "always()") }, Steps = new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "always()") },
Expected = TaskResult.Failed Expected = TaskResult.Failed
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Failed, "success()", continueOnError: true), CreateStep(TaskResult.Failed, "success()") }, Steps = new[] { CreateStep(hc, TaskResult.Failed, "success()", continueOnError: true), CreateStep(hc, TaskResult.Failed, "success()") },
Expected = TaskResult.Failed Expected = TaskResult.Failed
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Failed, "success()", continueOnError: true), CreateStep(TaskResult.Succeeded, "success()") }, Steps = new[] { CreateStep(hc, TaskResult.Failed, "success()", continueOnError: true), CreateStep(hc, TaskResult.Succeeded, "success()") },
Expected = TaskResult.Succeeded Expected = TaskResult.Succeeded
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Failed, "success()", continueOnError: true), CreateStep(TaskResult.Failed, "success()", continueOnError: true) }, Steps = new[] { CreateStep(hc, TaskResult.Failed, "success()", continueOnError: true), CreateStep(hc, TaskResult.Failed, "success()", continueOnError: true) },
Expected = TaskResult.Succeeded Expected = TaskResult.Succeeded
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Succeeded, "success() || failure()") }, Steps = new[] { CreateStep(hc, TaskResult.Succeeded, "success() || failure()") },
Expected = TaskResult.Succeeded Expected = TaskResult.Succeeded
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Succeeded, "success()"), CreateStep(TaskResult.Failed, "success()") }, Steps = new[] { CreateStep(hc, TaskResult.Succeeded, "success()"), CreateStep(hc, TaskResult.Failed, "success()") },
Expected = TaskResult.Failed Expected = TaskResult.Failed
}, },
new new
{ {
Steps = new[] { CreateStep(TaskResult.Succeeded, "success()"), CreateStep(TaskResult.Succeeded, "success()") }, Steps = new[] { CreateStep(hc, TaskResult.Succeeded, "success()"), CreateStep(hc, TaskResult.Succeeded, "success()") },
Expected = TaskResult.Succeeded Expected = TaskResult.Succeeded
}, },
// Abandoned // Abandoned
@@ -310,17 +310,17 @@ namespace GitHub.Runner.Common.Tests.Worker
{ {
new new
{ {
Step = new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "success()") }, Step = new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "success()") },
Expected = false Expected = false
}, },
new new
{ {
Step = new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "success() || failure()") }, Step = new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "success() || failure()") },
Expected = true Expected = true
}, },
new new
{ {
Step = new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "always()") }, Step = new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "always()") },
Expected = true Expected = true
} }
}; };
@@ -351,9 +351,9 @@ namespace GitHub.Runner.Common.Tests.Worker
// Arrange. // Arrange.
var variableSets = new[] var variableSets = new[]
{ {
new[] { CreateStep(TaskResult.Succeeded, "success()"), CreateStep(TaskResult.Succeeded, "always()") }, new[] { CreateStep(hc, TaskResult.Succeeded, "success()"), CreateStep(hc, TaskResult.Succeeded, "always()") },
new[] { CreateStep(TaskResult.Failed, "success()"), CreateStep(TaskResult.Succeeded, "always()") }, new[] { CreateStep(hc, TaskResult.Failed, "success()"), CreateStep(hc, TaskResult.Succeeded, "always()") },
new[] { CreateStep(TaskResult.Canceled, "success()"), CreateStep(TaskResult.Succeeded, "always()") } new[] { CreateStep(hc, TaskResult.Canceled, "success()"), CreateStep(hc, TaskResult.Succeeded, "always()") }
}; };
foreach (var variableSet in variableSets) foreach (var variableSet in variableSets)
{ {
@@ -387,8 +387,8 @@ namespace GitHub.Runner.Common.Tests.Worker
// Arrange. // Arrange.
var variableSets = new[] var variableSets = new[]
{ {
new[] { CreateStep(TaskResult.Succeeded, "success()") }, new[] { CreateStep(hc, TaskResult.Succeeded, "success()") },
new[] { CreateStep(TaskResult.Succeeded, "success()") }, new[] { CreateStep(hc, TaskResult.Succeeded, "success()") },
}; };
foreach (var variableSet in variableSets) foreach (var variableSet in variableSets)
{ {
@@ -416,7 +416,7 @@ namespace GitHub.Runner.Common.Tests.Worker
var env1 = new MappingToken(null, null, null); var env1 = new MappingToken(null, null, null);
env1.Add(new StringToken(null, null, null, "env1"), new StringToken(null, null, null, "100")); env1.Add(new StringToken(null, null, null, "env1"), new StringToken(null, null, null, "100"));
env1.Add(new StringToken(null, null, null, "env2"), new BasicExpressionToken(null, null, null, "env.test")); env1.Add(new StringToken(null, null, null, "env2"), new BasicExpressionToken(null, null, null, "env.test"));
var step1 = CreateStep(TaskResult.Succeeded, "success()", env: env1); var step1 = CreateStep(hc, TaskResult.Succeeded, "success()", env: env1);
_ec.Object.Result = null; _ec.Object.Result = null;
@@ -449,12 +449,12 @@ namespace GitHub.Runner.Common.Tests.Worker
var env1 = new MappingToken(null, null, null); var env1 = new MappingToken(null, null, null);
env1.Add(new StringToken(null, null, null, "env1"), new StringToken(null, null, null, "100")); env1.Add(new StringToken(null, null, null, "env1"), new StringToken(null, null, null, "100"));
env1.Add(new StringToken(null, null, null, "env2"), new BasicExpressionToken(null, null, null, "env.test")); env1.Add(new StringToken(null, null, null, "env2"), new BasicExpressionToken(null, null, null, "env.test"));
var step1 = CreateStep(TaskResult.Succeeded, "success()", env: env1); var step1 = CreateStep(hc, TaskResult.Succeeded, "success()", env: env1);
var env2 = new MappingToken(null, null, null); var env2 = new MappingToken(null, null, null);
env2.Add(new StringToken(null, null, null, "env1"), new StringToken(null, null, null, "1000")); env2.Add(new StringToken(null, null, null, "env1"), new StringToken(null, null, null, "1000"));
env2.Add(new StringToken(null, null, null, "env3"), new BasicExpressionToken(null, null, null, "env.test")); env2.Add(new StringToken(null, null, null, "env3"), new BasicExpressionToken(null, null, null, "env.test"));
var step2 = CreateStep(TaskResult.Succeeded, "success()", env: env2); var step2 = CreateStep(hc, TaskResult.Succeeded, "success()", env: env2);
_ec.Object.Result = null; _ec.Object.Result = null;
@@ -477,17 +477,52 @@ namespace GitHub.Runner.Common.Tests.Worker
} }
} }
private Mock<IActionRunner> CreateStep(TaskResult result, string condition, Boolean continueOnError = false, MappingToken env = null) [Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public async Task PopulateEnvContextAfterSetupStepsContext()
{
using (TestHostContext hc = CreateTestContext())
{
// Arrange.
var env1 = new MappingToken(null, null, null);
env1.Add(new StringToken(null, null, null, "env1"), new StringToken(null, null, null, "100"));
var step1 = CreateStep(hc, TaskResult.Succeeded, "success()", env: env1, name: "foo", setOutput: true);
var env2 = new MappingToken(null, null, null);
env2.Add(new StringToken(null, null, null, "env1"), new StringToken(null, null, null, "1000"));
env2.Add(new StringToken(null, null, null, "env2"), new BasicExpressionToken(null, null, null, "steps.foo.outputs.test"));
var step2 = CreateStep(hc, TaskResult.Succeeded, "success()", env: env2);
_ec.Object.Result = null;
_ec.Setup(x => x.JobSteps).Returns(new Queue<IStep>(new[] { step1.Object, step2.Object }));
// Act.
await _stepsRunner.RunAsync(jobContext: _ec.Object);
// Assert.
Assert.Equal(TaskResult.Succeeded, _ec.Object.Result ?? TaskResult.Succeeded);
#if OS_WINDOWS
Assert.Equal("1000", _ec.Object.ExpressionValues["env"].AssertDictionary("env")["env1"].AssertString("1000"));
Assert.Equal("something", _ec.Object.ExpressionValues["env"].AssertDictionary("env")["env2"].AssertString("something"));
#else
Assert.Equal("1000", _ec.Object.ExpressionValues["env"].AssertCaseSensitiveDictionary("env")["env1"].AssertString("1000"));
Assert.Equal("something", _ec.Object.ExpressionValues["env"].AssertCaseSensitiveDictionary("env")["env2"].AssertString("something"));
#endif
}
}
private Mock<IActionRunner> CreateStep(TestHostContext hc, TaskResult result, string condition, Boolean continueOnError = false, MappingToken env = null, string name = "Test", bool setOutput = false)
{ {
// Setup the step. // Setup the step.
var step = new Mock<IActionRunner>(); var step = new Mock<IActionRunner>();
step.Setup(x => x.Condition).Returns(condition); step.Setup(x => x.Condition).Returns(condition);
step.Setup(x => x.ContinueOnError).Returns(new BooleanToken(null, null, null, continueOnError)); step.Setup(x => x.ContinueOnError).Returns(new BooleanToken(null, null, null, continueOnError));
step.Setup(x => x.RunAsync()).Returns(Task.CompletedTask);
step.Setup(x => x.Action) step.Setup(x => x.Action)
.Returns(new DistributedTask.Pipelines.ActionStep() .Returns(new DistributedTask.Pipelines.ActionStep()
{ {
Name = "Test", Name = name,
Id = Guid.NewGuid(), Id = Guid.NewGuid(),
Environment = env Environment = env
}); });
@@ -495,6 +530,7 @@ namespace GitHub.Runner.Common.Tests.Worker
// Setup the step execution context. // Setup the step execution context.
var stepContext = new Mock<IExecutionContext>(); var stepContext = new Mock<IExecutionContext>();
stepContext.SetupAllProperties(); stepContext.SetupAllProperties();
stepContext.Setup(x => x.WriteDebug).Returns(true);
stepContext.Setup(x => x.Variables).Returns(_variables); stepContext.Setup(x => x.Variables).Returns(_variables);
stepContext.Setup(x => x.EnvironmentVariables).Returns(_env); stepContext.Setup(x => x.EnvironmentVariables).Returns(_env);
stepContext.Setup(x => x.ExpressionValues).Returns(_contexts); stepContext.Setup(x => x.ExpressionValues).Returns(_contexts);
@@ -508,9 +544,20 @@ namespace GitHub.Runner.Common.Tests.Worker
stepContext.Object.Result = r; stepContext.Object.Result = r;
} }
}); });
var trace = hc.GetTrace();
stepContext.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>())).Callback((string tag, string message) => { trace.Info($"[{tag}]{message}"); });
stepContext.Object.Result = result; stepContext.Object.Result = result;
step.Setup(x => x.ExecutionContext).Returns(stepContext.Object); step.Setup(x => x.ExecutionContext).Returns(stepContext.Object);
if (setOutput)
{
step.Setup(x => x.RunAsync()).Callback(() => { _stepContext.SetOutput(null, name, "test", "something", out string reference); }).Returns(Task.CompletedTask);
}
else
{
step.Setup(x => x.RunAsync()).Returns(Task.CompletedTask);
}
return step; return step;
} }

View File

@@ -1,5 +1,16 @@
@setlocal @setlocal
@echo off @echo off
rem add expected utils to path
IF EXIST C:\Program Files\Git\usr\bin (
SET PATH=C:\Program Files\Git\usr\bin;%PATH%
)
IF EXIST C:\Program Files\Git\mingw64\bin (
SET PATH=C:\Program Files\Git\mingw64\bin;%PATH%
)
IF EXIST C:\Program Files\Git\bin (
SET PATH=C:\Program Files\Git\bin;%PATH%
)
rem Check if SH_PATH is defined. rem Check if SH_PATH is defined.
if defined SH_PATH ( if defined SH_PATH (
goto run goto run