mirror of
https://github.com/actions/runner.git
synced 2025-12-11 12:57:05 +00:00
Compare commits
1 Commits
v2.299.1
...
thboop/fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0508abb77 |
@@ -1,24 +0,0 @@
|
|||||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
|
||||||
{
|
|
||||||
"name": "Actions Runner Devcontainer",
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:focal",
|
|
||||||
"features": {
|
|
||||||
"ghcr.io/devcontainers/features/docker-in-docker:1": {},
|
|
||||||
"ghcr.io/devcontainers/features/dotnet": {
|
|
||||||
"version": "6.0.300"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-azuretools.vscode-docker",
|
|
||||||
"ms-dotnettools.csharp",
|
|
||||||
"eamodio.gitlens"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// dotnet restore to install dependencies so OmniSharp works out of the box
|
|
||||||
// src/Test restores all other projects it references, src/Runner.PluginHost is not one of them
|
|
||||||
"postCreateCommand": "dotnet restore src/Test && dotnet restore src/Runner.PluginHost",
|
|
||||||
"remoteUser": "vscode"
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
# https://editorconfig.org/
|
# https://editorconfig.org/
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8 # Set default charset to utf-8
|
|
||||||
insert_final_newline = true # ensure all files end with a single newline
|
insert_final_newline = true # ensure all files end with a single newline
|
||||||
trim_trailing_whitespace = true # attempt to remove trailing whitespace on save
|
trim_trailing_whitespace = true # attempt to remove trailing whitespace on save
|
||||||
|
|
||||||
|
|||||||
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -10,7 +10,7 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- '**'
|
- '*'
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, win-arm64, osx-x64, osx-arm64 ]
|
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64, osx-arm64 ]
|
||||||
include:
|
include:
|
||||||
- runtime: linux-x64
|
- runtime: linux-x64
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
@@ -44,10 +44,6 @@ jobs:
|
|||||||
os: windows-2019
|
os: windows-2019
|
||||||
devScript: ./dev
|
devScript: ./dev
|
||||||
|
|
||||||
- runtime: win-arm64
|
|
||||||
os: windows-latest
|
|
||||||
devScript: ./dev
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@@ -86,7 +82,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
${{ matrix.devScript }} test
|
${{ matrix.devScript }} test
|
||||||
working-directory: src
|
working-directory: src
|
||||||
if: matrix.runtime != 'linux-arm64' && matrix.runtime != 'linux-arm' && matrix.runtime != 'osx-arm64' && matrix.runtime != 'win-arm64'
|
if: matrix.runtime != 'linux-arm64' && matrix.runtime != 'linux-arm' && matrix.runtime != 'osx-arm64'
|
||||||
|
|
||||||
# Create runner package tar.gz/zip
|
# Create runner package tar.gz/zip
|
||||||
- name: Package Release
|
- name: Package Release
|
||||||
@@ -101,7 +97,7 @@ jobs:
|
|||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: runner-package-${{ matrix.runtime }}
|
name: runner-package-${{ matrix.runtime }}
|
||||||
path: |
|
path: |
|
||||||
_package
|
_package
|
||||||
_package_trims/trim_externals
|
_package_trims/trim_externals
|
||||||
_package_trims/trim_runtime
|
_package_trims/trim_runtime
|
||||||
|
|||||||
25
.github/workflows/lint.yml
vendored
25
.github/workflows/lint.yml
vendored
@@ -1,25 +0,0 @@
|
|||||||
name: Lint
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [ main ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Lint
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
# Ensure full list of changed files within `super-linter`
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Run linters
|
|
||||||
uses: github/super-linter@v4
|
|
||||||
env:
|
|
||||||
DEFAULT_BRANCH: ${{ github.base_ref }}
|
|
||||||
DISABLE_ERRORS: true
|
|
||||||
EDITORCONFIG_FILE_NAME: .editorconfig
|
|
||||||
LINTER_RULES_PATH: /src/
|
|
||||||
VALIDATE_ALL_CODEBASE: false
|
|
||||||
VALIDATE_CSHARP: true
|
|
||||||
77
.github/workflows/release.yml
vendored
77
.github/workflows/release.yml
vendored
@@ -50,33 +50,29 @@ jobs:
|
|||||||
linux-arm64-sha: ${{ steps.sha.outputs.linux-arm64-sha256 }}
|
linux-arm64-sha: ${{ steps.sha.outputs.linux-arm64-sha256 }}
|
||||||
linux-arm-sha: ${{ steps.sha.outputs.linux-arm-sha256 }}
|
linux-arm-sha: ${{ steps.sha.outputs.linux-arm-sha256 }}
|
||||||
win-x64-sha: ${{ steps.sha.outputs.win-x64-sha256 }}
|
win-x64-sha: ${{ steps.sha.outputs.win-x64-sha256 }}
|
||||||
win-arm64-sha: ${{ steps.sha.outputs.win-arm64-sha256 }}
|
|
||||||
osx-x64-sha: ${{ steps.sha.outputs.osx-x64-sha256 }}
|
osx-x64-sha: ${{ steps.sha.outputs.osx-x64-sha256 }}
|
||||||
osx-arm64-sha: ${{ steps.sha.outputs.osx-arm64-sha256 }}
|
osx-arm64-sha: ${{ steps.sha.outputs.osx-arm64-sha256 }}
|
||||||
linux-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-x64-sha256 }}
|
linux-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-x64-sha256 }}
|
||||||
linux-arm64-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-arm64-sha256 }}
|
linux-arm64-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-arm64-sha256 }}
|
||||||
linux-arm-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-arm-sha256 }}
|
linux-arm-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-arm-sha256 }}
|
||||||
win-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.win-x64-sha256 }}
|
win-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.win-x64-sha256 }}
|
||||||
win-arm64-sha-noexternals: ${{ steps.sha_noexternals.outputs.win-arm64-sha256 }}
|
|
||||||
osx-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.osx-x64-sha256 }}
|
osx-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.osx-x64-sha256 }}
|
||||||
osx-arm64-sha-noexternals: ${{ steps.sha_noexternals.outputs.osx-arm64-sha256 }}
|
osx-arm64-sha-noexternals: ${{ steps.sha_noexternals.outputs.osx-arm64-sha256 }}
|
||||||
linux-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-x64-sha256 }}
|
linux-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-x64-sha256 }}
|
||||||
linux-arm64-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-arm64-sha256 }}
|
linux-arm64-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-arm64-sha256 }}
|
||||||
linux-arm-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-arm-sha256 }}
|
linux-arm-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-arm-sha256 }}
|
||||||
win-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.win-x64-sha256 }}
|
win-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.win-x64-sha256 }}
|
||||||
win-arm64-sha-noruntime: ${{ steps.sha_noruntime.outputs.win-arm64-sha256 }}
|
|
||||||
osx-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.osx-x64-sha256 }}
|
osx-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.osx-x64-sha256 }}
|
||||||
osx-arm64-sha-noruntime: ${{ steps.sha_noruntime.outputs.osx-arm64-sha256 }}
|
osx-arm64-sha-noruntime: ${{ steps.sha_noruntime.outputs.osx-arm64-sha256 }}
|
||||||
linux-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-x64-sha256 }}
|
linux-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-x64-sha256 }}
|
||||||
linux-arm64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-arm64-sha256 }}
|
linux-arm64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-arm64-sha256 }}
|
||||||
linux-arm-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-arm-sha256 }}
|
linux-arm-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-arm-sha256 }}
|
||||||
win-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.win-x64-sha256 }}
|
win-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.win-x64-sha256 }}
|
||||||
win-arm64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.win-arm64-sha256 }}
|
|
||||||
osx-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.osx-x64-sha256 }}
|
osx-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.osx-x64-sha256 }}
|
||||||
osx-arm64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.osx-arm64-sha256 }}
|
osx-arm64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.osx-arm64-sha256 }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64, osx-arm64, win-arm64 ]
|
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64, osx-arm64 ]
|
||||||
include:
|
include:
|
||||||
- runtime: linux-x64
|
- runtime: linux-x64
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
@@ -93,7 +89,7 @@ jobs:
|
|||||||
- runtime: osx-x64
|
- runtime: osx-x64
|
||||||
os: macOS-latest
|
os: macOS-latest
|
||||||
devScript: ./dev.sh
|
devScript: ./dev.sh
|
||||||
|
|
||||||
- runtime: osx-arm64
|
- runtime: osx-arm64
|
||||||
os: macOS-latest
|
os: macOS-latest
|
||||||
devScript: ./dev.sh
|
devScript: ./dev.sh
|
||||||
@@ -102,10 +98,6 @@ jobs:
|
|||||||
os: windows-2019
|
os: windows-2019
|
||||||
devScript: ./dev
|
devScript: ./dev
|
||||||
|
|
||||||
- runtime: win-arm64
|
|
||||||
os: windows-latest
|
|
||||||
devScript: ./dev
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@@ -166,9 +158,9 @@ jobs:
|
|||||||
id: sha_noruntime_noexternals
|
id: sha_noruntime_noexternals
|
||||||
name: Compute SHA256
|
name: Compute SHA256
|
||||||
working-directory: _package_trims/trim_runtime_externals
|
working-directory: _package_trims/trim_runtime_externals
|
||||||
|
|
||||||
- name: Create trimmedpackages.json for ${{ matrix.runtime }}
|
- name: Create trimmedpackages.json for ${{ matrix.runtime }}
|
||||||
if: matrix.runtime == 'win-x64' || matrix.runtime == 'win-arm64'
|
if: matrix.runtime == 'win-x64'
|
||||||
uses: actions/github-script@0.3.0
|
uses: actions/github-script@0.3.0
|
||||||
with:
|
with:
|
||||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||||
@@ -188,7 +180,7 @@ jobs:
|
|||||||
fs.writeFileSync('${{ matrix.runtime }}-trimmedpackages.json', trimmedPackages)
|
fs.writeFileSync('${{ matrix.runtime }}-trimmedpackages.json', trimmedPackages)
|
||||||
|
|
||||||
- name: Create trimmedpackages.json for ${{ matrix.runtime }}
|
- name: Create trimmedpackages.json for ${{ matrix.runtime }}
|
||||||
if: matrix.runtime != 'win-x64' && matrix.runtime != 'win-arm64'
|
if: matrix.runtime != 'win-x64'
|
||||||
uses: actions/github-script@0.3.0
|
uses: actions/github-script@0.3.0
|
||||||
with:
|
with:
|
||||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||||
@@ -247,28 +239,24 @@ jobs:
|
|||||||
const runnerVersion = fs.readFileSync('${{ github.workspace }}/src/runnerversion', 'utf8').replace(/\n$/g, '')
|
const runnerVersion = fs.readFileSync('${{ github.workspace }}/src/runnerversion', 'utf8').replace(/\n$/g, '')
|
||||||
var releaseNote = fs.readFileSync('${{ github.workspace }}/releaseNote.md', 'utf8').replace(/<RUNNER_VERSION>/g, runnerVersion)
|
var releaseNote = fs.readFileSync('${{ github.workspace }}/releaseNote.md', 'utf8').replace(/<RUNNER_VERSION>/g, runnerVersion)
|
||||||
releaseNote = releaseNote.replace(/<WIN_X64_SHA>/g, '${{needs.build.outputs.win-x64-sha}}')
|
releaseNote = releaseNote.replace(/<WIN_X64_SHA>/g, '${{needs.build.outputs.win-x64-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA>/g, '${{needs.build.outputs.win-arm64-sha}}')
|
|
||||||
releaseNote = releaseNote.replace(/<OSX_X64_SHA>/g, '${{needs.build.outputs.osx-x64-sha}}')
|
releaseNote = releaseNote.replace(/<OSX_X64_SHA>/g, '${{needs.build.outputs.osx-x64-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA>/g, '${{needs.build.outputs.osx-arm64-sha}}')
|
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA>/g, '${{needs.build.outputs.osx-arm64-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_X64_SHA>/g, '${{needs.build.outputs.linux-x64-sha}}')
|
releaseNote = releaseNote.replace(/<LINUX_X64_SHA>/g, '${{needs.build.outputs.linux-x64-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA>/g, '${{needs.build.outputs.linux-arm-sha}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA>/g, '${{needs.build.outputs.linux-arm-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA>/g, '${{needs.build.outputs.linux-arm64-sha}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA>/g, '${{needs.build.outputs.linux-arm64-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.win-x64-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.win-x64-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.win-arm64-sha-noexternals}}')
|
|
||||||
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.osx-x64-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.osx-x64-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.osx-arm64-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.osx-arm64-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-x64-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-x64-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm64-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm64-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.win-x64-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.win-x64-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.win-arm64-sha-noruntime}}')
|
|
||||||
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.osx-x64-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.osx-x64-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.osx-arm64-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.osx-arm64-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-x64-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-x64-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-arm-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-arm-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-arm64-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-arm64-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.win-x64-sha-noruntime-noexternals}}')
|
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.win-x64-sha-noruntime-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.win-arm64-sha-noruntime-noexternals}}')
|
|
||||||
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.osx-x64-sha-noruntime-noexternals}}')
|
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.osx-x64-sha-noruntime-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.osx-arm64-sha-noruntime-noexternals}}')
|
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.osx-arm64-sha-noruntime-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.linux-x64-sha-noruntime-noexternals}}')
|
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.linux-x64-sha-noruntime-noexternals}}')
|
||||||
@@ -283,7 +271,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
ls -l
|
ls -l
|
||||||
echo "${{needs.build.outputs.win-x64-sha}} actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip" | shasum -a 256 -c
|
echo "${{needs.build.outputs.win-x64-sha}} actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip" | shasum -a 256 -c
|
||||||
echo "${{needs.build.outputs.win-arm64-sha}} actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}.zip" | shasum -a 256 -c
|
|
||||||
echo "${{needs.build.outputs.osx-x64-sha}} actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
|
echo "${{needs.build.outputs.osx-x64-sha}} actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
|
||||||
echo "${{needs.build.outputs.osx-arm64-sha}} actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
|
echo "${{needs.build.outputs.osx-arm64-sha}} actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
|
||||||
echo "${{needs.build.outputs.linux-x64-sha}} actions-runner-linux-x64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
|
echo "${{needs.build.outputs.linux-x64-sha}} actions-runner-linux-x64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
|
||||||
@@ -313,16 +300,6 @@ jobs:
|
|||||||
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip
|
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
- name: Upload Release Asset (win-arm64)
|
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/_package/actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}.zip
|
|
||||||
asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}.zip
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Release Asset (linux-x64)
|
- name: Upload Release Asset (linux-x64)
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
env:
|
env:
|
||||||
@@ -384,17 +361,6 @@ jobs:
|
|||||||
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noexternals.zip
|
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noexternals.zip
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
# Upload release assets (trim externals)
|
|
||||||
- name: Upload Release Asset (win-arm64-noexternals)
|
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/_package_trims/trim_externals/actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noexternals.zip
|
|
||||||
asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noexternals.zip
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Release Asset (linux-x64-noexternals)
|
- name: Upload Release Asset (linux-x64-noexternals)
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
env:
|
env:
|
||||||
@@ -456,17 +422,6 @@ jobs:
|
|||||||
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noruntime.zip
|
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noruntime.zip
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
# Upload release assets (trim runtime)
|
|
||||||
- name: Upload Release Asset (win-arm64-noruntime)
|
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/_package_trims/trim_runtime/actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noruntime.zip
|
|
||||||
asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noruntime.zip
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Release Asset (linux-x64-noruntime)
|
- name: Upload Release Asset (linux-x64-noruntime)
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
env:
|
env:
|
||||||
@@ -528,17 +483,6 @@ jobs:
|
|||||||
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.zip
|
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.zip
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
# Upload release assets (trim runtime and externals)
|
|
||||||
- name: Upload Release Asset (win-arm64-noruntime-noexternals)
|
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/_package_trims/trim_runtime_externals/actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.zip
|
|
||||||
asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.zip
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Release Asset (linux-x64-noruntime-noexternals)
|
- name: Upload Release Asset (linux-x64-noruntime-noexternals)
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
env:
|
env:
|
||||||
@@ -600,17 +544,6 @@ jobs:
|
|||||||
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json
|
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
# Upload release assets (trimmedpackages.json)
|
|
||||||
- name: Upload Release Asset (win-arm64-trimmedpackages.json)
|
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/win-arm64-trimmedpackages.json
|
|
||||||
asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Release Asset (linux-x64-trimmedpackages.json)
|
- name: Upload Release Asset (linux-x64-trimmedpackages.json)
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -64,4 +64,4 @@ Make sure the runner has access to actions service for GitHub.com or GitHub Ente
|
|||||||
|
|
||||||
## Still not working?
|
## Still not working?
|
||||||
|
|
||||||
Contact [GitHub Support](https://support.github.com) if you have further questuons, or log an issue at https://github.com/actions/runner if you think it's a runner issue.
|
Contact [GitHub Support](https://support.github.com] if you have further questuons, or log an issue at https://github.com/actions/runner if you think it's a runner issue.
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ An ADR is an Architectural Decision Record. This allows consensus on the direct
|
|||||||
|
|
||||||
 Visual Studio 2017 or newer [Install here](https://visualstudio.microsoft.com) (needed for dev sh script)
|
 Visual Studio 2017 or newer [Install here](https://visualstudio.microsoft.com) (needed for dev sh script)
|
||||||
|
|
||||||
 Visual Studio 2022 17.3 Preview or later. [Install here](https://docs.microsoft.com/en-us/visualstudio/releases/2022/release-notes-preview)
|
|
||||||
|
|
||||||
## Quickstart: Run a job from a real repository
|
## Quickstart: Run a job from a real repository
|
||||||
|
|
||||||
If you just want to get from building the sourcecode to using it to execute an action, you will need:
|
If you just want to get from building the sourcecode to using it to execute an action, you will need:
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
## Features
|
|
||||||
- Displays the error logs in dedicated sub-sections of the Initialize containers section (#2182)
|
|
||||||
- Add generateServiceConfig option for configure command (#2226)
|
|
||||||
- Setting debug using GitHub Action variables (#2234)
|
|
||||||
- run.sh installs SIGINT and SIGTERM traps to gracefully stop runner (#2233, 2240)
|
|
||||||
|
|
||||||
|
|
||||||
## Bugs
|
## Bugs
|
||||||
- Use Global.Variables instead of JobContext and include action path/ref in the message. (#2214)
|
- Fixed an issue where job and service container envs were corrupted (#2091)
|
||||||
|
|
||||||
## Misc
|
## Misc
|
||||||
- Allow '--disableupdate' in create-latest-svc.sh (#2201)
|
|
||||||
- Fix markup for support link (#2114)
|
|
||||||
- Add runner devcontainer (#2187)
|
|
||||||
- Setup linter for Runner (#2211, #2213, #2216)
|
|
||||||
|
|
||||||
## Windows x64
|
## 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.
|
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.
|
||||||
@@ -28,22 +16,6 @@ Add-Type -AssemblyName System.IO.Compression.FileSystem ;
|
|||||||
[System.IO.Compression.ZipFile]::ExtractToDirectory("$PWD\actions-runner-win-x64-<RUNNER_VERSION>.zip", "$PWD")
|
[System.IO.Compression.ZipFile]::ExtractToDirectory("$PWD\actions-runner-win-x64-<RUNNER_VERSION>.zip", "$PWD")
|
||||||
```
|
```
|
||||||
|
|
||||||
## [Pre-release] Windows arm64
|
|
||||||
**Warning:** Windows arm64 runners are currently in preview status and use [unofficial versions of nodejs](https://unofficial-builds.nodejs.org/). They are not intended for production workflows.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
The following snipped needs to be run on `powershell`:
|
|
||||||
``` powershell
|
|
||||||
# Create a folder under the drive root
|
|
||||||
mkdir \actions-runner ; cd \actions-runner
|
|
||||||
# Download the latest runner package
|
|
||||||
Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-win-arm64-<RUNNER_VERSION>.zip -OutFile actions-runner-win-arm64-<RUNNER_VERSION>.zip
|
|
||||||
# Extract the installer
|
|
||||||
Add-Type -AssemblyName System.IO.Compression.FileSystem ;
|
|
||||||
[System.IO.Compression.ZipFile]::ExtractToDirectory("$PWD\actions-runner-win-arm64-<RUNNER_VERSION>.zip", "$PWD")
|
|
||||||
```
|
|
||||||
|
|
||||||
## OSX x64
|
## OSX x64
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
@@ -107,7 +79,6 @@ For additional details about configuring, running, or shutting down the runner p
|
|||||||
The SHA-256 checksums for the packages included in this build are shown below:
|
The SHA-256 checksums for the packages included in this build are shown below:
|
||||||
|
|
||||||
- actions-runner-win-x64-<RUNNER_VERSION>.zip <!-- BEGIN SHA win-x64 --><WIN_X64_SHA><!-- END SHA win-x64 -->
|
- actions-runner-win-x64-<RUNNER_VERSION>.zip <!-- BEGIN SHA win-x64 --><WIN_X64_SHA><!-- END SHA win-x64 -->
|
||||||
- actions-runner-win-arm64-<RUNNER_VERSION>.zip <!-- BEGIN SHA win-arm64 --><WIN_ARM64_SHA><!-- END SHA win-arm64 -->
|
|
||||||
- actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA osx-x64 --><OSX_X64_SHA><!-- END SHA osx-x64 -->
|
- actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA osx-x64 --><OSX_X64_SHA><!-- END SHA osx-x64 -->
|
||||||
- actions-runner-osx-arm64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA osx-arm64 --><OSX_ARM64_SHA><!-- END SHA osx-arm64 -->
|
- actions-runner-osx-arm64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA osx-arm64 --><OSX_ARM64_SHA><!-- END SHA osx-arm64 -->
|
||||||
- actions-runner-linux-x64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA linux-x64 --><LINUX_X64_SHA><!-- END SHA linux-x64 -->
|
- actions-runner-linux-x64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA linux-x64 --><LINUX_X64_SHA><!-- END SHA linux-x64 -->
|
||||||
@@ -115,7 +86,6 @@ The SHA-256 checksums for the packages included in this build are shown below:
|
|||||||
- actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA linux-arm --><LINUX_ARM_SHA><!-- END SHA linux-arm -->
|
- actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA linux-arm --><LINUX_ARM_SHA><!-- END SHA linux-arm -->
|
||||||
|
|
||||||
- actions-runner-win-x64-<RUNNER_VERSION>-noexternals.zip <!-- BEGIN SHA win-x64_noexternals --><WIN_X64_SHA_NOEXTERNALS><!-- END SHA win-x64_noexternals -->
|
- actions-runner-win-x64-<RUNNER_VERSION>-noexternals.zip <!-- BEGIN SHA win-x64_noexternals --><WIN_X64_SHA_NOEXTERNALS><!-- END SHA win-x64_noexternals -->
|
||||||
- actions-runner-win-arm64-<RUNNER_VERSION>-noexternals.zip <!-- BEGIN SHA win-arm64_noexternals --><WIN_ARM64_SHA_NOEXTERNALS><!-- END SHA win-arm64_noexternals -->
|
|
||||||
- actions-runner-osx-x64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA osx-x64_noexternals --><OSX_X64_SHA_NOEXTERNALS><!-- END SHA osx-x64_noexternals -->
|
- actions-runner-osx-x64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA osx-x64_noexternals --><OSX_X64_SHA_NOEXTERNALS><!-- END SHA osx-x64_noexternals -->
|
||||||
- actions-runner-osx-arm64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA osx-arm64_noexternals --><OSX_ARM64_SHA_NOEXTERNALS><!-- END SHA osx-arm64_noexternals -->
|
- actions-runner-osx-arm64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA osx-arm64_noexternals --><OSX_ARM64_SHA_NOEXTERNALS><!-- END SHA osx-arm64_noexternals -->
|
||||||
- actions-runner-linux-x64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA linux-x64_noexternals --><LINUX_X64_SHA_NOEXTERNALS><!-- END SHA linux-x64_noexternals -->
|
- actions-runner-linux-x64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA linux-x64_noexternals --><LINUX_X64_SHA_NOEXTERNALS><!-- END SHA linux-x64_noexternals -->
|
||||||
@@ -123,7 +93,6 @@ The SHA-256 checksums for the packages included in this build are shown below:
|
|||||||
- actions-runner-linux-arm-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA linux-arm_noexternals --><LINUX_ARM_SHA_NOEXTERNALS><!-- END SHA linux-arm_noexternals -->
|
- actions-runner-linux-arm-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA linux-arm_noexternals --><LINUX_ARM_SHA_NOEXTERNALS><!-- END SHA linux-arm_noexternals -->
|
||||||
|
|
||||||
- actions-runner-win-x64-<RUNNER_VERSION>-noruntime.zip <!-- BEGIN SHA win-x64_noruntime --><WIN_X64_SHA_NORUNTIME><!-- END SHA win-x64_noruntime -->
|
- actions-runner-win-x64-<RUNNER_VERSION>-noruntime.zip <!-- BEGIN SHA win-x64_noruntime --><WIN_X64_SHA_NORUNTIME><!-- END SHA win-x64_noruntime -->
|
||||||
- actions-runner-win-arm64-<RUNNER_VERSION>-noruntime.zip <!-- BEGIN SHA win-arm64_noruntime --><WIN_ARM64_SHA_NORUNTIME><!-- END SHA win-arm64_noruntime -->
|
|
||||||
- actions-runner-osx-x64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA osx-x64_noruntime --><OSX_X64_SHA_NORUNTIME><!-- END SHA osx-x64_noruntime -->
|
- actions-runner-osx-x64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA osx-x64_noruntime --><OSX_X64_SHA_NORUNTIME><!-- END SHA osx-x64_noruntime -->
|
||||||
- actions-runner-osx-arm64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA osx-arm64_noruntime --><OSX_ARM64_SHA_NORUNTIME><!-- END SHA osx-arm64_noruntime -->
|
- actions-runner-osx-arm64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA osx-arm64_noruntime --><OSX_ARM64_SHA_NORUNTIME><!-- END SHA osx-arm64_noruntime -->
|
||||||
- actions-runner-linux-x64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA linux-x64_noruntime --><LINUX_X64_SHA_NORUNTIME><!-- END SHA linux-x64_noruntime -->
|
- actions-runner-linux-x64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA linux-x64_noruntime --><LINUX_X64_SHA_NORUNTIME><!-- END SHA linux-x64_noruntime -->
|
||||||
@@ -131,7 +100,6 @@ The SHA-256 checksums for the packages included in this build are shown below:
|
|||||||
- actions-runner-linux-arm-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA linux-arm_noruntime --><LINUX_ARM_SHA_NORUNTIME><!-- END SHA linux-arm_noruntime -->
|
- actions-runner-linux-arm-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA linux-arm_noruntime --><LINUX_ARM_SHA_NORUNTIME><!-- END SHA linux-arm_noruntime -->
|
||||||
|
|
||||||
- actions-runner-win-x64-<RUNNER_VERSION>-noruntime-noexternals.zip <!-- BEGIN SHA win-x64_noruntime_noexternals --><WIN_X64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA win-x64_noruntime_noexternals -->
|
- actions-runner-win-x64-<RUNNER_VERSION>-noruntime-noexternals.zip <!-- BEGIN SHA win-x64_noruntime_noexternals --><WIN_X64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA win-x64_noruntime_noexternals -->
|
||||||
- actions-runner-win-arm64-<RUNNER_VERSION>-noruntime-noexternals.zip <!-- BEGIN SHA win-arm64_noruntime_noexternals --><WIN_ARM64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA win-arm64_noruntime_noexternals -->
|
|
||||||
- actions-runner-osx-x64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA osx-x64_noruntime_noexternals --><OSX_X64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA osx-x64_noruntime_noexternals -->
|
- actions-runner-osx-x64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA osx-x64_noruntime_noexternals --><OSX_X64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA osx-x64_noruntime_noexternals -->
|
||||||
- actions-runner-osx-arm64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA osx-arm64_noruntime_noexternals --><OSX_ARM64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA osx-arm64_noruntime_noexternals -->
|
- actions-runner-osx-arm64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA osx-arm64_noruntime_noexternals --><OSX_ARM64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA osx-arm64_noruntime_noexternals -->
|
||||||
- actions-runner-linux-x64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA linux-x64_noruntime_noexternals --><LINUX_X64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA linux-x64_noruntime_noexternals -->
|
- actions-runner-linux-x64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA linux-x64_noruntime_noexternals --><LINUX_X64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA linux-x64_noruntime_noexternals -->
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.299.1
|
<Update to ./src/runnerversion when creating release>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ set -e
|
|||||||
|
|
||||||
flags_found=false
|
flags_found=false
|
||||||
|
|
||||||
while getopts 's:g:n:r:u:l:d' opt; do
|
while getopts 's:g:n:r:u:l:' opt; do
|
||||||
flags_found=true
|
flags_found=true
|
||||||
|
|
||||||
case $opt in
|
case $opt in
|
||||||
@@ -35,9 +35,6 @@ while getopts 's:g:n:r:u:l:d' opt; do
|
|||||||
l)
|
l)
|
||||||
labels=$OPTARG
|
labels=$OPTARG
|
||||||
;;
|
;;
|
||||||
d)
|
|
||||||
disableupdate='true'
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
echo "
|
echo "
|
||||||
Runner Service Installer
|
Runner Service Installer
|
||||||
@@ -52,8 +49,7 @@ Usage:
|
|||||||
-n optional name of the runner, defaults to hostname
|
-n optional name of the runner, defaults to hostname
|
||||||
-r optional name of the runner group to add the runner to, defaults to the Default group
|
-r optional name of the runner group to add the runner to, defaults to the Default group
|
||||||
-u optional user svc will run as, defaults to current
|
-u optional user svc will run as, defaults to current
|
||||||
-l optional list of labels (split by comma) applied on the runner
|
-l optional list of labels (split by comma) applied on the runner"
|
||||||
-d optional allow runner to remain on the current version for one month after the release of a newer version"
|
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -173,8 +169,8 @@ fi
|
|||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Configuring ${runner_name} @ $runner_url"
|
echo "Configuring ${runner_name} @ $runner_url"
|
||||||
echo "./config.sh --unattended --url $runner_url --token *** --name $runner_name ${labels:+--labels $labels} ${runner_group:+--runnergroup \"$runner_group\"} ${disableupdate:+--disableupdate}"
|
echo "./config.sh --unattended --url $runner_url --token *** --name $runner_name ${labels:+--labels $labels} ${runner_group:+--runnergroup \"$runner_group\"}"
|
||||||
sudo -E -u ${svc_user} ./config.sh --unattended --url $runner_url --token $RUNNER_TOKEN --name $runner_name ${labels:+--labels $labels} ${runner_group:+--runnergroup "$runner_group"} ${disableupdate:+--disableupdate}
|
sudo -E -u ${svc_user} ./config.sh --unattended --url $runner_url --token $RUNNER_TOKEN --name $runner_name ${labels:+--labels $labels} ${runner_group:+--runnergroup "$runner_group"}
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
# Configuring as a service
|
# Configuring as a service
|
||||||
|
|||||||
@@ -24,9 +24,6 @@
|
|||||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Windows' AND '$(PackageRuntime)' == 'win-x86'">
|
<PropertyGroup Condition="'$(BUILD_OS)' == 'Windows' AND '$(PackageRuntime)' == 'win-x86'">
|
||||||
<DefineConstants>$(DefineConstants);X86</DefineConstants>
|
<DefineConstants>$(DefineConstants);X86</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Windows' AND '$(PackageRuntime)' == 'win-arm64'">
|
|
||||||
<DefineConstants>$(DefineConstants);ARM64</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'OSX' AND '$(PackageRuntime)' == 'osx-x64'">
|
<PropertyGroup Condition="'$(BUILD_OS)' == 'OSX' AND '$(PackageRuntime)' == 'osx-x64'">
|
||||||
<DefineConstants>$(DefineConstants);X64</DefineConstants>
|
<DefineConstants>$(DefineConstants);X64</DefineConstants>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
39d0683f0f115a211cb10c473e9574c16549a19d4e9a6c637ded3d7022bf809f
|
|
||||||
1
src/Misc/contentHash/externals/win-arm64
vendored
1
src/Misc/contentHash/externals/win-arm64
vendored
@@ -1 +0,0 @@
|
|||||||
e5dace2d41cc0682d096dcce4970079ad48ec7107e46195970eecfdb3df2acef
|
|
||||||
@@ -1,4 +1 @@
|
|||||||
To compile this package (output will be stored in `Misc/layoutbin`) run `npm install && npm run all`.
|
To update hashFiles under `Misc/layoutbin` run `npm install && npm run all`
|
||||||
|
|
||||||
> Note: this package also needs to be recompiled for dependabot PRs updating one of
|
|
||||||
> its dependencies.
|
|
||||||
62
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
62
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
@@ -22,13 +22,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/core": {
|
"node_modules/@actions/core": {
|
||||||
"version": "1.9.1",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz",
|
||||||
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
|
"integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA=="
|
||||||
"dependencies": {
|
|
||||||
"@actions/http-client": "^2.0.1",
|
|
||||||
"uuid": "^8.3.2"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/@actions/glob": {
|
"node_modules/@actions/glob": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
@@ -39,14 +35,6 @@
|
|||||||
"minimatch": "^3.0.4"
|
"minimatch": "^3.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/http-client": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
|
||||||
"dependencies": {
|
|
||||||
"tunnel": "^0.0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@eslint/eslintrc": {
|
"node_modules/@eslint/eslintrc": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
|
||||||
@@ -2393,14 +2381,6 @@
|
|||||||
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
|
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tunnel": {
|
|
||||||
"version": "0.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
|
||||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/type-check": {
|
"node_modules/type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
@@ -2462,14 +2442,6 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
|
||||||
"version": "8.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
|
||||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
|
||||||
"bin": {
|
|
||||||
"uuid": "dist/bin/uuid"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/v8-compile-cache": {
|
"node_modules/v8-compile-cache": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
|
||||||
@@ -2531,13 +2503,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": {
|
"@actions/core": {
|
||||||
"version": "1.9.1",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz",
|
||||||
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
|
"integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA=="
|
||||||
"requires": {
|
|
||||||
"@actions/http-client": "^2.0.1",
|
|
||||||
"uuid": "^8.3.2"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"@actions/glob": {
|
"@actions/glob": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
@@ -2548,14 +2516,6 @@
|
|||||||
"minimatch": "^3.0.4"
|
"minimatch": "^3.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@actions/http-client": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
|
||||||
"requires": {
|
|
||||||
"tunnel": "^0.0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@eslint/eslintrc": {
|
"@eslint/eslintrc": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
|
||||||
@@ -4229,11 +4189,6 @@
|
|||||||
"tslib": "^1.8.1"
|
"tslib": "^1.8.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tunnel": {
|
|
||||||
"version": "0.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
|
||||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
|
||||||
},
|
|
||||||
"type-check": {
|
"type-check": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||||
@@ -4276,11 +4231,6 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"uuid": {
|
|
||||||
"version": "8.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
|
||||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
|
||||||
},
|
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ PACKAGERUNTIME=$1
|
|||||||
PRECACHE=$2
|
PRECACHE=$2
|
||||||
|
|
||||||
NODE_URL=https://nodejs.org/dist
|
NODE_URL=https://nodejs.org/dist
|
||||||
UNOFFICIAL_NODE_URL=https://unofficial-builds.nodejs.org/download/release
|
|
||||||
NODE12_VERSION="12.22.7"
|
NODE12_VERSION="12.22.7"
|
||||||
NODE16_VERSION="16.13.0"
|
NODE16_VERSION="16.13.0"
|
||||||
|
|
||||||
@@ -135,16 +134,6 @@ if [[ "$PACKAGERUNTIME" == "win-x64" || "$PACKAGERUNTIME" == "win-x86" ]]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Download the external tools only for Windows.
|
|
||||||
if [[ "$PACKAGERUNTIME" == "win-arm64" ]]; then
|
|
||||||
# todo: replace these with official release when available
|
|
||||||
acquireExternalTool "$UNOFFICIAL_NODE_URL/v${NODE16_VERSION}/$PACKAGERUNTIME/node.exe" node16/bin
|
|
||||||
acquireExternalTool "$UNOFFICIAL_NODE_URL/v${NODE16_VERSION}/$PACKAGERUNTIME/node.lib" node16/bin
|
|
||||||
if [[ "$PRECACHE" != "" ]]; then
|
|
||||||
acquireExternalTool "https://github.com/microsoft/vswhere/releases/download/2.6.7/vswhere.exe" vswhere
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Download the external tools only for OSX.
|
# Download the external tools only for OSX.
|
||||||
if [[ "$PACKAGERUNTIME" == "osx-x64" ]]; then
|
if [[ "$PACKAGERUNTIME" == "osx-x64" ]]; then
|
||||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-darwin-x64.tar.gz" node12 fix_nested_dir
|
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-darwin-x64.tar.gz" node12 fix_nested_dir
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,52 +9,16 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
|
|||||||
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||||
done
|
done
|
||||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
# run the helper process which keep the listener alive
|
||||||
run() {
|
while :;
|
||||||
# run the helper process which keep the listener alive
|
do
|
||||||
while :;
|
cp -f "$DIR"/run-helper.sh.template "$DIR"/run-helper.sh
|
||||||
do
|
"$DIR"/run-helper.sh $*
|
||||||
cp -f "$DIR"/run-helper.sh.template "$DIR"/run-helper.sh
|
returnCode=$?
|
||||||
"$DIR"/run-helper.sh $*
|
if [[ $returnCode -eq 2 ]]; then
|
||||||
returnCode=$?
|
echo "Restarting runner..."
|
||||||
if [[ $returnCode -eq 2 ]]; then
|
else
|
||||||
echo "Restarting runner..."
|
echo "Exiting runner..."
|
||||||
else
|
exit 0
|
||||||
echo "Exiting runner..."
|
fi
|
||||||
exit 0
|
done
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
runWithManualTrap() {
|
|
||||||
# Set job control
|
|
||||||
set -m
|
|
||||||
|
|
||||||
trap 'kill -INT -$PID' INT TERM
|
|
||||||
|
|
||||||
# run the helper process which keep the listener alive
|
|
||||||
while :;
|
|
||||||
do
|
|
||||||
cp -f "$DIR"/run-helper.sh.template "$DIR"/run-helper.sh
|
|
||||||
"$DIR"/run-helper.sh $* &
|
|
||||||
PID=$!
|
|
||||||
wait -f $PID
|
|
||||||
returnCode=$?
|
|
||||||
if [[ $returnCode -eq 2 ]]; then
|
|
||||||
echo "Restarting runner..."
|
|
||||||
else
|
|
||||||
echo "Exiting runner..."
|
|
||||||
# Unregister signal handling before exit
|
|
||||||
trap - INT TERM
|
|
||||||
# wait for last parts to be logged
|
|
||||||
wait $PID
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
if [[ -z "$RUNNER_MANUALLY_TRAP_SIG" ]]; then
|
|
||||||
run $*
|
|
||||||
else
|
|
||||||
runWithManualTrap $*
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -66,14 +66,12 @@ libmscordbi.dylib
|
|||||||
libmscordbi.so
|
libmscordbi.so
|
||||||
Microsoft.CSharp.dll
|
Microsoft.CSharp.dll
|
||||||
Microsoft.DiaSymReader.Native.amd64.dll
|
Microsoft.DiaSymReader.Native.amd64.dll
|
||||||
Microsoft.DiaSymReader.Native.arm64.dll
|
|
||||||
Microsoft.VisualBasic.Core.dll
|
Microsoft.VisualBasic.Core.dll
|
||||||
Microsoft.VisualBasic.dll
|
Microsoft.VisualBasic.dll
|
||||||
Microsoft.Win32.Primitives.dll
|
Microsoft.Win32.Primitives.dll
|
||||||
Microsoft.Win32.Registry.dll
|
Microsoft.Win32.Registry.dll
|
||||||
mscordaccore.dll
|
mscordaccore.dll
|
||||||
mscordaccore_amd64_amd64_6.0.522.21309.dll
|
mscordaccore_amd64_amd64_6.0.522.21309.dll
|
||||||
mscordaccore_arm64_arm64_6.0.522.21309.dll
|
|
||||||
mscordbi.dll
|
mscordbi.dll
|
||||||
mscorlib.dll
|
mscorlib.dll
|
||||||
mscorrc.debug.dll
|
mscorrc.debug.dll
|
||||||
@@ -263,4 +261,4 @@ System.Xml.XmlSerializer.dll
|
|||||||
System.Xml.XPath.dll
|
System.Xml.XPath.dll
|
||||||
System.Xml.XPath.XDocument.dll
|
System.Xml.XPath.XDocument.dll
|
||||||
ucrtbase.dll
|
ucrtbase.dll
|
||||||
WindowsBase.dll
|
WindowsBase.dll
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -31,7 +32,7 @@ namespace GitHub.Runner.Common
|
|||||||
new EscapeMapping(token: "%", replacement: "%25"),
|
new EscapeMapping(token: "%", replacement: "%25"),
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly Dictionary<string, string> _properties = new(StringComparer.OrdinalIgnoreCase);
|
private readonly Dictionary<string, string> _properties = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
public const string Prefix = "##[";
|
public const string Prefix = "##[";
|
||||||
public const string _commandKey = "::";
|
public const string _commandKey = "::";
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
{
|
{
|
||||||
public enum ActionResult
|
public enum ActionResult
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using GitHub.DistributedTask.Pipelines;
|
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
using GitHub.Services.Common;
|
|
||||||
using GitHub.Services.WebApi;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
|
||||||
{
|
|
||||||
[ServiceLocator(Default = typeof(ActionsRunServer))]
|
|
||||||
public interface IActionsRunServer : IRunnerService
|
|
||||||
{
|
|
||||||
Task ConnectAsync(Uri serverUrl, VssCredentials credentials);
|
|
||||||
|
|
||||||
Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class ActionsRunServer : RunnerService, IActionsRunServer
|
|
||||||
{
|
|
||||||
private bool _hasConnection;
|
|
||||||
private VssConnection _connection;
|
|
||||||
private TaskAgentHttpClient _taskAgentClient;
|
|
||||||
|
|
||||||
public async Task ConnectAsync(Uri serverUrl, VssCredentials credentials)
|
|
||||||
{
|
|
||||||
_connection = await EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(100));
|
|
||||||
_taskAgentClient = _connection.GetClient<TaskAgentHttpClient>();
|
|
||||||
_hasConnection = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckConnection()
|
|
||||||
{
|
|
||||||
if (!_hasConnection)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"SetConnection");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
CheckConnection();
|
|
||||||
var jobMessage = RetryRequest<AgentJobRequestMessage>(async () =>
|
|
||||||
{
|
|
||||||
return await _taskAgentClient.GetJobMessageAsync(id, cancellationToken);
|
|
||||||
}, cancellationToken);
|
|
||||||
|
|
||||||
return jobMessage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using GitHub.DistributedTask.Logging;
|
using GitHub.DistributedTask.Logging;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -74,18 +75,17 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Uri accountUri = new(this.ServerUrl);
|
Uri accountUri = new Uri(this.ServerUrl);
|
||||||
string repoOrOrgName = string.Empty;
|
string repoOrOrgName = string.Empty;
|
||||||
|
|
||||||
if (accountUri.Host.EndsWith(".githubusercontent.com", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(this.GitHubUrl))
|
if (accountUri.Host.EndsWith(".githubusercontent.com", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Uri gitHubUrl = new(this.GitHubUrl);
|
Uri gitHubUrl = new Uri(this.GitHubUrl);
|
||||||
|
|
||||||
// Use the "NWO part" from the GitHub URL path
|
// Use the "NWO part" from the GitHub URL path
|
||||||
repoOrOrgName = gitHubUrl.AbsolutePath.Trim('/');
|
repoOrOrgName = gitHubUrl.AbsolutePath.Trim('/');
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (string.IsNullOrEmpty(repoOrOrgName))
|
|
||||||
{
|
{
|
||||||
repoOrOrgName = accountUri.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
|
repoOrOrgName = accountUri.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace GitHub.Runner.Common
|
|||||||
public static readonly Architecture PlatformArchitecture = Architecture.X64;
|
public static readonly Architecture PlatformArchitecture = Architecture.X64;
|
||||||
#elif ARM
|
#elif ARM
|
||||||
public static readonly Architecture PlatformArchitecture = Architecture.Arm;
|
public static readonly Architecture PlatformArchitecture = Architecture.Arm;
|
||||||
#elif ARM64
|
#elif ARM64
|
||||||
public static readonly Architecture PlatformArchitecture = Architecture.Arm64;
|
public static readonly Architecture PlatformArchitecture = Architecture.Arm64;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -128,7 +128,6 @@ namespace GitHub.Runner.Common
|
|||||||
public static readonly string Check = "check";
|
public static readonly string Check = "check";
|
||||||
public static readonly string Commit = "commit";
|
public static readonly string Commit = "commit";
|
||||||
public static readonly string Ephemeral = "ephemeral";
|
public static readonly string Ephemeral = "ephemeral";
|
||||||
public static readonly string GenerateServiceConfig = "generateServiceConfig";
|
|
||||||
public static readonly string Help = "help";
|
public static readonly string Help = "help";
|
||||||
public static readonly string Replace = "replace";
|
public static readonly string Replace = "replace";
|
||||||
public static readonly string DisableUpdate = "disableupdate";
|
public static readonly string DisableUpdate = "disableupdate";
|
||||||
@@ -153,18 +152,17 @@ namespace GitHub.Runner.Common
|
|||||||
public static readonly string DiskSpaceWarning = "runner.diskspace.warning";
|
public static readonly string DiskSpaceWarning = "runner.diskspace.warning";
|
||||||
public static readonly string Node12Warning = "DistributedTask.AddWarningToNode12Action";
|
public static readonly string Node12Warning = "DistributedTask.AddWarningToNode12Action";
|
||||||
public static readonly string UseContainerPathForTemplate = "DistributedTask.UseContainerPathForTemplate";
|
public static readonly string UseContainerPathForTemplate = "DistributedTask.UseContainerPathForTemplate";
|
||||||
public static readonly string AllowRunnerContainerHooks = "DistributedTask.AllowRunnerContainerHooks";
|
public static readonly string AllowRunnerContainerHooks = "DistributedTask.AllowRunnerContainerHooks";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly string InternalTelemetryIssueDataKey = "_internal_telemetry";
|
public static readonly string InternalTelemetryIssueDataKey = "_internal_telemetry";
|
||||||
public static readonly string WorkerCrash = "WORKER_CRASH";
|
public static readonly string WorkerCrash = "WORKER_CRASH";
|
||||||
public static readonly string LowDiskSpace = "LOW_DISK_SPACE";
|
public static readonly string LowDiskSpace = "LOW_DISK_SPACE";
|
||||||
public static readonly string UnsupportedCommand = "UNSUPPORTED_COMMAND";
|
public static readonly string UnsupportedCommand = "UNSUPPORTED_COMMAND";
|
||||||
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 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`.";
|
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`.";
|
||||||
public static readonly string UnsupportedSummarySize = "$GITHUB_STEP_SUMMARY upload aborted, supports content up to a size of {0}k, got {1}k. For more information see: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-markdown-summary";
|
public static readonly string UnsupportedSummarySize = "$GITHUB_STEP_SUMMARY upload aborted, supports content up to a size of {0}k, got {1}k. For more information see: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-markdown-summary";
|
||||||
public static readonly string Node12DetectedAfterEndOfLife = "Node.js 12 actions are deprecated. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/. Please update the following actions to use Node.js 16: {0}";
|
public static readonly string Node12DetectedAfterEndOfLife = "Node.js 12 actions are deprecated. Please update the following actions to use Node.js 16: {0}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RunnerEvent
|
public static class RunnerEvent
|
||||||
@@ -243,8 +241,8 @@ namespace GitHub.Runner.Common
|
|||||||
public static readonly string ToolsDirectory = "agent.ToolsDirectory";
|
public static readonly string ToolsDirectory = "agent.ToolsDirectory";
|
||||||
|
|
||||||
// Set this env var to "node12" to downgrade the node version for internal functions (e.g hashfiles). This does NOT affect the version of node actions.
|
// Set this env var to "node12" to downgrade the node version for internal functions (e.g hashfiles). This does NOT affect the version of node actions.
|
||||||
public static readonly string ForcedInternalNodeVersion = "ACTIONS_RUNNER_FORCED_INTERNAL_NODE_VERSION";
|
public static readonly string ForcedInternalNodeVersion = "ACTIONS_RUNNER_FORCED_INTERNAL_NODE_VERSION";
|
||||||
public static readonly string ForcedActionsNodeVersion = "ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION";
|
public static readonly string ForcedActionsNodeVersion = "ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class System
|
public static class System
|
||||||
@@ -257,12 +255,5 @@ namespace GitHub.Runner.Common
|
|||||||
public static readonly string PhaseDisplayName = "system.phaseDisplayName";
|
public static readonly string PhaseDisplayName = "system.phaseDisplayName";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class OperatingSystem
|
|
||||||
{
|
|
||||||
public static readonly int Windows11BuildVersion = 22000;
|
|
||||||
// Both windows 10 and windows 11 share the same Major Version 10, need to use the build version to differentiate
|
|
||||||
public static readonly int Windows11MajorVersion = 10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
@@ -14,7 +15,7 @@ namespace GitHub.Runner.Common
|
|||||||
|
|
||||||
public sealed class ExtensionManager : RunnerService, IExtensionManager
|
public sealed class ExtensionManager : RunnerService, IExtensionManager
|
||||||
{
|
{
|
||||||
private readonly ConcurrentDictionary<Type, List<IExtension>> _cache = new();
|
private readonly ConcurrentDictionary<Type, List<IExtension>> _cache = new ConcurrentDictionary<Type, List<IExtension>>();
|
||||||
|
|
||||||
public List<T> GetExtensions<T>() where T : class, IExtension
|
public List<T> GetExtensions<T>() where T : class, IExtension
|
||||||
{
|
{
|
||||||
@@ -60,8 +61,6 @@ namespace GitHub.Runner.Common
|
|||||||
Add<T>(extensions, "GitHub.Runner.Worker.AddPathFileCommand, Runner.Worker");
|
Add<T>(extensions, "GitHub.Runner.Worker.AddPathFileCommand, Runner.Worker");
|
||||||
Add<T>(extensions, "GitHub.Runner.Worker.SetEnvFileCommand, Runner.Worker");
|
Add<T>(extensions, "GitHub.Runner.Worker.SetEnvFileCommand, Runner.Worker");
|
||||||
Add<T>(extensions, "GitHub.Runner.Worker.CreateStepSummaryCommand, Runner.Worker");
|
Add<T>(extensions, "GitHub.Runner.Worker.CreateStepSummaryCommand, Runner.Worker");
|
||||||
Add<T>(extensions, "GitHub.Runner.Worker.SaveStateFileCommand, Runner.Worker");
|
|
||||||
Add<T>(extensions, "GitHub.Runner.Worker.SetOutputFileCommand, Runner.Worker");
|
|
||||||
break;
|
break;
|
||||||
case "GitHub.Runner.Listener.Check.ICheckExtension":
|
case "GitHub.Runner.Listener.Check.ICheckExtension":
|
||||||
Add<T>(extensions, "GitHub.Runner.Listener.Check.InternetCheck, Runner.Listener");
|
Add<T>(extensions, "GitHub.Runner.Listener.Check.InternetCheck, Runner.Listener");
|
||||||
|
|||||||
@@ -51,12 +51,12 @@ namespace GitHub.Runner.Common
|
|||||||
private static int _defaultLogRetentionDays = 30;
|
private static int _defaultLogRetentionDays = 30;
|
||||||
private static int[] _vssHttpMethodEventIds = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 24 };
|
private static int[] _vssHttpMethodEventIds = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 24 };
|
||||||
private static int[] _vssHttpCredentialEventIds = new int[] { 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 27, 29 };
|
private static int[] _vssHttpCredentialEventIds = new int[] { 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 27, 29 };
|
||||||
private readonly ConcurrentDictionary<Type, object> _serviceInstances = new();
|
private readonly ConcurrentDictionary<Type, object> _serviceInstances = new ConcurrentDictionary<Type, object>();
|
||||||
private readonly ConcurrentDictionary<Type, Type> _serviceTypes = new();
|
private readonly ConcurrentDictionary<Type, Type> _serviceTypes = new ConcurrentDictionary<Type, Type>();
|
||||||
private readonly ISecretMasker _secretMasker = new SecretMasker();
|
private readonly ISecretMasker _secretMasker = new SecretMasker();
|
||||||
private readonly List<ProductInfoHeaderValue> _userAgents = new() { new ProductInfoHeaderValue($"GitHubActionsRunner-{BuildConstants.RunnerPackage.PackageName}", BuildConstants.RunnerPackage.Version) };
|
private readonly List<ProductInfoHeaderValue> _userAgents = new List<ProductInfoHeaderValue>() { new ProductInfoHeaderValue($"GitHubActionsRunner-{BuildConstants.RunnerPackage.PackageName}", BuildConstants.RunnerPackage.Version) };
|
||||||
private CancellationTokenSource _runnerShutdownTokenSource = new();
|
private CancellationTokenSource _runnerShutdownTokenSource = new CancellationTokenSource();
|
||||||
private object _perfLock = new();
|
private object _perfLock = new object();
|
||||||
private Tracing _trace;
|
private Tracing _trace;
|
||||||
private Tracing _actionsHttpTrace;
|
private Tracing _actionsHttpTrace;
|
||||||
private Tracing _netcoreHttpTrace;
|
private Tracing _netcoreHttpTrace;
|
||||||
@@ -66,7 +66,7 @@ namespace GitHub.Runner.Common
|
|||||||
private IDisposable _diagListenerSubscription;
|
private IDisposable _diagListenerSubscription;
|
||||||
private StartupType _startupType;
|
private StartupType _startupType;
|
||||||
private string _perfFile;
|
private string _perfFile;
|
||||||
private RunnerWebProxy _webProxy = new();
|
private RunnerWebProxy _webProxy = new RunnerWebProxy();
|
||||||
|
|
||||||
public event EventHandler Unloading;
|
public event EventHandler Unloading;
|
||||||
public CancellationToken RunnerShutdownToken => _runnerShutdownTokenSource.Token;
|
public CancellationToken RunnerShutdownToken => _runnerShutdownTokenSource.Token;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -164,7 +165,7 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
if (_enableLogRetention)
|
if (_enableLogRetention)
|
||||||
{
|
{
|
||||||
DirectoryInfo diags = new(_logFileDirectory);
|
DirectoryInfo diags = new DirectoryInfo(_logFileDirectory);
|
||||||
var logs = diags.GetFiles($"{_logFilePrefix}*.log");
|
var logs = diags.GetFiles($"{_logFilePrefix}*.log");
|
||||||
foreach (var log in logs)
|
foreach (var log in logs)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Pipes;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -13,6 +13,7 @@ using GitHub.Runner.Sdk;
|
|||||||
using GitHub.Services.Common;
|
using GitHub.Services.Common;
|
||||||
using GitHub.Services.WebApi;
|
using GitHub.Services.WebApi;
|
||||||
using GitHub.Services.WebApi.Utilities.Internal;
|
using GitHub.Services.WebApi.Utilities.Internal;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,19 +39,19 @@ namespace GitHub.Runner.Common
|
|||||||
private Guid _jobTimelineRecordId;
|
private Guid _jobTimelineRecordId;
|
||||||
|
|
||||||
// queue for web console line
|
// queue for web console line
|
||||||
private readonly ConcurrentQueue<ConsoleLineInfo> _webConsoleLineQueue = new();
|
private readonly ConcurrentQueue<ConsoleLineInfo> _webConsoleLineQueue = new ConcurrentQueue<ConsoleLineInfo>();
|
||||||
|
|
||||||
// queue for file upload (log file or attachment)
|
// queue for file upload (log file or attachment)
|
||||||
private readonly ConcurrentQueue<UploadFileInfo> _fileUploadQueue = new();
|
private readonly ConcurrentQueue<UploadFileInfo> _fileUploadQueue = new ConcurrentQueue<UploadFileInfo>();
|
||||||
|
|
||||||
// queue for timeline or timeline record update (one queue per timeline)
|
// queue for timeline or timeline record update (one queue per timeline)
|
||||||
private readonly ConcurrentDictionary<Guid, ConcurrentQueue<TimelineRecord>> _timelineUpdateQueue = new();
|
private readonly ConcurrentDictionary<Guid, ConcurrentQueue<TimelineRecord>> _timelineUpdateQueue = new ConcurrentDictionary<Guid, ConcurrentQueue<TimelineRecord>>();
|
||||||
|
|
||||||
// indicate how many timelines we have, we will process _timelineUpdateQueue base on the order of timeline in this list
|
// indicate how many timelines we have, we will process _timelineUpdateQueue base on the order of timeline in this list
|
||||||
private readonly List<Guid> _allTimelines = new();
|
private readonly List<Guid> _allTimelines = new List<Guid>();
|
||||||
|
|
||||||
// bufferd timeline records that fail to update
|
// bufferd timeline records that fail to update
|
||||||
private readonly Dictionary<Guid, List<TimelineRecord>> _bufferedRetryRecords = new();
|
private readonly Dictionary<Guid, List<TimelineRecord>> _bufferedRetryRecords = new Dictionary<Guid, List<TimelineRecord>>();
|
||||||
|
|
||||||
// Task for each queue's dequeue process
|
// Task for each queue's dequeue process
|
||||||
private Task _webConsoleLineDequeueTask;
|
private Task _webConsoleLineDequeueTask;
|
||||||
@@ -61,8 +61,8 @@ namespace GitHub.Runner.Common
|
|||||||
// common
|
// common
|
||||||
private IJobServer _jobServer;
|
private IJobServer _jobServer;
|
||||||
private Task[] _allDequeueTasks;
|
private Task[] _allDequeueTasks;
|
||||||
private readonly TaskCompletionSource<int> _jobCompletionSource = new();
|
private readonly TaskCompletionSource<int> _jobCompletionSource = new TaskCompletionSource<int>();
|
||||||
private readonly TaskCompletionSource<int> _jobRecordUpdated = new();
|
private readonly TaskCompletionSource<int> _jobRecordUpdated = new TaskCompletionSource<int>();
|
||||||
private bool _queueInProcess = false;
|
private bool _queueInProcess = false;
|
||||||
|
|
||||||
public TaskCompletionSource<int> JobRecordUpdated => _jobRecordUpdated;
|
public TaskCompletionSource<int> JobRecordUpdated => _jobRecordUpdated;
|
||||||
@@ -237,8 +237,8 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Group consolelines by timeline record of each step
|
// Group consolelines by timeline record of each step
|
||||||
Dictionary<Guid, List<TimelineRecordLogLine>> stepsConsoleLines = new();
|
Dictionary<Guid, List<TimelineRecordLogLine>> stepsConsoleLines = new Dictionary<Guid, List<TimelineRecordLogLine>>();
|
||||||
List<Guid> stepRecordIds = new(); // We need to keep lines in order
|
List<Guid> stepRecordIds = new List<Guid>(); // We need to keep lines in order
|
||||||
int linesCounter = 0;
|
int linesCounter = 0;
|
||||||
ConsoleLineInfo lineInfo;
|
ConsoleLineInfo lineInfo;
|
||||||
while (_webConsoleLineQueue.TryDequeue(out lineInfo))
|
while (_webConsoleLineQueue.TryDequeue(out lineInfo))
|
||||||
@@ -264,7 +264,7 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
// Split consolelines into batch, each batch will container at most 100 lines.
|
// Split consolelines into batch, each batch will container at most 100 lines.
|
||||||
int batchCounter = 0;
|
int batchCounter = 0;
|
||||||
List<List<TimelineRecordLogLine>> batchedLines = new();
|
List<List<TimelineRecordLogLine>> batchedLines = new List<List<TimelineRecordLogLine>>();
|
||||||
foreach (var line in stepsConsoleLines[stepRecordId])
|
foreach (var line in stepsConsoleLines[stepRecordId])
|
||||||
{
|
{
|
||||||
var currentBatch = batchedLines.ElementAtOrDefault(batchCounter);
|
var currentBatch = batchedLines.ElementAtOrDefault(batchCounter);
|
||||||
@@ -338,7 +338,7 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
while (!_jobCompletionSource.Task.IsCompleted || runOnce)
|
while (!_jobCompletionSource.Task.IsCompleted || runOnce)
|
||||||
{
|
{
|
||||||
List<UploadFileInfo> filesToUpload = new();
|
List<UploadFileInfo> filesToUpload = new List<UploadFileInfo>();
|
||||||
UploadFileInfo dequeueFile;
|
UploadFileInfo dequeueFile;
|
||||||
while (_fileUploadQueue.TryDequeue(out dequeueFile))
|
while (_fileUploadQueue.TryDequeue(out dequeueFile))
|
||||||
{
|
{
|
||||||
@@ -398,13 +398,13 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
while (!_jobCompletionSource.Task.IsCompleted || runOnce)
|
while (!_jobCompletionSource.Task.IsCompleted || runOnce)
|
||||||
{
|
{
|
||||||
List<PendingTimelineRecord> pendingUpdates = new();
|
List<PendingTimelineRecord> pendingUpdates = new List<PendingTimelineRecord>();
|
||||||
foreach (var timeline in _allTimelines)
|
foreach (var timeline in _allTimelines)
|
||||||
{
|
{
|
||||||
ConcurrentQueue<TimelineRecord> recordQueue;
|
ConcurrentQueue<TimelineRecord> recordQueue;
|
||||||
if (_timelineUpdateQueue.TryGetValue(timeline, out recordQueue))
|
if (_timelineUpdateQueue.TryGetValue(timeline, out recordQueue))
|
||||||
{
|
{
|
||||||
List<TimelineRecord> records = new();
|
List<TimelineRecord> records = new List<TimelineRecord>();
|
||||||
TimelineRecord record;
|
TimelineRecord record;
|
||||||
while (recordQueue.TryDequeue(out record))
|
while (recordQueue.TryDequeue(out record))
|
||||||
{
|
{
|
||||||
@@ -426,7 +426,7 @@ namespace GitHub.Runner.Common
|
|||||||
// we need track whether we have new sub-timeline been created on the last run.
|
// we need track whether we have new sub-timeline been created on the last run.
|
||||||
// if so, we need continue update timeline record even we on the last run.
|
// if so, we need continue update timeline record even we on the last run.
|
||||||
bool pendingSubtimelineUpdate = false;
|
bool pendingSubtimelineUpdate = false;
|
||||||
List<Exception> mainTimelineRecordsUpdateErrors = new();
|
List<Exception> mainTimelineRecordsUpdateErrors = new List<Exception>();
|
||||||
if (pendingUpdates.Count > 0)
|
if (pendingUpdates.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var update in pendingUpdates)
|
foreach (var update in pendingUpdates)
|
||||||
@@ -529,7 +529,7 @@ namespace GitHub.Runner.Common
|
|||||||
return timelineRecords;
|
return timelineRecords;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<Guid, TimelineRecord> dict = new();
|
Dictionary<Guid, TimelineRecord> dict = new Dictionary<Guid, TimelineRecord>();
|
||||||
foreach (TimelineRecord rec in timelineRecords)
|
foreach (TimelineRecord rec in timelineRecords)
|
||||||
{
|
{
|
||||||
if (rec == null)
|
if (rec == null)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace GitHub.Runner.Common
|
|||||||
|
|
||||||
public async Task<WorkerMessage> ReceiveAsync(CancellationToken cancellationToken)
|
public async Task<WorkerMessage> ReceiveAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
WorkerMessage result = new(MessageType.NotInitialized, string.Empty);
|
WorkerMessage result = new WorkerMessage(MessageType.NotInitialized, string.Empty);
|
||||||
result.MessageType = (MessageType)await _readStream.ReadInt32Async(cancellationToken);
|
result.MessageType = (MessageType)await _readStream.ReadInt32Async(cancellationToken);
|
||||||
result.Body = await _readStream.ReadStringAsync(cancellationToken);
|
result.Body = await _readStream.ReadStringAsync(cancellationToken);
|
||||||
Trace.Info($"Receiving message of length {result.Body.Length}, with hash '{IOUtil.GetSha256Hash(result.Body)}'");
|
Trace.Info($"Receiving message of length {result.Body.Length}, with hash '{IOUtil.GetSha256Hash(result.Body)}'");
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ namespace GitHub.Runner.Common
|
|||||||
public static string GetEnvironmentVariable(this Process process, IHostContext hostContext, string variable)
|
public static string GetEnvironmentVariable(this Process process, IHostContext hostContext, string variable)
|
||||||
{
|
{
|
||||||
var trace = hostContext.GetTrace(nameof(LinuxProcessExtensions));
|
var trace = hostContext.GetTrace(nameof(LinuxProcessExtensions));
|
||||||
Dictionary<string, string> env = new();
|
Dictionary<string, string> env = new Dictionary<string, string>();
|
||||||
|
|
||||||
if (Directory.Exists("/proc"))
|
if (Directory.Exists("/proc"))
|
||||||
{
|
{
|
||||||
@@ -322,8 +322,8 @@ namespace GitHub.Runner.Common
|
|||||||
// It doesn't escape '=' or ' ', so we can't parse the output into a dictionary of all envs.
|
// It doesn't escape '=' or ' ', so we can't parse the output into a dictionary of all envs.
|
||||||
// So we only look for the env you request, in the format of variable=value. (it won't work if you variable contains = or space)
|
// So we only look for the env you request, in the format of variable=value. (it won't work if you variable contains = or space)
|
||||||
trace.Info($"Read env from output of `ps e -p {process.Id} -o command`");
|
trace.Info($"Read env from output of `ps e -p {process.Id} -o command`");
|
||||||
List<string> psOut = new();
|
List<string> psOut = new List<string>();
|
||||||
object outputLock = new();
|
object outputLock = new object();
|
||||||
using (var p = hostContext.CreateService<IProcessInvoker>())
|
using (var p = hostContext.CreateService<IProcessInvoker>())
|
||||||
{
|
{
|
||||||
p.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stdout)
|
p.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stdout)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using GitHub.Runner.Common.Util;
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.DistributedTask.Pipelines;
|
using GitHub.DistributedTask.Pipelines;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using GitHub.Services.Common;
|
using GitHub.Services.Common;
|
||||||
using GitHub.Services.WebApi;
|
using GitHub.Services.WebApi;
|
||||||
using Sdk.WebApi.WebApi.RawClient;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
{
|
{
|
||||||
@@ -21,19 +23,42 @@ namespace GitHub.Runner.Common
|
|||||||
public sealed class RunServer : RunnerService, IRunServer
|
public sealed class RunServer : RunnerService, IRunServer
|
||||||
{
|
{
|
||||||
private bool _hasConnection;
|
private bool _hasConnection;
|
||||||
private Uri requestUri;
|
private VssConnection _connection;
|
||||||
private RawConnection _connection;
|
private TaskAgentHttpClient _taskAgentClient;
|
||||||
private RunServiceHttpClient _runServiceHttpClient;
|
|
||||||
|
|
||||||
public async Task ConnectAsync(Uri serverUri, VssCredentials credentials)
|
public async Task ConnectAsync(Uri serverUrl, VssCredentials credentials)
|
||||||
{
|
{
|
||||||
requestUri = serverUri;
|
_connection = await EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(100));
|
||||||
|
_taskAgentClient = _connection.GetClient<TaskAgentHttpClient>();
|
||||||
_connection = VssUtil.CreateRawConnection(new Uri(serverUri.Authority), credentials);
|
|
||||||
_runServiceHttpClient = await _connection.GetClientAsync<RunServiceHttpClient>();
|
|
||||||
_hasConnection = true;
|
_hasConnection = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<VssConnection> EstablishVssConnection(Uri serverUrl, VssCredentials credentials, TimeSpan timeout)
|
||||||
|
{
|
||||||
|
Trace.Info($"EstablishVssConnection");
|
||||||
|
Trace.Info($"Establish connection with {timeout.TotalSeconds} seconds timeout.");
|
||||||
|
int attemptCount = 5;
|
||||||
|
while (attemptCount-- > 0)
|
||||||
|
{
|
||||||
|
var connection = VssUtil.CreateConnection(serverUrl, credentials, timeout: timeout);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await connection.ConnectAsync();
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (attemptCount > 0)
|
||||||
|
{
|
||||||
|
Trace.Info($"Catch exception during connect. {attemptCount} attempt left.");
|
||||||
|
Trace.Error(ex);
|
||||||
|
|
||||||
|
await HostContext.Delay(TimeSpan.FromMilliseconds(100), CancellationToken.None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// should never reach here.
|
||||||
|
throw new InvalidOperationException(nameof(EstablishVssConnection));
|
||||||
|
}
|
||||||
|
|
||||||
private void CheckConnection()
|
private void CheckConnection()
|
||||||
{
|
{
|
||||||
if (!_hasConnection)
|
if (!_hasConnection)
|
||||||
@@ -45,15 +70,37 @@ namespace GitHub.Runner.Common
|
|||||||
public Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken cancellationToken)
|
public Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
CheckConnection();
|
CheckConnection();
|
||||||
var jobMessage = RetryRequest<AgentJobRequestMessage>(
|
var jobMessage = RetryRequest<AgentJobRequestMessage>(async () =>
|
||||||
async () => await _runServiceHttpClient.GetJobMessageAsync(requestUri, id, cancellationToken), cancellationToken);
|
{
|
||||||
if (jobMessage == null)
|
return await _taskAgentClient.GetJobMessageAsync(id, cancellationToken);
|
||||||
{
|
}, cancellationToken);
|
||||||
throw new TaskOrchestrationJobNotFoundException(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return jobMessage;
|
return jobMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<T> RetryRequest<T>(Func<Task<T>> func,
|
||||||
|
CancellationToken cancellationToken,
|
||||||
|
int maxRetryAttemptsCount = 5
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var retryCount = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
retryCount++;
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await func();
|
||||||
|
}
|
||||||
|
// 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 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.");
|
||||||
|
await Task.Delay(backOff, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64;win-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
<NoWarn>NU1701;NU1603</NoWarn>
|
<NoWarn>NU1701;NU1603</NoWarn>
|
||||||
<Version>$(Version)</Version>
|
<Version>$(Version)</Version>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Services.WebApi;
|
using GitHub.Services.WebApi;
|
||||||
using GitHub.Services.Common;
|
using GitHub.Services.Common;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
@@ -179,6 +180,31 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<VssConnection> EstablishVssConnection(Uri serverUrl, VssCredentials credentials, TimeSpan timeout)
|
||||||
|
{
|
||||||
|
Trace.Info($"Establish connection with {timeout.TotalSeconds} seconds timeout.");
|
||||||
|
int attemptCount = 5;
|
||||||
|
while (attemptCount-- > 0)
|
||||||
|
{
|
||||||
|
var connection = VssUtil.CreateConnection(serverUrl, credentials, timeout: timeout);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await connection.ConnectAsync();
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (attemptCount > 0)
|
||||||
|
{
|
||||||
|
Trace.Info($"Catch exception during connect. {attemptCount} attempt left.");
|
||||||
|
Trace.Error(ex);
|
||||||
|
|
||||||
|
await HostContext.Delay(TimeSpan.FromMilliseconds(100), CancellationToken.None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// should never reach here.
|
||||||
|
throw new InvalidOperationException(nameof(EstablishVssConnection));
|
||||||
|
}
|
||||||
|
|
||||||
private void CheckConnection(RunnerConnectionType connectionType)
|
private void CheckConnection(RunnerConnectionType connectionType)
|
||||||
{
|
{
|
||||||
switch (connectionType)
|
switch (connectionType)
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using GitHub.Runner.Sdk;
|
|
||||||
using GitHub.Services.Common;
|
|
||||||
using GitHub.Services.WebApi;
|
|
||||||
using Sdk.WebApi.WebApi.RawClient;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
{
|
{
|
||||||
@@ -27,9 +21,9 @@ namespace GitHub.Runner.Common
|
|||||||
protected IHostContext HostContext { get; private set; }
|
protected IHostContext HostContext { get; private set; }
|
||||||
protected Tracing Trace { get; private set; }
|
protected Tracing Trace { get; private set; }
|
||||||
|
|
||||||
public string TraceName
|
public string TraceName
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return GetType().Name;
|
return GetType().Name;
|
||||||
}
|
}
|
||||||
@@ -41,57 +35,5 @@ namespace GitHub.Runner.Common
|
|||||||
Trace = HostContext.GetTrace(TraceName);
|
Trace = HostContext.GetTrace(TraceName);
|
||||||
Trace.Entering();
|
Trace.Entering();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task<VssConnection> EstablishVssConnection(Uri serverUrl, VssCredentials credentials, TimeSpan timeout)
|
|
||||||
{
|
|
||||||
Trace.Info($"EstablishVssConnection");
|
|
||||||
Trace.Info($"Establish connection with {timeout.TotalSeconds} seconds timeout.");
|
|
||||||
int attemptCount = 5;
|
|
||||||
while (attemptCount-- > 0)
|
|
||||||
{
|
|
||||||
var connection = VssUtil.CreateConnection(serverUrl, credentials, timeout: timeout);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await connection.ConnectAsync();
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
catch (Exception ex) when (attemptCount > 0)
|
|
||||||
{
|
|
||||||
Trace.Info($"Catch exception during connect. {attemptCount} attempt left.");
|
|
||||||
Trace.Error(ex);
|
|
||||||
|
|
||||||
await HostContext.Delay(TimeSpan.FromMilliseconds(100), CancellationToken.None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// should never reach here.
|
|
||||||
throw new InvalidOperationException(nameof(EstablishVssConnection));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async Task<T> RetryRequest<T>(Func<Task<T>> func,
|
|
||||||
CancellationToken cancellationToken,
|
|
||||||
int maxRetryAttemptsCount = 5
|
|
||||||
)
|
|
||||||
{
|
|
||||||
var retryCount = 0;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
retryCount++;
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return await func();
|
|
||||||
}
|
|
||||||
// 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 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.");
|
|
||||||
await Task.Delay(backOff, cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trace whether a value was entered.
|
// Trace whether a value was entered.
|
||||||
string val = new(chars.ToArray());
|
string val = new String(chars.ToArray());
|
||||||
if (!string.IsNullOrEmpty(val))
|
if (!string.IsNullOrEmpty(val))
|
||||||
{
|
{
|
||||||
HostContext.SecretMasker.AddValue(val);
|
HostContext.SecretMasker.AddValue(val);
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using GitHub.Services.Common.Internal;
|
using GitHub.Services.Common.Internal;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -14,7 +15,7 @@ namespace GitHub.Runner.Common
|
|||||||
|
|
||||||
public sealed class TraceManager : ITraceManager
|
public sealed class TraceManager : ITraceManager
|
||||||
{
|
{
|
||||||
private readonly ConcurrentDictionary<string, Tracing> _sources = new(StringComparer.OrdinalIgnoreCase);
|
private readonly ConcurrentDictionary<string, Tracing> _sources = new ConcurrentDictionary<string, Tracing>(StringComparer.OrdinalIgnoreCase);
|
||||||
private readonly HostTraceListener _hostTraceListener;
|
private readonly HostTraceListener _hostTraceListener;
|
||||||
private TraceSetting _traceSetting;
|
private TraceSetting _traceSetting;
|
||||||
private ISecretMasker _secretMasker;
|
private ISecretMasker _secretMasker;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace GitHub.Runner.Common.Util
|
|||||||
{
|
{
|
||||||
private const string _defaultNodeVersion = "node16";
|
private const string _defaultNodeVersion = "node16";
|
||||||
|
|
||||||
#if (OS_OSX || OS_WINDOWS) && ARM64
|
#if OS_OSX && ARM64
|
||||||
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node16" });
|
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node16" });
|
||||||
#else
|
#else
|
||||||
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node12", "node16" });
|
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node12", "node16" });
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using GitHub.Runner.Sdk;
|
||||||
|
|
||||||
namespace GitHub.Runner.Common.Util
|
namespace GitHub.Runner.Common.Util
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -347,8 +347,8 @@ namespace GitHub.Runner.Listener.Check
|
|||||||
public sealed class HttpEventSourceListener : EventListener
|
public sealed class HttpEventSourceListener : EventListener
|
||||||
{
|
{
|
||||||
private readonly List<string> _logs;
|
private readonly List<string> _logs;
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new object();
|
||||||
private readonly Dictionary<string, HashSet<string>> _ignoredEvent = new()
|
private readonly Dictionary<string, HashSet<string>> _ignoredEvent = new Dictionary<string, HashSet<string>>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"Microsoft-System-Net-Http",
|
"Microsoft-System-Net-Http",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
@@ -167,4 +168,4 @@ namespace GitHub.Runner.Listener.Check
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
@@ -86,7 +87,7 @@ namespace GitHub.Runner.Listener.Check
|
|||||||
result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ***************************************************************************************************************");
|
result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ***************************************************************************************************************");
|
||||||
|
|
||||||
// Request to github.com or ghes server
|
// Request to github.com or ghes server
|
||||||
Uri requestUrl = new(url);
|
Uri requestUrl = new Uri(url);
|
||||||
var env = new Dictionary<string, string>()
|
var env = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "HOSTNAME", requestUrl.Host },
|
{ "HOSTNAME", requestUrl.Host },
|
||||||
@@ -178,4 +179,4 @@ namespace GitHub.Runner.Listener.Check
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using GitHub.DistributedTask.Logging;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
|
|
||||||
@@ -11,7 +12,7 @@ namespace GitHub.Runner.Listener
|
|||||||
{
|
{
|
||||||
public sealed class CommandSettings
|
public sealed class CommandSettings
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, string> _envArgs = new(StringComparer.OrdinalIgnoreCase);
|
private readonly Dictionary<string, string> _envArgs = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private readonly CommandLineParser _parser;
|
private readonly CommandLineParser _parser;
|
||||||
private readonly IPromptManager _promptManager;
|
private readonly IPromptManager _promptManager;
|
||||||
private readonly Tracing _trace;
|
private readonly Tracing _trace;
|
||||||
@@ -26,7 +27,7 @@ namespace GitHub.Runner.Listener
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Valid flags and args for specific command - key: command, value: array of valid flags and args
|
// Valid flags and args for specific command - key: command, value: array of valid flags and args
|
||||||
private readonly Dictionary<string, string[]> validOptions = new()
|
private readonly Dictionary<string, string[]> validOptions = new Dictionary<string, string[]>
|
||||||
{
|
{
|
||||||
// Valid configure flags and args
|
// Valid configure flags and args
|
||||||
[Constants.Runner.CommandLine.Commands.Configure] =
|
[Constants.Runner.CommandLine.Commands.Configure] =
|
||||||
@@ -34,7 +35,6 @@ namespace GitHub.Runner.Listener
|
|||||||
{
|
{
|
||||||
Constants.Runner.CommandLine.Flags.DisableUpdate,
|
Constants.Runner.CommandLine.Flags.DisableUpdate,
|
||||||
Constants.Runner.CommandLine.Flags.Ephemeral,
|
Constants.Runner.CommandLine.Flags.Ephemeral,
|
||||||
Constants.Runner.CommandLine.Flags.GenerateServiceConfig,
|
|
||||||
Constants.Runner.CommandLine.Flags.Replace,
|
Constants.Runner.CommandLine.Flags.Replace,
|
||||||
Constants.Runner.CommandLine.Flags.RunAsService,
|
Constants.Runner.CommandLine.Flags.RunAsService,
|
||||||
Constants.Runner.CommandLine.Flags.Unattended,
|
Constants.Runner.CommandLine.Flags.Unattended,
|
||||||
@@ -80,12 +80,11 @@ namespace GitHub.Runner.Listener
|
|||||||
// Flags.
|
// Flags.
|
||||||
public bool Check => TestFlag(Constants.Runner.CommandLine.Flags.Check);
|
public bool Check => TestFlag(Constants.Runner.CommandLine.Flags.Check);
|
||||||
public bool Commit => TestFlag(Constants.Runner.CommandLine.Flags.Commit);
|
public bool Commit => TestFlag(Constants.Runner.CommandLine.Flags.Commit);
|
||||||
public bool DisableUpdate => TestFlag(Constants.Runner.CommandLine.Flags.DisableUpdate);
|
|
||||||
public bool Ephemeral => TestFlag(Constants.Runner.CommandLine.Flags.Ephemeral);
|
|
||||||
public bool GenerateServiceConfig => TestFlag(Constants.Runner.CommandLine.Flags.GenerateServiceConfig);
|
|
||||||
public bool Help => TestFlag(Constants.Runner.CommandLine.Flags.Help);
|
public bool Help => TestFlag(Constants.Runner.CommandLine.Flags.Help);
|
||||||
public bool Unattended => TestFlag(Constants.Runner.CommandLine.Flags.Unattended);
|
public bool Unattended => TestFlag(Constants.Runner.CommandLine.Flags.Unattended);
|
||||||
public bool Version => TestFlag(Constants.Runner.CommandLine.Flags.Version);
|
public bool Version => TestFlag(Constants.Runner.CommandLine.Flags.Version);
|
||||||
|
public bool Ephemeral => TestFlag(Constants.Runner.CommandLine.Flags.Ephemeral);
|
||||||
|
public bool DisableUpdate => TestFlag(Constants.Runner.CommandLine.Flags.DisableUpdate);
|
||||||
|
|
||||||
// Keep this around since customers still relies on it
|
// Keep this around since customers still relies on it
|
||||||
public bool RunOnce => TestFlag(Constants.Runner.CommandLine.Flags.Once);
|
public bool RunOnce => TestFlag(Constants.Runner.CommandLine.Flags.Once);
|
||||||
@@ -139,7 +138,7 @@ namespace GitHub.Runner.Listener
|
|||||||
// Validate commandline parser result
|
// Validate commandline parser result
|
||||||
public List<string> Validate()
|
public List<string> Validate()
|
||||||
{
|
{
|
||||||
List<string> unknowns = new();
|
List<string> unknowns = new List<string>();
|
||||||
|
|
||||||
// detect unknown commands
|
// detect unknown commands
|
||||||
unknowns.AddRange(_parser.Commands.Where(x => !validOptions.Keys.Contains(x, StringComparer.OrdinalIgnoreCase)));
|
unknowns.AddRange(_parser.Commands.Where(x => !validOptions.Keys.Contains(x, StringComparer.OrdinalIgnoreCase)));
|
||||||
|
|||||||
@@ -81,33 +81,12 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
_term.WriteLine("--------------------------------------------------------------------------------");
|
_term.WriteLine("--------------------------------------------------------------------------------");
|
||||||
|
|
||||||
Trace.Info(nameof(ConfigureAsync));
|
Trace.Info(nameof(ConfigureAsync));
|
||||||
|
|
||||||
if (command.GenerateServiceConfig)
|
|
||||||
{
|
|
||||||
#if OS_LINUX
|
|
||||||
if (!IsConfigured())
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("--generateServiceConfig requires that the runner is already configured. For configuring a new runner as a service, run './config.sh'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerSettings settings = _store.GetSettings();
|
|
||||||
|
|
||||||
Trace.Info($"generate service config for runner: {settings.AgentId}");
|
|
||||||
var controlManager = HostContext.GetService<ILinuxServiceControlManager>();
|
|
||||||
controlManager.GenerateScripts(settings);
|
|
||||||
|
|
||||||
return;
|
|
||||||
#else
|
|
||||||
throw new NotSupportedException("--generateServiceConfig is only supported on Linux.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsConfigured())
|
if (IsConfigured())
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Cannot configure the runner because it is already configured. To reconfigure the runner, run 'config.cmd remove' or './config.sh remove' first.");
|
throw new InvalidOperationException("Cannot configure the runner because it is already configured. To reconfigure the runner, run 'config.cmd remove' or './config.sh remove' first.");
|
||||||
}
|
}
|
||||||
|
|
||||||
RunnerSettings runnerSettings = new();
|
RunnerSettings runnerSettings = new RunnerSettings();
|
||||||
|
|
||||||
// Loop getting url and creds until you can connect
|
// Loop getting url and creds until you can connect
|
||||||
ICredentialProvider credProvider = null;
|
ICredentialProvider credProvider = null;
|
||||||
@@ -542,7 +521,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
|
|
||||||
private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey, ISet<string> userLabels, bool ephemeral, bool disableUpdate)
|
private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey, ISet<string> userLabels, bool ephemeral, bool disableUpdate)
|
||||||
{
|
{
|
||||||
TaskAgent agent = new(agentName)
|
TaskAgent agent = new TaskAgent(agentName)
|
||||||
{
|
{
|
||||||
Authorization = new TaskAgentAuthorization
|
Authorization = new TaskAgentAuthorization
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
|
|
||||||
public class CredentialManager : RunnerService, ICredentialManager
|
public class CredentialManager : RunnerService, ICredentialManager
|
||||||
{
|
{
|
||||||
public static readonly Dictionary<string, Type> CredentialTypes = new(StringComparer.OrdinalIgnoreCase)
|
public static readonly Dictionary<string, Type> CredentialTypes = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
{ Constants.Configuration.OAuth, typeof(OAuthCredential)},
|
{ Constants.Configuration.OAuth, typeof(OAuthCredential)},
|
||||||
{ Constants.Configuration.OAuthAccessToken, typeof(OAuthAccessTokenCredential)},
|
{ Constants.Configuration.OAuthAccessToken, typeof(OAuthAccessTokenCredential)},
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
ArgUtil.NotNullOrEmpty(token, nameof(token));
|
ArgUtil.NotNullOrEmpty(token, nameof(token));
|
||||||
|
|
||||||
trace.Info("token retrieved: {0} chars", token.Length);
|
trace.Info("token retrieved: {0} chars", token.Length);
|
||||||
VssCredentials creds = new(new VssOAuthAccessTokenCredential(token), CredentialPromptType.DoNotPrompt);
|
VssCredentials creds = new VssCredentials(new VssOAuthAccessTokenCredential(token), CredentialPromptType.DoNotPrompt);
|
||||||
trace.Info("cred created");
|
trace.Info("cred created");
|
||||||
|
|
||||||
return creds;
|
return creds;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
{
|
{
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
else if (isOptional)
|
else if (isOptional)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
@@ -86,12 +87,11 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
// Write the message prompt.
|
// Write the message prompt.
|
||||||
_terminal.Write($"{description} ");
|
_terminal.Write($"{description} ");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(defaultValue))
|
if(!string.IsNullOrEmpty(defaultValue))
|
||||||
{
|
{
|
||||||
_terminal.Write($"[press Enter for {defaultValue}] ");
|
_terminal.Write($"[press Enter for {defaultValue}] ");
|
||||||
}
|
}
|
||||||
else if (isOptional)
|
else if (isOptional){
|
||||||
{
|
|
||||||
_terminal.Write($"[press Enter to skip] ");
|
_terminal.Write($"[press Enter to skip] ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the value if it is not empty and it is valid.
|
// Return the value if it is not empty and it is valid.
|
||||||
// Otherwise try the loop again.
|
// Otherwise try the loop again.
|
||||||
if (!string.IsNullOrEmpty(value))
|
if (!string.IsNullOrEmpty(value))
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For the service name, replace any characters outside of the alpha-numeric set and ".", "_", "-" with "-"
|
// For the service name, replace any characters outside of the alpha-numeric set and ".", "_", "-" with "-"
|
||||||
Regex regex = new(@"[^0-9a-zA-Z._\-]");
|
Regex regex = new Regex(@"[^0-9a-zA-Z._\-]");
|
||||||
string repoOrOrgName = regex.Replace(settings.RepoOrOrgName, "-");
|
string repoOrOrgName = regex.Replace(settings.RepoOrOrgName, "-");
|
||||||
|
|
||||||
serviceName = StringUtil.Format(serviceNamePattern, repoOrOrgName, settings.AgentName);
|
serviceName = StringUtil.Format(serviceNamePattern, repoOrOrgName, settings.AgentName);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#if OS_LINUX
|
#if OS_LINUX
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -6,6 +6,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using GitHub.Runner.Common.Util;
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
|
using GitHub.Runner.Sdk;
|
||||||
|
|
||||||
namespace GitHub.Runner.Listener.Configuration
|
namespace GitHub.Runner.Listener.Configuration
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ namespace GitHub.Runner.Listener
|
|||||||
// and the server will not send another job while this one is still running.
|
// and the server will not send another job while this one is still running.
|
||||||
public sealed class JobDispatcher : RunnerService, IJobDispatcher
|
public sealed class JobDispatcher : RunnerService, IJobDispatcher
|
||||||
{
|
{
|
||||||
private static Regex _invalidJsonRegex = new(@"invalid\ Json\ at\ position\ '(\d+)':", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static Regex _invalidJsonRegex = new Regex(@"invalid\ Json\ at\ position\ '(\d+)':", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
private readonly Lazy<Dictionary<long, TaskResult>> _localRunJobResult = new();
|
private readonly Lazy<Dictionary<long, TaskResult>> _localRunJobResult = new Lazy<Dictionary<long, TaskResult>>();
|
||||||
private int _poolId;
|
private int _poolId;
|
||||||
|
|
||||||
IConfigurationStore _configurationStore;
|
IConfigurationStore _configurationStore;
|
||||||
@@ -47,14 +47,14 @@ namespace GitHub.Runner.Listener
|
|||||||
private static readonly string _workerProcessName = $"Runner.Worker{IOUtil.ExeExtension}";
|
private static readonly string _workerProcessName = $"Runner.Worker{IOUtil.ExeExtension}";
|
||||||
|
|
||||||
// this is not thread-safe
|
// this is not thread-safe
|
||||||
private readonly Queue<Guid> _jobDispatchedQueue = new();
|
private readonly Queue<Guid> _jobDispatchedQueue = new Queue<Guid>();
|
||||||
private readonly ConcurrentDictionary<Guid, WorkerDispatcher> _jobInfos = new();
|
private readonly ConcurrentDictionary<Guid, WorkerDispatcher> _jobInfos = new ConcurrentDictionary<Guid, WorkerDispatcher>();
|
||||||
|
|
||||||
// allow up to 30sec for any data to be transmitted over the process channel
|
// allow up to 30sec for any data to be transmitted over the process channel
|
||||||
// timeout limit can be overwritten by environment GITHUB_ACTIONS_RUNNER_CHANNEL_TIMEOUT
|
// timeout limit can be overwritten by environment GITHUB_ACTIONS_RUNNER_CHANNEL_TIMEOUT
|
||||||
private TimeSpan _channelTimeout;
|
private TimeSpan _channelTimeout;
|
||||||
|
|
||||||
private TaskCompletionSource<bool> _runOnceJobCompleted = new();
|
private TaskCompletionSource<bool> _runOnceJobCompleted = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
public event EventHandler<JobStatusEventArgs> JobStatus;
|
public event EventHandler<JobStatusEventArgs> JobStatus;
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkerDispatcher newDispatch = new(jobRequestMessage.JobId, jobRequestMessage.RequestId);
|
WorkerDispatcher newDispatch = new WorkerDispatcher(jobRequestMessage.JobId, jobRequestMessage.RequestId);
|
||||||
if (runOnce)
|
if (runOnce)
|
||||||
{
|
{
|
||||||
Trace.Info("Start dispatcher for one time used runner.");
|
Trace.Info("Start dispatcher for one time used runner.");
|
||||||
@@ -357,7 +357,7 @@ namespace GitHub.Runner.Listener
|
|||||||
term.WriteLine($"{DateTime.UtcNow:u}: Running job: {message.JobDisplayName}");
|
term.WriteLine($"{DateTime.UtcNow:u}: Running job: {message.JobDisplayName}");
|
||||||
|
|
||||||
// first job request renew succeed.
|
// first job request renew succeed.
|
||||||
TaskCompletionSource<int> firstJobRequestRenewed = new();
|
TaskCompletionSource<int> firstJobRequestRenewed = new TaskCompletionSource<int>();
|
||||||
var notification = HostContext.GetService<IJobNotification>();
|
var notification = HostContext.GetService<IJobNotification>();
|
||||||
|
|
||||||
// lock renew cancellation token.
|
// lock renew cancellation token.
|
||||||
@@ -398,8 +398,8 @@ namespace GitHub.Runner.Listener
|
|||||||
HostContext.WritePerfCounter($"JobRequestRenewed_{requestId.ToString()}");
|
HostContext.WritePerfCounter($"JobRequestRenewed_{requestId.ToString()}");
|
||||||
|
|
||||||
Task<int> workerProcessTask = null;
|
Task<int> workerProcessTask = null;
|
||||||
object _outputLock = new();
|
object _outputLock = new object();
|
||||||
List<string> workerOutput = new();
|
List<string> workerOutput = new List<string>();
|
||||||
using (var processChannel = HostContext.CreateService<IProcessChannel>())
|
using (var processChannel = HostContext.CreateService<IProcessChannel>())
|
||||||
using (var processInvoker = HostContext.CreateService<IProcessInvoker>())
|
using (var processInvoker = HostContext.CreateService<IProcessInvoker>())
|
||||||
{
|
{
|
||||||
@@ -936,7 +936,7 @@ namespace GitHub.Runner.Listener
|
|||||||
|
|
||||||
var runnerServer = HostContext.GetService<IRunnerServer>();
|
var runnerServer = HostContext.GetService<IRunnerServer>();
|
||||||
int completeJobRequestRetryLimit = 5;
|
int completeJobRequestRetryLimit = 5;
|
||||||
List<Exception> exceptions = new();
|
List<Exception> exceptions = new List<Exception>();
|
||||||
while (completeJobRequestRetryLimit-- > 0)
|
while (completeJobRequestRetryLimit-- > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -1039,7 +1039,7 @@ namespace GitHub.Runner.Listener
|
|||||||
public Task WorkerDispatch { get; set; }
|
public Task WorkerDispatch { get; set; }
|
||||||
public CancellationTokenSource WorkerCancellationTokenSource { get; private set; }
|
public CancellationTokenSource WorkerCancellationTokenSource { get; private set; }
|
||||||
public CancellationTokenSource WorkerCancelTimeoutKillTokenSource { get; private set; }
|
public CancellationTokenSource WorkerCancelTimeoutKillTokenSource { get; private set; }
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new object();
|
||||||
|
|
||||||
public WorkerDispatcher(Guid jobId, long requestId)
|
public WorkerDispatcher(Guid jobId, long requestId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace GitHub.Runner.Listener
|
|||||||
private readonly TimeSpan _sessionCreationRetryInterval = TimeSpan.FromSeconds(30);
|
private readonly TimeSpan _sessionCreationRetryInterval = TimeSpan.FromSeconds(30);
|
||||||
private readonly TimeSpan _sessionConflictRetryLimit = TimeSpan.FromMinutes(4);
|
private readonly TimeSpan _sessionConflictRetryLimit = TimeSpan.FromMinutes(4);
|
||||||
private readonly TimeSpan _clockSkewRetryLimit = TimeSpan.FromMinutes(30);
|
private readonly TimeSpan _clockSkewRetryLimit = TimeSpan.FromMinutes(30);
|
||||||
private readonly Dictionary<string, int> _sessionCreationExceptionTracker = new();
|
private readonly Dictionary<string, int> _sessionCreationExceptionTracker = new Dictionary<string, int>();
|
||||||
private TaskAgentStatus runnerStatus = TaskAgentStatus.Online;
|
private TaskAgentStatus runnerStatus = TaskAgentStatus.Online;
|
||||||
private CancellationTokenSource _getMessagesTokenSource;
|
private CancellationTokenSource _getMessagesTokenSource;
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ namespace GitHub.Runner.Listener
|
|||||||
bool encounteringError = false;
|
bool encounteringError = false;
|
||||||
int continuousError = 0;
|
int continuousError = 0;
|
||||||
string errorMessage = string.Empty;
|
string errorMessage = string.Empty;
|
||||||
Stopwatch heartbeat = new();
|
Stopwatch heartbeat = new Stopwatch();
|
||||||
heartbeat.Restart();
|
heartbeat.Restart();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace GitHub.Runner.Listener
|
namespace GitHub.Runner.Listener
|
||||||
@@ -16,7 +18,7 @@ namespace GitHub.Runner.Listener
|
|||||||
// Add environment variables from .env file
|
// Add environment variables from .env file
|
||||||
LoadAndSetEnv();
|
LoadAndSetEnv();
|
||||||
|
|
||||||
using (HostContext context = new("Runner"))
|
using (HostContext context = new HostContext("Runner"))
|
||||||
{
|
{
|
||||||
return MainAsync(context, args).GetAwaiter().GetResult();
|
return MainAsync(context, args).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
@@ -58,18 +60,6 @@ namespace GitHub.Runner.Listener
|
|||||||
terminal.WriteLine("This runner version is built for Windows. Please install a correct build for your OS.");
|
terminal.WriteLine("This runner version is built for Windows. Please install a correct build for your OS.");
|
||||||
return Constants.Runner.ReturnCode.TerminatedError;
|
return Constants.Runner.ReturnCode.TerminatedError;
|
||||||
}
|
}
|
||||||
#if ARM64
|
|
||||||
// A little hacky, but windows gives no way to differentiate between windows 10 and 11.
|
|
||||||
// By default only 11 supports native x64 app emulation on arm, so we only want to support windows 11
|
|
||||||
// https://docs.microsoft.com/en-us/windows/arm/overview#build-windows-apps-that-run-on-arm
|
|
||||||
// Windows 10 and 11 share a MajorVersion, so we also check the build version. Minor for both is 0, so doing < 0 doesn't really make a lot of sense.
|
|
||||||
if (Environment.OSVersion.Version.Major < Constants.OperatingSystem.Windows11MajorVersion ||
|
|
||||||
Environment.OSVersion.Version.Build < Constants.OperatingSystem.Windows11BuildVersion)
|
|
||||||
{
|
|
||||||
terminal.WriteLine("Win-arm64 runners require windows 11 or later. Please upgrade your operating system.");
|
|
||||||
return Constants.Runner.ReturnCode.TerminatedError;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
terminal.WriteLine($"Running the runner on this platform is not supported. The current platform is {RuntimeInformation.OSDescription} and it was built for {Constants.Runner.Platform.ToString()}.");
|
terminal.WriteLine($"Running the runner on this platform is not supported. The current platform is {RuntimeInformation.OSDescription} and it was built for {Constants.Runner.Platform.ToString()}.");
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64;win-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
<NoWarn>NU1701;NU1603</NoWarn>
|
<NoWarn>NU1701;NU1603</NoWarn>
|
||||||
<Version>$(Version)</Version>
|
<Version>$(Version)</Version>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@@ -28,7 +29,7 @@ namespace GitHub.Runner.Listener
|
|||||||
private IMessageListener _listener;
|
private IMessageListener _listener;
|
||||||
private ITerminal _term;
|
private ITerminal _term;
|
||||||
private bool _inConfigStage;
|
private bool _inConfigStage;
|
||||||
private ManualResetEvent _completedCommand = new(false);
|
private ManualResetEvent _completedCommand = new ManualResetEvent(false);
|
||||||
|
|
||||||
public override void Initialize(IHostContext hostContext)
|
public override void Initialize(IHostContext hostContext)
|
||||||
{
|
{
|
||||||
@@ -496,26 +497,16 @@ namespace GitHub.Runner.Listener
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var messageRef = StringUtil.ConvertFromJson<RunnerJobRequestRef>(message.Body);
|
var messageRef = StringUtil.ConvertFromJson<RunnerJobRequestRef>(message.Body);
|
||||||
Pipelines.AgentJobRequestMessage jobRequestMessage = null;
|
|
||||||
|
|
||||||
// Create connection
|
// Create connection
|
||||||
var credMgr = HostContext.GetService<ICredentialManager>();
|
var credMgr = HostContext.GetService<ICredentialManager>();
|
||||||
var creds = credMgr.LoadCredentials();
|
var creds = credMgr.LoadCredentials();
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(messageRef.RunServiceUrl))
|
var runServer = HostContext.CreateService<IRunServer>();
|
||||||
{
|
await runServer.ConnectAsync(new Uri(settings.ServerUrl), creds);
|
||||||
var actionsRunServer = HostContext.CreateService<IActionsRunServer>();
|
var jobMessage = await runServer.GetJobMessageAsync(messageRef.RunnerRequestId, messageQueueLoopTokenSource.Token);
|
||||||
await actionsRunServer.ConnectAsync(new Uri(settings.ServerUrl), creds);
|
|
||||||
jobRequestMessage = await actionsRunServer.GetJobMessageAsync(messageRef.RunnerRequestId, messageQueueLoopTokenSource.Token);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var runServer = HostContext.CreateService<IRunServer>();
|
|
||||||
await runServer.ConnectAsync(new Uri(messageRef.RunServiceUrl), creds);
|
|
||||||
jobRequestMessage = await runServer.GetJobMessageAsync(messageRef.RunnerRequestId, messageQueueLoopTokenSource.Token);
|
|
||||||
}
|
|
||||||
|
|
||||||
jobDispatcher.Run(jobRequestMessage, runOnce);
|
jobDispatcher.Run(jobMessage, runOnce);
|
||||||
if (runOnce)
|
if (runOnce)
|
||||||
{
|
{
|
||||||
Trace.Info("One time used runner received job message.");
|
Trace.Info("One time used runner received job message.");
|
||||||
|
|||||||
@@ -9,7 +9,5 @@ namespace GitHub.Runner.Listener
|
|||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
[DataMember(Name = "runner_request_id")]
|
[DataMember(Name = "runner_request_id")]
|
||||||
public string RunnerRequestId { get; set; }
|
public string RunnerRequestId { get; set; }
|
||||||
[DataMember(Name = "run_service_url")]
|
|
||||||
public string RunServiceUrl { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,14 +32,14 @@ namespace GitHub.Runner.Listener
|
|||||||
private static string _platform = BuildConstants.RunnerPackage.PackageName;
|
private static string _platform = BuildConstants.RunnerPackage.PackageName;
|
||||||
private static string _dotnetRuntime = "dotnetRuntime";
|
private static string _dotnetRuntime = "dotnetRuntime";
|
||||||
private static string _externals = "externals";
|
private static string _externals = "externals";
|
||||||
private readonly Dictionary<string, string> _contentHashes = new();
|
private readonly Dictionary<string, string> _contentHashes = new Dictionary<string, string>();
|
||||||
|
|
||||||
private PackageMetadata _targetPackage;
|
private PackageMetadata _targetPackage;
|
||||||
private ITerminal _terminal;
|
private ITerminal _terminal;
|
||||||
private IRunnerServer _runnerServer;
|
private IRunnerServer _runnerServer;
|
||||||
private int _poolId;
|
private int _poolId;
|
||||||
private int _agentId;
|
private int _agentId;
|
||||||
private readonly ConcurrentQueue<string> _updateTrace = new();
|
private readonly ConcurrentQueue<string> _updateTrace = new ConcurrentQueue<string>();
|
||||||
private Task _cloneAndCalculateContentHashTask;
|
private Task _cloneAndCalculateContentHashTask;
|
||||||
private string _dotnetRuntimeCloneDirectory;
|
private string _dotnetRuntimeCloneDirectory;
|
||||||
private string _externalsCloneDirectory;
|
private string _externalsCloneDirectory;
|
||||||
@@ -134,7 +134,7 @@ namespace GitHub.Runner.Listener
|
|||||||
string flagFile = "update.finished";
|
string flagFile = "update.finished";
|
||||||
IOUtil.DeleteFile(flagFile);
|
IOUtil.DeleteFile(flagFile);
|
||||||
// kick off update script
|
// kick off update script
|
||||||
Process invokeScript = new();
|
Process invokeScript = new Process();
|
||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
invokeScript.StartInfo.FileName = WhichUtil.Which("cmd.exe", trace: Trace);
|
invokeScript.StartInfo.FileName = WhichUtil.Which("cmd.exe", trace: Trace);
|
||||||
invokeScript.StartInfo.Arguments = $"/c \"{updateScript}\"";
|
invokeScript.StartInfo.Arguments = $"/c \"{updateScript}\"";
|
||||||
@@ -191,9 +191,9 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
Trace.Info($"Version '{_targetPackage.Version}' of '{_targetPackage.Type}' package available in server.");
|
Trace.Info($"Version '{_targetPackage.Version}' of '{_targetPackage.Type}' package available in server.");
|
||||||
PackageVersion serverVersion = new(_targetPackage.Version);
|
PackageVersion serverVersion = new PackageVersion(_targetPackage.Version);
|
||||||
Trace.Info($"Current running runner version is {BuildConstants.RunnerPackage.Version}");
|
Trace.Info($"Current running runner version is {BuildConstants.RunnerPackage.Version}");
|
||||||
PackageVersion runnerVersion = new(BuildConstants.RunnerPackage.Version);
|
PackageVersion runnerVersion = new PackageVersion(BuildConstants.RunnerPackage.Version);
|
||||||
|
|
||||||
return serverVersion.CompareTo(runnerVersion) > 0;
|
return serverVersion.CompareTo(runnerVersion) > 0;
|
||||||
}
|
}
|
||||||
@@ -476,7 +476,7 @@ namespace GitHub.Runner.Listener
|
|||||||
long downloadSize = 0;
|
long downloadSize = 0;
|
||||||
|
|
||||||
//open zip stream in async mode
|
//open zip stream in async mode
|
||||||
using (HttpClient httpClient = new(HostContext.CreateHttpClientHandler()))
|
using (HttpClient httpClient = new HttpClient(HostContext.CreateHttpClientHandler()))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_targetPackage.Token))
|
if (!string.IsNullOrEmpty(_targetPackage.Token))
|
||||||
{
|
{
|
||||||
@@ -486,7 +486,7 @@ namespace GitHub.Runner.Listener
|
|||||||
|
|
||||||
Trace.Info($"Downloading {packageDownloadUrl}");
|
Trace.Info($"Downloading {packageDownloadUrl}");
|
||||||
|
|
||||||
using (FileStream fs = new(archiveFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
|
using (FileStream fs = new FileStream(archiveFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
|
||||||
using (Stream result = await httpClient.GetStreamAsync(packageDownloadUrl))
|
using (Stream result = await httpClient.GetStreamAsync(packageDownloadUrl))
|
||||||
{
|
{
|
||||||
//81920 is the default used by System.IO.Stream.CopyTo and is under the large object heap threshold (85k).
|
//81920 is the default used by System.IO.Stream.CopyTo and is under the large object heap threshold (85k).
|
||||||
@@ -596,7 +596,7 @@ namespace GitHub.Runner.Listener
|
|||||||
int exitCode = await processInvoker.ExecuteAsync(extractDirectory, tar, $"-xzf \"{archiveFile}\"", null, token);
|
int exitCode = await processInvoker.ExecuteAsync(extractDirectory, tar, $"-xzf \"{archiveFile}\"", null, token);
|
||||||
if (exitCode != 0)
|
if (exitCode != 0)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException($"Can't use 'tar -xzf' to extract archive file: {archiveFile}. return code: {exitCode}.");
|
throw new NotSupportedException($"Can't use 'tar -xzf' extract archive file: {archiveFile}. return code: {exitCode}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Loader;
|
using System.Runtime.Loader;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
|
|
||||||
@@ -12,7 +15,7 @@ namespace GitHub.Runner.PluginHost
|
|||||||
{
|
{
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
private static CancellationTokenSource tokenSource = new();
|
private static CancellationTokenSource tokenSource = new CancellationTokenSource();
|
||||||
private static string executingAssemblyLocation = string.Empty;
|
private static string executingAssemblyLocation = string.Empty;
|
||||||
|
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64;win-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
<NoWarn>NU1701;NU1603</NoWarn>
|
<NoWarn>NU1701;NU1603</NoWarn>
|
||||||
<Version>$(Version)</Version>
|
<Version>$(Version)</Version>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
string containerPath = actionsStorageArtifact.Name; // In actions storage artifacts, name equals the path
|
string containerPath = actionsStorageArtifact.Name; // In actions storage artifacts, name equals the path
|
||||||
long containerId = actionsStorageArtifact.ContainerId;
|
long containerId = actionsStorageArtifact.ContainerId;
|
||||||
|
|
||||||
FileContainerServer fileContainerServer = new(context.VssConnection, projectId: new Guid(), containerId, containerPath);
|
FileContainerServer fileContainerServer = new FileContainerServer(context.VssConnection, projectId: new Guid(), containerId, containerPath);
|
||||||
await fileContainerServer.DownloadFromContainerAsync(context, targetPath, token);
|
await fileContainerServer.DownloadFromContainerAsync(context, targetPath, token);
|
||||||
|
|
||||||
context.Output("Artifact download finished.");
|
context.Output("Artifact download finished.");
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
//81920 is the default used by System.IO.Stream.CopyTo and is under the large object heap threshold (85k).
|
//81920 is the default used by System.IO.Stream.CopyTo and is under the large object heap threshold (85k).
|
||||||
private const int _defaultCopyBufferSize = 81920;
|
private const int _defaultCopyBufferSize = 81920;
|
||||||
|
|
||||||
private readonly ConcurrentQueue<string> _fileUploadQueue = new();
|
private readonly ConcurrentQueue<string> _fileUploadQueue = new ConcurrentQueue<string>();
|
||||||
private readonly ConcurrentQueue<DownloadInfo> _fileDownloadQueue = new();
|
private readonly ConcurrentQueue<DownloadInfo> _fileDownloadQueue = new ConcurrentQueue<DownloadInfo>();
|
||||||
private readonly ConcurrentDictionary<string, ConcurrentQueue<string>> _fileUploadTraceLog = new();
|
private readonly ConcurrentDictionary<string, ConcurrentQueue<string>> _fileUploadTraceLog = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||||
private readonly ConcurrentDictionary<string, ConcurrentQueue<string>> _fileUploadProgressLog = new();
|
private readonly ConcurrentDictionary<string, ConcurrentQueue<string>> _fileUploadProgressLog = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
|
||||||
private readonly FileContainerHttpClient _fileContainerHttpClient;
|
private readonly FileContainerHttpClient _fileContainerHttpClient;
|
||||||
|
|
||||||
private CancellationTokenSource _uploadCancellationTokenSource;
|
private CancellationTokenSource _uploadCancellationTokenSource;
|
||||||
@@ -67,7 +67,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Find out all container items need to be processed
|
// Find out all container items need to be processed
|
||||||
List<FileContainerItem> containerItems = new();
|
List<FileContainerItem> containerItems = new List<FileContainerItem>();
|
||||||
int retryCount = 0;
|
int retryCount = 0;
|
||||||
while (retryCount < 3)
|
while (retryCount < 3)
|
||||||
{
|
{
|
||||||
@@ -106,7 +106,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
// Create all required empty folders and emptry files, gather a list of files that we need to download from server.
|
// Create all required empty folders and emptry files, gather a list of files that we need to download from server.
|
||||||
int foldersCreated = 0;
|
int foldersCreated = 0;
|
||||||
int emptryFilesCreated = 0;
|
int emptryFilesCreated = 0;
|
||||||
List<DownloadInfo> downloadFiles = new();
|
List<DownloadInfo> downloadFiles = new List<DownloadInfo>();
|
||||||
foreach (var item in containerItems.OrderBy(x => x.Path))
|
foreach (var item in containerItems.OrderBy(x => x.Path))
|
||||||
{
|
{
|
||||||
if (!item.Path.StartsWith(_containerPath, StringComparison.OrdinalIgnoreCase))
|
if (!item.Path.StartsWith(_containerPath, StringComparison.OrdinalIgnoreCase))
|
||||||
@@ -306,7 +306,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
Task downloadMonitor = DownloadReportingAsync(context, files.Count(), token);
|
Task downloadMonitor = DownloadReportingAsync(context, files.Count(), token);
|
||||||
|
|
||||||
// Start parallel download tasks.
|
// Start parallel download tasks.
|
||||||
List<Task<DownloadResult>> parallelDownloadingTasks = new();
|
List<Task<DownloadResult>> parallelDownloadingTasks = new List<Task<DownloadResult>>();
|
||||||
for (int downloader = 0; downloader < concurrentDownloads; downloader++)
|
for (int downloader = 0; downloader < concurrentDownloads; downloader++)
|
||||||
{
|
{
|
||||||
parallelDownloadingTasks.Add(DownloadAsync(context, downloader, token));
|
parallelDownloadingTasks.Add(DownloadAsync(context, downloader, token));
|
||||||
@@ -358,7 +358,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
Task uploadMonitor = UploadReportingAsync(context, files.Count(), _uploadCancellationTokenSource.Token);
|
Task uploadMonitor = UploadReportingAsync(context, files.Count(), _uploadCancellationTokenSource.Token);
|
||||||
|
|
||||||
// Start parallel upload tasks.
|
// Start parallel upload tasks.
|
||||||
List<Task<UploadResult>> parallelUploadingTasks = new();
|
List<Task<UploadResult>> parallelUploadingTasks = new List<Task<UploadResult>>();
|
||||||
for (int uploader = 0; uploader < concurrentUploads; uploader++)
|
for (int uploader = 0; uploader < concurrentUploads; uploader++)
|
||||||
{
|
{
|
||||||
parallelUploadingTasks.Add(UploadAsync(context, uploader, _uploadCancellationTokenSource.Token));
|
parallelUploadingTasks.Add(UploadAsync(context, uploader, _uploadCancellationTokenSource.Token));
|
||||||
@@ -381,8 +381,8 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
|
|
||||||
private async Task<DownloadResult> DownloadAsync(RunnerActionPluginExecutionContext context, int downloaderId, CancellationToken token)
|
private async Task<DownloadResult> DownloadAsync(RunnerActionPluginExecutionContext context, int downloaderId, CancellationToken token)
|
||||||
{
|
{
|
||||||
List<DownloadInfo> failedFiles = new();
|
List<DownloadInfo> failedFiles = new List<DownloadInfo>();
|
||||||
Stopwatch downloadTimer = new();
|
Stopwatch downloadTimer = new Stopwatch();
|
||||||
while (_fileDownloadQueue.TryDequeue(out DownloadInfo fileToDownload))
|
while (_fileDownloadQueue.TryDequeue(out DownloadInfo fileToDownload))
|
||||||
{
|
{
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
@@ -396,7 +396,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
{
|
{
|
||||||
context.Debug($"Start downloading file: '{fileToDownload.ItemPath}' (Downloader {downloaderId})");
|
context.Debug($"Start downloading file: '{fileToDownload.ItemPath}' (Downloader {downloaderId})");
|
||||||
downloadTimer.Restart();
|
downloadTimer.Restart();
|
||||||
using (FileStream fs = new(fileToDownload.LocalPath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: _defaultFileStreamBufferSize, useAsync: true))
|
using (FileStream fs = new FileStream(fileToDownload.LocalPath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: _defaultFileStreamBufferSize, useAsync: true))
|
||||||
using (var downloadStream = await _fileContainerHttpClient.DownloadFileAsync(_containerId, fileToDownload.ItemPath, token, _projectId))
|
using (var downloadStream = await _fileContainerHttpClient.DownloadFileAsync(_containerId, fileToDownload.ItemPath, token, _projectId))
|
||||||
{
|
{
|
||||||
await downloadStream.CopyToAsync(fs, _defaultCopyBufferSize, token);
|
await downloadStream.CopyToAsync(fs, _defaultCopyBufferSize, token);
|
||||||
@@ -453,10 +453,10 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
|
|
||||||
private async Task<UploadResult> UploadAsync(RunnerActionPluginExecutionContext context, int uploaderId, CancellationToken token)
|
private async Task<UploadResult> UploadAsync(RunnerActionPluginExecutionContext context, int uploaderId, CancellationToken token)
|
||||||
{
|
{
|
||||||
List<string> failedFiles = new();
|
List<string> failedFiles = new List<string>();
|
||||||
long uploadedSize = 0;
|
long uploadedSize = 0;
|
||||||
string fileToUpload;
|
string fileToUpload;
|
||||||
Stopwatch uploadTimer = new();
|
Stopwatch uploadTimer = new Stopwatch();
|
||||||
while (_fileUploadQueue.TryDequeue(out fileToUpload))
|
while (_fileUploadQueue.TryDequeue(out fileToUpload))
|
||||||
{
|
{
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.Actions.Pipelines.WebApi;
|
using GitHub.Actions.Pipelines.WebApi;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
|
|
||||||
context.Output($"Uploading artifact '{artifactName}' from '{fullPath}' for run #{buildId}");
|
context.Output($"Uploading artifact '{artifactName}' from '{fullPath}' for run #{buildId}");
|
||||||
|
|
||||||
FileContainerServer fileContainerHelper = new(context.VssConnection, projectId: Guid.Empty, containerId, artifactName);
|
FileContainerServer fileContainerHelper = new FileContainerServer(context.VssConnection, projectId: Guid.Empty, containerId, artifactName);
|
||||||
var propertiesDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
var propertiesDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
long size = 0;
|
long size = 0;
|
||||||
@@ -87,7 +87,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
|||||||
// Definition ID is a dummy value only used by HTTP client routing purposes
|
// Definition ID is a dummy value only used by HTTP client routing purposes
|
||||||
int definitionId = 1;
|
int definitionId = 1;
|
||||||
|
|
||||||
PipelinesServer pipelinesHelper = new(context.VssConnection);
|
PipelinesServer pipelinesHelper = new PipelinesServer(context.VssConnection);
|
||||||
|
|
||||||
var artifact = await pipelinesHelper.AssociateActionsStorageArtifactAsync(
|
var artifact = await pipelinesHelper.AssociateActionsStorageArtifactAsync(
|
||||||
definitionId,
|
definitionId,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@@ -8,6 +9,7 @@ using System.Threading.Tasks;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using GitHub.Services.Common;
|
using GitHub.Services.Common;
|
||||||
|
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||||
|
|
||||||
namespace GitHub.Runner.Plugins.Repository
|
namespace GitHub.Runner.Plugins.Repository
|
||||||
{
|
{
|
||||||
@@ -18,7 +20,7 @@ namespace GitHub.Runner.Plugins.Repository
|
|||||||
#else
|
#else
|
||||||
private static readonly Encoding s_encoding = null;
|
private static readonly Encoding s_encoding = null;
|
||||||
#endif
|
#endif
|
||||||
private readonly Dictionary<string, string> gitEnv = new(StringComparer.OrdinalIgnoreCase)
|
private readonly Dictionary<string, string> gitEnv = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
{ "GIT_TERMINAL_PROMPT", "0" },
|
{ "GIT_TERMINAL_PROMPT", "0" },
|
||||||
};
|
};
|
||||||
@@ -92,11 +94,11 @@ namespace GitHub.Runner.Plugins.Repository
|
|||||||
}
|
}
|
||||||
|
|
||||||
// required 2.0, all git operation commandline args need min git version 2.0
|
// required 2.0, all git operation commandline args need min git version 2.0
|
||||||
Version minRequiredGitVersion = new(2, 0);
|
Version minRequiredGitVersion = new Version(2, 0);
|
||||||
EnsureGitVersion(minRequiredGitVersion, throwOnNotMatch: true);
|
EnsureGitVersion(minRequiredGitVersion, throwOnNotMatch: true);
|
||||||
|
|
||||||
// suggest user upgrade to 2.9 for better git experience
|
// suggest user upgrade to 2.9 for better git experience
|
||||||
Version recommendGitVersion = new(2, 9);
|
Version recommendGitVersion = new Version(2, 9);
|
||||||
if (!EnsureGitVersion(recommendGitVersion, throwOnNotMatch: false))
|
if (!EnsureGitVersion(recommendGitVersion, throwOnNotMatch: false))
|
||||||
{
|
{
|
||||||
context.Output($"To get a better Git experience, upgrade your Git to at least version '{recommendGitVersion}'. Your current Git version is '{gitVersion}'.");
|
context.Output($"To get a better Git experience, upgrade your Git to at least version '{recommendGitVersion}'. Your current Git version is '{gitVersion}'.");
|
||||||
@@ -430,7 +432,7 @@ namespace GitHub.Runner.Plugins.Repository
|
|||||||
context.Debug($"Inspect remote.origin.url for repository under {repositoryPath}");
|
context.Debug($"Inspect remote.origin.url for repository under {repositoryPath}");
|
||||||
Uri fetchUrl = null;
|
Uri fetchUrl = null;
|
||||||
|
|
||||||
List<string> outputStrings = new();
|
List<string> outputStrings = new List<string>();
|
||||||
int exitCode = await ExecuteGitCommandAsync(context, repositoryPath, "config", "--get remote.origin.url", outputStrings);
|
int exitCode = await ExecuteGitCommandAsync(context, repositoryPath, "config", "--get remote.origin.url", outputStrings);
|
||||||
|
|
||||||
if (exitCode != 0)
|
if (exitCode != 0)
|
||||||
@@ -477,7 +479,7 @@ namespace GitHub.Runner.Plugins.Repository
|
|||||||
context.Debug($"Checking git config {configKey} exist or not");
|
context.Debug($"Checking git config {configKey} exist or not");
|
||||||
|
|
||||||
// ignore any outputs by redirect them into a string list, since the output might contains secrets.
|
// ignore any outputs by redirect them into a string list, since the output might contains secrets.
|
||||||
List<string> outputStrings = new();
|
List<string> outputStrings = new List<string>();
|
||||||
int exitcode = await ExecuteGitCommandAsync(context, repositoryPath, "config", StringUtil.Format($"--get-all {configKey}"), outputStrings);
|
int exitcode = await ExecuteGitCommandAsync(context, repositoryPath, "config", StringUtil.Format($"--get-all {configKey}"), outputStrings);
|
||||||
|
|
||||||
return exitcode == 0;
|
return exitcode == 0;
|
||||||
@@ -539,7 +541,7 @@ namespace GitHub.Runner.Plugins.Repository
|
|||||||
string runnerWorkspace = context.GetRunnerContext("workspace");
|
string runnerWorkspace = context.GetRunnerContext("workspace");
|
||||||
ArgUtil.Directory(runnerWorkspace, "runnerWorkspace");
|
ArgUtil.Directory(runnerWorkspace, "runnerWorkspace");
|
||||||
Version version = null;
|
Version version = null;
|
||||||
List<string> outputStrings = new();
|
List<string> outputStrings = new List<string>();
|
||||||
int exitCode = await ExecuteGitCommandAsync(context, runnerWorkspace, "version", null, outputStrings);
|
int exitCode = await ExecuteGitCommandAsync(context, runnerWorkspace, "version", null, outputStrings);
|
||||||
context.Output($"{string.Join(Environment.NewLine, outputStrings)}");
|
context.Output($"{string.Join(Environment.NewLine, outputStrings)}");
|
||||||
if (exitCode == 0)
|
if (exitCode == 0)
|
||||||
@@ -550,7 +552,7 @@ namespace GitHub.Runner.Plugins.Repository
|
|||||||
{
|
{
|
||||||
string verString = outputStrings.First();
|
string verString = outputStrings.First();
|
||||||
// we interested about major.minor.patch version
|
// we interested about major.minor.patch version
|
||||||
Regex verRegex = new("\\d+\\.\\d+(\\.\\d+)?", RegexOptions.IgnoreCase);
|
Regex verRegex = new Regex("\\d+\\.\\d+(\\.\\d+)?", RegexOptions.IgnoreCase);
|
||||||
var matchResult = verRegex.Match(verString);
|
var matchResult = verRegex.Match(verString);
|
||||||
if (matchResult.Success && !string.IsNullOrEmpty(matchResult.Value))
|
if (matchResult.Success && !string.IsNullOrEmpty(matchResult.Value))
|
||||||
{
|
{
|
||||||
@@ -572,7 +574,7 @@ namespace GitHub.Runner.Plugins.Repository
|
|||||||
string runnerWorkspace = context.GetRunnerContext("workspace");
|
string runnerWorkspace = context.GetRunnerContext("workspace");
|
||||||
ArgUtil.Directory(runnerWorkspace, "runnerWorkspace");
|
ArgUtil.Directory(runnerWorkspace, "runnerWorkspace");
|
||||||
Version version = null;
|
Version version = null;
|
||||||
List<string> outputStrings = new();
|
List<string> outputStrings = new List<string>();
|
||||||
int exitCode = await ExecuteGitCommandAsync(context, runnerWorkspace, "lfs version", null, outputStrings);
|
int exitCode = await ExecuteGitCommandAsync(context, runnerWorkspace, "lfs version", null, outputStrings);
|
||||||
context.Output($"{string.Join(Environment.NewLine, outputStrings)}");
|
context.Output($"{string.Join(Environment.NewLine, outputStrings)}");
|
||||||
if (exitCode == 0)
|
if (exitCode == 0)
|
||||||
@@ -583,7 +585,7 @@ namespace GitHub.Runner.Plugins.Repository
|
|||||||
{
|
{
|
||||||
string verString = outputStrings.First();
|
string verString = outputStrings.First();
|
||||||
// we interested about major.minor.patch version
|
// we interested about major.minor.patch version
|
||||||
Regex verRegex = new("\\d+\\.\\d+(\\.\\d+)?", RegexOptions.IgnoreCase);
|
Regex verRegex = new Regex("\\d+\\.\\d+(\\.\\d+)?", RegexOptions.IgnoreCase);
|
||||||
var matchResult = verRegex.Match(verString);
|
var matchResult = verRegex.Match(verString);
|
||||||
if (matchResult.Success && !string.IsNullOrEmpty(matchResult.Value))
|
if (matchResult.Success && !string.IsNullOrEmpty(matchResult.Value))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ using System.Threading.Tasks;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Diagnostics;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
|
using GitHub.Services.WebApi;
|
||||||
|
|
||||||
namespace GitHub.Runner.Plugins.Repository.v1_0
|
namespace GitHub.Runner.Plugins.Repository.v1_0
|
||||||
{
|
{
|
||||||
@@ -21,7 +23,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_0
|
|||||||
private const string _remotePullRefsPrefix = "refs/remotes/pull/";
|
private const string _remotePullRefsPrefix = "refs/remotes/pull/";
|
||||||
|
|
||||||
// min git version that support add extra auth header.
|
// min git version that support add extra auth header.
|
||||||
private Version _minGitVersionSupportAuthHeader = new(2, 9);
|
private Version _minGitVersionSupportAuthHeader = new Version(2, 9);
|
||||||
|
|
||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
// min git version that support override sslBackend setting.
|
// min git version that support override sslBackend setting.
|
||||||
@@ -29,7 +31,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_0
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// min git-lfs version that support add extra auth header.
|
// min git-lfs version that support add extra auth header.
|
||||||
private Version _minGitLfsVersionSupportAuthHeader = new(2, 1);
|
private Version _minGitLfsVersionSupportAuthHeader = new Version(2, 1);
|
||||||
|
|
||||||
private void RequirementCheck(RunnerActionPluginExecutionContext executionContext, GitCliManager gitCommandManager, bool checkGitLfs)
|
private void RequirementCheck(RunnerActionPluginExecutionContext executionContext, GitCliManager gitCommandManager, bool checkGitLfs)
|
||||||
{
|
{
|
||||||
@@ -83,7 +85,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_0
|
|||||||
var githubUrl = executionContext.GetGitHubContext("server_url");
|
var githubUrl = executionContext.GetGitHubContext("server_url");
|
||||||
var githubUri = new Uri(!string.IsNullOrEmpty(githubUrl) ? githubUrl : "https://github.com");
|
var githubUri = new Uri(!string.IsNullOrEmpty(githubUrl) ? githubUrl : "https://github.com");
|
||||||
var portInfo = githubUri.IsDefaultPort ? string.Empty : $":{githubUri.Port}";
|
var portInfo = githubUri.IsDefaultPort ? string.Empty : $":{githubUri.Port}";
|
||||||
Uri repositoryUrl = new($"{githubUri.Scheme}://{githubUri.Host}{portInfo}/{repoFullName}");
|
Uri repositoryUrl = new Uri($"{githubUri.Scheme}://{githubUri.Host}{portInfo}/{repoFullName}");
|
||||||
if (!repositoryUrl.IsAbsoluteUri)
|
if (!repositoryUrl.IsAbsoluteUri)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Repository url need to be an absolute uri.");
|
throw new InvalidOperationException("Repository url need to be an absolute uri.");
|
||||||
@@ -121,7 +123,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_0
|
|||||||
executionContext.Debug($"gitLfsSupport={gitLfsSupport}");
|
executionContext.Debug($"gitLfsSupport={gitLfsSupport}");
|
||||||
|
|
||||||
// Initialize git command manager with additional environment variables.
|
// Initialize git command manager with additional environment variables.
|
||||||
Dictionary<string, string> gitEnv = new(StringComparer.OrdinalIgnoreCase);
|
Dictionary<string, string> gitEnv = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
// Disable prompting for git credential manager
|
// Disable prompting for git credential manager
|
||||||
gitEnv["GCM_INTERACTIVE"] = "Never";
|
gitEnv["GCM_INTERACTIVE"] = "Never";
|
||||||
@@ -141,7 +143,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_0
|
|||||||
gitEnv[formattedKey] = variable.Value?.Value ?? string.Empty;
|
gitEnv[formattedKey] = variable.Value?.Value ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
GitCliManager gitCommandManager = new(gitEnv);
|
GitCliManager gitCommandManager = new GitCliManager(gitEnv);
|
||||||
await gitCommandManager.LoadGitExecutionInfo(executionContext);
|
await gitCommandManager.LoadGitExecutionInfo(executionContext);
|
||||||
|
|
||||||
// Make sure the build machine met all requirements for the git repository
|
// Make sure the build machine met all requirements for the git repository
|
||||||
@@ -293,8 +295,8 @@ namespace GitHub.Runner.Plugins.Repository.v1_0
|
|||||||
await RemoveGitConfig(executionContext, gitCommandManager, targetPath, $"http.{repositoryUrl.AbsoluteUri}.extraheader", string.Empty);
|
await RemoveGitConfig(executionContext, gitCommandManager, targetPath, $"http.{repositoryUrl.AbsoluteUri}.extraheader", string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> additionalFetchArgs = new();
|
List<string> additionalFetchArgs = new List<string>();
|
||||||
List<string> additionalLfsFetchArgs = new();
|
List<string> additionalLfsFetchArgs = new List<string>();
|
||||||
|
|
||||||
// add accessToken as basic auth header to handle auth challenge.
|
// add accessToken as basic auth header to handle auth challenge.
|
||||||
if (!string.IsNullOrEmpty(accessToken))
|
if (!string.IsNullOrEmpty(accessToken))
|
||||||
@@ -320,7 +322,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_0
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> additionalFetchSpecs = new();
|
List<string> additionalFetchSpecs = new List<string>();
|
||||||
additionalFetchSpecs.Add("+refs/heads/*:refs/remotes/origin/*");
|
additionalFetchSpecs.Add("+refs/heads/*:refs/remotes/origin/*");
|
||||||
|
|
||||||
if (IsPullRequest(sourceBranch))
|
if (IsPullRequest(sourceBranch))
|
||||||
@@ -395,7 +397,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_0
|
|||||||
throw new InvalidOperationException($"Git submodule sync failed with exit code: {exitCode_submoduleSync}");
|
throw new InvalidOperationException($"Git submodule sync failed with exit code: {exitCode_submoduleSync}");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> additionalSubmoduleUpdateArgs = new();
|
List<string> additionalSubmoduleUpdateArgs = new List<string>();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(accessToken))
|
if (!string.IsNullOrEmpty(accessToken))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using GitHub.DistributedTask.Pipelines.Expressions;
|
using GitHub.DistributedTask.Pipelines.Expressions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -12,7 +15,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_0
|
|||||||
{
|
{
|
||||||
public class CheckoutTask : IRunnerActionPlugin
|
public class CheckoutTask : IRunnerActionPlugin
|
||||||
{
|
{
|
||||||
private readonly Regex _validSha1 = new(@"\b[0-9a-f]{40}\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled, TimeSpan.FromSeconds(2));
|
private readonly Regex _validSha1 = new Regex(@"\b[0-9a-f]{40}\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled, TimeSpan.FromSeconds(2));
|
||||||
|
|
||||||
public async Task RunAsync(RunnerActionPluginExecutionContext executionContext, CancellationToken token)
|
public async Task RunAsync(RunnerActionPluginExecutionContext executionContext, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ using System.Collections.Generic;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Diagnostics;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
@@ -22,7 +24,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_1
|
|||||||
private const string _tagRefsPrefix = "refs/tags/";
|
private const string _tagRefsPrefix = "refs/tags/";
|
||||||
|
|
||||||
// min git version that support add extra auth header.
|
// min git version that support add extra auth header.
|
||||||
private Version _minGitVersionSupportAuthHeader = new(2, 9);
|
private Version _minGitVersionSupportAuthHeader = new Version(2, 9);
|
||||||
|
|
||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
// min git version that support override sslBackend setting.
|
// min git version that support override sslBackend setting.
|
||||||
@@ -30,7 +32,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_1
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// min git-lfs version that support add extra auth header.
|
// min git-lfs version that support add extra auth header.
|
||||||
private Version _minGitLfsVersionSupportAuthHeader = new(2, 1);
|
private Version _minGitLfsVersionSupportAuthHeader = new Version(2, 1);
|
||||||
|
|
||||||
public static string ProblemMatcher => @"
|
public static string ProblemMatcher => @"
|
||||||
{
|
{
|
||||||
@@ -62,9 +64,9 @@ namespace GitHub.Runner.Plugins.Repository.v1_1
|
|||||||
{
|
{
|
||||||
// Validate args.
|
// Validate args.
|
||||||
ArgUtil.NotNull(executionContext, nameof(executionContext));
|
ArgUtil.NotNull(executionContext, nameof(executionContext));
|
||||||
Dictionary<string, string> configModifications = new();
|
Dictionary<string, string> configModifications = new Dictionary<string, string>();
|
||||||
executionContext.Output($"Syncing repository: {repoFullName}");
|
executionContext.Output($"Syncing repository: {repoFullName}");
|
||||||
Uri repositoryUrl = new($"https://github.com/{repoFullName}");
|
Uri repositoryUrl = new Uri($"https://github.com/{repoFullName}");
|
||||||
if (!repositoryUrl.IsAbsoluteUri)
|
if (!repositoryUrl.IsAbsoluteUri)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Repository url need to be an absolute uri.");
|
throw new InvalidOperationException("Repository url need to be an absolute uri.");
|
||||||
@@ -102,7 +104,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_1
|
|||||||
executionContext.Debug($"gitLfsSupport={gitLfsSupport}");
|
executionContext.Debug($"gitLfsSupport={gitLfsSupport}");
|
||||||
|
|
||||||
// Initialize git command manager with additional environment variables.
|
// Initialize git command manager with additional environment variables.
|
||||||
Dictionary<string, string> gitEnv = new(StringComparer.OrdinalIgnoreCase);
|
Dictionary<string, string> gitEnv = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
// Disable git prompt
|
// Disable git prompt
|
||||||
gitEnv["GIT_TERMINAL_PROMPT"] = "0";
|
gitEnv["GIT_TERMINAL_PROMPT"] = "0";
|
||||||
@@ -125,7 +127,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_1
|
|||||||
gitEnv[formattedKey] = variable.Value?.Value ?? string.Empty;
|
gitEnv[formattedKey] = variable.Value?.Value ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
GitCliManager gitCommandManager = new(gitEnv);
|
GitCliManager gitCommandManager = new GitCliManager(gitEnv);
|
||||||
await gitCommandManager.LoadGitExecutionInfo(executionContext);
|
await gitCommandManager.LoadGitExecutionInfo(executionContext);
|
||||||
|
|
||||||
// Make sure the build machine met all requirements for the git repository
|
// Make sure the build machine met all requirements for the git repository
|
||||||
@@ -277,8 +279,8 @@ namespace GitHub.Runner.Plugins.Repository.v1_1
|
|||||||
await RemoveGitConfig(executionContext, gitCommandManager, targetPath, $"http.{repositoryUrl.AbsoluteUri}.extraheader", string.Empty);
|
await RemoveGitConfig(executionContext, gitCommandManager, targetPath, $"http.{repositoryUrl.AbsoluteUri}.extraheader", string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> additionalFetchArgs = new();
|
List<string> additionalFetchArgs = new List<string>();
|
||||||
List<string> additionalLfsFetchArgs = new();
|
List<string> additionalLfsFetchArgs = new List<string>();
|
||||||
|
|
||||||
// Add http.https://github.com.extraheader=... to gitconfig
|
// Add http.https://github.com.extraheader=... to gitconfig
|
||||||
// accessToken as basic auth header to handle any auth challenge from github.com
|
// accessToken as basic auth header to handle any auth challenge from github.com
|
||||||
@@ -303,7 +305,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_1
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> additionalFetchSpecs = new();
|
List<string> additionalFetchSpecs = new List<string>();
|
||||||
additionalFetchSpecs.Add("+refs/heads/*:refs/remotes/origin/*");
|
additionalFetchSpecs.Add("+refs/heads/*:refs/remotes/origin/*");
|
||||||
|
|
||||||
if (IsPullRequest(sourceBranch))
|
if (IsPullRequest(sourceBranch))
|
||||||
@@ -378,7 +380,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_1
|
|||||||
throw new InvalidOperationException($"Git submodule sync failed with exit code: {exitCode_submoduleSync}");
|
throw new InvalidOperationException($"Git submodule sync failed with exit code: {exitCode_submoduleSync}");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> additionalSubmoduleUpdateArgs = new();
|
List<string> additionalSubmoduleUpdateArgs = new List<string>();
|
||||||
|
|
||||||
int exitCode_submoduleUpdate = await gitCommandManager.GitSubmoduleUpdate(executionContext, targetPath, fetchDepth, string.Join(" ", additionalSubmoduleUpdateArgs), checkoutNestedSubmodules, cancellationToken);
|
int exitCode_submoduleUpdate = await gitCommandManager.GitSubmoduleUpdate(executionContext, targetPath, fetchDepth, string.Join(" ", additionalSubmoduleUpdateArgs), checkoutNestedSubmodules, cancellationToken);
|
||||||
if (exitCode_submoduleUpdate != 0)
|
if (exitCode_submoduleUpdate != 0)
|
||||||
@@ -404,7 +406,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_1
|
|||||||
executionContext.Output($"Cleanup cached git credential from {repositoryPath}.");
|
executionContext.Output($"Cleanup cached git credential from {repositoryPath}.");
|
||||||
|
|
||||||
// Initialize git command manager
|
// Initialize git command manager
|
||||||
GitCliManager gitCommandManager = new();
|
GitCliManager gitCommandManager = new GitCliManager();
|
||||||
await gitCommandManager.LoadGitExecutionInfo(executionContext);
|
await gitCommandManager.LoadGitExecutionInfo(executionContext);
|
||||||
|
|
||||||
executionContext.Debug("Remove any extraheader setting from git config.");
|
executionContext.Debug("Remove any extraheader setting from git config.");
|
||||||
@@ -499,7 +501,7 @@ namespace GitHub.Runner.Plugins.Repository.v1_1
|
|||||||
string gitConfig = Path.Combine(targetPath, ".git/config");
|
string gitConfig = Path.Combine(targetPath, ".git/config");
|
||||||
if (File.Exists(gitConfig))
|
if (File.Exists(gitConfig))
|
||||||
{
|
{
|
||||||
List<string> safeGitConfig = new();
|
List<string> safeGitConfig = new List<string>();
|
||||||
var gitConfigContents = File.ReadAllLines(gitConfig);
|
var gitConfigContents = File.ReadAllLines(gitConfig);
|
||||||
foreach (var line in gitConfigContents)
|
foreach (var line in gitConfigContents)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using GitHub.DistributedTask.Pipelines.Expressions;
|
using GitHub.DistributedTask.Pipelines.Expressions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64;win-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
<NoWarn>NU1701;NU1603</NoWarn>
|
<NoWarn>NU1701;NU1603</NoWarn>
|
||||||
<Version>$(Version)</Version>
|
<Version>$(Version)</Version>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -10,6 +11,7 @@ using GitHub.DistributedTask.WebApi;
|
|||||||
using GitHub.Services.Common;
|
using GitHub.Services.Common;
|
||||||
using GitHub.Services.WebApi;
|
using GitHub.Services.WebApi;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||||
|
|
||||||
namespace GitHub.Runner.Sdk
|
namespace GitHub.Runner.Sdk
|
||||||
{
|
{
|
||||||
@@ -23,7 +25,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
private readonly string DebugEnvironmentalVariable = "ACTIONS_STEP_DEBUG";
|
private readonly string DebugEnvironmentalVariable = "ACTIONS_STEP_DEBUG";
|
||||||
private VssConnection _connection;
|
private VssConnection _connection;
|
||||||
private RunnerWebProxy _webProxy;
|
private RunnerWebProxy _webProxy;
|
||||||
private readonly object _stdoutLock = new();
|
private readonly object _stdoutLock = new object();
|
||||||
private readonly ITraceWriter _trace; // for unit tests
|
private readonly ITraceWriter _trace; // for unit tests
|
||||||
|
|
||||||
public RunnerActionPluginExecutionContext()
|
public RunnerActionPluginExecutionContext()
|
||||||
@@ -220,7 +222,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, string> _commandEscapeMappings = new(StringComparer.OrdinalIgnoreCase)
|
private Dictionary<string, string> _commandEscapeMappings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
";", "%3B"
|
";", "%3B"
|
||||||
|
|||||||
@@ -24,18 +24,18 @@ namespace GitHub.Runner.Sdk
|
|||||||
private Stopwatch _stopWatch;
|
private Stopwatch _stopWatch;
|
||||||
private int _asyncStreamReaderCount = 0;
|
private int _asyncStreamReaderCount = 0;
|
||||||
private bool _waitingOnStreams = false;
|
private bool _waitingOnStreams = false;
|
||||||
private readonly AsyncManualResetEvent _outputProcessEvent = new();
|
private readonly AsyncManualResetEvent _outputProcessEvent = new AsyncManualResetEvent();
|
||||||
private readonly TaskCompletionSource<bool> _processExitedCompletionSource = new();
|
private readonly TaskCompletionSource<bool> _processExitedCompletionSource = new TaskCompletionSource<bool>();
|
||||||
private readonly CancellationTokenSource _processStandardInWriteCancellationTokenSource = new();
|
private readonly CancellationTokenSource _processStandardInWriteCancellationTokenSource = new CancellationTokenSource();
|
||||||
private readonly ConcurrentQueue<string> _errorData = new();
|
private readonly ConcurrentQueue<string> _errorData = new ConcurrentQueue<string>();
|
||||||
private readonly ConcurrentQueue<string> _outputData = new();
|
private readonly ConcurrentQueue<string> _outputData = new ConcurrentQueue<string>();
|
||||||
private readonly TimeSpan _sigintTimeout = TimeSpan.FromMilliseconds(7500);
|
private readonly TimeSpan _sigintTimeout = TimeSpan.FromMilliseconds(7500);
|
||||||
private readonly TimeSpan _sigtermTimeout = TimeSpan.FromMilliseconds(2500);
|
private readonly TimeSpan _sigtermTimeout = TimeSpan.FromMilliseconds(2500);
|
||||||
private ITraceWriter Trace { get; set; }
|
private ITraceWriter Trace { get; set; }
|
||||||
|
|
||||||
private class AsyncManualResetEvent
|
private class AsyncManualResetEvent
|
||||||
{
|
{
|
||||||
private volatile TaskCompletionSource<bool> m_tcs = new();
|
private volatile TaskCompletionSource<bool> m_tcs = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
public Task WaitAsync() { return m_tcs.Task; }
|
public Task WaitAsync() { return m_tcs.Task; }
|
||||||
|
|
||||||
@@ -387,8 +387,8 @@ namespace GitHub.Runner.Sdk
|
|||||||
|
|
||||||
private void ProcessOutput()
|
private void ProcessOutput()
|
||||||
{
|
{
|
||||||
List<string> errorData = new();
|
List<string> errorData = new List<string>();
|
||||||
List<string> outputData = new();
|
List<string> outputData = new List<string>();
|
||||||
|
|
||||||
string errorLine;
|
string errorLine;
|
||||||
while (_errorData.TryDequeue(out errorLine))
|
while (_errorData.TryDequeue(out errorLine))
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64;win-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
<NoWarn>NU1701;NU1603</NoWarn>
|
<NoWarn>NU1701;NU1603</NoWarn>
|
||||||
<Version>$(Version)</Version>
|
<Version>$(Version)</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Sdk\Sdk.csproj" />
|
<ProjectReference Include="..\Sdk\Sdk.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ namespace GitHub.Runner.Sdk
|
|||||||
private string _httpsProxyPassword;
|
private string _httpsProxyPassword;
|
||||||
private string _noProxyString;
|
private string _noProxyString;
|
||||||
|
|
||||||
private readonly List<ByPassInfo> _noProxyList = new();
|
private readonly List<ByPassInfo> _noProxyList = new List<ByPassInfo>();
|
||||||
private readonly HashSet<string> _noProxyUnique = new(StringComparer.OrdinalIgnoreCase);
|
private readonly HashSet<string> _noProxyUnique = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private readonly Regex _validIpRegex = new("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$", RegexOptions.Compiled);
|
private readonly Regex _validIpRegex = new Regex("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$", RegexOptions.Compiled);
|
||||||
|
|
||||||
public string HttpProxyAddress => _httpProxyAddress;
|
public string HttpProxyAddress => _httpProxyAddress;
|
||||||
public string HttpProxyUsername => _httpProxyUsername;
|
public string HttpProxyUsername => _httpProxyUsername;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -52,7 +53,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
using (SHA256 sha256hash = SHA256.Create())
|
using (SHA256 sha256hash = SHA256.Create())
|
||||||
{
|
{
|
||||||
byte[] data = sha256hash.ComputeHash(Encoding.UTF8.GetBytes(hashString));
|
byte[] data = sha256hash.ComputeHash(Encoding.UTF8.GetBytes(hashString));
|
||||||
StringBuilder sBuilder = new();
|
StringBuilder sBuilder = new StringBuilder();
|
||||||
for (int i = 0; i < data.Length; i++)
|
for (int i = 0; i < data.Length; i++)
|
||||||
{
|
{
|
||||||
sBuilder.Append(data[i].ToString("x2"));
|
sBuilder.Append(data[i].ToString("x2"));
|
||||||
@@ -77,7 +78,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
public static void DeleteDirectory(string path, bool contentsOnly, bool continueOnContentDeleteError, CancellationToken cancellationToken)
|
public static void DeleteDirectory(string path, bool contentsOnly, bool continueOnContentDeleteError, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
ArgUtil.NotNullOrEmpty(path, nameof(path));
|
ArgUtil.NotNullOrEmpty(path, nameof(path));
|
||||||
DirectoryInfo directory = new(path);
|
DirectoryInfo directory = new DirectoryInfo(path);
|
||||||
if (!directory.Exists)
|
if (!directory.Exists)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -363,12 +364,12 @@ namespace GitHub.Runner.Sdk
|
|||||||
Directory.CreateDirectory(target);
|
Directory.CreateDirectory(target);
|
||||||
|
|
||||||
// Get the file contents of the directory to copy.
|
// Get the file contents of the directory to copy.
|
||||||
DirectoryInfo sourceDir = new(source);
|
DirectoryInfo sourceDir = new DirectoryInfo(source);
|
||||||
foreach (FileInfo sourceFile in sourceDir.GetFiles() ?? new FileInfo[0])
|
foreach (FileInfo sourceFile in sourceDir.GetFiles() ?? new FileInfo[0])
|
||||||
{
|
{
|
||||||
// Check if the file already exists.
|
// Check if the file already exists.
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
FileInfo targetFile = new(Path.Combine(target, sourceFile.Name));
|
FileInfo targetFile = new FileInfo(Path.Combine(target, sourceFile.Name));
|
||||||
if (!targetFile.Exists ||
|
if (!targetFile.Exists ||
|
||||||
sourceFile.Length != targetFile.Length ||
|
sourceFile.Length != targetFile.Length ||
|
||||||
sourceFile.LastWriteTime != targetFile.LastWriteTime)
|
sourceFile.LastWriteTime != targetFile.LastWriteTime)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace GitHub.Runner.Sdk
|
namespace GitHub.Runner.Sdk
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
using GitHub.Services.WebApi;
|
using GitHub.Services.WebApi;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace GitHub.Runner.Sdk
|
namespace GitHub.Runner.Sdk
|
||||||
@@ -9,7 +13,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
public static class StringUtil
|
public static class StringUtil
|
||||||
{
|
{
|
||||||
private static readonly object[] s_defaultFormatArgs = new object[] { null };
|
private static readonly object[] s_defaultFormatArgs = new object[] { null };
|
||||||
private static Lazy<JsonSerializerSettings> s_serializerSettings = new(() =>
|
private static Lazy<JsonSerializerSettings> s_serializerSettings = new Lazy<JsonSerializerSettings>(() =>
|
||||||
{
|
{
|
||||||
var settings = new VssJsonMediaTypeFormatter().SerializerSettings;
|
var settings = new VssJsonMediaTypeFormatter().SerializerSettings;
|
||||||
settings.DateParseHandling = DateParseHandling.None;
|
settings.DateParseHandling = DateParseHandling.None;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
return baseUrl;
|
return baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
UriBuilder credUri = new(baseUrl);
|
UriBuilder credUri = new UriBuilder(baseUrl);
|
||||||
|
|
||||||
// ensure we have a username, uribuild will throw if username is empty but password is not.
|
// ensure we have a username, uribuild will throw if username is empty but password is not.
|
||||||
if (string.IsNullOrEmpty(username))
|
if (string.IsNullOrEmpty(username))
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ using GitHub.Services.OAuth;
|
|||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Sdk.WebApi.WebApi.RawClient;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Sdk
|
namespace GitHub.Runner.Sdk
|
||||||
{
|
{
|
||||||
@@ -35,11 +34,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VssConnection CreateConnection(
|
public static VssConnection CreateConnection(Uri serverUri, VssCredentials credentials, IEnumerable<DelegatingHandler> additionalDelegatingHandler = null, TimeSpan? timeout = null)
|
||||||
Uri serverUri,
|
|
||||||
VssCredentials credentials,
|
|
||||||
IEnumerable<DelegatingHandler> additionalDelegatingHandler = null,
|
|
||||||
TimeSpan? timeout = null)
|
|
||||||
{
|
{
|
||||||
VssClientHttpRequestSettings settings = VssClientHttpRequestSettings.Default.Clone();
|
VssClientHttpRequestSettings settings = VssClientHttpRequestSettings.Default.Clone();
|
||||||
|
|
||||||
@@ -76,47 +71,7 @@ namespace GitHub.Runner.Sdk
|
|||||||
// settings are applied to an HttpRequestMessage.
|
// settings are applied to an HttpRequestMessage.
|
||||||
settings.AcceptLanguages.Remove(CultureInfo.InvariantCulture);
|
settings.AcceptLanguages.Remove(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
VssConnection connection = new(serverUri, new VssHttpMessageHandler(credentials, settings), additionalDelegatingHandler);
|
VssConnection connection = new VssConnection(serverUri, new VssHttpMessageHandler(credentials, settings), additionalDelegatingHandler);
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RawConnection CreateRawConnection(
|
|
||||||
Uri serverUri,
|
|
||||||
VssCredentials credentials,
|
|
||||||
IEnumerable<DelegatingHandler> additionalDelegatingHandler = null,
|
|
||||||
TimeSpan? timeout = null)
|
|
||||||
{
|
|
||||||
RawClientHttpRequestSettings settings = RawClientHttpRequestSettings.Default.Clone();
|
|
||||||
|
|
||||||
int maxRetryRequest;
|
|
||||||
if (!int.TryParse(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_HTTP_RETRY") ?? string.Empty, out maxRetryRequest))
|
|
||||||
{
|
|
||||||
maxRetryRequest = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure MaxRetryRequest in range [3, 10]
|
|
||||||
settings.MaxRetryRequest = Math.Min(Math.Max(maxRetryRequest, 3), 10);
|
|
||||||
|
|
||||||
if (!int.TryParse(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_HTTP_TIMEOUT") ?? string.Empty, out int httpRequestTimeoutSeconds))
|
|
||||||
{
|
|
||||||
settings.SendTimeout = timeout ?? TimeSpan.FromSeconds(100);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// prefer environment variable
|
|
||||||
settings.SendTimeout = TimeSpan.FromSeconds(Math.Min(Math.Max(httpRequestTimeoutSeconds, 100), 1200));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove Invariant from the list of accepted languages.
|
|
||||||
//
|
|
||||||
// The constructor of VssHttpRequestSettings (base class of VssClientHttpRequestSettings) adds the current
|
|
||||||
// UI culture to the list of accepted languages. The UI culture will be Invariant on OSX/Linux when the
|
|
||||||
// LANG environment variable is not set when the program starts. If Invariant is in the list of accepted
|
|
||||||
// languages, then "System.ArgumentException: The value cannot be null or empty." will be thrown when the
|
|
||||||
// settings are applied to an HttpRequestMessage.
|
|
||||||
settings.AcceptLanguages.Remove(CultureInfo.InvariantCulture);
|
|
||||||
|
|
||||||
RawConnection connection = new(serverUri, new RawHttpMessageHandler(credentials.ToOAuthCredentials(), settings), additionalDelegatingHandler);
|
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<startup>
|
<startup>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||||
</startup>
|
</startup>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<configuration>
|
|
||||||
<startup>
|
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
|
|
||||||
</startup>
|
|
||||||
</configuration>
|
|
||||||
@@ -11,15 +11,10 @@
|
|||||||
<AssemblyName>RunnerService</AssemblyName>
|
<AssemblyName>RunnerService</AssemblyName>
|
||||||
<SignAssembly>false</SignAssembly>
|
<SignAssembly>false</SignAssembly>
|
||||||
<DelaySign>false</DelaySign>
|
<DelaySign>false</DelaySign>
|
||||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(PackageRuntime)' == 'win-arm64' ">
|
|
||||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(PackageRuntime)' != 'win-arm64' ">
|
|
||||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@@ -66,10 +61,7 @@
|
|||||||
<DependentUpon>Resource.resx</DependentUpon>
|
<DependentUpon>Resource.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition=" '$(Platform)' == 'ARM' ">
|
<ItemGroup>
|
||||||
<None Include="AppARM.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup Condition=" '$(Platform)' != 'ARM' ">
|
|
||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -79,7 +71,7 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
</Target>
|
</Target>
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ namespace GitHub.Runner.Worker
|
|||||||
public sealed class ActionCommandManager : RunnerService, IActionCommandManager
|
public sealed class ActionCommandManager : RunnerService, IActionCommandManager
|
||||||
{
|
{
|
||||||
private const string _stopCommand = "stop-commands";
|
private const string _stopCommand = "stop-commands";
|
||||||
private readonly Dictionary<string, IActionCommandExtension> _commandExtensions = new(StringComparer.OrdinalIgnoreCase);
|
private readonly Dictionary<string, IActionCommandExtension> _commandExtensions = new Dictionary<string, IActionCommandExtension>(StringComparer.OrdinalIgnoreCase);
|
||||||
private readonly HashSet<string> _registeredCommands = new(StringComparer.OrdinalIgnoreCase);
|
private readonly HashSet<string> _registeredCommands = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private readonly object _commandSerializeLock = new();
|
private readonly object _commandSerializeLock = new object();
|
||||||
private bool _stopProcessCommand = false;
|
private bool _stopProcessCommand = false;
|
||||||
private string _stopToken = null;
|
private string _stopToken = null;
|
||||||
|
|
||||||
@@ -307,17 +307,6 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
if (context.Global.Variables.GetBoolean("DistributedTask.DeprecateStepOutputCommands") ?? false)
|
|
||||||
{
|
|
||||||
var issue = new Issue()
|
|
||||||
{
|
|
||||||
Type = IssueType.Warning,
|
|
||||||
Message = String.Format(Constants.Runner.UnsupportedCommandMessage, this.Command)
|
|
||||||
};
|
|
||||||
issue.Data[Constants.Runner.InternalTelemetryIssueDataKey] = Constants.Runner.UnsupportedCommand;
|
|
||||||
context.AddIssue(issue);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!command.Properties.TryGetValue(SetOutputCommandProperties.Name, out string outputName) || string.IsNullOrEmpty(outputName))
|
if (!command.Properties.TryGetValue(SetOutputCommandProperties.Name, out string outputName) || string.IsNullOrEmpty(outputName))
|
||||||
{
|
{
|
||||||
throw new Exception("Required field 'name' is missing in ##[set-output] command.");
|
throw new Exception("Required field 'name' is missing in ##[set-output] command.");
|
||||||
@@ -342,17 +331,6 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
if (context.Global.Variables.GetBoolean("DistributedTask.DeprecateStepOutputCommands") ?? false)
|
|
||||||
{
|
|
||||||
var issue = new Issue()
|
|
||||||
{
|
|
||||||
Type = IssueType.Warning,
|
|
||||||
Message = String.Format(Constants.Runner.UnsupportedCommandMessage, this.Command)
|
|
||||||
};
|
|
||||||
issue.Data[Constants.Runner.InternalTelemetryIssueDataKey] = Constants.Runner.UnsupportedCommand;
|
|
||||||
context.AddIssue(issue);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!command.Properties.TryGetValue(SaveStateCommandProperties.Name, out string stateName) || string.IsNullOrEmpty(stateName))
|
if (!command.Properties.TryGetValue(SaveStateCommandProperties.Name, out string stateName) || string.IsNullOrEmpty(stateName))
|
||||||
{
|
{
|
||||||
throw new Exception("Required field 'name' is missing in ##[save-state] command.");
|
throw new Exception("Required field 'name' is missing in ##[save-state] command.");
|
||||||
@@ -608,7 +586,7 @@ namespace GitHub.Runner.Worker
|
|||||||
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
ValidateLinesAndColumns(command, context);
|
ValidateLinesAndColumns(command, context);
|
||||||
|
|
||||||
command.Properties.TryGetValue(IssueCommandProperties.File, out string file);
|
command.Properties.TryGetValue(IssueCommandProperties.File, out string file);
|
||||||
command.Properties.TryGetValue(IssueCommandProperties.Line, out string line);
|
command.Properties.TryGetValue(IssueCommandProperties.Line, out string line);
|
||||||
command.Properties.TryGetValue(IssueCommandProperties.Column, out string column);
|
command.Properties.TryGetValue(IssueCommandProperties.Column, out string column);
|
||||||
@@ -618,7 +596,7 @@ namespace GitHub.Runner.Worker
|
|||||||
context.Debug("Enhanced Annotations not enabled on the server. The 'title', 'end_line', and 'end_column' fields are unsupported.");
|
context.Debug("Enhanced Annotations not enabled on the server. The 'title', 'end_line', and 'end_column' fields are unsupported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Issue issue = new()
|
Issue issue = new Issue()
|
||||||
{
|
{
|
||||||
Category = "General",
|
Category = "General",
|
||||||
Type = this.Type,
|
Type = this.Type,
|
||||||
|
|||||||
@@ -52,16 +52,16 @@ namespace GitHub.Runner.Worker
|
|||||||
private const int _defaultCopyBufferSize = 81920;
|
private const int _defaultCopyBufferSize = 81920;
|
||||||
private const string _dotcomApiUrl = "https://api.github.com";
|
private const string _dotcomApiUrl = "https://api.github.com";
|
||||||
|
|
||||||
private readonly Dictionary<Guid, ContainerInfo> _cachedActionContainers = new();
|
private readonly Dictionary<Guid, ContainerInfo> _cachedActionContainers = new Dictionary<Guid, ContainerInfo>();
|
||||||
public Dictionary<Guid, ContainerInfo> CachedActionContainers => _cachedActionContainers;
|
public Dictionary<Guid, ContainerInfo> CachedActionContainers => _cachedActionContainers;
|
||||||
|
|
||||||
private readonly Dictionary<Guid, List<Pipelines.ActionStep>> _cachedEmbeddedPreSteps = new();
|
private readonly Dictionary<Guid, List<Pipelines.ActionStep>> _cachedEmbeddedPreSteps = new Dictionary<Guid, List<Pipelines.ActionStep>>();
|
||||||
public Dictionary<Guid, List<Pipelines.ActionStep>> CachedEmbeddedPreSteps => _cachedEmbeddedPreSteps;
|
public Dictionary<Guid, List<Pipelines.ActionStep>> CachedEmbeddedPreSteps => _cachedEmbeddedPreSteps;
|
||||||
|
|
||||||
private readonly Dictionary<Guid, List<Guid>> _cachedEmbeddedStepIds = new();
|
private readonly Dictionary<Guid, List<Guid>> _cachedEmbeddedStepIds = new Dictionary<Guid, List<Guid>>();
|
||||||
public Dictionary<Guid, List<Guid>> CachedEmbeddedStepIds => _cachedEmbeddedStepIds;
|
public Dictionary<Guid, List<Guid>> CachedEmbeddedStepIds => _cachedEmbeddedStepIds;
|
||||||
|
|
||||||
private readonly Dictionary<Guid, Stack<Pipelines.ActionStep>> _cachedEmbeddedPostSteps = new();
|
private readonly Dictionary<Guid, Stack<Pipelines.ActionStep>> _cachedEmbeddedPostSteps = new Dictionary<Guid, Stack<Pipelines.ActionStep>>();
|
||||||
public Dictionary<Guid, Stack<Pipelines.ActionStep>> CachedEmbeddedPostSteps => _cachedEmbeddedPostSteps;
|
public Dictionary<Guid, Stack<Pipelines.ActionStep>> CachedEmbeddedPostSteps => _cachedEmbeddedPostSteps;
|
||||||
|
|
||||||
public async Task<PrepareResult> PrepareActionsAsync(IExecutionContext executionContext, IEnumerable<Pipelines.JobStep> steps, Guid rootStepId = default(Guid))
|
public async Task<PrepareResult> PrepareActionsAsync(IExecutionContext executionContext, IEnumerable<Pipelines.JobStep> steps, Guid rootStepId = default(Guid))
|
||||||
@@ -791,7 +791,7 @@ namespace GitHub.Runner.Worker
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
//open zip stream in async mode
|
//open zip stream in async mode
|
||||||
using (FileStream fs = new(archiveFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: _defaultFileStreamBufferSize, useAsync: true))
|
using (FileStream fs = new FileStream(archiveFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: _defaultFileStreamBufferSize, useAsync: true))
|
||||||
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
|
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
|
||||||
using (var httpClient = new HttpClient(httpClientHandler))
|
using (var httpClient = new HttpClient(httpClientHandler))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -10,6 +10,9 @@ using GitHub.DistributedTask.ObjectTemplating.Schema;
|
|||||||
using GitHub.DistributedTask.ObjectTemplating;
|
using GitHub.DistributedTask.ObjectTemplating;
|
||||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||||
|
using YamlDotNet.Core;
|
||||||
|
using YamlDotNet.Core.Events;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||||
|
|
||||||
@@ -53,7 +56,7 @@ namespace GitHub.Runner.Worker
|
|||||||
public ActionDefinitionData Load(IExecutionContext executionContext, string manifestFile)
|
public ActionDefinitionData Load(IExecutionContext executionContext, string manifestFile)
|
||||||
{
|
{
|
||||||
var templateContext = CreateTemplateContext(executionContext);
|
var templateContext = CreateTemplateContext(executionContext);
|
||||||
ActionDefinitionData actionDefinition = new();
|
ActionDefinitionData actionDefinition = new ActionDefinitionData();
|
||||||
|
|
||||||
// Clean up file name real quick
|
// Clean up file name real quick
|
||||||
// Instead of using Regex which can be computationally expensive,
|
// Instead of using Regex which can be computationally expensive,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.DistributedTask.ObjectTemplating;
|
using GitHub.DistributedTask.ObjectTemplating;
|
||||||
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
using GitHub.DistributedTask.ObjectTemplating.Tokens;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using GitHub.DistributedTask.Pipelines;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using ObjectTemplating = GitHub.DistributedTask.ObjectTemplating;
|
using ObjectTemplating = GitHub.DistributedTask.ObjectTemplating;
|
||||||
@@ -10,7 +11,7 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
private readonly IExecutionContext _executionContext;
|
private readonly IExecutionContext _executionContext;
|
||||||
private readonly Tracing _trace;
|
private readonly Tracing _trace;
|
||||||
private readonly StringBuilder _traceBuilder = new();
|
private readonly StringBuilder _traceBuilder = new StringBuilder();
|
||||||
|
|
||||||
public string Trace => _traceBuilder.ToString();
|
public string Trace => _traceBuilder.ToString();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
private IDictionary<string, string> _userPortMappings;
|
private IDictionary<string, string> _userPortMappings;
|
||||||
private List<PortMapping> _portMappings;
|
private List<PortMapping> _portMappings;
|
||||||
private IDictionary<string, string> _environmentVariables;
|
private IDictionary<string, string> _environmentVariables;
|
||||||
private List<PathMapping> _pathMappings = new();
|
private List<PathMapping> _pathMappings = new List<PathMapping>();
|
||||||
|
|
||||||
public ContainerInfo()
|
public ContainerInfo()
|
||||||
{
|
{
|
||||||
@@ -92,8 +92,6 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
public bool IsJobContainer { get; set; }
|
public bool IsJobContainer { get; set; }
|
||||||
public bool IsAlpine { get; set; }
|
public bool IsAlpine { get; set; }
|
||||||
|
|
||||||
public bool FailedInitialization { get; set; }
|
|
||||||
|
|
||||||
public IDictionary<string, string> ContainerEnvironmentVariables
|
public IDictionary<string, string> ContainerEnvironmentVariables
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
context.Output($"Docker client API version: {clientVersionStr}");
|
context.Output($"Docker client API version: {clientVersionStr}");
|
||||||
|
|
||||||
// we interested about major.minor.patch version
|
// we interested about major.minor.patch version
|
||||||
Regex verRegex = new("\\d+\\.\\d+(\\.\\d+)?", RegexOptions.IgnoreCase);
|
Regex verRegex = new Regex("\\d+\\.\\d+(\\.\\d+)?", RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
Version serverVersion = null;
|
Version serverVersion = null;
|
||||||
var serverVersionMatchResult = verRegex.Match(serverVersionStr);
|
var serverVersionMatchResult = verRegex.Match(serverVersionStr);
|
||||||
@@ -107,6 +107,7 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
public async Task<string> DockerCreate(IExecutionContext context, ContainerInfo container)
|
public async Task<string> DockerCreate(IExecutionContext context, ContainerInfo container)
|
||||||
{
|
{
|
||||||
IList<string> dockerOptions = new List<string>();
|
IList<string> dockerOptions = new List<string>();
|
||||||
|
IDictionary<string, string> environment = new Dictionary<string, string>();
|
||||||
// OPTIONS
|
// OPTIONS
|
||||||
dockerOptions.Add($"--name {container.ContainerDisplayName}");
|
dockerOptions.Add($"--name {container.ContainerDisplayName}");
|
||||||
dockerOptions.Add($"--label {DockerInstanceLabel}");
|
dockerOptions.Add($"--label {DockerInstanceLabel}");
|
||||||
@@ -135,7 +136,8 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dockerOptions.Add(DockerUtil.CreateEscapedOption("-e", env.Key, env.Value));
|
environment.Add(env.Key, env.Value);
|
||||||
|
dockerOptions.Add(DockerUtil.CreateEscapedOption("-e", env.Key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +185,7 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
dockerOptions.Add($"{container.ContainerEntryPointArgs}");
|
dockerOptions.Add($"{container.ContainerEntryPointArgs}");
|
||||||
|
|
||||||
var optionsString = string.Join(" ", dockerOptions);
|
var optionsString = string.Join(" ", dockerOptions);
|
||||||
List<string> outputStrings = await ExecuteDockerCommandAsync(context, "create", optionsString);
|
List<string> outputStrings = await ExecuteDockerCommandAsync(context, "create", optionsString, environment);
|
||||||
|
|
||||||
return outputStrings.FirstOrDefault();
|
return outputStrings.FirstOrDefault();
|
||||||
}
|
}
|
||||||
@@ -309,7 +311,7 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
string arg = $"exec {options} {containerId} {command}".Trim();
|
string arg = $"exec {options} {containerId} {command}".Trim();
|
||||||
context.Command($"{DockerPath} {arg}");
|
context.Command($"{DockerPath} {arg}");
|
||||||
|
|
||||||
object outputLock = new();
|
object outputLock = new object();
|
||||||
var processInvoker = HostContext.CreateService<IProcessInvoker>();
|
var processInvoker = HostContext.CreateService<IProcessInvoker>();
|
||||||
processInvoker.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs message)
|
processInvoker.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs message)
|
||||||
{
|
{
|
||||||
@@ -443,11 +445,16 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task<List<string>> ExecuteDockerCommandAsync(IExecutionContext context, string command, string options)
|
private async Task<List<string>> ExecuteDockerCommandAsync(IExecutionContext context, string command, string options)
|
||||||
|
{
|
||||||
|
return await ExecuteDockerCommandAsync(context, command, options, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<List<string>> ExecuteDockerCommandAsync(IExecutionContext context, string command, string options, IDictionary<string, string> environment)
|
||||||
{
|
{
|
||||||
string arg = $"{command} {options}".Trim();
|
string arg = $"{command} {options}".Trim();
|
||||||
context.Command($"{DockerPath} {arg}");
|
context.Command($"{DockerPath} {arg}");
|
||||||
|
|
||||||
List<string> output = new();
|
List<string> output = new List<string>();
|
||||||
var processInvoker = HostContext.CreateService<IProcessInvoker>();
|
var processInvoker = HostContext.CreateService<IProcessInvoker>();
|
||||||
processInvoker.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs message)
|
processInvoker.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs message)
|
||||||
{
|
{
|
||||||
@@ -470,7 +477,7 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
workingDirectory: context.GetGitHubContext("workspace"),
|
workingDirectory: context.GetGitHubContext("workspace"),
|
||||||
fileName: DockerPath,
|
fileName: DockerPath,
|
||||||
arguments: arg,
|
arguments: arg,
|
||||||
environment: null,
|
environment: environment,
|
||||||
requireExitCodeZero: true,
|
requireExitCodeZero: true,
|
||||||
outputEncoding: null,
|
outputEncoding: null,
|
||||||
cancellationToken: CancellationToken.None);
|
cancellationToken: CancellationToken.None);
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
{
|
{
|
||||||
public class DockerUtil
|
public class DockerUtil
|
||||||
{
|
{
|
||||||
private static readonly Regex QuoteEscape = new(@"(\\*)" + "\"", RegexOptions.Compiled);
|
|
||||||
private static readonly Regex EndOfStringEscape = new(@"(\\+)$", RegexOptions.Compiled);
|
|
||||||
|
|
||||||
public static List<PortMapping> ParseDockerPort(IList<string> portMappingLines)
|
public static List<PortMapping> ParseDockerPort(IList<string> portMappingLines)
|
||||||
{
|
{
|
||||||
const string targetPort = "targetPort";
|
const string targetPort = "targetPort";
|
||||||
@@ -19,7 +16,7 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
//"TARGET_PORT/PROTO -> HOST:HOST_PORT"
|
//"TARGET_PORT/PROTO -> HOST:HOST_PORT"
|
||||||
string pattern = $"^(?<{targetPort}>\\d+)/(?<{proto}>\\w+) -> (?<{host}>.+):(?<{hostPort}>\\d+)$";
|
string pattern = $"^(?<{targetPort}>\\d+)/(?<{proto}>\\w+) -> (?<{host}>.+):(?<{hostPort}>\\d+)$";
|
||||||
|
|
||||||
List<PortMapping> portMappings = new();
|
List<PortMapping> portMappings = new List<PortMapping>();
|
||||||
foreach (var line in portMappingLines)
|
foreach (var line in portMappingLines)
|
||||||
{
|
{
|
||||||
Match m = Regex.Match(line, pattern, RegexOptions.None, TimeSpan.FromSeconds(1));
|
Match m = Regex.Match(line, pattern, RegexOptions.None, TimeSpan.FromSeconds(1));
|
||||||
@@ -71,37 +68,12 @@ namespace GitHub.Runner.Worker.Container
|
|||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return $"{flag} {EscapeString(key)}";
|
return $"{flag} \"{EscapeString(key)}\"";
|
||||||
}
|
|
||||||
|
|
||||||
public static string CreateEscapedOption(string flag, string key, string value)
|
|
||||||
{
|
|
||||||
if (String.IsNullOrEmpty(key))
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
var escapedString = EscapeString($"{key}={value}");
|
|
||||||
return $"{flag} {escapedString}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string EscapeString(string value)
|
private static string EscapeString(string value)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(value))
|
return value.Replace("\\", "\\\\").Replace("\"", "\\\"");
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
// Dotnet escaping rules are weird here, we can only escape \ if it precedes a "
|
|
||||||
// If a double quotation mark follows two or an even number of backslashes, each proceeding backslash pair is replaced with one backslash and the double quotation mark is removed.
|
|
||||||
// If a double quotation mark follows an odd number of backslashes, including just one, each preceding pair is replaced with one backslash and the remaining backslash is removed; however, in this case the double quotation mark is not removed.
|
|
||||||
// https://docs.microsoft.com/en-us/dotnet/api/system.environment.getcommandlineargs?redirectedfrom=MSDN&view=net-6.0#remarks
|
|
||||||
|
|
||||||
// First, find any \ followed by a " and double the number of \ + 1.
|
|
||||||
value = QuoteEscape.Replace(value, @"$1$1\" + "\"");
|
|
||||||
// Next, what if it ends in `\`, it would escape the end quote. So, we need to detect that at the end of the string and perform the same escape
|
|
||||||
// Luckily, we can just use the $ character with detects the end of string in regex
|
|
||||||
value = EndOfStringEscape.Replace(value, @"$1$1");
|
|
||||||
// Finally, wrap it in quotes
|
|
||||||
return $"\"{value}\"";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,41 +98,12 @@ namespace GitHub.Runner.Worker
|
|||||||
await StartContainerAsync(executionContext, container);
|
await StartContainerAsync(executionContext, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
await RunContainersHealthcheck(executionContext, containers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task RunContainersHealthcheck(IExecutionContext executionContext, List<ContainerInfo> containers)
|
|
||||||
{
|
|
||||||
executionContext.Output("##[group]Waiting for all services to be ready");
|
executionContext.Output("##[group]Waiting for all services to be ready");
|
||||||
|
|
||||||
var unhealthyContainers = new List<ContainerInfo>();
|
|
||||||
foreach (var container in containers.Where(c => !c.IsJobContainer))
|
foreach (var container in containers.Where(c => !c.IsJobContainer))
|
||||||
{
|
{
|
||||||
var healthy_container = await ContainerHealthcheck(executionContext, container);
|
await ContainerHealthcheck(executionContext, container);
|
||||||
|
|
||||||
if (!healthy_container)
|
|
||||||
{
|
|
||||||
unhealthyContainers.Add(container);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
executionContext.Output($"{container.ContainerNetworkAlias} service is healthy.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
executionContext.Output("##[endgroup]");
|
executionContext.Output("##[endgroup]");
|
||||||
|
|
||||||
if (unhealthyContainers.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (var container in unhealthyContainers)
|
|
||||||
{
|
|
||||||
executionContext.Output($"##[group]Service container {container.ContainerNetworkAlias} failed.");
|
|
||||||
await _dockerManager.DockerLogs(context: executionContext, containerId: container.ContainerId);
|
|
||||||
executionContext.Error($"Failed to initialize container {container.ContainerImage}");
|
|
||||||
container.FailedInitialization = true;
|
|
||||||
executionContext.Output("##[endgroup]");
|
|
||||||
}
|
|
||||||
throw new InvalidOperationException("One or more containers failed to start.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StopContainersAsync(IExecutionContext executionContext, object data)
|
public async Task StopContainersAsync(IExecutionContext executionContext, object data)
|
||||||
@@ -328,8 +299,9 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
if (!string.IsNullOrEmpty(container.ContainerId))
|
if (!string.IsNullOrEmpty(container.ContainerId))
|
||||||
{
|
{
|
||||||
if (!container.IsJobContainer && !container.FailedInitialization)
|
if (!container.IsJobContainer)
|
||||||
{
|
{
|
||||||
|
// Print logs for service container jobs (not the "action" job itself b/c that's already logged).
|
||||||
executionContext.Output($"Print service container logs: {container.ContainerDisplayName}");
|
executionContext.Output($"Print service container logs: {container.ContainerDisplayName}");
|
||||||
|
|
||||||
int logsExitCode = await _dockerManager.DockerLogs(executionContext, container.ContainerId);
|
int logsExitCode = await _dockerManager.DockerLogs(executionContext, container.ContainerId);
|
||||||
@@ -354,8 +326,8 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
context.Command($"{command} {arg}");
|
context.Command($"{command} {arg}");
|
||||||
|
|
||||||
List<string> outputs = new();
|
List<string> outputs = new List<string>();
|
||||||
object outputLock = new();
|
object outputLock = new object();
|
||||||
var processInvoker = HostContext.CreateService<IProcessInvoker>();
|
var processInvoker = HostContext.CreateService<IProcessInvoker>();
|
||||||
processInvoker.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs message)
|
processInvoker.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs message)
|
||||||
{
|
{
|
||||||
@@ -423,14 +395,14 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> ContainerHealthcheck(IExecutionContext executionContext, ContainerInfo container)
|
private async Task ContainerHealthcheck(IExecutionContext executionContext, ContainerInfo container)
|
||||||
{
|
{
|
||||||
string healthCheck = "--format=\"{{if .Config.Healthcheck}}{{print .State.Health.Status}}{{end}}\"";
|
string healthCheck = "--format=\"{{if .Config.Healthcheck}}{{print .State.Health.Status}}{{end}}\"";
|
||||||
string serviceHealth = (await _dockerManager.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault();
|
string serviceHealth = (await _dockerManager.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault();
|
||||||
if (string.IsNullOrEmpty(serviceHealth))
|
if (string.IsNullOrEmpty(serviceHealth))
|
||||||
{
|
{
|
||||||
// Container has no HEALTHCHECK
|
// Container has no HEALTHCHECK
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
var retryCount = 0;
|
var retryCount = 0;
|
||||||
while (string.Equals(serviceHealth, "starting", StringComparison.OrdinalIgnoreCase))
|
while (string.Equals(serviceHealth, "starting", StringComparison.OrdinalIgnoreCase))
|
||||||
@@ -441,7 +413,14 @@ namespace GitHub.Runner.Worker
|
|||||||
serviceHealth = (await _dockerManager.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault();
|
serviceHealth = (await _dockerManager.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault();
|
||||||
retryCount++;
|
retryCount++;
|
||||||
}
|
}
|
||||||
return string.Equals(serviceHealth, "healthy", StringComparison.OrdinalIgnoreCase);
|
if (string.Equals(serviceHealth, "healthy", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
executionContext.Output($"{container.ContainerNetworkAlias} service is healthy.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Failed to initialize, {container.ContainerNetworkAlias} service is {serviceHealth}.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ContainerRegistryLogin(IExecutionContext executionContext, ContainerInfo container)
|
private async Task<string> ContainerRegistryLogin(IExecutionContext executionContext, ContainerInfo container)
|
||||||
@@ -562,7 +541,7 @@ namespace GitHub.Runner.Worker
|
|||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
Version requiredDockerEngineAPIVersion = new Version(1, 30); // Docker-EE version 17.6
|
Version requiredDockerEngineAPIVersion = new Version(1, 30); // Docker-EE version 17.6
|
||||||
#else
|
#else
|
||||||
Version requiredDockerEngineAPIVersion = new(1, 35); // Docker-CE version 17.12
|
Version requiredDockerEngineAPIVersion = new Version(1, 35); // Docker-CE version 17.12
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dockerVersion.ServerVersion < requiredDockerEngineAPIVersion)
|
if (dockerVersion.ServerVersion < requiredDockerEngineAPIVersion)
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ namespace GitHub.Runner.Worker
|
|||||||
// Keep track of embedded steps states
|
// Keep track of embedded steps states
|
||||||
Dictionary<Guid, Dictionary<string, string>> EmbeddedIntraActionState { get; }
|
Dictionary<Guid, Dictionary<string, string>> EmbeddedIntraActionState { get; }
|
||||||
|
|
||||||
|
IList<Issue> EmbeddedIssues { get; }
|
||||||
|
|
||||||
bool EchoOnActionCommand { get; set; }
|
bool EchoOnActionCommand { get; set; }
|
||||||
|
|
||||||
bool IsEmbedded { get; }
|
bool IsEmbedded { get; }
|
||||||
@@ -91,6 +93,7 @@ namespace GitHub.Runner.Worker
|
|||||||
void SetOutput(string name, string value, out string reference);
|
void SetOutput(string name, string value, out string reference);
|
||||||
void SetTimeout(TimeSpan? timeout);
|
void SetTimeout(TimeSpan? timeout);
|
||||||
void AddIssue(Issue issue, string message = null);
|
void AddIssue(Issue issue, string message = null);
|
||||||
|
void AddIssueToTimelineRecord(Issue issue);
|
||||||
void Progress(int percentage, string currentOperation = null);
|
void Progress(int percentage, string currentOperation = null);
|
||||||
void UpdateDetailTimelineRecord(TimelineRecord record);
|
void UpdateDetailTimelineRecord(TimelineRecord record);
|
||||||
|
|
||||||
@@ -122,10 +125,10 @@ namespace GitHub.Runner.Worker
|
|||||||
private const int _maxIssueCountInTelemetry = 3; // Only send the first 3 issues to telemetry
|
private const int _maxIssueCountInTelemetry = 3; // Only send the first 3 issues to telemetry
|
||||||
private const int _maxIssueMessageLengthInTelemetry = 256; // Only send the first 256 characters of issue message to telemetry
|
private const int _maxIssueMessageLengthInTelemetry = 256; // Only send the first 256 characters of issue message to telemetry
|
||||||
|
|
||||||
private readonly TimelineRecord _record = new();
|
private readonly TimelineRecord _record = new TimelineRecord();
|
||||||
private readonly Dictionary<Guid, TimelineRecord> _detailRecords = new();
|
private readonly Dictionary<Guid, TimelineRecord> _detailRecords = new Dictionary<Guid, TimelineRecord>();
|
||||||
private readonly object _loggerLock = new();
|
private readonly object _loggerLock = new object();
|
||||||
private readonly object _matchersLock = new();
|
private readonly object _matchersLock = new object();
|
||||||
|
|
||||||
private event OnMatcherChanged _onMatcherChanged;
|
private event OnMatcherChanged _onMatcherChanged;
|
||||||
|
|
||||||
@@ -140,7 +143,7 @@ namespace GitHub.Runner.Worker
|
|||||||
private bool _expandedForPostJob = false;
|
private bool _expandedForPostJob = false;
|
||||||
private int _childTimelineRecordOrder = 0;
|
private int _childTimelineRecordOrder = 0;
|
||||||
private CancellationTokenSource _cancellationTokenSource;
|
private CancellationTokenSource _cancellationTokenSource;
|
||||||
private TaskCompletionSource<int> _forceCompleted = new();
|
private TaskCompletionSource<int> _forceCompleted = new TaskCompletionSource<int>();
|
||||||
private bool _throttlingReported = false;
|
private bool _throttlingReported = false;
|
||||||
|
|
||||||
// only job level ExecutionContext will track throttling delay.
|
// only job level ExecutionContext will track throttling delay.
|
||||||
@@ -180,6 +183,8 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Dictionary<Guid, Dictionary<string, string>> EmbeddedIntraActionState { get; private set; }
|
public Dictionary<Guid, Dictionary<string, string>> EmbeddedIntraActionState { get; private set; }
|
||||||
|
|
||||||
|
public IList<Issue> EmbeddedIssues { get; } = new List<Issue>();
|
||||||
|
|
||||||
public bool EchoOnActionCommand { get; set; }
|
public bool EchoOnActionCommand { get; set; }
|
||||||
|
|
||||||
// An embedded execution context shares the same record ID, record name, and logger
|
// An embedded execution context shares the same record ID, record name, and logger
|
||||||
@@ -575,7 +580,31 @@ namespace GitHub.Runner.Worker
|
|||||||
long logLineNumber = Write(WellKnownTags.Error, logMessage);
|
long logLineNumber = Write(WellKnownTags.Error, logMessage);
|
||||||
issue.Data["logFileLineNumber"] = logLineNumber.ToString();
|
issue.Data["logFileLineNumber"] = logLineNumber.ToString();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (issue.Type == IssueType.Warning)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(logMessage))
|
||||||
|
{
|
||||||
|
long logLineNumber = Write(WellKnownTags.Warning, logMessage);
|
||||||
|
issue.Data["logFileLineNumber"] = logLineNumber.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (issue.Type == IssueType.Notice)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(logMessage))
|
||||||
|
{
|
||||||
|
long logLineNumber = Write(WellKnownTags.Notice, logMessage);
|
||||||
|
issue.Data["logFileLineNumber"] = logLineNumber.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AddIssueToTimelineRecord(issue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddIssueToTimelineRecord(Issue issue)
|
||||||
|
{
|
||||||
|
ArgUtil.NotNull(issue, nameof(issue));
|
||||||
|
if (issue.Type == IssueType.Error)
|
||||||
|
{
|
||||||
if (_record.ErrorCount < _maxIssueCount)
|
if (_record.ErrorCount < _maxIssueCount)
|
||||||
{
|
{
|
||||||
_record.Issues.Add(issue);
|
_record.Issues.Add(issue);
|
||||||
@@ -585,12 +614,6 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
else if (issue.Type == IssueType.Warning)
|
else if (issue.Type == IssueType.Warning)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(logMessage))
|
|
||||||
{
|
|
||||||
long logLineNumber = Write(WellKnownTags.Warning, logMessage);
|
|
||||||
issue.Data["logFileLineNumber"] = logLineNumber.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_record.WarningCount < _maxIssueCount)
|
if (_record.WarningCount < _maxIssueCount)
|
||||||
{
|
{
|
||||||
_record.Issues.Add(issue);
|
_record.Issues.Add(issue);
|
||||||
@@ -600,12 +623,6 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
else if (issue.Type == IssueType.Notice)
|
else if (issue.Type == IssueType.Notice)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(logMessage))
|
|
||||||
{
|
|
||||||
long logLineNumber = Write(WellKnownTags.Notice, logMessage);
|
|
||||||
issue.Data["logFileLineNumber"] = logLineNumber.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_record.NoticeCount < _maxIssueCount)
|
if (_record.NoticeCount < _maxIssueCount)
|
||||||
{
|
{
|
||||||
_record.Issues.Add(issue);
|
_record.Issues.Add(issue);
|
||||||
@@ -613,8 +630,17 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
_record.NoticeCount++;
|
_record.NoticeCount++;
|
||||||
}
|
}
|
||||||
|
// Composite actions should never upload a timeline record to the server
|
||||||
|
// We add these to a list and let composite action handler bubble it up recursively
|
||||||
|
if (this.IsEmbedded)
|
||||||
|
{
|
||||||
|
EmbeddedIssues.Add(issue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_jobServerQueue.QueueTimelineRecordUpdate(_mainTimelineId, _record);
|
||||||
|
}
|
||||||
|
|
||||||
_jobServerQueue.QueueTimelineRecordUpdate(_mainTimelineId, _record);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateDetailTimelineRecord(TimelineRecord record)
|
public void UpdateDetailTimelineRecord(TimelineRecord record)
|
||||||
@@ -686,11 +712,8 @@ namespace GitHub.Runner.Worker
|
|||||||
// Endpoints
|
// Endpoints
|
||||||
Global.Endpoints = message.Resources.Endpoints;
|
Global.Endpoints = message.Resources.Endpoints;
|
||||||
|
|
||||||
// Ser debug using vars context if debug variables are not already present.
|
// Variables
|
||||||
var variables = message.Variables;
|
Global.Variables = new Variables(HostContext, message.Variables);
|
||||||
SetDebugUsingVars(variables, message.ContextData);
|
|
||||||
|
|
||||||
Global.Variables = new Variables(HostContext, variables);
|
|
||||||
|
|
||||||
if (Global.Variables.GetBoolean("DistributedTask.ForceInternalNodeVersionOnRunnerTo12") ?? false)
|
if (Global.Variables.GetBoolean("DistributedTask.ForceInternalNodeVersionOnRunnerTo12") ?? false)
|
||||||
{
|
{
|
||||||
@@ -1080,31 +1103,6 @@ namespace GitHub.Runner.Worker
|
|||||||
return CreateChild(newGuid, displayName, newGuid.ToString("N"), null, null, ActionRunStage.Post, intraActionState, _childTimelineRecordOrder - Root.PostJobSteps.Count, siblingScopeName: siblingScopeName);
|
return CreateChild(newGuid, displayName, newGuid.ToString("N"), null, null, ActionRunStage.Post, intraActionState, _childTimelineRecordOrder - Root.PostJobSteps.Count, siblingScopeName: siblingScopeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets debug using vars context in case debug variables are not present.
|
|
||||||
private static void SetDebugUsingVars(IDictionary<string, VariableValue> variables, IDictionary<string, PipelineContextData> contextData)
|
|
||||||
{
|
|
||||||
if (contextData != null &&
|
|
||||||
contextData.TryGetValue(PipelineTemplateConstants.Vars, out var varsPipelineContextData) &&
|
|
||||||
varsPipelineContextData != null &&
|
|
||||||
varsPipelineContextData is DictionaryContextData varsContextData)
|
|
||||||
{
|
|
||||||
// Set debug variables only when StepDebug/RunnerDebug variables are not present.
|
|
||||||
if (!variables.ContainsKey(Constants.Variables.Actions.StepDebug) &&
|
|
||||||
varsContextData.TryGetValue(Constants.Variables.Actions.StepDebug, out var stepDebugValue) &&
|
|
||||||
stepDebugValue is StringContextData)
|
|
||||||
{
|
|
||||||
variables[Constants.Variables.Actions.StepDebug] = stepDebugValue.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!variables.ContainsKey(Constants.Variables.Actions.RunnerDebug) &&
|
|
||||||
varsContextData.TryGetValue(Constants.Variables.Actions.RunnerDebug, out var runDebugValue) &&
|
|
||||||
runDebugValue is StringContextData)
|
|
||||||
{
|
|
||||||
variables[Constants.Variables.Actions.RunnerDebug] = runDebugValue.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ApplyContinueOnError(TemplateToken continueOnErrorToken)
|
public void ApplyContinueOnError(TemplateToken continueOnErrorToken)
|
||||||
{
|
{
|
||||||
if (Result != TaskResult.Failed)
|
if (Result != TaskResult.Failed)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace GitHub.Runner.Worker.Expressions
|
|||||||
|
|
||||||
string githubWorkspace = workspaceData.Value;
|
string githubWorkspace = workspaceData.Value;
|
||||||
bool followSymlink = false;
|
bool followSymlink = false;
|
||||||
List<string> patterns = new();
|
List<string> patterns = new List<string>();
|
||||||
var firstParameter = true;
|
var firstParameter = true;
|
||||||
foreach (var parameter in Parameters)
|
foreach (var parameter in Parameters)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using GitHub.Runner.Worker.Container;
|
using GitHub.Runner.Worker.Container;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -66,7 +68,7 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fileCommand.ProcessCommand(context, Path.Combine(_fileCommandDirectory, fileCommand.FilePrefix + _fileSuffix), container);
|
fileCommand.ProcessCommand(context, Path.Combine(_fileCommandDirectory, fileCommand.FilePrefix + _fileSuffix),container);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -116,7 +118,7 @@ namespace GitHub.Runner.Worker
|
|||||||
if (File.Exists(filePath))
|
if (File.Exists(filePath))
|
||||||
{
|
{
|
||||||
var lines = File.ReadAllLines(filePath, Encoding.UTF8);
|
var lines = File.ReadAllLines(filePath, Encoding.UTF8);
|
||||||
foreach (var line in lines)
|
foreach(var line in lines)
|
||||||
{
|
{
|
||||||
if (line == string.Empty)
|
if (line == string.Empty)
|
||||||
{
|
{
|
||||||
@@ -138,10 +140,74 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string filePath, ContainerInfo container)
|
public void ProcessCommand(IExecutionContext context, string filePath, ContainerInfo container)
|
||||||
{
|
{
|
||||||
var pairs = new EnvFileKeyValuePairs(context, filePath);
|
try
|
||||||
foreach (var pair in pairs)
|
|
||||||
{
|
{
|
||||||
SetEnvironmentVariable(context, pair.Key, pair.Value);
|
var text = File.ReadAllText(filePath) ?? string.Empty;
|
||||||
|
var index = 0;
|
||||||
|
var line = ReadLine(text, ref index);
|
||||||
|
while (line != null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(line))
|
||||||
|
{
|
||||||
|
var equalsIndex = line.IndexOf("=", StringComparison.Ordinal);
|
||||||
|
var heredocIndex = line.IndexOf("<<", StringComparison.Ordinal);
|
||||||
|
|
||||||
|
// Normal style NAME=VALUE
|
||||||
|
if (equalsIndex >= 0 && (heredocIndex < 0 || equalsIndex < heredocIndex))
|
||||||
|
{
|
||||||
|
var split = line.Split(new[] { '=' }, 2, StringSplitOptions.None);
|
||||||
|
if (string.IsNullOrEmpty(line))
|
||||||
|
{
|
||||||
|
throw new Exception($"Invalid environment variable format '{line}'. Environment variable name must not be empty");
|
||||||
|
}
|
||||||
|
SetEnvironmentVariable(context, split[0], split[1]);
|
||||||
|
}
|
||||||
|
// Heredoc style NAME<<EOF
|
||||||
|
else if (heredocIndex >= 0 && (equalsIndex < 0 || heredocIndex < equalsIndex))
|
||||||
|
{
|
||||||
|
var split = line.Split(new[] { "<<" }, 2, StringSplitOptions.None);
|
||||||
|
if (string.IsNullOrEmpty(split[0]) || string.IsNullOrEmpty(split[1]))
|
||||||
|
{
|
||||||
|
throw new Exception($"Invalid environment variable format '{line}'. Environment variable name must not be empty and delimiter must not be empty");
|
||||||
|
}
|
||||||
|
var name = split[0];
|
||||||
|
var delimiter = split[1];
|
||||||
|
var startIndex = index; // Start index of the value (inclusive)
|
||||||
|
var endIndex = index; // End index of the value (exclusive)
|
||||||
|
var tempLine = ReadLine(text, ref index, out var newline);
|
||||||
|
while (!string.Equals(tempLine, delimiter, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
if (tempLine == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Invalid environment variable value. Matching delimiter not found '{delimiter}'");
|
||||||
|
}
|
||||||
|
if (newline == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Invalid environment variable value. EOF marker missing new line.");
|
||||||
|
}
|
||||||
|
endIndex = index - newline.Length;
|
||||||
|
tempLine = ReadLine(text, ref index, out newline);
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = endIndex > startIndex ? text.Substring(startIndex, endIndex - startIndex) : string.Empty;
|
||||||
|
SetEnvironmentVariable(context, name, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"Invalid environment variable format '{line}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line = ReadLine(text, ref index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (DirectoryNotFoundException)
|
||||||
|
{
|
||||||
|
context.Debug($"Environment variables file does not exist '{filePath}'");
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
context.Debug($"Environment variables file does not exist '{filePath}'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +220,48 @@ namespace GitHub.Runner.Worker
|
|||||||
context.SetEnvContext(name, value);
|
context.SetEnvContext(name, value);
|
||||||
context.Debug($"{name}='{value}'");
|
context.Debug($"{name}='{value}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string ReadLine(
|
||||||
|
string text,
|
||||||
|
ref int index)
|
||||||
|
{
|
||||||
|
return ReadLine(text, ref index, out _);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ReadLine(
|
||||||
|
string text,
|
||||||
|
ref int index,
|
||||||
|
out string newline)
|
||||||
|
{
|
||||||
|
if (index >= text.Length)
|
||||||
|
{
|
||||||
|
newline = null;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var originalIndex = index;
|
||||||
|
var lfIndex = text.IndexOf("\n", index, StringComparison.Ordinal);
|
||||||
|
if (lfIndex < 0)
|
||||||
|
{
|
||||||
|
index = text.Length;
|
||||||
|
newline = null;
|
||||||
|
return text.Substring(originalIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if OS_WINDOWS
|
||||||
|
var crLFIndex = text.IndexOf("\r\n", index, StringComparison.Ordinal);
|
||||||
|
if (crLFIndex >= 0 && crLFIndex < lfIndex)
|
||||||
|
{
|
||||||
|
index = crLFIndex + 2; // Skip over CRLF
|
||||||
|
newline = "\r\n";
|
||||||
|
return text.Substring(originalIndex, crLFIndex - originalIndex);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
index = lfIndex + 1; // Skip over LF
|
||||||
|
newline = "\n";
|
||||||
|
return text.Substring(originalIndex, lfIndex - originalIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class CreateStepSummaryCommand : RunnerService, IFileCommandExtension
|
public sealed class CreateStepSummaryCommand : RunnerService, IFileCommandExtension
|
||||||
@@ -204,9 +312,7 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var attachmentName = !context.IsEmbedded
|
var attachmentName = context.Id.ToString();
|
||||||
? context.Id.ToString()
|
|
||||||
: context.EmbeddedId.ToString();
|
|
||||||
|
|
||||||
Trace.Info($"Queueing file ({filePath}) for attachment upload ({attachmentName})");
|
Trace.Info($"Queueing file ({filePath}) for attachment upload ({attachmentName})");
|
||||||
// Attachments must be added to the parent context (job), not the current context (step)
|
// Attachments must be added to the parent context (job), not the current context (step)
|
||||||
@@ -219,200 +325,4 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class SaveStateFileCommand : RunnerService, IFileCommandExtension
|
|
||||||
{
|
|
||||||
public string ContextName => "state";
|
|
||||||
public string FilePrefix => "save_state_";
|
|
||||||
|
|
||||||
public Type ExtensionType => typeof(IFileCommandExtension);
|
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string filePath, ContainerInfo container)
|
|
||||||
{
|
|
||||||
var pairs = new EnvFileKeyValuePairs(context, filePath);
|
|
||||||
foreach (var pair in pairs)
|
|
||||||
{
|
|
||||||
// Embedded steps (composite) keep track of the state at the root level
|
|
||||||
if (context.IsEmbedded)
|
|
||||||
{
|
|
||||||
var id = context.EmbeddedId;
|
|
||||||
if (!context.Root.EmbeddedIntraActionState.ContainsKey(id))
|
|
||||||
{
|
|
||||||
context.Root.EmbeddedIntraActionState[id] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
context.Root.EmbeddedIntraActionState[id][pair.Key] = pair.Value;
|
|
||||||
}
|
|
||||||
// Otherwise modify the ExecutionContext
|
|
||||||
else
|
|
||||||
{
|
|
||||||
context.IntraActionState[pair.Key] = pair.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
context.Debug($"Save intra-action state {pair.Key} = {pair.Value}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class SetOutputFileCommand : RunnerService, IFileCommandExtension
|
|
||||||
{
|
|
||||||
public string ContextName => "output";
|
|
||||||
public string FilePrefix => "set_output_";
|
|
||||||
|
|
||||||
public Type ExtensionType => typeof(IFileCommandExtension);
|
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string filePath, ContainerInfo container)
|
|
||||||
{
|
|
||||||
var pairs = new EnvFileKeyValuePairs(context, filePath);
|
|
||||||
foreach (var pair in pairs)
|
|
||||||
{
|
|
||||||
context.SetOutput(pair.Key, pair.Value, out var reference);
|
|
||||||
context.Debug($"Set output {pair.Key} = {pair.Value}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class EnvFileKeyValuePairs: IEnumerable<KeyValuePair<string, string>>
|
|
||||||
{
|
|
||||||
private IExecutionContext _context;
|
|
||||||
private string _filePath;
|
|
||||||
|
|
||||||
public EnvFileKeyValuePairs(IExecutionContext context, string filePath)
|
|
||||||
{
|
|
||||||
_context = context;
|
|
||||||
_filePath = filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
|
|
||||||
{
|
|
||||||
var text = string.Empty;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
text = File.ReadAllText(_filePath) ?? string.Empty;
|
|
||||||
}
|
|
||||||
catch (DirectoryNotFoundException)
|
|
||||||
{
|
|
||||||
_context.Debug($"File does not exist '{_filePath}'");
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
catch (FileNotFoundException)
|
|
||||||
{
|
|
||||||
_context.Debug($"File does not exist '{_filePath}'");
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var index = 0;
|
|
||||||
var line = ReadLine(text, ref index);
|
|
||||||
while (line != null)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(line))
|
|
||||||
{
|
|
||||||
var key = string.Empty;
|
|
||||||
var output = string.Empty;
|
|
||||||
|
|
||||||
var equalsIndex = line.IndexOf("=", StringComparison.Ordinal);
|
|
||||||
var heredocIndex = line.IndexOf("<<", StringComparison.Ordinal);
|
|
||||||
|
|
||||||
// Normal style NAME=VALUE
|
|
||||||
if (equalsIndex >= 0 && (heredocIndex < 0 || equalsIndex < heredocIndex))
|
|
||||||
{
|
|
||||||
var split = line.Split(new[] { '=' }, 2, StringSplitOptions.None);
|
|
||||||
if (string.IsNullOrEmpty(line))
|
|
||||||
{
|
|
||||||
throw new Exception($"Invalid format '{line}'. Name must not be empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
key = split[0];
|
|
||||||
output = split[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Heredoc style NAME<<EOF
|
|
||||||
else if (heredocIndex >= 0 && (equalsIndex < 0 || heredocIndex < equalsIndex))
|
|
||||||
{
|
|
||||||
var split = line.Split(new[] { "<<" }, 2, StringSplitOptions.None);
|
|
||||||
if (string.IsNullOrEmpty(split[0]) || string.IsNullOrEmpty(split[1]))
|
|
||||||
{
|
|
||||||
throw new Exception($"Invalid format '{line}'. Name must not be empty and delimiter must not be empty");
|
|
||||||
}
|
|
||||||
key = split[0];
|
|
||||||
var delimiter = split[1];
|
|
||||||
var startIndex = index; // Start index of the value (inclusive)
|
|
||||||
var endIndex = index; // End index of the value (exclusive)
|
|
||||||
var tempLine = ReadLine(text, ref index, out var newline);
|
|
||||||
while (!string.Equals(tempLine, delimiter, StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
if (tempLine == null)
|
|
||||||
{
|
|
||||||
throw new Exception($"Invalid value. Matching delimiter not found '{delimiter}'");
|
|
||||||
}
|
|
||||||
if (newline == null)
|
|
||||||
{
|
|
||||||
throw new Exception($"Invalid value. EOF marker missing new line.");
|
|
||||||
}
|
|
||||||
endIndex = index - newline.Length;
|
|
||||||
tempLine = ReadLine(text, ref index, out newline);
|
|
||||||
}
|
|
||||||
|
|
||||||
output = endIndex > startIndex ? text.Substring(startIndex, endIndex - startIndex) : string.Empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception($"Invalid format '{line}'");
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return new KeyValuePair<string, string>(key, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
line = ReadLine(text, ref index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.Collections.IEnumerator
|
|
||||||
System.Collections.IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
// Invoke IEnumerator<KeyValuePair<string, string>> GetEnumerator() above.
|
|
||||||
return GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ReadLine(
|
|
||||||
string text,
|
|
||||||
ref int index)
|
|
||||||
{
|
|
||||||
return ReadLine(text, ref index, out _);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ReadLine(
|
|
||||||
string text,
|
|
||||||
ref int index,
|
|
||||||
out string newline)
|
|
||||||
{
|
|
||||||
if (index >= text.Length)
|
|
||||||
{
|
|
||||||
newline = null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var originalIndex = index;
|
|
||||||
var lfIndex = text.IndexOf("\n", index, StringComparison.Ordinal);
|
|
||||||
if (lfIndex < 0)
|
|
||||||
{
|
|
||||||
index = text.Length;
|
|
||||||
newline = null;
|
|
||||||
return text.Substring(originalIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if OS_WINDOWS
|
|
||||||
var crLFIndex = text.IndexOf("\r\n", index, StringComparison.Ordinal);
|
|
||||||
if (crLFIndex >= 0 && crLFIndex < lfIndex)
|
|
||||||
{
|
|
||||||
index = crLFIndex + 2; // Skip over CRLF
|
|
||||||
newline = "\r\n";
|
|
||||||
return text.Substring(originalIndex, crLFIndex - originalIndex);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
index = lfIndex + 1; // Skip over LF
|
|
||||||
newline = "\n";
|
|
||||||
return text.Substring(originalIndex, lfIndex - originalIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
public sealed class GitHubContext : DictionaryContextData, IEnvironmentContextData
|
public sealed class GitHubContext : DictionaryContextData, IEnvironmentContextData
|
||||||
{
|
{
|
||||||
private readonly HashSet<string> _contextEnvAllowlist = new(StringComparer.OrdinalIgnoreCase)
|
private readonly HashSet<string> _contextEnvAllowlist = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
"action_path",
|
"action_path",
|
||||||
"action_ref",
|
"action_ref",
|
||||||
@@ -21,7 +21,6 @@ namespace GitHub.Runner.Worker
|
|||||||
"graphql_url",
|
"graphql_url",
|
||||||
"head_ref",
|
"head_ref",
|
||||||
"job",
|
"job",
|
||||||
"output",
|
|
||||||
"path",
|
"path",
|
||||||
"ref_name",
|
"ref_name",
|
||||||
"ref_protected",
|
"ref_protected",
|
||||||
@@ -35,7 +34,6 @@ namespace GitHub.Runner.Worker
|
|||||||
"run_number",
|
"run_number",
|
||||||
"server_url",
|
"server_url",
|
||||||
"sha",
|
"sha",
|
||||||
"state",
|
|
||||||
"step_summary",
|
"step_summary",
|
||||||
"triggering_actor",
|
"triggering_actor",
|
||||||
"workflow",
|
"workflow",
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user