Compare commits

...

22 Commits

Author SHA1 Message Date
Tingluo Huang
f764f5dfa7 Release 2.301.1 runner with reverting #2333 (#2384)
* Revert "split by regex (#2333)"

This reverts commit 72830cfc12.

* Release 2.301.1 runner.
2023-01-18 19:38:19 -05:00
Tingluo Huang
e4716930a9 Create 2.301.0 runner release. 2023-01-18 15:04:38 -05:00
Tingluo Huang
6412390a22 Prepare 2.301.0 runner release. (#2382)
* Prepare 2.301.0 runner release.

* Update releaseNote.md

Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com>

* Update releaseNote.md

Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com>

* Update releaseNote.md

Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com>

* Update releaseNote.md

Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com>

* Update releaseNote.md

Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com>

* Update releaseNote.md

Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com>

* Update releaseNote.md

Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com>
2023-01-18 15:03:24 -05:00
John Sudol
7306014861 Update Node dependencies (#2381)
Co-authored-by: Tingluo Huang <tingluohuang@github.com>
2023-01-18 14:19:28 -05:00
John Sudol
d6f8633efc new option to remove local config files (#2367) 2023-01-18 11:28:43 -05:00
Cory Miller
130f6788d5 Add a disclaimer for which runner version is available to a given tenant (#2362)
* Add a disclaimer for which runner version is available to a given tenant

* Update releaseNote.md
2023-01-18 10:41:53 -05:00
John Sudol
9b390e0531 update node to 16.16.0 (#2371) 2023-01-18 10:41:15 -05:00
yujincat
a7101008a2 Show more information in the runner log (#2377)
* fix typo

* add workflow ref in the log

* show job name for all jobs

* update ref

* reflect the feedback

* fix a small bug
2023-01-18 10:40:35 -05:00
Tingluo Huang
4a6630531b Allow provide extra User-Agent for better correlation. (#2370) 2023-01-16 10:18:55 -05:00
Yang Cao
caec043085 Always upload to avoid issues (#2334)
* Remove unnecessary timelineId and timelineRecordId and use Guid stepId

* Log upload error to kusto

* Remove try-catch

* Using a well known telmetry record to avoid replacing issues

* fix Guid format
2022-12-28 11:56:53 -05:00
Tingluo Huang
a1244d2269 Add Header/Footer to multi-line message in StdoutTraceListener. (#2336) 2022-12-22 10:38:29 -05:00
Nikola Jokic
332b97f838 Treat jitconfig as secret. (#2335)
Co-authored-by: TingluoHuang <TingluoHuang@github.com>
2022-12-21 13:30:22 -05:00
Stefan Ruvceski
72830cfc12 split by regex (#2333)
* split by regex

* pr fix

* adding tests

* test fix
2022-12-20 14:28:29 +01:00
Tingluo Huang
29a28a870f Make runner image print diag log to STDOUT. (#2331) 2022-12-19 16:57:16 -05:00
Tingluo Huang
0dd7a113f1 Log GitHub RequestId for better traceability. (#2332) 2022-12-19 19:46:29 +00:00
TingluoHuang
83b8baa45e Bump runner version to 2.300.2 to match released version. 2022-12-19 14:22:51 -05:00
Ferenc Hammerl
d5e566ad17 Release notes for 2.300.1 (#2326)
* Update runnerversion

* Update releaseNote.md
2022-12-19 13:08:36 -05:00
Bethany
64381cca6a Re-add file size check prior to reading file (#2321) (#2330)
* Re-add file size check prior to reading file

* Remove redundant file size check
2022-12-19 12:56:28 -05:00
Stefan Ruvceski
f1b1532f32 set env in ProcessInvoker sanitized (#2280)
* set env in ProcessInvoker sanitized
2022-12-19 15:01:53 +01:00
Nikola Jokic
04761e5353 Initialize container manager based on whether the ContainerHooksPath is set (#2317)
* Added tests around checking if correct manager's Initialize method has been called

* repaired missing initialization on container action handler
2022-12-16 15:40:49 +01:00
Ava Stancu
f9e2fa939c Updated contact links for feature requests (#2314)
Users need to use the Github Community feedback page for all feature/enhancement requests.
2022-12-15 17:17:41 +02:00
Ferenc Hammerl
92acb625fb Update Dockerfile (#2315) 2022-12-15 15:44:07 +01:00
37 changed files with 4124 additions and 3867 deletions

View File

@@ -6,6 +6,9 @@
"ghcr.io/devcontainers/features/docker-in-docker:1": {},
"ghcr.io/devcontainers/features/dotnet": {
"version": "6.0.300"
},
"ghcr.io/devcontainers/features/node:1": {
"version": "16"
}
},
"customizations": {

View File

@@ -1,5 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: 🛑 Request a feature in the runner application
url: https://github.com/orgs/community/discussions/categories/actions-and-packages
about: If you have feature requests for GitHub Actions, please use the Actions and Packages section on the Github Product Feedback page.
- name: ✅ Support for GitHub Actions
url: https://github.community/c/code-to-cloud/52
about: If you have questions about GitHub Actions or need support writing workflows, please ask in the GitHub Community Support forum.

View File

@@ -1,32 +0,0 @@
---
name: 🛑 Request a feature in the runner application
about: If you have feature requests for GitHub Actions, please use the "feedback and suggestions for GitHub Actions" link below.
title: ''
labels: enhancement
assignees: ''
---
<!--
👋 You're opening a request for an enhancement in the GitHub Actions **runner application**.
🛑 Please stop if you're not certain that the feature you want is in the runner application - if you have a suggestion for improving GitHub Actions, please see the [GitHub Actions Feedback](https://github.com/github/feedback/discussions/categories/actions-and-packages-feedback) discussion forum which is actively monitored. Using the forum ensures that we route your problem to the correct team. 😃
Some additional useful links:
* If you have found a security issue [please submit it here](https://hackerone.com/github)
* If you have questions or issues with the service, writing workflows or actions, then please [visit the GitHub Community Forum's Actions Board](https://github.community/t5/GitHub-Actions/bd-p/actions)
* If you are having an issue or have a question about GitHub Actions then please [contact customer support](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-github-actions#contacting-support)
If you have a feature request that is relevant to this repository, the runner, then please include the information below:
-->
**Describe the enhancement**
A clear and concise description of what the features or enhancement you need.
**Code Snippet**
If applicable, add a code snippet.
**Additional information**
Add any other context about the feature here.
NOTE: if the feature request has been agreed upon then the assignee will create an ADR. See docs/adrs/README.md

View File

@@ -35,7 +35,7 @@ All the configs below can be found in `.vscode/launch.json`.
If you launch `Run` or `Run [build]`, it starts a process called `Runner.Listener`.
This process will receive any job queued on this repository if the job runs on matching labels (e.g `runs-on: self-hosted`).
Once a job is received, a `Runner.Listener` starts a new process of `Runner.Worker`.
Since this is a diferent process, you can't use the same debugger session debug it.
Since this is a different process, you can't use the same debugger session debug it.
Instead, a parallel debugging session has to be started, using a different launch config.
Luckily, VS Code supports multiple parallel debugging sessions.

View File

@@ -2,7 +2,7 @@ FROM mcr.microsoft.com/dotnet/runtime-deps:6.0 as build
ARG RUNNER_VERSION
ARG RUNNER_ARCH="x64"
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.1.3
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.2.0
RUN apt update -y && apt install curl unzip -y
@@ -19,6 +19,7 @@ FROM mcr.microsoft.com/dotnet/runtime-deps:6.0
ENV RUNNER_ALLOW_RUNASROOT=1
ENV RUNNER_MANUALLY_TRAP_SIG=1
ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1
WORKDIR /actions-runner
COPY --from=build /actions-runner .

View File

@@ -1,17 +1,23 @@
## Features
- Expose github.actor_id, github.workflow_ref & github.workflow_sha as environment variable (#2249)
- Added worker and listener logs to stdout (#2291, #2307)
- Log GitHub RequestId for better traceability (#2332)
- Dual upload summary to Actions and Result service (#2334)
- Allow providing extra User-Agent for better correlation (#2370)
- Show more information in the runner log (#2377)
- New option to remove local config files (#2367)
## Bugs
- Made github.action_status output lowercase to be consistent with job.status' output (#1944)
- Treat jitconfig as secret (#2335)
- Add Header/Footer to multi-line message in StdoutTraceListener (#2336)
- Update Node dependencies (#2381)
## Misc
- Added small size runner image for ARC (#2250)
- Small change to Node.js 12 deprecation message (#2262)
- Added the option to use the --replace argument to the create-latest-svc.sh (#2273)
- Made runner_name optional defaulting to hostname in delete.sh script (#1871)
- Return exit code when MANUALLY_TRAP_SIG is exported (#2285)
- Use results for uploading step summaries (#2301)
- Make runner image print diag log to STDOUT (#2331)
- Update Node.js to 16.16.0 (#2371)
- Add a disclaimer for which runner version is available to a given tenant (#2362)
_Note: Actions Runner follows a progressive release policy, so the latest release might not be available to your enterprise, organization, or repository yet.
To confirm which version of the Actions Runner you should expect, please view the download instructions for your enterprise, organization, or repository.
See https://docs.github.com/en/enterprise-cloud@latest/actions/hosting-your-own-runners/adding-self-hosted-runners_
## Windows x64
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.

View File

@@ -1 +1 @@
<Update to ./src/runnerversion when creating release>
2.301.1

View File

@@ -1 +1 @@
6ed30a2c1ee403a610d63e82bb230b9ba846a9c25cec9e4ea8672fb6ed4e1a51
3807dcbf947e840c33535fb466b096d76bf09e5c0254af8fc8cbbb24c6388222

View File

@@ -1 +1 @@
711c30c51ec52c9b7a9a2eb399d6ab2ab5ee1dc72de11879f2f36f919f163d78
ee01eee80cd8a460a4b9780ee13fdd20f25c59e754b4ccd99df55fbba2a85634

View File

@@ -1 +1 @@
a49479ca4b4988a06c097e8d22c51fd08a11c13f40807366236213d0e008cf6a
a9fb9c14e24e79aec97d4da197dd7bfc6364297d6fce573afb2df48cc9a931f8

View File

@@ -1 +1 @@
cc4708962a80325de0baa5ae8484e0cb9ae976ac6a4178c1c0d448b8c52bd7f7
a4e0e8fc62eba0967a39c7d693dcd0aeb8b2bed0765f9c38df80d42884f65341

View File

@@ -1 +1 @@
8e97df75230b843462a9b4c578ccec604ee4b4a1066120c85b04374317fa372b
17ac17fbe785b3d6fa2868d8d17185ebfe0c90b4b0ddf6b67eac70e42bcd989b

View File

@@ -1 +1 @@
e5dace2d41cc0682d096dcce4970079ad48ec7107e46195970eecfdb3df2acef
89f24657a550f1e818b0e9975e5b80edcf4dd22b7d4bccbb9e48e37f45d30fb1

View File

@@ -1 +1 @@
f75a671e5a188c76680739689aa75331a2c09d483dce9c80023518c48fd67a18
24fd131b5dce33ef16038b771407bc0507da8682a72fb3b7780607235f76db0b

View File

@@ -14,7 +14,7 @@
"devDependencies": {
"@types/node": "^12.7.12",
"@typescript-eslint/parser": "^5.15.0",
"@zeit/ncc": "^0.20.5",
"@vercel/ncc": "^0.36.0",
"eslint": "^8.11.0",
"eslint-plugin-github": "^4.3.5",
"prettier": "^1.19.1",
@@ -346,11 +346,10 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@zeit/ncc": {
"version": "0.20.5",
"resolved": "https://registry.npmjs.org/@zeit/ncc/-/ncc-0.20.5.tgz",
"integrity": "sha512-XU6uzwvv95DqxciQx+aOLhbyBx/13ky+RK1y88Age9Du3BlA4mMPCy13BGjayOrrumOzlq1XV3SD/BWiZENXlw==",
"deprecated": "@zeit/ncc is no longer maintained. Please use @vercel/ncc instead.",
"node_modules/@vercel/ncc": {
"version": "0.36.0",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.0.tgz",
"integrity": "sha512-/ZTUJ/ZkRt694k7KJNimgmHjtQcRuVwsST2Z6XfYveQIuBbHR+EqkTc1jfgPkQmMyk/vtpxo3nVxe8CNuau86A==",
"dev": true,
"bin": {
"ncc": "dist/ncc/cli.js"
@@ -1722,9 +1721,9 @@
"dev": true
},
"node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@@ -1824,9 +1823,9 @@
}
},
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -2747,10 +2746,10 @@
"eslint-visitor-keys": "^3.0.0"
}
},
"@zeit/ncc": {
"version": "0.20.5",
"resolved": "https://registry.npmjs.org/@zeit/ncc/-/ncc-0.20.5.tgz",
"integrity": "sha512-XU6uzwvv95DqxciQx+aOLhbyBx/13ky+RK1y88Age9Du3BlA4mMPCy13BGjayOrrumOzlq1XV3SD/BWiZENXlw==",
"@vercel/ncc": {
"version": "0.36.0",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.0.tgz",
"integrity": "sha512-/ZTUJ/ZkRt694k7KJNimgmHjtQcRuVwsST2Z6XfYveQIuBbHR+EqkTc1jfgPkQmMyk/vtpxo3nVxe8CNuau86A==",
"dev": true
},
"acorn": {
@@ -3756,9 +3755,9 @@
"dev": true
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
@@ -3840,9 +3839,9 @@
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"requires": {
"brace-expansion": "^1.1.7"
}

View File

@@ -26,7 +26,7 @@
"devDependencies": {
"@types/node": "^12.7.12",
"@typescript-eslint/parser": "^5.15.0",
"@zeit/ncc": "^0.20.5",
"@vercel/ncc": "^0.36.0",
"eslint": "^8.11.0",
"eslint-plugin-github": "^4.3.5",
"prettier": "^1.19.1",

View File

@@ -5,7 +5,7 @@ PRECACHE=$2
NODE_URL=https://nodejs.org/dist
UNOFFICIAL_NODE_URL=https://unofficial-builds.nodejs.org/download/release
NODE12_VERSION="12.22.7"
NODE16_VERSION="16.13.0"
NODE16_VERSION="16.16.0"
get_abs_path() {
# exploits the fact that pwd will print abs path when no args

File diff suppressed because it is too large Load Diff

View File

@@ -90,7 +90,6 @@ namespace GitHub.Runner.Common
public static class Args
{
public static readonly string Auth = "auth";
public static readonly string JitConfig = "jitconfig";
public static readonly string Labels = "labels";
public static readonly string MonitorSocketAddress = "monitorsocketaddress";
public static readonly string Name = "name";
@@ -105,11 +104,13 @@ namespace GitHub.Runner.Common
public static readonly string Token = "token";
public static readonly string PAT = "pat";
public static readonly string WindowsLogonPassword = "windowslogonpassword";
public static readonly string JitConfig = "jitconfig";
public static string[] Secrets => new[]
{
PAT,
Token,
WindowsLogonPassword,
JitConfig,
};
}
@@ -130,6 +131,7 @@ namespace GitHub.Runner.Common
public static readonly string Ephemeral = "ephemeral";
public static readonly string GenerateServiceConfig = "generateServiceConfig";
public static readonly string Help = "help";
public static readonly string Local = "local";
public static readonly string Replace = "replace";
public static readonly string DisableUpdate = "disableupdate";
public static readonly string Once = "once"; // Keep this around since customers still relies on it
@@ -157,9 +159,11 @@ namespace GitHub.Runner.Common
}
public static readonly string InternalTelemetryIssueDataKey = "_internal_telemetry";
public static readonly Guid TelemetryRecordId = new Guid("11111111-1111-1111-1111-111111111111");
public static readonly string WorkerCrash = "WORKER_CRASH";
public static readonly string LowDiskSpace = "LOW_DISK_SPACE";
public static readonly string UnsupportedCommand = "UNSUPPORTED_COMMAND";
public static readonly string ResultsUploadFailure = "RESULTS_UPLOAD_FAILURE";
public static readonly string UnsupportedCommandMessage = "The `{0}` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/";
public static readonly string UnsupportedCommandMessageDisabled = "The `{0}` command is disabled. Please upgrade to using Environment Files or opt into unsecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_COMMANDS` environment variable to `true`. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/";
public static readonly string UnsupportedStopCommandTokenDisabled = "You cannot use a endToken that is an empty string, the string 'pause-logging', or another workflow command. For more information see: https://docs.github.com/actions/learn-github-actions/workflow-commands-for-github-actions#example-stopping-and-starting-workflow-commands or opt into insecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_STOPCOMMAND_TOKENS` environment variable to `true`.";

View File

@@ -226,6 +226,20 @@ namespace GitHub.Runner.Common
}
_userAgents.Add(new ProductInfoHeaderValue("CommitSHA", BuildConstants.Source.CommitHash));
var extraUserAgent = Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT");
if (!string.IsNullOrEmpty(extraUserAgent))
{
var extraUserAgentSplit = extraUserAgent.Split('/', StringSplitOptions.RemoveEmptyEntries);
if (extraUserAgentSplit.Length != 2)
{
_trace.Error($"GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT is not in the format of 'name/version'.");
}
var extraUserAgentHeader = new ProductInfoHeaderValue(extraUserAgentSplit[0], extraUserAgentSplit[1]);
_trace.Info($"Adding extra user agent '{extraUserAgentHeader}' to all HTTP requests.");
_userAgents.Add(extraUserAgentHeader);
}
}
public string GetDirectory(WellKnownDirectory directory)

View File

@@ -20,7 +20,7 @@ namespace GitHub.Runner.Common
void Start(Pipelines.AgentJobRequestMessage jobRequest);
void QueueWebConsoleLine(Guid stepRecordId, string line, long? lineNumber = null);
void QueueFileUpload(Guid timelineId, Guid timelineRecordId, string type, string name, string path, bool deleteSource);
void QueueSummaryUpload(Guid timelineId, Guid timelineRecordId, string stepId, string name, string path, bool deleteSource);
void QueueSummaryUpload(Guid stepRecordId, string name, string path, bool deleteSource);
void QueueTimelineRecordUpdate(Guid timelineId, TimelineRecord timelineRecord);
}
@@ -230,25 +230,20 @@ namespace GitHub.Runner.Common
_fileUploadQueue.Enqueue(newFile);
}
public void QueueSummaryUpload(Guid timelineId, Guid timelineRecordId, string stepId, string name, string path, bool deleteSource)
public void QueueSummaryUpload(Guid stepRecordId, string name, string path, bool deleteSource)
{
ArgUtil.NotEmpty(timelineId, nameof(timelineId));
ArgUtil.NotEmpty(timelineRecordId, nameof(timelineRecordId));
// all parameter not null, file path exist.
var newFile = new SummaryUploadFileInfo()
{
TimelineId = timelineId,
TimelineRecordId = timelineRecordId,
Name = name,
Path = path,
PlanId = _planId.ToString(),
JobId = _jobTimelineRecordId.ToString(),
StepId = stepId,
StepId = stepRecordId.ToString(),
DeleteSource = deleteSource
};
Trace.Verbose("Enqueue results file upload queue: file '{0}' attach to record {1}", newFile.Path, timelineRecordId);
Trace.Verbose("Enqueue results file upload queue: file '{0}' attach to job {1} step {2}", newFile.Path, _jobTimelineRecordId, stepRecordId);
_summaryFileUploadQueue.Enqueue(newFile);
}
@@ -476,8 +471,21 @@ namespace GitHub.Runner.Common
}
catch (Exception ex)
{
var issue = new Issue() { Type = IssueType.Warning, Message = $"Caught exception during summary file upload to results. {ex.Message}" };
issue.Data[Constants.Runner.InternalTelemetryIssueDataKey] = Constants.Runner.ResultsUploadFailure;
var telemetryRecord = new TimelineRecord()
{
Id = Constants.Runner.TelemetryRecordId,
};
telemetryRecord.Issues.Add(issue);
QueueTimelineRecordUpdate(_jobTimelineId, telemetryRecord);
Trace.Info("Catch exception during summary file upload to results, keep going since the process is best effort.");
Trace.Error(ex);
}
finally
{
errorCount++;
}
}
@@ -816,8 +824,6 @@ namespace GitHub.Runner.Common
internal class SummaryUploadFileInfo
{
public Guid TimelineId { get; set; }
public Guid TimelineRecordId { get; set; }
public string Name { get; set; }
public string Path { get; set; }
public string PlanId { get; set; }

View File

@@ -1,8 +1,8 @@
using GitHub.Runner.Sdk;
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using GitHub.Runner.Sdk;
namespace GitHub.Runner.Common
{
@@ -24,9 +24,16 @@ namespace GitHub.Runner.Common
return;
}
WriteHeader(source, eventType, id);
WriteLine(message);
WriteFooter(eventCache);
if (!string.IsNullOrEmpty(message))
{
var messageLines = message.Split(Environment.NewLine);
foreach (var messageLine in messageLines)
{
WriteHeader(source, eventType, id);
WriteLine(messageLine);
WriteFooter(eventCache);
}
}
}
internal bool IsEnabled(TraceOptions opts)
@@ -86,5 +93,4 @@ namespace GitHub.Runner.Common
IndentLevel--;
}
}
}
}

View File

@@ -56,7 +56,8 @@ namespace GitHub.Runner.Listener
new string[]
{
Constants.Runner.CommandLine.Args.Token,
Constants.Runner.CommandLine.Args.PAT
Constants.Runner.CommandLine.Args.PAT,
Constants.Runner.CommandLine.Flags.Local
},
// Valid run flags and args
[Constants.Runner.CommandLine.Commands.Run] =
@@ -86,6 +87,7 @@ namespace GitHub.Runner.Listener
public bool Help => TestFlag(Constants.Runner.CommandLine.Flags.Help);
public bool Unattended => TestFlag(Constants.Runner.CommandLine.Flags.Unattended);
public bool Version => TestFlag(Constants.Runner.CommandLine.Flags.Version);
public bool RemoveLocalConfig => TestFlag(Constants.Runner.CommandLine.Flags.Local);
// Keep this around since customers still relies on it
public bool RunOnce => TestFlag(Constants.Runner.CommandLine.Flags.Once);

View File

@@ -1,10 +1,3 @@
using GitHub.DistributedTask.WebApi;
using GitHub.Runner.Common;
using GitHub.Runner.Common.Util;
using GitHub.Runner.Sdk;
using GitHub.Services.Common;
using GitHub.Services.Common.Internal;
using GitHub.Services.OAuth;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -14,6 +7,13 @@ using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using GitHub.DistributedTask.WebApi;
using GitHub.Runner.Common;
using GitHub.Runner.Common.Util;
using GitHub.Runner.Sdk;
using GitHub.Services.Common;
using GitHub.Services.Common.Internal;
using GitHub.Services.OAuth;
namespace GitHub.Runner.Listener.Configuration
{
@@ -636,7 +636,7 @@ namespace GitHub.Runner.Listener.Configuration
}
int retryCount = 0;
while(retryCount < 3)
while (retryCount < 3)
{
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
using (var httpClient = new HttpClient(httpClientHandler))
@@ -646,28 +646,29 @@ namespace GitHub.Runner.Listener.Configuration
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("basic", base64EncodingToken);
httpClient.DefaultRequestHeaders.UserAgent.AddRange(HostContext.UserAgents);
httpClient.DefaultRequestHeaders.Accept.ParseAdd("application/vnd.github.v3+json");
var responseStatus = System.Net.HttpStatusCode.OK;
try
{
var response = await httpClient.PostAsync(githubApiUrl, new StringContent(string.Empty));
responseStatus = response.StatusCode;
var githubRequestId = GetGitHubRequestId(response.Headers);
if (response.IsSuccessStatusCode)
{
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' ({githubRequestId})");
var jsonResponse = await response.Content.ReadAsStringAsync();
return StringUtil.ConvertFromJson<GitHubRunnerRegisterToken>(jsonResponse);
}
else
{
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' (Request Id: {githubRequestId})");
var errorResponse = await response.Content.ReadAsStringAsync();
_term.WriteError(errorResponse);
response.EnsureSuccessStatusCode();
}
}
catch(Exception ex) when (retryCount < 2 && responseStatus != System.Net.HttpStatusCode.NotFound)
catch (Exception ex) when (retryCount < 2 && responseStatus != System.Net.HttpStatusCode.NotFound)
{
retryCount++;
Trace.Error($"Failed to get JIT runner token -- Atempt: {retryCount}");
@@ -714,22 +715,23 @@ namespace GitHub.Runner.Listener.Configuration
{
var response = await httpClient.PostAsync(githubApiUrl, new StringContent(StringUtil.ConvertToJson(bodyObject), null, "application/json"));
responseStatus = response.StatusCode;
var githubRequestId = GetGitHubRequestId(response.Headers);
if(response.IsSuccessStatusCode)
if (response.IsSuccessStatusCode)
{
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' ({githubRequestId})");
var jsonResponse = await response.Content.ReadAsStringAsync();
return StringUtil.ConvertFromJson<GitHubAuthResult>(jsonResponse);
}
else
{
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' (Request Id: {githubRequestId})");
var errorResponse = await response.Content.ReadAsStringAsync();
_term.WriteError(errorResponse);
response.EnsureSuccessStatusCode();
}
}
catch(Exception ex) when (retryCount < 2 && responseStatus != System.Net.HttpStatusCode.NotFound)
catch (Exception ex) when (retryCount < 2 && responseStatus != System.Net.HttpStatusCode.NotFound)
{
retryCount++;
Trace.Error($"Failed to get tenant credentials -- Atempt: {retryCount}");
@@ -742,5 +744,14 @@ namespace GitHub.Runner.Listener.Configuration
}
return null;
}
private string GetGitHubRequestId(HttpResponseHeaders headers)
{
if (headers.TryGetValues("x-github-request-id", out var headerValues))
{
return headerValues.FirstOrDefault();
}
return string.Empty;
}
}
}

View File

@@ -135,6 +135,12 @@ namespace GitHub.Runner.Listener
// remove config files, remove service, and exit
if (command.Remove)
{
// only remove local config files and exit
if(command.RemoveLocalConfig)
{
configManager.DeleteLocalRunnerConfig();
return Constants.Runner.ReturnCode.Success;
}
try
{
await configManager.UnconfigureAsync(command);
@@ -647,6 +653,7 @@ Config Options:
--name string Name of the runner to configure (default {Environment.MachineName ?? "myrunner"})
--runnergroup string Name of the runner group to add this runner to (defaults to the default runner group)
--labels string Extra labels in addition to the default: 'self-hosted,{Constants.Runner.Platform},{Constants.Runner.PlatformArchitecture}'
--local Removes the runner config files from your local machine. Used as an option to the remove command
--work string Relative runner work directory (default {Constants.Path.WorkDirectory})
--replace Replace any existing runner with the same name (default false)
--pat GitHub personal access token with repo scope. Used for checking network connectivity when executing `.{separator}run.{ext} --check`

View File

@@ -264,7 +264,17 @@ namespace GitHub.Runner.Sdk
{
foreach (KeyValuePair<string, string> kvp in environment)
{
#if OS_WINDOWS
string tempKey = String.IsNullOrWhiteSpace(kvp.Key) ? kvp.Key : kvp.Key.Split('\0')[0];
string tempValue = String.IsNullOrWhiteSpace(kvp.Value) ? kvp.Value : kvp.Value.Split('\0')[0];
if(!String.IsNullOrWhiteSpace(tempKey))
{
_proc.StartInfo.Environment[tempKey] = tempValue;
}
#else
_proc.StartInfo.Environment[kvp.Key] = kvp.Value;
#endif
}
}

View File

@@ -33,8 +33,14 @@ namespace GitHub.Runner.Worker
public override void Initialize(IHostContext hostContext)
{
base.Initialize(hostContext);
_dockerManager = HostContext.GetService<IDockerCommandManager>();
_containerHookManager = HostContext.GetService<IContainerHookManager>();
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable(Constants.Hooks.ContainerHooksPath)))
{
_dockerManager = HostContext.GetService<IDockerCommandManager>();
}
else
{
_containerHookManager = HostContext.GetService<IContainerHookManager>();
}
}
public async Task StartContainersAsync(IExecutionContext executionContext, object data)

View File

@@ -80,7 +80,7 @@ namespace GitHub.Runner.Worker
// logging
long Write(string tag, string message);
void QueueAttachFile(string type, string name, string filePath);
void QueueSummaryFile(string name, string filePath, string stepId);
void QueueSummaryFile(string name, string filePath, Guid stepRecordId);
// timeline record update methods
void Start(string currentOperation = null);
@@ -847,7 +847,7 @@ namespace GitHub.Runner.Worker
_jobServerQueue.QueueFileUpload(_mainTimelineId, _record.Id, type, name, filePath, deleteSource: false);
}
public void QueueSummaryFile(string name, string filePath, string stepId)
public void QueueSummaryFile(string name, string filePath, Guid stepRecordId)
{
ArgUtil.NotNullOrEmpty(name, nameof(name));
ArgUtil.NotNullOrEmpty(filePath, nameof(filePath));
@@ -857,7 +857,7 @@ namespace GitHub.Runner.Worker
throw new FileNotFoundException($"Can't upload (name:{name}) file: {filePath}. File does not exist.");
}
_jobServerQueue.QueueSummaryUpload(_mainTimelineId, _record.Id, stepId, name, filePath, deleteSource: false);
_jobServerQueue.QueueSummaryUpload(stepRecordId, name, filePath, deleteSource: false);
}
// Add OnMatcherChanged

View File

@@ -182,6 +182,14 @@ namespace GitHub.Runner.Worker
return;
}
if (fileSize > AttachmentSizeLimit)
{
context.Error(String.Format(Constants.Runner.UnsupportedSummarySize, AttachmentSizeLimit / 1024, fileSize / 1024));
Trace.Info($"Step Summary file ({filePath}) is too large ({fileSize} bytes); skipping attachment upload");
return;
}
Trace.Verbose($"Step Summary file exists: {filePath} and has a file size of {fileSize} bytes");
var scrubbedFilePath = filePath + "-scrubbed";
@@ -200,28 +208,19 @@ namespace GitHub.Runner.Worker
? context.Id.ToString()
: context.EmbeddedId.ToString();
Trace.Info($"Queueing file ({filePath}) for attachment upload ({attachmentName})");
// Attachments must be added to the parent context (job), not the current context (step)
context.Root.QueueAttachFile(ChecksAttachmentType.StepSummary, attachmentName, scrubbedFilePath);
// Dual upload the same files to Results Service
context.Global.Variables.TryGetValue("system.github.results_endpoint", out string resultsReceiverEndpoint);
if (resultsReceiverEndpoint != null)
{
Trace.Info($"Queueing results file ({filePath}) for attachment upload ({attachmentName})");
var stepId = context.Id.ToString();
var stepId = context.Id;
// Attachments must be added to the parent context (job), not the current context (step)
context.Root.QueueSummaryFile(attachmentName, scrubbedFilePath, stepId);
}
else
{
if (fileSize > AttachmentSizeLimit)
{
context.Error(String.Format(Constants.Runner.UnsupportedSummarySize, AttachmentSizeLimit / 1024, fileSize / 1024));
Trace.Info($"Step Summary file ({filePath}) is too large ({fileSize} bytes); skipping attachment upload");
return;
}
Trace.Info($"Queueing file ({filePath}) for attachment upload ({attachmentName})");
// Attachments must be added to the parent context (job), not the current context (step)
context.Root.QueueAttachFile(ChecksAttachmentType.StepSummary, attachmentName, scrubbedFilePath);
}
}
catch (Exception e)
{

View File

@@ -38,8 +38,17 @@ namespace GitHub.Runner.Worker.Handlers
// Update the env dictionary.
AddInputsToEnvironment();
var dockerManager = HostContext.GetService<IDockerCommandManager>();
var containerHookManager = HostContext.GetService<IContainerHookManager>();
IDockerCommandManager dockerManager = null;
IContainerHookManager containerHookManager = null;
if (FeatureManager.IsContainerHooksEnabled(ExecutionContext.Global.Variables))
{
containerHookManager = HostContext.GetService<IContainerHookManager>();
}
else
{
dockerManager = HostContext.GetService<IDockerCommandManager>();
}
string dockerFile = null;
// container image haven't built/pull

View File

@@ -321,7 +321,10 @@ namespace GitHub.Runner.Worker
if (message.Variables.TryGetValue("system.workflowFileFullPath", out VariableValue workflowFileFullPath))
{
context.Output($"Uses: {workflowFileFullPath.Value}");
var usesLogText = $"Uses: {workflowFileFullPath.Value}";
var reference = GetWorkflowReference(message.Variables);
context.Output(usesLogText + reference);
if (message.ContextData.TryGetValue("inputs", out var pipelineContextData))
{
var inputs = pipelineContextData.AssertDictionary("inputs");
@@ -335,11 +338,11 @@ namespace GitHub.Runner.Worker
context.Output("##[endgroup]");
}
}
}
if (!string.IsNullOrWhiteSpace(message.JobDisplayName))
{
context.Output($"Complete job name: {message.JobDisplayName}");
}
if (!string.IsNullOrWhiteSpace(message.JobDisplayName))
{
context.Output($"Complete job name: {message.JobDisplayName}");
}
var intraActionStates = new Dictionary<Guid, Dictionary<string, string>>();
@@ -452,6 +455,24 @@ namespace GitHub.Runner.Worker
}
}
private string GetWorkflowReference(IDictionary<string, VariableValue> variables)
{
var reference = "";
if (variables.TryGetValue("system.workflowFileSha", out VariableValue workflowFileSha))
{
if (variables.TryGetValue("system.workflowFileRef", out VariableValue workflowFileRef)
&& !string.IsNullOrEmpty(workflowFileRef.Value))
{
reference += $"@{workflowFileRef.Value} ({workflowFileSha.Value})";
}
else
{
reference += $"@{workflowFileSha.Value}";
}
}
return reference;
}
public void FinalizeJob(IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, DateTime jobStartTimeUtc)
{
Trace.Entering();

View File

@@ -113,6 +113,10 @@ namespace GitHub.Services.Results.Client
{
// Get the upload url
var uploadUrlResponse = await GetStepSummaryUploadUrlAsync(planId, jobId, stepId, cancellationToken);
if (uploadUrlResponse == null)
{
throw new Exception("Failed to get step summary upload url");
}
// Do we want to throw an exception here or should we just be uploading/truncating the data
var fileSize = new FileInfo(file).Length;

View File

@@ -824,6 +824,7 @@ namespace GitHub.Runner.Common.Tests
[InlineData("remove", "version")]
[InlineData("remove", "commit")]
[InlineData("remove", "check")]
[InlineData("remove", "local")]
[InlineData("run", "help")]
[InlineData("run", "version")]
[InlineData("run", "commit")]

View File

@@ -502,5 +502,34 @@ namespace GitHub.Runner.Common.Tests.Listener
_messageListener.Verify(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()), Times.Once());
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Runner")]
public async void TestRemoveLocalRunnerConfig()
{
using (var hc = new TestHostContext(this))
{
hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
hc.SetSingleton<IConfigurationStore>(_configStore.Object);
hc.SetSingleton<IPromptManager>(_promptManager.Object);
var command = new CommandSettings(hc, new[] { "remove", "--local" });
_configStore.Setup(x => x.IsConfigured())
.Returns(true);
_configStore.Setup(x => x.HasCredentials())
.Returns(true);
var runner = new Runner.Listener.Runner();
runner.Initialize(hc);
await runner.ExecuteCommand(command);
// verify that we delete the local runner config with the correct remove parameter
_configurationManager.Verify(x => x.DeleteLocalRunnerConfig(), Times.Once());
}
}
}
}

View File

@@ -128,7 +128,76 @@ namespace GitHub.Runner.Common.Tests
}
}
}
#if OS_WINDOWS
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Common")]
public async Task SetTestEnvWithNullInKey()
{
using (TestHostContext hc = new(this))
{
Tracing trace = hc.GetTrace();
Int32 exitCode = -1;
var processInvoker = new ProcessInvokerWrapper();
processInvoker.Initialize(hc);
var stdout = new List<string>();
var stderr = new List<string>();
processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) =>
{
trace.Info(e.Data);
stdout.Add(e.Data);
};
processInvoker.ErrorDataReceived += (object sender, ProcessDataReceivedEventArgs e) =>
{
trace.Info(e.Data);
stderr.Add(e.Data);
};
exitCode = await processInvoker.ExecuteAsync("", "cmd.exe", "/c \"echo %TEST%\"", new Dictionary<string, string>() { { "TEST\0second", "first" } }, CancellationToken.None);
trace.Info("Exit Code: {0}", exitCode);
Assert.Equal(0, exitCode);
Assert.Equal("first", stdout.First(x => !string.IsNullOrWhiteSpace(x)));
}
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Common")]
public async Task SetTestEnvWithNullInValue()
{
using (TestHostContext hc = new(this))
{
Tracing trace = hc.GetTrace();
Int32 exitCode = -1;
var processInvoker = new ProcessInvokerWrapper();
processInvoker.Initialize(hc);
var stdout = new List<string>();
var stderr = new List<string>();
processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) =>
{
trace.Info(e.Data);
stdout.Add(e.Data);
};
processInvoker.ErrorDataReceived += (object sender, ProcessDataReceivedEventArgs e) =>
{
trace.Info(e.Data);
stderr.Add(e.Data);
};
exitCode = await processInvoker.ExecuteAsync("", "cmd.exe", "/c \"echo %TEST%\"", new Dictionary<string, string>() { { "TEST", "first\0second" } }, CancellationToken.None);
trace.Info("Exit Code: {0}", exitCode);
Assert.Equal(0, exitCode);
Assert.Equal("first", stdout.First(x => !string.IsNullOrWhiteSpace(x)));
}
}
#endif
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Common")]

View File

@@ -99,6 +99,46 @@ namespace GitHub.Runner.Common.Tests.Worker
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void InitializeWithCorrectManager()
{
containers.Add(new ContainerInfo() { ContainerImage = "ubuntu:16.04" });
_hc = new TestHostContext(this, "Test");
_ec = new Mock<IExecutionContext>();
serverQueue = new Mock<IJobServerQueue>();
pagingLogger = new Mock<IPagingLogger>();
containerOperationProvider = new ContainerOperationProvider();
_hc.SetSingleton<IJobServerQueue>(serverQueue.Object);
_hc.SetSingleton<IPagingLogger>(pagingLogger.Object);
_ec.Setup(x => x.Global).Returns(new GlobalContext());
Environment.SetEnvironmentVariable(Constants.Hooks.ContainerHooksPath, "/tmp/k8s/index.js");
_dockerManager = new Mock<IDockerCommandManager>();
_dockerManager.Setup(x => x.Initialize(_hc)).Throws(new Exception("Docker manager's Initialize should not be called"));
_containerHookManager = new Mock<IContainerHookManager>();
_hc.SetSingleton<IDockerCommandManager>(_dockerManager.Object);
_hc.SetSingleton<IContainerHookManager>(_containerHookManager.Object);
containerOperationProvider.Initialize(_hc);
Environment.SetEnvironmentVariable(Constants.Hooks.ContainerHooksPath, null);
_containerHookManager = new Mock<IContainerHookManager>();
_containerHookManager.Setup(x => x.Initialize(_hc)).Throws(new Exception("Container hook manager's Initialize should not be called"));
_dockerManager = new Mock<IDockerCommandManager>();
_hc.SetSingleton<IDockerCommandManager>(_dockerManager.Object);
_hc.SetSingleton<IContainerHookManager>(_containerHookManager.Object);
containerOperationProvider.Initialize(_hc);
}
private void Setup([CallerMemberName] string testName = "")
{
containers.Add(new ContainerInfo() { ContainerImage = "ubuntu:16.04" });
@@ -111,7 +151,6 @@ namespace GitHub.Runner.Common.Tests.Worker
_containerHookManager = new Mock<IContainerHookManager>();
containerOperationProvider = new ContainerOperationProvider();
_hc.SetSingleton<IDockerCommandManager>(_dockerManager.Object);
_hc.SetSingleton<IJobServerQueue>(serverQueue.Object);
_hc.SetSingleton<IPagingLogger>(pagingLogger.Object);

View File

@@ -1 +1 @@
2.300.0
2.301.1