mirror of
https://github.com/actions/runner.git
synced 2025-12-10 12:36:23 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edb3681ccc | ||
|
|
10aafef52f | ||
|
|
2b89a7ffea | ||
|
|
ffae5b7a54 | ||
|
|
b3e56206cf |
@@ -5,10 +5,7 @@
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:1": {},
|
||||
"ghcr.io/devcontainers/features/dotnet": {
|
||||
"version": "6.0.405"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "16"
|
||||
"version": "6.0.300"
|
||||
}
|
||||
},
|
||||
"customizations": {
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/config.yml
vendored
3
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,5 @@
|
||||
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.
|
||||
|
||||
32
.github/ISSUE_TEMPLATE/enhancement_request.md
vendored
Normal file
32
.github/ISSUE_TEMPLATE/enhancement_request.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
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
|
||||
@@ -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 different process, you can't use the same debugger session debug it.
|
||||
Since this is a diferent 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.
|
||||
|
||||
|
||||
@@ -2,8 +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.2.0
|
||||
ARG DOCKER_VERSION=20.10.23
|
||||
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.1.3
|
||||
|
||||
RUN apt update -y && apt install curl unzip -y
|
||||
|
||||
@@ -16,19 +15,10 @@ RUN curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-c
|
||||
&& unzip ./runner-container-hooks.zip -d ./k8s \
|
||||
&& rm runner-container-hooks.zip
|
||||
|
||||
RUN export DOCKER_ARCH=x86_64 \
|
||||
&& if [ "$RUNNER_ARCH" = "arm64" ]; then export DOCKER_ARCH=aarch64 ; fi \
|
||||
&& curl -fLo docker.tgz https://download.docker.com/linux/static/stable/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz \
|
||||
&& tar zxvf docker.tgz \
|
||||
&& rm -rf docker.tgz
|
||||
|
||||
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 .
|
||||
|
||||
RUN install -o root -g root -m 755 docker/* /usr/bin/ && rm -rf docker
|
||||
@@ -1,19 +1,17 @@
|
||||
## Features
|
||||
- Add support for ghe.com domain (#2420)
|
||||
- Add docker cli to the runner image. (#2425)
|
||||
- Expose github.actor_id, github.workflow_ref & github.workflow_sha as environment variable (#2249)
|
||||
- Added worker and listener logs to stdout (#2291, #2307)
|
||||
|
||||
## Bugs
|
||||
- Fix URL construction bug for RunService (#2396)
|
||||
- Defer evaluation of a step's DisplayName until its condition is evaluated. (#2313)
|
||||
- Replace '(' and ')' with '[' and '] from OS.Description for fixing User-Agent header validation (#2288)
|
||||
- Made github.action_status output lowercase to be consistent with job.status' output (#1944)
|
||||
|
||||
## Misc
|
||||
- Bump dotnet sdk to latest version. (#2392)
|
||||
- Start calling run service for job completion (#2412, #2423)
|
||||
|
||||
_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_
|
||||
- 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) with limited size (#2321)
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.302.1
|
||||
2.300.1
|
||||
|
||||
@@ -1 +1 @@
|
||||
39f2a931565d6a10e695ac8ed14bb9dcbb568151410349b32dbf9c27bae29602
|
||||
1d709d93e5d3c6c6c656a61aa6c1781050224788a05b0e6ecc4c3c0408bdf89c
|
||||
@@ -1 +1 @@
|
||||
29ffb303537d8ba674fbebc7729292c21c4ebd17b3198f91ed593ef4cbbb67b5
|
||||
b92a47cfeaad02255b1f7a377060651b73ae5e5db22a188dbbcb4183ab03a03d
|
||||
@@ -1 +1 @@
|
||||
de6868a836fa3cb9e5ddddbc079da1c25e819aa2d2fc193cc9931c353687c57c
|
||||
68a9a8ef0843a8bb74241894f6f63fd76241a82295c5337d3cc7a940a314c78e
|
||||
@@ -1 +1 @@
|
||||
339d3e1a5fd28450c0fe6cb820cc7aae291f0f9e2d153ac34e1f7b080e35d30e
|
||||
02c7126ff4d63ee2a0ae390c81434c125630522aadf35903bbeebb1a99d8af99
|
||||
@@ -1 +1 @@
|
||||
dcb7f606c1d7d290381e5020ee73e7f16dcbd2f20ac9b431362ccbb5120d449c
|
||||
c9d5a542f8d765168855a89e83ae0a8970d00869041c4f9a766651c04c72b212
|
||||
@@ -1 +1 @@
|
||||
1bbcb0e9a2cf4be4b1fce77458de139b70ac58efcbb415a6db028b9373ae1673
|
||||
39d0683f0f115a211cb10c473e9574c16549a19d4e9a6c637ded3d7022bf809f
|
||||
|
||||
@@ -1 +1 @@
|
||||
44cd25f3c104d0abb44d262397a80e0b2c4f206465c5d899a22eec043dac0fb3
|
||||
d94f2fbaf210297162bc9f3add819d73682c3aa6899e321c3872412b924d5504
|
||||
2
src/Misc/contentHash/externals/linux-arm
vendored
2
src/Misc/contentHash/externals/linux-arm
vendored
@@ -1 +1 @@
|
||||
3807dcbf947e840c33535fb466b096d76bf09e5c0254af8fc8cbbb24c6388222
|
||||
6ed30a2c1ee403a610d63e82bb230b9ba846a9c25cec9e4ea8672fb6ed4e1a51
|
||||
2
src/Misc/contentHash/externals/linux-arm64
vendored
2
src/Misc/contentHash/externals/linux-arm64
vendored
@@ -1 +1 @@
|
||||
ee01eee80cd8a460a4b9780ee13fdd20f25c59e754b4ccd99df55fbba2a85634
|
||||
711c30c51ec52c9b7a9a2eb399d6ab2ab5ee1dc72de11879f2f36f919f163d78
|
||||
2
src/Misc/contentHash/externals/linux-x64
vendored
2
src/Misc/contentHash/externals/linux-x64
vendored
@@ -1 +1 @@
|
||||
a9fb9c14e24e79aec97d4da197dd7bfc6364297d6fce573afb2df48cc9a931f8
|
||||
a49479ca4b4988a06c097e8d22c51fd08a11c13f40807366236213d0e008cf6a
|
||||
2
src/Misc/contentHash/externals/osx-arm64
vendored
2
src/Misc/contentHash/externals/osx-arm64
vendored
@@ -1 +1 @@
|
||||
a4e0e8fc62eba0967a39c7d693dcd0aeb8b2bed0765f9c38df80d42884f65341
|
||||
cc4708962a80325de0baa5ae8484e0cb9ae976ac6a4178c1c0d448b8c52bd7f7
|
||||
2
src/Misc/contentHash/externals/osx-x64
vendored
2
src/Misc/contentHash/externals/osx-x64
vendored
@@ -1 +1 @@
|
||||
17ac17fbe785b3d6fa2868d8d17185ebfe0c90b4b0ddf6b67eac70e42bcd989b
|
||||
8e97df75230b843462a9b4c578ccec604ee4b4a1066120c85b04374317fa372b
|
||||
2
src/Misc/contentHash/externals/win-arm64
vendored
2
src/Misc/contentHash/externals/win-arm64
vendored
@@ -1 +1 @@
|
||||
89f24657a550f1e818b0e9975e5b80edcf4dd22b7d4bccbb9e48e37f45d30fb1
|
||||
e5dace2d41cc0682d096dcce4970079ad48ec7107e46195970eecfdb3df2acef
|
||||
|
||||
2
src/Misc/contentHash/externals/win-x64
vendored
2
src/Misc/contentHash/externals/win-x64
vendored
@@ -1 +1 @@
|
||||
24fd131b5dce33ef16038b771407bc0507da8682a72fb3b7780607235f76db0b
|
||||
f75a671e5a188c76680739689aa75331a2c09d483dce9c80023518c48fd67a18
|
||||
43
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
43
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
@@ -14,7 +14,7 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.7.12",
|
||||
"@typescript-eslint/parser": "^5.15.0",
|
||||
"@vercel/ncc": "^0.36.0",
|
||||
"@zeit/ncc": "^0.20.5",
|
||||
"eslint": "^8.11.0",
|
||||
"eslint-plugin-github": "^4.3.5",
|
||||
"prettier": "^1.19.1",
|
||||
@@ -346,10 +346,11 @@
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"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.",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"ncc": "dist/ncc/cli.js"
|
||||
@@ -1721,9 +1722,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -1823,9 +1824,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
@@ -2746,10 +2747,10 @@
|
||||
"eslint-visitor-keys": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"@vercel/ncc": {
|
||||
"version": "0.36.0",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.0.tgz",
|
||||
"integrity": "sha512-/ZTUJ/ZkRt694k7KJNimgmHjtQcRuVwsST2Z6XfYveQIuBbHR+EqkTc1jfgPkQmMyk/vtpxo3nVxe8CNuau86A==",
|
||||
"@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==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn": {
|
||||
@@ -3755,9 +3756,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -3839,9 +3840,9 @@
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.7.12",
|
||||
"@typescript-eslint/parser": "^5.15.0",
|
||||
"@vercel/ncc": "^0.36.0",
|
||||
"@zeit/ncc": "^0.20.5",
|
||||
"eslint": "^8.11.0",
|
||||
"eslint-plugin-github": "^4.3.5",
|
||||
"prettier": "^1.19.1",
|
||||
|
||||
@@ -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.16.0"
|
||||
NODE16_VERSION="16.13.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
@@ -18,20 +18,6 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
|
||||
done
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
|
||||
# Wait for docker to start
|
||||
if [ ! -z "$RUNNER_WAIT_FOR_DOCKER_IN_SECONDS" ]; then
|
||||
if [ "$RUNNER_WAIT_FOR_DOCKER_IN_SECONDS" -gt 0 ]; then
|
||||
echo "Waiting for docker to be ready."
|
||||
for i in $(seq "$RUNNER_WAIT_FOR_DOCKER_IN_SECONDS"); do
|
||||
if docker ps > /dev/null 2>&1; then
|
||||
echo "Docker is ready."
|
||||
break
|
||||
fi
|
||||
"$DIR"/safe_sleep.sh 1
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
updateFile="update.finished"
|
||||
"$DIR"/bin/Runner.Listener run $*
|
||||
|
||||
|
||||
@@ -74,7 +74,6 @@ Microsoft.Win32.Registry.dll
|
||||
mscordaccore.dll
|
||||
mscordaccore_amd64_amd64_6.0.522.21309.dll
|
||||
mscordaccore_arm64_arm64_6.0.522.21309.dll
|
||||
mscordaccore_amd64_amd64_6.0.1322.58009.dll
|
||||
mscordbi.dll
|
||||
mscorlib.dll
|
||||
mscorrc.debug.dll
|
||||
|
||||
@@ -90,6 +90,7 @@ 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";
|
||||
@@ -104,13 +105,11 @@ 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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -131,7 +130,6 @@ 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
|
||||
@@ -159,11 +157,9 @@ 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`.";
|
||||
|
||||
@@ -226,20 +226,6 @@ 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)
|
||||
|
||||
@@ -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 stepRecordId, string name, string path, bool deleteSource);
|
||||
void QueueSummaryUpload(Guid timelineId, Guid timelineRecordId, string stepId, string name, string path, bool deleteSource);
|
||||
void QueueTimelineRecordUpdate(Guid timelineId, TimelineRecord timelineRecord);
|
||||
}
|
||||
|
||||
@@ -230,20 +230,25 @@ namespace GitHub.Runner.Common
|
||||
_fileUploadQueue.Enqueue(newFile);
|
||||
}
|
||||
|
||||
public void QueueSummaryUpload(Guid stepRecordId, string name, string path, bool deleteSource)
|
||||
public void QueueSummaryUpload(Guid timelineId, Guid timelineRecordId, string stepId, 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 = stepRecordId.ToString(),
|
||||
StepId = stepId,
|
||||
DeleteSource = deleteSource
|
||||
};
|
||||
|
||||
Trace.Verbose("Enqueue results file upload queue: file '{0}' attach to job {1} step {2}", newFile.Path, _jobTimelineRecordId, stepRecordId);
|
||||
Trace.Verbose("Enqueue results file upload queue: file '{0}' attach to record {1}", newFile.Path, timelineRecordId);
|
||||
_summaryFileUploadQueue.Enqueue(newFile);
|
||||
}
|
||||
|
||||
@@ -471,21 +476,8 @@ 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++;
|
||||
}
|
||||
}
|
||||
@@ -824,6 +816,8 @@ 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; }
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Actions.RunService.WebApi;
|
||||
using GitHub.DistributedTask.Pipelines;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Sdk;
|
||||
using GitHub.Services.Common;
|
||||
using GitHub.Services.WebApi;
|
||||
using Sdk.WebApi.WebApi.RawClient;
|
||||
|
||||
namespace GitHub.Runner.Common
|
||||
@@ -17,8 +16,6 @@ namespace GitHub.Runner.Common
|
||||
Task ConnectAsync(Uri serverUrl, VssCredentials credentials);
|
||||
|
||||
Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken token);
|
||||
|
||||
Task CompleteJobAsync(Guid planId, Guid jobId, TaskResult result, Dictionary<String, VariableValue> outputs, IList<StepResult> stepResults, CancellationToken token);
|
||||
}
|
||||
|
||||
public sealed class RunServer : RunnerService, IRunServer
|
||||
@@ -32,7 +29,7 @@ namespace GitHub.Runner.Common
|
||||
{
|
||||
requestUri = serverUri;
|
||||
|
||||
_connection = VssUtil.CreateRawConnection(serverUri, credentials);
|
||||
_connection = VssUtil.CreateRawConnection(new Uri(serverUri.Authority), credentials);
|
||||
_runServiceHttpClient = await _connection.GetClientAsync<RunServiceHttpClient>();
|
||||
_hasConnection = true;
|
||||
}
|
||||
@@ -58,11 +55,5 @@ namespace GitHub.Runner.Common
|
||||
return jobMessage;
|
||||
}
|
||||
|
||||
public Task CompleteJobAsync(Guid planId, Guid jobId, TaskResult result, Dictionary<String, VariableValue> outputs, IList<StepResult> stepResults, CancellationToken cancellationToken)
|
||||
{
|
||||
CheckConnection();
|
||||
return RetryRequest(
|
||||
async () => await _runServiceHttpClient.CompleteJobAsync(requestUri, planId, jobId, result, outputs, stepResults, cancellationToken), cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,19 +68,6 @@ namespace GitHub.Runner.Common
|
||||
throw new InvalidOperationException(nameof(EstablishVssConnection));
|
||||
}
|
||||
|
||||
protected async Task RetryRequest(Func<Task> func,
|
||||
CancellationToken cancellationToken,
|
||||
int maxRetryAttemptsCount = 5
|
||||
)
|
||||
{
|
||||
async Task<Unit> wrappedFunc()
|
||||
{
|
||||
await func();
|
||||
return Unit.Value;
|
||||
}
|
||||
await RetryRequest<Unit>(wrappedFunc, cancellationToken, maxRetryAttemptsCount);
|
||||
}
|
||||
|
||||
protected async Task<T> RetryRequest<T>(Func<Task<T>> func,
|
||||
CancellationToken cancellationToken,
|
||||
int maxRetryAttemptsCount = 5
|
||||
@@ -98,7 +85,7 @@ namespace GitHub.Runner.Common
|
||||
// TODO: Add handling of non-retriable exceptions: https://github.com/github/actions-broker/issues/122
|
||||
catch (Exception ex) when (retryCount < maxRetryAttemptsCount)
|
||||
{
|
||||
Trace.Error("Catch exception during request");
|
||||
Trace.Error("Catch exception during get full job message");
|
||||
Trace.Error(ex);
|
||||
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
|
||||
Trace.Warning($"Back off {backOff.TotalSeconds} seconds before next retry. {maxRetryAttemptsCount - retryCount} attempt left.");
|
||||
|
||||
@@ -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,17 +24,10 @@ namespace GitHub.Runner.Common
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
var messageLines = message.Split(Environment.NewLine);
|
||||
foreach (var messageLine in messageLines)
|
||||
{
|
||||
WriteHeader(source, eventType, id);
|
||||
WriteLine(messageLine);
|
||||
WriteLine(message);
|
||||
WriteFooter(eventCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsEnabled(TraceOptions opts)
|
||||
{
|
||||
@@ -94,3 +87,4 @@ namespace GitHub.Runner.Common
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
// Represents absence of value.
|
||||
namespace GitHub.Runner.Common
|
||||
{
|
||||
public readonly struct Unit
|
||||
{
|
||||
public static readonly Unit Value = default;
|
||||
}
|
||||
}
|
||||
@@ -56,8 +56,7 @@ namespace GitHub.Runner.Listener
|
||||
new string[]
|
||||
{
|
||||
Constants.Runner.CommandLine.Args.Token,
|
||||
Constants.Runner.CommandLine.Args.PAT,
|
||||
Constants.Runner.CommandLine.Flags.Local
|
||||
Constants.Runner.CommandLine.Args.PAT
|
||||
},
|
||||
// Valid run flags and args
|
||||
[Constants.Runner.CommandLine.Commands.Run] =
|
||||
@@ -87,7 +86,6 @@ 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);
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
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;
|
||||
@@ -7,13 +14,6 @@ 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
|
||||
{
|
||||
@@ -652,17 +652,16 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
{
|
||||
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}' ({githubRequestId})");
|
||||
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
|
||||
var jsonResponse = await response.Content.ReadAsStringAsync();
|
||||
return StringUtil.ConvertFromJson<GitHubRunnerRegisterToken>(jsonResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' (Request Id: {githubRequestId})");
|
||||
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
|
||||
var errorResponse = await response.Content.ReadAsStringAsync();
|
||||
_term.WriteError(errorResponse);
|
||||
response.EnsureSuccessStatusCode();
|
||||
@@ -715,17 +714,16 @@ 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)
|
||||
{
|
||||
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' ({githubRequestId})");
|
||||
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
|
||||
var jsonResponse = await response.Content.ReadAsStringAsync();
|
||||
return StringUtil.ConvertFromJson<GitHubAuthResult>(jsonResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' (Request Id: {githubRequestId})");
|
||||
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
|
||||
var errorResponse = await response.Content.ReadAsStringAsync();
|
||||
_term.WriteError(errorResponse);
|
||||
response.EnsureSuccessStatusCode();
|
||||
@@ -744,14 +742,5 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,12 +135,6 @@ 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);
|
||||
@@ -653,7 +647,6 @@ 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`
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace GitHub.Runner.Sdk
|
||||
{
|
||||
var headerValues = new List<ProductInfoHeaderValue>();
|
||||
headerValues.Add(new ProductInfoHeaderValue($"GitHubActionsRunner-Plugin", BuildConstants.RunnerPackage.Version));
|
||||
headerValues.Add(new ProductInfoHeaderValue($"({StringUtil.SanitizeUserAgentHeader(RuntimeInformation.OSDescription)})"));
|
||||
headerValues.Add(new ProductInfoHeaderValue($"({RuntimeInformation.OSDescription.Trim()})"));
|
||||
|
||||
if (VssClientHttpRequestSettings.Default.UserAgent != null && VssClientHttpRequestSettings.Default.UserAgent.Count > 0)
|
||||
{
|
||||
|
||||
@@ -264,17 +264,7 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,12 +123,5 @@ namespace GitHub.Runner.Sdk
|
||||
{
|
||||
return value?.Substring(0, Math.Min(value.Length, count));
|
||||
}
|
||||
|
||||
// Fixes format violations e.g. https://github.com/actions/runner/issues/2165
|
||||
public static string SanitizeUserAgentHeader(string header)
|
||||
{
|
||||
return header.Replace("(", "[").Replace(")", "]").Trim();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,16 +6,9 @@ namespace GitHub.Runner.Sdk
|
||||
{
|
||||
public static bool IsHostedServer(UriBuilder gitHubUrl)
|
||||
{
|
||||
if (StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_FORCE_GHES")))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return
|
||||
string.Equals(gitHubUrl.Host, "github.com", StringComparison.OrdinalIgnoreCase) ||
|
||||
return string.Equals(gitHubUrl.Host, "github.com", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(gitHubUrl.Host, "www.github.com", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(gitHubUrl.Host, "github.localhost", StringComparison.OrdinalIgnoreCase) ||
|
||||
gitHubUrl.Host.EndsWith(".ghe.com", StringComparison.OrdinalIgnoreCase);
|
||||
string.Equals(gitHubUrl.Host, "github.localhost", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static Uri GetCredentialEmbeddedUrl(Uri baseUrl, string username, string password)
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace GitHub.Runner.Sdk
|
||||
{
|
||||
var headerValues = new List<ProductInfoHeaderValue>();
|
||||
headerValues.AddRange(additionalUserAgents);
|
||||
headerValues.Add(new ProductInfoHeaderValue($"({StringUtil.SanitizeUserAgentHeader(RuntimeInformation.OSDescription)})"));
|
||||
headerValues.Add(new ProductInfoHeaderValue($"({RuntimeInformation.OSDescription.Trim()})"));
|
||||
|
||||
if (VssClientHttpRequestSettings.Default.UserAgent != null && VssClientHttpRequestSettings.Default.UserAgent.Count > 0)
|
||||
{
|
||||
@@ -116,7 +116,7 @@ namespace GitHub.Runner.Sdk
|
||||
// settings are applied to an HttpRequestMessage.
|
||||
settings.AcceptLanguages.Remove(CultureInfo.InvariantCulture);
|
||||
|
||||
RawConnection connection = new(serverUri, new RawHttpMessageHandler(credentials.Federated, settings), additionalDelegatingHandler);
|
||||
RawConnection connection = new(serverUri, new RawHttpMessageHandler(credentials.ToOAuthCredentials(), settings), additionalDelegatingHandler);
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace GitHub.Runner.Worker
|
||||
public interface IActionRunner : IStep, IRunnerService
|
||||
{
|
||||
ActionRunStage Stage { get; set; }
|
||||
bool TryEvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context);
|
||||
Pipelines.ActionStep Action { get; set; }
|
||||
}
|
||||
|
||||
@@ -284,67 +285,25 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to update the DisplayName.
|
||||
/// As the "Try..." name implies, this method should never throw an exception.
|
||||
/// Returns true if the DisplayName is already present or it was successfully updated.
|
||||
/// </summary>
|
||||
public bool TryUpdateDisplayName(out bool updated)
|
||||
{
|
||||
updated = false;
|
||||
|
||||
// REVIEW: This try/catch can be removed if some future implementation of EvaluateDisplayName and UpdateTimelineRecordDisplayName
|
||||
// can make reasonable guarantees that they won't throw an exception.
|
||||
try
|
||||
{
|
||||
// This attempt is only worthwhile at the "Main" stage.
|
||||
// When the job starts, there's an initial attempt to evaluate the DisplayName. (see JobExtension::InitializeJob)
|
||||
// During the "Pre" stage, we expect that no contexts will have changed since the initial evaluation.
|
||||
// "Main" stage is handled here.
|
||||
// During the "Post" stage, it no longer matters.
|
||||
if (this.Stage == ActionRunStage.Main && EvaluateDisplayName(this.ExecutionContext.ExpressionValues, this.ExecutionContext, out updated))
|
||||
{
|
||||
if (updated)
|
||||
{
|
||||
this.ExecutionContext.UpdateTimelineRecordDisplayName(this.DisplayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.Warning("Caught exception while attempting to evaulate/update the step's DisplayName. Exception Details: {0}", ex);
|
||||
}
|
||||
|
||||
// For consistency with other implementations of TryUpdateDisplayName we use !string.IsNullOrEmpty below,
|
||||
// but note that (at the time of this writing) ActionRunner::DisplayName::get always returns a non-empty string due to its fallback logic.
|
||||
// In other words, the net effect is that this particular implementation of TryUpdateDisplayName will always return true.
|
||||
return !string.IsNullOrEmpty(this.DisplayName);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to evaluate the DisplayName of this IActionRunner.
|
||||
/// Returns true if the DisplayName is already present or it was successfully evaluated.
|
||||
/// </summary>
|
||||
public bool EvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context, out bool updated)
|
||||
public bool TryEvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context)
|
||||
{
|
||||
ArgUtil.NotNull(context, nameof(context));
|
||||
ArgUtil.NotNull(Action, nameof(Action));
|
||||
|
||||
updated = false;
|
||||
// If we have already expanded the display name, don't bother attempting [re-]expansion.
|
||||
// If we have already expanded the display name, there is no need to expand it again
|
||||
// TODO: Remove the ShouldEvaluateDisplayName check and field post m158 deploy, we should do it by default once the server is updated
|
||||
if (_didFullyEvaluateDisplayName || !string.IsNullOrEmpty(Action.DisplayName))
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
_displayName = GenerateDisplayName(Action, contextData, context, out bool didFullyEvaluate);
|
||||
bool didFullyEvaluate;
|
||||
_displayName = GenerateDisplayName(Action, contextData, context, out didFullyEvaluate);
|
||||
|
||||
// If we evaluated, fully mask any secrets
|
||||
// If we evaluated fully mask any secrets
|
||||
if (didFullyEvaluate)
|
||||
{
|
||||
_displayName = HostContext.SecretMasker.MaskSecrets(_displayName);
|
||||
updated = true;
|
||||
}
|
||||
context.Debug($"Set step '{Action.Name}' display name to: '{_displayName}'");
|
||||
_didFullyEvaluateDisplayName = didFullyEvaluate;
|
||||
|
||||
@@ -33,15 +33,9 @@ namespace GitHub.Runner.Worker
|
||||
public override void Initialize(IHostContext hostContext)
|
||||
{
|
||||
base.Initialize(hostContext);
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Actions.RunService.WebApi;
|
||||
using GitHub.DistributedTask.Expressions2;
|
||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
@@ -81,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, Guid stepRecordId);
|
||||
void QueueSummaryFile(string name, string filePath, string stepId);
|
||||
|
||||
// timeline record update methods
|
||||
void Start(string currentOperation = null);
|
||||
@@ -438,17 +437,6 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
PublishStepTelemetry();
|
||||
|
||||
var stepResult = new StepResult();
|
||||
stepResult.ExternalID = _record.Id;
|
||||
stepResult.Conclusion = _record.Result ?? TaskResult.Succeeded;
|
||||
stepResult.Status = _record.State;
|
||||
stepResult.Number = _record.Order;
|
||||
stepResult.Name = _record.Name;
|
||||
stepResult.StartedAt = _record.StartTime;
|
||||
stepResult.CompletedAt = _record.FinishTime;
|
||||
|
||||
Global.StepsResult.Add(stepResult);
|
||||
|
||||
if (Root != this)
|
||||
{
|
||||
// only dispose TokenSource for step level ExecutionContext
|
||||
@@ -722,9 +710,6 @@ namespace GitHub.Runner.Worker
|
||||
// ActionsStepTelemetry for entire job
|
||||
Global.StepsTelemetry = new List<ActionsStepTelemetry>();
|
||||
|
||||
// Steps results for entire job
|
||||
Global.StepsResult = new List<StepResult>();
|
||||
|
||||
// Job Outputs
|
||||
JobOutputs = new Dictionary<string, VariableValue>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
@@ -862,7 +847,7 @@ namespace GitHub.Runner.Worker
|
||||
_jobServerQueue.QueueFileUpload(_mainTimelineId, _record.Id, type, name, filePath, deleteSource: false);
|
||||
}
|
||||
|
||||
public void QueueSummaryFile(string name, string filePath, Guid stepRecordId)
|
||||
public void QueueSummaryFile(string name, string filePath, string stepId)
|
||||
{
|
||||
ArgUtil.NotNullOrEmpty(name, nameof(name));
|
||||
ArgUtil.NotNullOrEmpty(filePath, nameof(filePath));
|
||||
@@ -872,7 +857,7 @@ namespace GitHub.Runner.Worker
|
||||
throw new FileNotFoundException($"Can't upload (name:{name}) file: {filePath}. File does not exist.");
|
||||
}
|
||||
|
||||
_jobServerQueue.QueueSummaryUpload(stepRecordId, name, filePath, deleteSource: false);
|
||||
_jobServerQueue.QueueSummaryUpload(_mainTimelineId, _record.Id, stepId, name, filePath, deleteSource: false);
|
||||
}
|
||||
|
||||
// Add OnMatcherChanged
|
||||
|
||||
@@ -208,19 +208,20 @@ 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;
|
||||
var stepId = context.Id.ToString();
|
||||
// Attachments must be added to the parent context (job), not the current context (step)
|
||||
context.Root.QueueSummaryFile(attachmentName, scrubbedFilePath, stepId);
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using GitHub.Actions.RunService.WebApi;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Runner.Worker.Container;
|
||||
@@ -17,7 +16,6 @@ namespace GitHub.Runner.Worker
|
||||
public IList<String> FileTable { get; set; }
|
||||
public IDictionary<String, IDictionary<String, String>> JobDefaults { get; set; }
|
||||
public List<ActionsStepTelemetry> StepsTelemetry { get; set; }
|
||||
public List<StepResult> StepsResult { get; set; }
|
||||
public List<JobTelemetry> JobTelemetry { get; set; }
|
||||
public TaskOrchestrationPlanReference Plan { get; set; }
|
||||
public List<string> PrependPath { get; set; }
|
||||
|
||||
@@ -38,17 +38,8 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
// Update the env dictionary.
|
||||
AddInputsToEnvironment();
|
||||
|
||||
IDockerCommandManager dockerManager = null;
|
||||
IContainerHookManager containerHookManager = null;
|
||||
if (FeatureManager.IsContainerHooksEnabled(ExecutionContext.Global.Variables))
|
||||
{
|
||||
containerHookManager = HostContext.GetService<IContainerHookManager>();
|
||||
}
|
||||
else
|
||||
{
|
||||
dockerManager = HostContext.GetService<IDockerCommandManager>();
|
||||
}
|
||||
|
||||
var dockerManager = HostContext.GetService<IDockerCommandManager>();
|
||||
var containerHookManager = HostContext.GetService<IContainerHookManager>();
|
||||
string dockerFile = null;
|
||||
|
||||
// container image haven't built/pull
|
||||
|
||||
@@ -306,13 +306,13 @@ namespace GitHub.Runner.Worker
|
||||
}
|
||||
}
|
||||
|
||||
actionRunner.EvaluateDisplayName(contextData, context, out _);
|
||||
actionRunner.TryEvaluateDisplayName(contextData, context);
|
||||
jobSteps.Add(actionRunner);
|
||||
|
||||
if (prepareResult.PreStepTracker.TryGetValue(step.Id, out var preStep))
|
||||
{
|
||||
Trace.Info($"Adding pre-{action.DisplayName}.");
|
||||
preStep.EvaluateDisplayName(contextData, context, out _);
|
||||
preStep.TryEvaluateDisplayName(contextData, context);
|
||||
preStep.DisplayName = $"Pre {preStep.DisplayName}";
|
||||
preJobSteps.Add(preStep);
|
||||
}
|
||||
@@ -321,10 +321,7 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
if (message.Variables.TryGetValue("system.workflowFileFullPath", out VariableValue workflowFileFullPath))
|
||||
{
|
||||
var usesLogText = $"Uses: {workflowFileFullPath.Value}";
|
||||
var reference = GetWorkflowReference(message.Variables);
|
||||
context.Output(usesLogText + reference);
|
||||
|
||||
context.Output($"Uses: {workflowFileFullPath.Value}");
|
||||
if (message.ContextData.TryGetValue("inputs", out var pipelineContextData))
|
||||
{
|
||||
var inputs = pipelineContextData.AssertDictionary("inputs");
|
||||
@@ -338,12 +335,12 @@ namespace GitHub.Runner.Worker
|
||||
context.Output("##[endgroup]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(message.JobDisplayName))
|
||||
{
|
||||
context.Output($"Complete job name: {message.JobDisplayName}");
|
||||
}
|
||||
}
|
||||
|
||||
var intraActionStates = new Dictionary<Guid, Dictionary<string, string>>();
|
||||
foreach (var preStep in prepareResult.PreStepTracker)
|
||||
@@ -455,24 +452,6 @@ 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();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
|
||||
namespace GitHub.Runner.Worker
|
||||
{
|
||||
@@ -33,18 +32,5 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
await _runAsync(ExecutionContext, _data);
|
||||
}
|
||||
|
||||
public bool TryUpdateDisplayName(out bool updated)
|
||||
{
|
||||
updated = false;
|
||||
return !string.IsNullOrEmpty(this.DisplayName);
|
||||
}
|
||||
|
||||
public bool EvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context, out bool updated)
|
||||
{
|
||||
updated = false;
|
||||
return !string.IsNullOrEmpty(this.DisplayName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Common;
|
||||
using GitHub.Runner.Common.Util;
|
||||
@@ -39,18 +40,9 @@ namespace GitHub.Runner.Worker
|
||||
Trace.Info("Job ID {0}", message.JobId);
|
||||
|
||||
DateTime jobStartTimeUtc = DateTime.UtcNow;
|
||||
IRunnerService server = null;
|
||||
|
||||
ServiceEndpoint systemConnection = message.Resources.Endpoints.Single(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase));
|
||||
if (string.Equals(message.MessageType, JobRequestMessageTypes.RunnerJobRequest, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var runServer = HostContext.GetService<IRunServer>();
|
||||
VssCredentials jobServerCredential = VssUtil.GetVssCredential(systemConnection);
|
||||
await runServer.ConnectAsync(systemConnection.Url, jobServerCredential);
|
||||
server = runServer;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Setup the job server and job server queue.
|
||||
var jobServer = HostContext.GetService<IJobServer>();
|
||||
VssCredentials jobServerCredential = VssUtil.GetVssCredential(systemConnection);
|
||||
@@ -63,10 +55,6 @@ namespace GitHub.Runner.Worker
|
||||
await jobServer.ConnectAsync(jobConnection);
|
||||
|
||||
_jobServerQueue.Start(message);
|
||||
server = jobServer;
|
||||
}
|
||||
|
||||
|
||||
HostContext.WritePerfCounter($"WorkerJobServerQueueStarted_{message.RequestId.ToString()}");
|
||||
|
||||
IExecutionContext jobContext = null;
|
||||
@@ -111,7 +99,7 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
Trace.Error(ex);
|
||||
jobContext.Error(ex);
|
||||
return await CompleteJobAsync(server, jobContext, message, TaskResult.Failed);
|
||||
return await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed);
|
||||
}
|
||||
|
||||
if (jobContext.Global.WriteDebug)
|
||||
@@ -148,7 +136,7 @@ namespace GitHub.Runner.Worker
|
||||
// don't log error issue to job ExecutionContext, since server owns the job level issue
|
||||
Trace.Error($"Job is cancelled during initialize.");
|
||||
Trace.Error($"Caught exception: {ex}");
|
||||
return await CompleteJobAsync(server, jobContext, message, TaskResult.Canceled);
|
||||
return await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Canceled);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -156,7 +144,7 @@ namespace GitHub.Runner.Worker
|
||||
// don't log error issue to job ExecutionContext, since server owns the job level issue
|
||||
Trace.Error($"Job initialize failed.");
|
||||
Trace.Error($"Caught exception from {nameof(jobExtension.InitializeJob)}: {ex}");
|
||||
return await CompleteJobAsync(server, jobContext, message, TaskResult.Failed);
|
||||
return await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed);
|
||||
}
|
||||
|
||||
// trace out all steps
|
||||
@@ -193,7 +181,7 @@ namespace GitHub.Runner.Worker
|
||||
// Log the error and fail the job.
|
||||
Trace.Error($"Caught exception from job steps {nameof(StepsRunner)}: {ex}");
|
||||
jobContext.Error(ex);
|
||||
return await CompleteJobAsync(server, jobContext, message, TaskResult.Failed);
|
||||
return await CompleteJobAsync(jobServer, jobContext, message, TaskResult.Failed);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -204,7 +192,7 @@ namespace GitHub.Runner.Worker
|
||||
Trace.Info($"Job result after all job steps finish: {jobContext.Result ?? TaskResult.Succeeded}");
|
||||
|
||||
Trace.Info("Completing the job execution context.");
|
||||
return await CompleteJobAsync(server, jobContext, message);
|
||||
return await CompleteJobAsync(jobServer, jobContext, message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -218,66 +206,6 @@ namespace GitHub.Runner.Worker
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<TaskResult> CompleteJobAsync(IRunnerService server, IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, TaskResult? taskResult = null)
|
||||
{
|
||||
if (server is IRunServer runServer)
|
||||
{
|
||||
return await CompleteJobAsync(runServer, jobContext, message, taskResult);
|
||||
}
|
||||
else if (server is IJobServer jobServer)
|
||||
{
|
||||
return await CompleteJobAsync(jobServer, jobContext, message, taskResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<TaskResult> CompleteJobAsync(IRunServer runServer, IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, TaskResult? taskResult = null)
|
||||
{
|
||||
jobContext.Debug($"Finishing: {message.JobDisplayName}");
|
||||
TaskResult result = jobContext.Complete(taskResult);
|
||||
if (jobContext.Global.Variables.TryGetValue("Node12ActionsWarnings", out var node12Warnings))
|
||||
{
|
||||
var actions = string.Join(", ", StringUtil.ConvertFromJson<HashSet<string>>(node12Warnings));
|
||||
jobContext.Warning(string.Format(Constants.Runner.Node12DetectedAfterEndOfLife, actions));
|
||||
}
|
||||
|
||||
// Make sure to clean temp after file upload since they may be pending fileupload still use the TEMP dir.
|
||||
_tempDirectoryManager?.CleanupTempDirectory();
|
||||
|
||||
// Load any upgrade telemetry
|
||||
LoadFromTelemetryFile(jobContext.Global.JobTelemetry);
|
||||
|
||||
// Make sure we don't submit secrets as telemetry
|
||||
MaskTelemetrySecrets(jobContext.Global.JobTelemetry);
|
||||
|
||||
Trace.Info($"Raising job completed against run service");
|
||||
var completeJobRetryLimit = 5;
|
||||
var exceptions = new List<Exception>();
|
||||
while (completeJobRetryLimit-- > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
await runServer.CompleteJobAsync(message.Plan.PlanId, message.JobId, result, jobContext.JobOutputs, jobContext.Global.StepsResult, default);
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.Error($"Catch exception while attempting to complete job {message.JobId}, job request {message.RequestId}.");
|
||||
Trace.Error(ex);
|
||||
exceptions.Add(ex);
|
||||
}
|
||||
|
||||
// delay 5 seconds before next retry.
|
||||
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
// rethrow exceptions from all attempts.
|
||||
throw new AggregateException(exceptions);
|
||||
}
|
||||
|
||||
private async Task<TaskResult> CompleteJobAsync(IJobServer jobServer, IExecutionContext jobContext, Pipelines.AgentJobRequestMessage message, TaskResult? taskResult = null)
|
||||
{
|
||||
jobContext.Debug($"Finishing: {message.JobDisplayName}");
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.DistributedTask.Expressions2;
|
||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||
using GitHub.DistributedTask.Pipelines;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
@@ -11,6 +14,8 @@ using GitHub.Runner.Common;
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Runner.Sdk;
|
||||
using GitHub.Runner.Worker.Expressions;
|
||||
using ObjectTemplating = GitHub.DistributedTask.ObjectTemplating;
|
||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||
|
||||
namespace GitHub.Runner.Worker
|
||||
{
|
||||
@@ -21,8 +26,6 @@ namespace GitHub.Runner.Worker
|
||||
string DisplayName { get; set; }
|
||||
IExecutionContext ExecutionContext { get; set; }
|
||||
TemplateToken Timeout { get; }
|
||||
bool TryUpdateDisplayName(out bool updated);
|
||||
bool EvaluateDisplayName(DictionaryContextData contextData, IExecutionContext context, out bool updated);
|
||||
Task RunAsync();
|
||||
}
|
||||
|
||||
@@ -192,12 +195,6 @@ namespace GitHub.Runner.Worker
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is our last, best chance to expand the display name. (At this point, all the requirements for successful expansion should be met.)
|
||||
// That being said, evaluating the display name should still be considered as a "best effort" exercise. (It's not critical or paramount.)
|
||||
// For that reason, we call a safe "Try..." wrapper method to ensure that any potential problems we encounter in evaluating the display name
|
||||
// don't interfere with our ultimate goal within this code block: evaluation of the condition.
|
||||
step.TryUpdateDisplayName(out _);
|
||||
|
||||
try
|
||||
{
|
||||
var templateEvaluator = step.ExecutionContext.ToPipelineTemplateEvaluator(conditionTraceWriter);
|
||||
@@ -259,6 +256,14 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
private async Task RunStepAsync(IStep step, CancellationToken jobCancellationToken)
|
||||
{
|
||||
// Check to see if we can expand the display name
|
||||
if (step is IActionRunner actionRunner &&
|
||||
actionRunner.Stage == ActionRunStage.Main &&
|
||||
actionRunner.TryEvaluateDisplayName(step.ExecutionContext.ExpressionValues, step.ExecutionContext))
|
||||
{
|
||||
step.ExecutionContext.UpdateTimelineRecordDisplayName(actionRunner.DisplayName);
|
||||
}
|
||||
|
||||
// Start the step
|
||||
Trace.Info("Starting the step.");
|
||||
step.ExecutionContext.Debug($"Starting: {step.DisplayName}");
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using GitHub.Services.OAuth;
|
||||
|
||||
namespace GitHub.Services.Common
|
||||
{
|
||||
public static class VssCredentialsExtension
|
||||
{
|
||||
public static VssOAuthCredential ToOAuthCredentials(
|
||||
this VssCredentials credentials)
|
||||
{
|
||||
if (credentials.Federated.CredentialType == VssCredentialsType.OAuth)
|
||||
{
|
||||
return credentials.Federated as VssOAuthCredential;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,20 +12,20 @@ namespace GitHub.Services.Common
|
||||
public class RawHttpMessageHandler: HttpMessageHandler
|
||||
{
|
||||
public RawHttpMessageHandler(
|
||||
FederatedCredential credentials)
|
||||
VssOAuthCredential credentials)
|
||||
: this(credentials, new RawClientHttpRequestSettings())
|
||||
{
|
||||
}
|
||||
|
||||
public RawHttpMessageHandler(
|
||||
FederatedCredential credentials,
|
||||
VssOAuthCredential credentials,
|
||||
RawClientHttpRequestSettings settings)
|
||||
: this(credentials, settings, new HttpClientHandler())
|
||||
{
|
||||
}
|
||||
|
||||
public RawHttpMessageHandler(
|
||||
FederatedCredential credentials,
|
||||
VssOAuthCredential credentials,
|
||||
RawClientHttpRequestSettings settings,
|
||||
HttpMessageHandler innerHandler)
|
||||
{
|
||||
@@ -56,7 +56,7 @@ namespace GitHub.Services.Common
|
||||
/// <summary>
|
||||
/// Gets the credentials associated with this handler.
|
||||
/// </summary>
|
||||
public FederatedCredential Credentials
|
||||
public VssOAuthCredential Credentials
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
@@ -111,7 +111,7 @@ namespace GitHub.Services.Common
|
||||
// Ensure that we attempt to use the most appropriate authentication mechanism by default.
|
||||
if (m_tokenProvider == null)
|
||||
{
|
||||
m_tokenProvider = this.Credentials.CreateTokenProvider(request.RequestUri, null, null);
|
||||
m_tokenProvider = this.Credentials.GetTokenProvider(request.RequestUri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace GitHub.Services.Common
|
||||
private CredentialWrapper m_credentialWrapper;
|
||||
private object m_thisLock;
|
||||
private const Int32 m_maxAuthRetries = 3;
|
||||
private IssuedTokenProvider m_tokenProvider;
|
||||
private VssOAuthTokenProvider m_tokenProvider;
|
||||
|
||||
//.Net Core does not attempt NTLM schema on Linux, unless ICredentials is a CredentialCache instance
|
||||
//This workaround may not be needed after this corefx fix is consumed: https://github.com/dotnet/corefx/pull/7923
|
||||
|
||||
@@ -42,10 +42,9 @@ namespace GitHub.DistributedTask.Pipelines
|
||||
IList<String> fileTable,
|
||||
TemplateToken jobOutputs,
|
||||
IList<TemplateToken> defaults,
|
||||
ActionsEnvironmentReference actionsEnvironment,
|
||||
String messageType = JobRequestMessageTypes.PipelineAgentJobRequest)
|
||||
ActionsEnvironmentReference actionsEnvironment)
|
||||
{
|
||||
this.MessageType = messageType;
|
||||
this.MessageType = JobRequestMessageTypes.PipelineAgentJobRequest;
|
||||
this.Plan = plan;
|
||||
this.JobId = jobId;
|
||||
this.JobDisplayName = jobDisplayName;
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.DistributedTask.Pipelines;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Services.Common;
|
||||
using GitHub.Services.OAuth;
|
||||
using GitHub.Services.WebApi;
|
||||
using Sdk.WebApi.WebApi;
|
||||
|
||||
namespace GitHub.Actions.RunService.WebApi
|
||||
namespace GitHub.DistributedTask.WebApi
|
||||
{
|
||||
[ResourceArea(TaskResourceIds.AreaId)]
|
||||
public class RunServiceHttpClient : RawHttpClientBase
|
||||
{
|
||||
public RunServiceHttpClient(
|
||||
@@ -54,54 +52,24 @@ namespace GitHub.Actions.RunService.WebApi
|
||||
{
|
||||
}
|
||||
|
||||
public Task<AgentJobRequestMessage> GetJobMessageAsync(
|
||||
public Task<Pipelines.AgentJobRequestMessage> GetJobMessageAsync(
|
||||
Uri requestUri,
|
||||
string messageId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
HttpMethod httpMethod = new HttpMethod("POST");
|
||||
var payload = new AcquireJobRequest
|
||||
{
|
||||
var payload = new {
|
||||
StreamID = messageId
|
||||
};
|
||||
|
||||
requestUri = new Uri(requestUri, "acquirejob");
|
||||
|
||||
var requestContent = new ObjectContent<AcquireJobRequest>(payload, new VssJsonMediaTypeFormatter(true));
|
||||
return SendAsync<AgentJobRequestMessage>(
|
||||
var payloadJson = JsonUtility.ToString(payload);
|
||||
var requestContent = new StringContent(payloadJson, System.Text.Encoding.UTF8, "application/json");
|
||||
return SendAsync<Pipelines.AgentJobRequestMessage>(
|
||||
httpMethod,
|
||||
additionalHeaders: null,
|
||||
requestUri: requestUri,
|
||||
content: requestContent,
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public Task CompleteJobAsync(
|
||||
Uri requestUri,
|
||||
Guid planId,
|
||||
Guid jobId,
|
||||
TaskResult result,
|
||||
Dictionary<String, VariableValue> outputs,
|
||||
IList<StepResult> stepResults,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
HttpMethod httpMethod = new HttpMethod("POST");
|
||||
var payload = new CompleteJobRequest()
|
||||
{
|
||||
PlanID = planId,
|
||||
JobID = jobId,
|
||||
Conclusion = result,
|
||||
Outputs = outputs,
|
||||
StepResults = stepResults
|
||||
};
|
||||
|
||||
requestUri = new Uri(requestUri, "completejob");
|
||||
|
||||
var requestContent = new ObjectContent<CompleteJobRequest>(payload, new VssJsonMediaTypeFormatter(true));
|
||||
return SendAsync(
|
||||
httpMethod,
|
||||
requestUri,
|
||||
content: requestContent,
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
|
||||
namespace GitHub.Actions.RunService.WebApi
|
||||
{
|
||||
[DataContract]
|
||||
public class AcquireJobRequest
|
||||
{
|
||||
[DataMember(Name = "streamId", EmitDefaultValue = false)]
|
||||
public string StreamID { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
|
||||
namespace GitHub.Actions.RunService.WebApi
|
||||
{
|
||||
[DataContract]
|
||||
public class CompleteJobRequest
|
||||
{
|
||||
[DataMember(Name = "planId", EmitDefaultValue = false)]
|
||||
public Guid PlanID { get; set; }
|
||||
|
||||
[DataMember(Name = "jobId", EmitDefaultValue = false)]
|
||||
public Guid JobID { get; set; }
|
||||
|
||||
[DataMember(Name = "conclusion")]
|
||||
public TaskResult Conclusion { get; set; }
|
||||
|
||||
[DataMember(Name = "outputs", EmitDefaultValue = false)]
|
||||
public Dictionary<string, VariableValue> Outputs { get; set; }
|
||||
|
||||
[DataMember(Name = "stepResults", EmitDefaultValue = false)]
|
||||
public IList<StepResult> StepResults { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
|
||||
namespace GitHub.Actions.RunService.WebApi
|
||||
{
|
||||
[DataContract]
|
||||
public class StepResult
|
||||
{
|
||||
[DataMember(Name = "external_id", EmitDefaultValue = false)]
|
||||
public Guid ExternalID { get; set; }
|
||||
|
||||
[DataMember(Name = "number", EmitDefaultValue = false)]
|
||||
public int? Number { get; set; }
|
||||
|
||||
[DataMember(Name = "name", EmitDefaultValue = false)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[DataMember(Name = "status")]
|
||||
public TimelineRecordState? Status { get; set; }
|
||||
|
||||
[DataMember(Name = "conclusion")]
|
||||
public TaskResult? Conclusion { get; set; }
|
||||
|
||||
[DataMember(Name = "started_at", EmitDefaultValue = false)]
|
||||
public DateTime? StartedAt { get; set; }
|
||||
|
||||
[DataMember(Name = "completed_at", EmitDefaultValue = false)]
|
||||
public DateTime? CompletedAt { get; set; }
|
||||
|
||||
[DataMember(Name = "completed_log_url", EmitDefaultValue = false)]
|
||||
public string CompletedLogURL { get; set; }
|
||||
|
||||
[DataMember(Name = "completed_log_lines", EmitDefaultValue = false)]
|
||||
public long? CompletedLogLines { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -101,17 +101,6 @@ namespace Sdk.WebApi.WebApi
|
||||
}
|
||||
}
|
||||
|
||||
protected Task<T> SendAsync<T>(
|
||||
HttpMethod method,
|
||||
Uri requestUri,
|
||||
HttpContent content = null,
|
||||
IEnumerable<KeyValuePair<String, String>> queryParameters = null,
|
||||
Object userState = null,
|
||||
CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return SendAsync<T>(method, null, requestUri, content, queryParameters, userState, cancellationToken);
|
||||
}
|
||||
|
||||
protected async Task<T> SendAsync<T>(
|
||||
HttpMethod method,
|
||||
IEnumerable<KeyValuePair<String, String>> additionalHeaders,
|
||||
|
||||
@@ -6,11 +6,11 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Services.Results.Contracts;
|
||||
using System.Net.Http.Formatting;
|
||||
using Sdk.WebApi.WebApi;
|
||||
using GitHub.Services.WebApi;
|
||||
|
||||
namespace GitHub.Services.Results.Client
|
||||
{
|
||||
public class ResultsHttpClient : RawHttpClientBase
|
||||
public class ResultsHttpClient : VssHttpClientBase
|
||||
{
|
||||
public ResultsHttpClient(
|
||||
Uri baseUrl,
|
||||
@@ -113,10 +113,6 @@ 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;
|
||||
|
||||
@@ -824,7 +824,6 @@ 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")]
|
||||
|
||||
@@ -502,34 +502,5 @@ 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,76 +128,7 @@ 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")]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using GitHub.Runner.Sdk;
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Runner.Sdk;
|
||||
using System.Globalization;
|
||||
using Xunit;
|
||||
|
||||
@@ -185,19 +186,5 @@ namespace GitHub.Runner.Common.Tests.Util
|
||||
Assert.False(result9, $"'{undefineString3}' should convert to false.");
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", "")]
|
||||
[InlineData("(())", "[[]]")]
|
||||
[InlineData("()()", "[][]")]
|
||||
[InlineData(" Liquorix kernel OS Description is poorly formatted (linux version ", "Liquorix kernel OS Description is poorly formatted [linux version")]
|
||||
[InlineData("Liquorix kernel OS Description is poorly formatted (linux version", "Liquorix kernel OS Description is poorly formatted [linux version")]
|
||||
[InlineData("()((.", "[][[.")]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void SanitizeUserAgentHeader(string input, string expected)
|
||||
{
|
||||
Assert.Equal(expected, StringUtil.SanitizeUserAgentHeader(input));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,20 @@ using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||
using GitHub.DistributedTask.Pipelines;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Runner.Worker;
|
||||
using GitHub.Runner.Worker.Container;
|
||||
using GitHub.Runner.Worker.Handlers;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||
|
||||
@@ -143,12 +149,11 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
_context.Add("matrix", matrixData);
|
||||
|
||||
// Act
|
||||
// Should report success with no updated required if there's already a valid display name.
|
||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
||||
// Should not do anything if we don't have a displayNameToken to expand
|
||||
var didUpdateDisplayName = _actionRunner.TryEvaluateDisplayName(_context, _actionRunner.ExecutionContext);
|
||||
|
||||
// Assert
|
||||
Assert.True(validDisplayName);
|
||||
Assert.False(updated);
|
||||
Assert.False(didUpdateDisplayName);
|
||||
Assert.Equal(actionDisplayName, _actionRunner.DisplayName);
|
||||
}
|
||||
|
||||
@@ -178,51 +183,13 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
|
||||
// Act
|
||||
// Should expand the displaynameToken and set the display name to that
|
||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
||||
var didUpdateDisplayName = _actionRunner.TryEvaluateDisplayName(_context, _actionRunner.ExecutionContext);
|
||||
|
||||
// Assert
|
||||
Assert.True(validDisplayName);
|
||||
Assert.True(updated);
|
||||
Assert.True(didUpdateDisplayName);
|
||||
Assert.Equal(expectedString, _actionRunner.DisplayName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void IgnoreDisplayNameTokenWhenDisplayNameIsExplicitlySet()
|
||||
{
|
||||
var explicitDisplayName = "Explcitly Set Name";
|
||||
|
||||
// Arrange
|
||||
Setup();
|
||||
var actionId = Guid.NewGuid();
|
||||
var action = new Pipelines.ActionStep()
|
||||
{
|
||||
Name = "action",
|
||||
Id = actionId,
|
||||
DisplayName = explicitDisplayName,
|
||||
DisplayNameToken = new BasicExpressionToken(null, null, null, "matrix.node"),
|
||||
};
|
||||
|
||||
_actionRunner.Action = action;
|
||||
|
||||
var matrixData = new DictionaryContextData
|
||||
{
|
||||
["node"] = new StringContextData("8")
|
||||
};
|
||||
_context.Add("matrix", matrixData);
|
||||
|
||||
// Act
|
||||
// Should ignore the displayNameToken since there's already an explicit value for DisplayName
|
||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
||||
|
||||
// Assert
|
||||
Assert.True(validDisplayName);
|
||||
Assert.False(updated);
|
||||
Assert.Equal(explicitDisplayName, _actionRunner.DisplayName);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
@@ -251,11 +218,10 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
|
||||
// Act
|
||||
// Should expand the displaynameToken and set the display name to that
|
||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
||||
var didUpdateDisplayName = _actionRunner.TryEvaluateDisplayName(_context, _actionRunner.ExecutionContext);
|
||||
|
||||
// Assert
|
||||
Assert.True(validDisplayName);
|
||||
Assert.True(updated);
|
||||
Assert.True(didUpdateDisplayName);
|
||||
Assert.Equal("Run 8", _actionRunner.DisplayName);
|
||||
}
|
||||
|
||||
@@ -280,11 +246,10 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
|
||||
// Act
|
||||
// Should expand the displaynameToken and set the display name to that
|
||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
||||
var didUpdateDisplayName = _actionRunner.TryEvaluateDisplayName(_context, _actionRunner.ExecutionContext);
|
||||
|
||||
// Assert
|
||||
Assert.True(validDisplayName);
|
||||
Assert.True(updated);
|
||||
Assert.True(didUpdateDisplayName);
|
||||
Assert.Equal("Run TestImageName:latest", _actionRunner.DisplayName);
|
||||
}
|
||||
|
||||
@@ -307,11 +272,10 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
|
||||
// Act
|
||||
// Should not do anything if we don't have context on the display name
|
||||
var validDisplayName = _actionRunner.EvaluateDisplayName(_context, _actionRunner.ExecutionContext, out bool updated);
|
||||
var didUpdateDisplayName = _actionRunner.TryEvaluateDisplayName(_context, _actionRunner.ExecutionContext);
|
||||
|
||||
// Assert
|
||||
Assert.False(validDisplayName);
|
||||
Assert.False(updated);
|
||||
Assert.False(didUpdateDisplayName);
|
||||
// Should use the pretty display name until we can eval
|
||||
Assert.Equal("${{ matrix.node }}", _actionRunner.DisplayName);
|
||||
}
|
||||
|
||||
@@ -99,46 +99,6 @@ 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" });
|
||||
@@ -151,6 +111,7 @@ 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);
|
||||
|
||||
|
||||
@@ -711,63 +711,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void PublishStepResult_EmbeddedStep()
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
// Arrange: Create a job request message.
|
||||
TaskOrchestrationPlanReference plan = new();
|
||||
TimelineReference timeline = new();
|
||||
Guid jobId = Guid.NewGuid();
|
||||
string jobName = "some job name";
|
||||
var jobRequest = new Pipelines.AgentJobRequestMessage(plan, timeline, jobId, jobName, jobName, null, null, null, new Dictionary<string, VariableValue>(), new List<MaskHint>(), new Pipelines.JobResources(), new Pipelines.ContextData.DictionaryContextData(), new Pipelines.WorkspaceOptions(), new List<Pipelines.ActionStep>(), null, null, null, null);
|
||||
jobRequest.Resources.Repositories.Add(new Pipelines.RepositoryResource()
|
||||
{
|
||||
Alias = Pipelines.PipelineConstants.SelfAlias,
|
||||
Id = "github",
|
||||
Version = "sha1"
|
||||
});
|
||||
jobRequest.ContextData["github"] = new Pipelines.ContextData.DictionaryContextData();
|
||||
|
||||
// Arrange: Setup the paging logger.
|
||||
var pagingLogger = new Mock<IPagingLogger>();
|
||||
var pagingLogger2 = new Mock<IPagingLogger>();
|
||||
var jobServerQueue = new Mock<IJobServerQueue>();
|
||||
jobServerQueue.Setup(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.IsAny<TimelineRecord>()));
|
||||
|
||||
hc.EnqueueInstance(pagingLogger.Object);
|
||||
hc.EnqueueInstance(pagingLogger2.Object);
|
||||
hc.SetSingleton(jobServerQueue.Object);
|
||||
|
||||
var ec = new Runner.Worker.ExecutionContext();
|
||||
ec.Initialize(hc);
|
||||
|
||||
// Act.
|
||||
ec.InitializeJob(jobRequest, CancellationToken.None);
|
||||
ec.Start();
|
||||
|
||||
var embeddedStep = ec.CreateChild(Guid.NewGuid(), "action_1_pre", "action_1_pre", null, null, ActionRunStage.Main, isEmbedded: true);
|
||||
embeddedStep.Start();
|
||||
|
||||
embeddedStep.StepTelemetry.Type = "node16";
|
||||
embeddedStep.StepTelemetry.Action = "actions/checkout";
|
||||
embeddedStep.StepTelemetry.Ref = "v2";
|
||||
|
||||
embeddedStep.AddIssue(new Issue() { Type = IssueType.Error, Message = "error" });
|
||||
embeddedStep.AddIssue(new Issue() { Type = IssueType.Warning, Message = "warning" });
|
||||
embeddedStep.AddIssue(new Issue() { Type = IssueType.Notice, Message = "notice" });
|
||||
|
||||
ec.Complete();
|
||||
|
||||
// Assert.
|
||||
Assert.Equal(1, ec.Global.StepsResult.Count);
|
||||
Assert.Equal(TaskResult.Succeeded, ec.Global.StepsResult.Single().Conclusion);
|
||||
}
|
||||
}
|
||||
|
||||
private TestHostContext CreateTestContext([CallerMemberName] String testName = "")
|
||||
{
|
||||
var hc = new TestHostContext(this, testName);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using GitHub.Actions.RunService.WebApi;
|
||||
using GitHub.DistributedTask.Pipelines;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Sdk;
|
||||
|
||||
@@ -16,10 +16,9 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
private IExecutionContext _jobEc;
|
||||
private JobRunner _jobRunner;
|
||||
private List<IStep> _initResult = new();
|
||||
private Pipelines.AgentJobRequestMessage _message;
|
||||
private CancellationTokenSource _tokenSource;
|
||||
private Mock<IJobServer> _jobServer;
|
||||
|
||||
private Mock<IRunServer> _runServer;
|
||||
private Mock<IJobServerQueue> _jobServerQueue;
|
||||
private Mock<IConfigurationStore> _config;
|
||||
private Mock<IExtensionManager> _extensions;
|
||||
@@ -39,7 +38,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
_extensions = new Mock<IExtensionManager>();
|
||||
_jobExtension = new Mock<IJobExtension>();
|
||||
_jobServer = new Mock<IJobServer>();
|
||||
_runServer = new Mock<IRunServer>();
|
||||
_jobServerQueue = new Mock<IJobServerQueue>();
|
||||
_stepRunner = new Mock<IStepsRunner>();
|
||||
_logger = new Mock<IPagingLogger>();
|
||||
@@ -57,6 +55,33 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
_jobRunner = new JobRunner();
|
||||
_jobRunner.Initialize(hc);
|
||||
|
||||
TaskOrchestrationPlanReference plan = new();
|
||||
TimelineReference timeline = new Timeline(Guid.NewGuid());
|
||||
Guid jobId = Guid.NewGuid();
|
||||
_message = new Pipelines.AgentJobRequestMessage(plan, timeline, jobId, testName, testName, null, null, null, new Dictionary<string, VariableValue>(), new List<MaskHint>(), new Pipelines.JobResources(), new Pipelines.ContextData.DictionaryContextData(), new Pipelines.WorkspaceOptions(), new List<Pipelines.ActionStep>(), null, null, null, null);
|
||||
_message.Variables[Constants.Variables.System.Culture] = "en-US";
|
||||
_message.Resources.Endpoints.Add(new ServiceEndpoint()
|
||||
{
|
||||
Name = WellKnownServiceEndpointNames.SystemVssConnection,
|
||||
Url = new Uri("https://pipelines.actions.githubusercontent.com"),
|
||||
Authorization = new EndpointAuthorization()
|
||||
{
|
||||
Scheme = "Test",
|
||||
Parameters = {
|
||||
{"AccessToken", "token"}
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
_message.Resources.Repositories.Add(new Pipelines.RepositoryResource()
|
||||
{
|
||||
Alias = Pipelines.PipelineConstants.SelfAlias,
|
||||
Id = "github",
|
||||
Version = "sha1"
|
||||
});
|
||||
_message.ContextData.Add("github", new Pipelines.ContextData.DictionaryContextData());
|
||||
|
||||
_initResult.Clear();
|
||||
|
||||
_jobExtension.Setup(x => x.InitializeJob(It.IsAny<IExecutionContext>(), It.IsAny<Pipelines.AgentJobRequestMessage>())).
|
||||
@@ -77,7 +102,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
|
||||
hc.SetSingleton(_config.Object);
|
||||
hc.SetSingleton(_jobServer.Object);
|
||||
hc.SetSingleton(_runServer.Object);
|
||||
hc.SetSingleton(_jobServerQueue.Object);
|
||||
hc.SetSingleton(_stepRunner.Object);
|
||||
hc.SetSingleton(_extensions.Object);
|
||||
@@ -89,43 +113,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
return hc;
|
||||
}
|
||||
|
||||
private Pipelines.AgentJobRequestMessage GetMessage(String messageType = JobRequestMessageTypes.PipelineAgentJobRequest, [CallerMemberName] String testName = "")
|
||||
{
|
||||
TaskOrchestrationPlanReference plan = new();
|
||||
TimelineReference timeline = new Timeline(Guid.NewGuid());
|
||||
Guid jobId = Guid.NewGuid();
|
||||
var message = new Pipelines.AgentJobRequestMessage(
|
||||
plan,
|
||||
timeline,
|
||||
jobId,
|
||||
testName,
|
||||
testName, null, null, null, new Dictionary<string, VariableValue>(), new List<MaskHint>(), new Pipelines.JobResources(), new Pipelines.ContextData.DictionaryContextData(), new Pipelines.WorkspaceOptions(), new List<Pipelines.ActionStep>(), null, null, null, null,
|
||||
messageType: messageType);
|
||||
message.Variables[Constants.Variables.System.Culture] = "en-US";
|
||||
message.Resources.Endpoints.Add(new ServiceEndpoint()
|
||||
{
|
||||
Name = WellKnownServiceEndpointNames.SystemVssConnection,
|
||||
Url = new Uri("https://pipelines.actions.githubusercontent.com"),
|
||||
Authorization = new EndpointAuthorization()
|
||||
{
|
||||
Scheme = "Test",
|
||||
Parameters = {
|
||||
{"AccessToken", "token"}
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
message.Resources.Repositories.Add(new Pipelines.RepositoryResource()
|
||||
{
|
||||
Alias = Pipelines.PipelineConstants.SelfAlias,
|
||||
Id = "github",
|
||||
Version = "sha1"
|
||||
});
|
||||
message.ContextData.Add("github", new Pipelines.ContextData.DictionaryContextData());
|
||||
return message;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
@@ -136,7 +123,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
_jobExtension.Setup(x => x.InitializeJob(It.IsAny<IExecutionContext>(), It.IsAny<Pipelines.AgentJobRequestMessage>()))
|
||||
.Throws(new Exception());
|
||||
|
||||
await _jobRunner.RunAsync(GetMessage(), _tokenSource.Token);
|
||||
await _jobRunner.RunAsync(_message, _tokenSource.Token);
|
||||
|
||||
Assert.Equal(TaskResult.Failed, _jobEc.Result);
|
||||
_stepRunner.Verify(x => x.RunAsync(It.IsAny<IExecutionContext>()), Times.Never);
|
||||
@@ -154,24 +141,11 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
.Throws(new OperationCanceledException());
|
||||
_tokenSource.Cancel();
|
||||
|
||||
await _jobRunner.RunAsync(GetMessage(), _tokenSource.Token);
|
||||
await _jobRunner.RunAsync(_message, _tokenSource.Token);
|
||||
|
||||
Assert.Equal(TaskResult.Canceled, _jobEc.Result);
|
||||
_stepRunner.Verify(x => x.RunAsync(It.IsAny<IExecutionContext>()), Times.Never);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public async Task WorksWithRunnerJobRequestMessageType()
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
var message = GetMessage(JobRequestMessageTypes.RunnerJobRequest);
|
||||
await _jobRunner.RunAsync(message, _tokenSource.Token);
|
||||
Assert.Equal(TaskResult.Succeeded, _jobEc.Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Actions.RunService.WebApi;
|
||||
using GitHub.Runner.Sdk;
|
||||
using GitHub.Runner.Worker;
|
||||
using GitHub.Runner.Worker.Container;
|
||||
|
||||
@@ -22,7 +22,7 @@ DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
|
||||
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
||||
PACKAGE_TRIMS_DIR="$SCRIPT_DIR/../_package_trims"
|
||||
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
||||
DOTNETSDK_VERSION="6.0.405"
|
||||
DOTNETSDK_VERSION="6.0.300"
|
||||
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
|
||||
RUNNER_VERSION=$(cat runnerversion)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "6.0.405"
|
||||
"version": "6.0.300"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.302.1
|
||||
2.300.1
|
||||
|
||||
Reference in New Issue
Block a user