mirror of
https://github.com/actions/runner.git
synced 2025-12-10 20:36:49 +00:00
Compare commits
1 Commits
v2.320.1
...
users/tihu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25cd3d808c |
67
src/Runner.Common/GitHubServer.cs
Normal file
67
src/Runner.Common/GitHubServer.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using GitHub.Services.Common;
|
||||||
|
|
||||||
|
namespace GitHub.Runner.Common
|
||||||
|
{
|
||||||
|
|
||||||
|
public class GitHubResult
|
||||||
|
{
|
||||||
|
public HttpStatusCode StatusCode { get; set; }
|
||||||
|
public String Message { get; set; }
|
||||||
|
public HttpResponseHeaders Headers { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[ServiceLocator(Default = typeof(GitHubServer))]
|
||||||
|
public interface IGitHubServer : IRunnerService
|
||||||
|
{
|
||||||
|
Task<GitHubResult> RevokeInstallationToken(string GithubApiUrl, string AccessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GitHubServer : RunnerService, IGitHubServer
|
||||||
|
{
|
||||||
|
public async Task<GitHubResult> RevokeInstallationToken(string GithubApiUrl, string AccessToken)
|
||||||
|
{
|
||||||
|
var result = new GitHubResult();
|
||||||
|
var requestUrl = new UriBuilder(GithubApiUrl);
|
||||||
|
requestUrl.Path = requestUrl.Path.TrimEnd('/') + "/installation/token";
|
||||||
|
|
||||||
|
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
|
||||||
|
using (var httpClient = HttpClientFactory.Create(httpClientHandler, new VssHttpRetryMessageHandler(3)))
|
||||||
|
{
|
||||||
|
httpClient.DefaultRequestHeaders.UserAgent.Add(HostContext.UserAgent);
|
||||||
|
var base64EncodingToken = Convert.ToBase64String(Encoding.UTF8.GetBytes($"x-access-token:{AccessToken}"));
|
||||||
|
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64EncodingToken);
|
||||||
|
var count = 1;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Delete, requestUrl.Uri))
|
||||||
|
{
|
||||||
|
requestMessage.Headers.Add("Accept", "application/vnd.github.gambit-preview+json");
|
||||||
|
var response = await httpClient.SendAsync(requestMessage, CancellationToken.None);
|
||||||
|
result.StatusCode = response.StatusCode;
|
||||||
|
result.Headers = response.Headers;
|
||||||
|
result.Message = await response.Content.ReadAsStringAsync();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (count++ < 3)
|
||||||
|
{
|
||||||
|
Trace.Error("Fail to revoke GITHUB_TOKEN, will try again later");
|
||||||
|
Trace.Error(ex);
|
||||||
|
var backoff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
|
||||||
|
await Task.Delay(backoff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Net;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
@@ -33,7 +34,7 @@ namespace GitHub.Runner.Worker
|
|||||||
public interface IJobExtension : IRunnerService
|
public interface IJobExtension : IRunnerService
|
||||||
{
|
{
|
||||||
Task<List<IStep>> InitializeJob(IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message);
|
Task<List<IStep>> InitializeJob(IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message);
|
||||||
void FinalizeJob(IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, DateTime jobStartTimeUtc);
|
Task FinalizeJobAsync(IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, DateTime jobStartTimeUtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class JobExtension : RunnerService, IJobExtension
|
public sealed class JobExtension : RunnerService, IJobExtension
|
||||||
@@ -311,7 +312,7 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FinalizeJob(IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, DateTime jobStartTimeUtc)
|
public async Task FinalizeJobAsync(IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, DateTime jobStartTimeUtc)
|
||||||
{
|
{
|
||||||
Trace.Entering();
|
Trace.Entering();
|
||||||
ArgUtil.NotNull(jobContext, nameof(jobContext));
|
ArgUtil.NotNull(jobContext, nameof(jobContext));
|
||||||
@@ -325,6 +326,39 @@ namespace GitHub.Runner.Worker
|
|||||||
context.Start();
|
context.Start();
|
||||||
context.Debug("Starting: Complete job");
|
context.Debug("Starting: Complete job");
|
||||||
|
|
||||||
|
// Revoke GITHUB_TOKEN
|
||||||
|
context.Debug("Revoking GITHUB_TOKEN");
|
||||||
|
var githubApiUrl = context.GetGitHubContext("api_url");
|
||||||
|
if (string.IsNullOrEmpty(githubApiUrl))
|
||||||
|
{
|
||||||
|
githubApiUrl = "https://api.github.com";
|
||||||
|
}
|
||||||
|
|
||||||
|
var githubToken = context.GetGitHubContext("token");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var githubServer = HostContext.GetService<IGitHubServer>();
|
||||||
|
var result = await githubServer.RevokeInstallationToken(githubApiUrl, githubToken);
|
||||||
|
if (result.StatusCode == HttpStatusCode.NoContent)
|
||||||
|
{
|
||||||
|
context.Debug("GITHUB_TOKEN revoked");
|
||||||
|
}
|
||||||
|
else if (result.StatusCode == HttpStatusCode.Unauthorized)
|
||||||
|
{
|
||||||
|
context.Debug("GITHUB_TOKEN already expired");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Trace.Error("Fail to revoke GITHUB_TOKEN");
|
||||||
|
Trace.Error(result.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Trace.Error("Fail to revoke GITHUB_TOKEN");
|
||||||
|
Trace.Error(ex);
|
||||||
|
}
|
||||||
|
|
||||||
// Evaluate job outputs
|
// Evaluate job outputs
|
||||||
if (message.JobOutputs != null && message.JobOutputs.Type != TokenType.Null)
|
if (message.JobOutputs != null && message.JobOutputs.Type != TokenType.Null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ namespace GitHub.Runner.Worker
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Trace.Info("Finalize job.");
|
Trace.Info("Finalize job.");
|
||||||
jobExtension.FinalizeJob(jobContext, message, jobStartTimeUtc);
|
await jobExtension.FinalizeJobAsync(jobContext, message, jobStartTimeUtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
Trace.Info($"Job result after all job steps finish: {jobContext.Result ?? TaskResult.Succeeded}");
|
Trace.Info($"Job result after all job steps finish: {jobContext.Result ?? TaskResult.Succeeded}");
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void UploadDiganosticLogIfEnvironmentVariableSet()
|
public async Task UploadDiganosticLogIfEnvironmentVariableSet()
|
||||||
{
|
{
|
||||||
using (TestHostContext hc = CreateTestContext())
|
using (TestHostContext hc = CreateTestContext())
|
||||||
{
|
{
|
||||||
@@ -220,7 +220,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
_jobEc.Initialize(hc);
|
_jobEc.Initialize(hc);
|
||||||
_jobEc.InitializeJob(_message, _tokenSource.Token);
|
_jobEc.InitializeJob(_message, _tokenSource.Token);
|
||||||
|
|
||||||
jobExtension.FinalizeJob(_jobEc, _message, DateTime.UtcNow);
|
await jobExtension.FinalizeJobAsync(_jobEc, _message, DateTime.UtcNow);
|
||||||
|
|
||||||
_diagnosticLogManager.Verify(x =>
|
_diagnosticLogManager.Verify(x =>
|
||||||
x.UploadDiagnosticLogs(
|
x.UploadDiagnosticLogs(
|
||||||
@@ -235,7 +235,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void DontUploadDiagnosticLogIfEnvironmentVariableFalse()
|
public async Task DontUploadDiagnosticLogIfEnvironmentVariableFalse()
|
||||||
{
|
{
|
||||||
using (TestHostContext hc = CreateTestContext())
|
using (TestHostContext hc = CreateTestContext())
|
||||||
{
|
{
|
||||||
@@ -248,7 +248,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
_jobEc.Initialize(hc);
|
_jobEc.Initialize(hc);
|
||||||
_jobEc.InitializeJob(_message, _tokenSource.Token);
|
_jobEc.InitializeJob(_message, _tokenSource.Token);
|
||||||
|
|
||||||
jobExtension.FinalizeJob(_jobEc, _message, DateTime.UtcNow);
|
await jobExtension.FinalizeJobAsync(_jobEc, _message, DateTime.UtcNow);
|
||||||
|
|
||||||
_diagnosticLogManager.Verify(x =>
|
_diagnosticLogManager.Verify(x =>
|
||||||
x.UploadDiagnosticLogs(
|
x.UploadDiagnosticLogs(
|
||||||
@@ -263,14 +263,14 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void DontUploadDiagnosticLogIfEnvironmentVariableMissing()
|
public async Task DontUploadDiagnosticLogIfEnvironmentVariableMissing()
|
||||||
{
|
{
|
||||||
using (TestHostContext hc = CreateTestContext())
|
using (TestHostContext hc = CreateTestContext())
|
||||||
{
|
{
|
||||||
var jobExtension = new JobExtension();
|
var jobExtension = new JobExtension();
|
||||||
jobExtension.Initialize(hc);
|
jobExtension.Initialize(hc);
|
||||||
|
|
||||||
jobExtension.FinalizeJob(_jobEc, _message, DateTime.UtcNow);
|
await jobExtension.FinalizeJobAsync(_jobEc, _message, DateTime.UtcNow);
|
||||||
|
|
||||||
_diagnosticLogManager.Verify(x =>
|
_diagnosticLogManager.Verify(x =>
|
||||||
x.UploadDiagnosticLogs(
|
x.UploadDiagnosticLogs(
|
||||||
|
|||||||
Reference in New Issue
Block a user