Compare commits

..

7 Commits

Author SHA1 Message Date
eric sciple
04ece46c6a temp tracing for client auth 2022-05-10 18:20:49 +00:00
eric sciple
e75d502ab1 use token for broker and actions service 2022-05-09 06:20:08 +00:00
eric sciple
5686904fbe temporarily dont renew the job lock 2022-04-28 03:04:35 +00:00
eric sciple
c278fb1736 working on running job 2022-04-28 02:32:40 +00:00
eric sciple
332b8f9240 send runner info on getNextMessage 2022-04-09 20:04:55 +00:00
eric sciple
25f6cc100f print retrieved message 2022-04-09 00:31:59 +00:00
eric sciple
6ec30ea522 adding compile-time const whether to use the broker service 2022-04-08 23:23:27 +00:00
78 changed files with 808 additions and 811 deletions

View File

@@ -18,7 +18,7 @@ jobs:
build: build:
strategy: strategy:
matrix: matrix:
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64, osx-arm64 ] runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64 ]
include: include:
- runtime: linux-x64 - runtime: linux-x64
os: ubuntu-latest os: ubuntu-latest
@@ -36,17 +36,13 @@ jobs:
os: macOS-latest os: macOS-latest
devScript: ./dev.sh devScript: ./dev.sh
- runtime: osx-arm64
os: macOS-latest
devScript: ./dev.sh
- runtime: win-x64 - runtime: win-x64
os: windows-2019 os: windows-2019
devScript: ./dev devScript: ./dev
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
# Build runner layout # Build runner layout
- name: Build & Layout Release - name: Build & Layout Release
@@ -82,7 +78,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' if: matrix.runtime != 'linux-arm64' && matrix.runtime != 'linux-arm'
# Create runner package tar.gz/zip # Create runner package tar.gz/zip
- name: Package Release - name: Package Release

View File

@@ -23,7 +23,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL

View File

@@ -11,7 +11,7 @@ jobs:
if: startsWith(github.ref, 'refs/heads/releases/') || github.ref == 'refs/heads/main' if: startsWith(github.ref, 'refs/heads/releases/') || github.ref == 'refs/heads/main'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
# Make sure ./releaseVersion match ./src/runnerversion # Make sure ./releaseVersion match ./src/runnerversion
# Query GitHub release ensure version is not used # Query GitHub release ensure version is not used
@@ -51,28 +51,24 @@ jobs:
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 }}
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 }}
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 }}
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 }}
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 }}
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 }}
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 }}
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 }}
strategy: strategy:
matrix: matrix:
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64, osx-arm64 ] runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64 ]
include: include:
- runtime: linux-x64 - runtime: linux-x64
os: ubuntu-latest os: ubuntu-latest
@@ -89,10 +85,6 @@ jobs:
- runtime: osx-x64 - runtime: osx-x64
os: macOS-latest os: macOS-latest
devScript: ./dev.sh devScript: ./dev.sh
- runtime: osx-arm64
os: macOS-latest
devScript: ./dev.sh
- runtime: win-x64 - runtime: win-x64
os: windows-2019 os: windows-2019
@@ -100,7 +92,7 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
# Build runner layout # Build runner layout
- name: Build & Layout Release - name: Build & Layout Release
@@ -108,6 +100,13 @@ jobs:
${{ matrix.devScript }} layout Release ${{ matrix.runtime }} ${{ matrix.devScript }} layout Release ${{ matrix.runtime }}
working-directory: src working-directory: src
# Run tests
- name: L0
run: |
${{ matrix.devScript }} test
working-directory: src
if: matrix.runtime != 'linux-arm64' && matrix.runtime != 'linux-arm'
# Create runner package tar.gz/zip # Create runner package tar.gz/zip
- name: Package Release - name: Package Release
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
@@ -218,7 +217,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
# Download runner package tar.gz/zip produced by 'build' job # Download runner package tar.gz/zip produced by 'build' job
- name: Download Artifact - name: Download Artifact
@@ -240,25 +239,21 @@ jobs:
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(/<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(/<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(/<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(/<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(/<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(/<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(/<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(/<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}}')
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm-sha-noruntime-noexternals}}') releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm-sha-noruntime-noexternals}}')
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm64-sha-noruntime-noexternals}}') releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm64-sha-noruntime-noexternals}}')
@@ -272,7 +267,6 @@ jobs:
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.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.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
echo "${{needs.build.outputs.linux-arm-sha}} actions-runner-linux-arm-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c echo "${{needs.build.outputs.linux-arm-sha}} actions-runner-linux-arm-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
echo "${{needs.build.outputs.linux-arm64-sha}} actions-runner-linux-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c echo "${{needs.build.outputs.linux-arm64-sha}} actions-runner-linux-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
@@ -320,16 +314,6 @@ jobs:
asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz
asset_content_type: application/octet-stream asset_content_type: application/octet-stream
- name: Upload Release Asset (osx-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-osx-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz
asset_name: actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz
asset_content_type: application/octet-stream
- name: Upload Release Asset (linux-arm) - name: Upload Release Asset (linux-arm)
uses: actions/upload-release-asset@v1.0.1 uses: actions/upload-release-asset@v1.0.1
env: env:
@@ -381,16 +365,6 @@ jobs:
asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}-noexternals.tar.gz asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}-noexternals.tar.gz
asset_content_type: application/octet-stream asset_content_type: application/octet-stream
- name: Upload Release Asset (osx-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-osx-arm64-${{ steps.releaseNote.outputs.version }}-noexternals.tar.gz
asset_name: actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}-noexternals.tar.gz
asset_content_type: application/octet-stream
- name: Upload Release Asset (linux-arm-noexternals) - name: Upload Release Asset (linux-arm-noexternals)
uses: actions/upload-release-asset@v1.0.1 uses: actions/upload-release-asset@v1.0.1
env: env:
@@ -442,16 +416,6 @@ jobs:
asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}-noruntime.tar.gz asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}-noruntime.tar.gz
asset_content_type: application/octet-stream asset_content_type: application/octet-stream
- name: Upload Release Asset (osx-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-osx-arm64-${{ steps.releaseNote.outputs.version }}-noruntime.tar.gz
asset_name: actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}-noruntime.tar.gz
asset_content_type: application/octet-stream
- name: Upload Release Asset (linux-arm-noruntime) - name: Upload Release Asset (linux-arm-noruntime)
uses: actions/upload-release-asset@v1.0.1 uses: actions/upload-release-asset@v1.0.1
env: env:
@@ -503,16 +467,6 @@ jobs:
asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.tar.gz asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.tar.gz
asset_content_type: application/octet-stream asset_content_type: application/octet-stream
- name: Upload Release Asset (osx-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-osx-arm64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.tar.gz
asset_name: actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.tar.gz
asset_content_type: application/octet-stream
- name: Upload Release Asset (linux-arm-noruntime-noexternals) - name: Upload Release Asset (linux-arm-noruntime-noexternals)
uses: actions/upload-release-asset@v1.0.1 uses: actions/upload-release-asset@v1.0.1
env: env:
@@ -564,16 +518,6 @@ jobs:
asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json asset_name: actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json
asset_content_type: application/octet-stream asset_content_type: application/octet-stream
- name: Upload Release Asset (osx-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 }}/osx-arm64-trimmedpackages.json
asset_name: actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json
asset_content_type: application/octet-stream
- name: Upload Release Asset (linux-arm-trimmedpackages.json) - name: Upload Release Asset (linux-arm-trimmedpackages.json)
uses: actions/upload-release-asset@v1.0.1 uses: actions/upload-release-asset@v1.0.1
env: env:

View File

@@ -1,83 +0,0 @@
# ADR: Notification Hooks for Runners
## Context
This ADR details the design changes for supporting custom configurable hooks for on various runner events. This has been a long requested user feature [here](https://github.com/actions/runner/issues/1543), [here](https://github.com/actions/runner/issues/699) and [here](https://github.com/actions/runner/issues/1116) for users to have more information on runner observability, and for the ability to run cleanup and teardown jobs.
This feature is mainly intended for self hosted runner administrators.
**What we hope to solve with this feature**
1. A runner admininstrator is able to add custom scripts to cleanup their runner environment at the start or end of a job
2. A runner admininstrator is able to add custom scripts to help setup their runner environment at the beginning of a job, for reasons like [caching](https://github.com/actions/runner/issues/1543#issuecomment-1050346279)
3. A runner administrator is able to grab custom telemetry of jobs running on their self hosted runner
**What we don't think this will solve**
- Policy features that require certain steps run at the beginning or end of all jobs
- This would be better solved to in a central place in settings, rather then decentralized on each runner.
- The Proposed `Notification Hooks for Runners` is limited to self hosted runners, we don't beileve Policy features should be
- Reuse scenarios between jobs are covered by [composite actions](https://docs.github.com/en/actions/creating-actions/creating-a-composite-action) and [resuable workflows](https://docs.github.com/en/actions/using-workflows/reusing-workflows)
- Security applications, security should be handled on the policy side on the server, not decentralized on each runner
## Hooks
- We will expose 2 variables that users can set to enable hooks
- `ACTIONS_RUNNER_HOOK_JOB_STARTED`
- `ACTIONS_RUNNER_HOOK_JOB_COMPLETED`
You can set these variables to the **absolute** path of a a `.sh` or `.ps1` file.
We will execute `pwsh` (fallback to `powershell`) or `bash` (fallback to `sh`) as appropriate.
- `.sh` files will execute with the args `-e {pathtofile}`
- `.ps1` files will execute with the args `-command \". '{pathtofile}'\"`
We will **not** set the [standard flags we typically set](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell) for `runs` commands. So, if you want to set `pipefail` on `bash` for example, you will need to do that in your script.
### UI
We want to ensure the experience for users invoking workflows is good, if hooks take too long, you may feel your job is delayed or broken. So, much like `Set Up Job`, we will generate two new steps automatically in your job, one for each configured hook:
- `Set up runner`
- `Complete runner`
These steps will contain all of the output from invoking your hook, so you will have visibility into the runtime. We will also provide information on the path to the hook, and what shell we are invoking it as, much like we do for `run: ` steps.
### Contexts
When running your hooks, some context on your job may be helpful.
- The scripts will have access to the standard [default environment variables](https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables)
- Some of these variables are step specific like `GITHUB_ACTION`, in which case they will not be set
- You can pull the full webhook event payload from `GITHUB_EVENT_PATH`
### Commands
Should we expose [Commands](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions) and [Environment Files](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#environment-files)
**Yes**. Imagine a scenario where a runner administrator is deprecating a runner pool, and they need to [warn users](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-a-warning-message) to swap to a different pool, we should support them in doing this. However, there are some limitations:
- [save-state](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#sending-values-to-the-pre-and-post-actions) will **not** be supported, these are not traditional steps with pre and post actions
- [set-output](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#using-workflow-commands-to-access-toolkit-functions) will **not** be supported, there is no `id` as this is not a traditional step
### Environment Files
We will also enable [Environment Files](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#environment-files) to support setup scenarios for the runner environment.
While a self hosted runner admin can [set env variables](https://docs.github.com/en/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners#using-a-env-file-to-set-the-proxy-configuration), these apply to all jobs. By enabling the ability to `add a path` and `set an env` we give runner admins the ability to do this dynamically based on the [workflows environment variables](https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables) to empower setup scenarios.
### Exit codes
These are **synchronous** hooks, so they will block job execution while they are being run. Exit code 0 will indicate a successful run of the hook and we will proceed with the job, any other exit code will fail the job with an appropriate annotation.
- There will be no support for `continue-on-error`
## Key Decisions
- We will expose 2 variables that users can set to enable hooks
- `ACTIONS_RUNNER_HOOK_JOB_STARTED`
- `ACTIONS_RUNNER_HOOK_JOB_COMPLETED`
- Users can set these variables to the path of a `.sh` or `.ps1` file, which we will execute when Jobs are started or completed.
- Output from these will be added to a new step at the start/end of a job named `Set up runner` or `Complete runner`.
- These steps will only be generated on runs with these hooks
- These hooks `always()` execute if the env variable is set
- These files will execute as the Runner user, outside of any container specification on the job
- These are **synchronous** hooks
- Runner admins can execute a background process for async hooks if they want
- We will fail the job and halt execution on any exit code that is not 0. The Runner admin is responsible for returning the correct exit code and ensuring resilency.
- This includes that the runner user needs access to the file in the env and the file must exist
- There will be no `continue-on-error` type option on launch
- There will be no `timeout` option on launch
## Consequences
- Runner admins have the ability to tie into the runner job execution to publish their own telemetry or perform their own cleanup or setup
- New steps will be added to the UI showcasing the output of these hooks

View File

@@ -5,6 +5,12 @@
## Supported Versions ## Supported Versions
- macOS High Sierra (10.13) and later versions - macOS High Sierra (10.13) and later versions
- x64 and arm64 (Apple Silicon)
## Apple Silicon M1
The runner is currently not supported on devices with an Apple M1 chip.
We are waiting for official .NET support. You can read more here about the [current state of support here](https://github.com/orgs/dotnet/projects/18#card-56812463).
Current .NET project board about M1 support:
https://github.com/orgs/dotnet/projects/18#card-56812463
## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/macos-prerequisites?tabs=netcore30) ## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/macos-prerequisites?tabs=netcore30)

View File

@@ -1,11 +1,8 @@
## Features ## Features
- Added a pre-release package for the `macOS-arm64` architecture
- Note that this packages is pre-release status and may not work with all existing actions
## Bugs ## Bugs
- Fixed an issue where live console logs would fail to close (#1903) - Fixed an issue where websockets failed to successfully close when posting log lines (#1790)
## Misc
## 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.
@@ -21,7 +18,7 @@ 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")
``` ```
## OSX x64 ## OSX
``` bash ``` bash
# Create a folder # Create a folder
@@ -32,17 +29,6 @@ curl -O -L https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>
tar xzf ./actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz tar xzf ./actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz
``` ```
## [Pre-release] OSX arm64 (Apple silicon)
``` bash
# Create a folder
mkdir actions-runner && cd actions-runner
# Download the latest runner package
curl -O -L https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-osx-arm64-<RUNNER_VERSION>.tar.gz
# Extract the installer
tar xzf ./actions-runner-osx-arm64-<RUNNER_VERSION>.tar.gz
```
## Linux x64 ## Linux x64
``` bash ``` bash
@@ -85,28 +71,24 @@ 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-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-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 -->
- actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA linux-arm64 --><LINUX_ARM64_SHA><!-- END SHA linux-arm64 --> - actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA linux-arm64 --><LINUX_ARM64_SHA><!-- END SHA linux-arm64 -->
- 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-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-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 -->
- actions-runner-linux-arm64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA linux-arm64_noexternals --><LINUX_ARM64_SHA_NOEXTERNALS><!-- END SHA linux-arm64_noexternals --> - actions-runner-linux-arm64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA linux-arm64_noexternals --><LINUX_ARM64_SHA_NOEXTERNALS><!-- END SHA linux-arm64_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-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-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-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 -->
- actions-runner-linux-arm64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA linux-arm64_noruntime --><LINUX_ARM64_SHA_NORUNTIME><!-- END SHA linux-arm64_noruntime --> - actions-runner-linux-arm64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA linux-arm64_noruntime --><LINUX_ARM64_SHA_NORUNTIME><!-- END SHA linux-arm64_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-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-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-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 -->
- actions-runner-linux-arm64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA linux-arm64_noruntime_noexternals --><LINUX_ARM64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA linux-arm64_noruntime_noexternals --> - actions-runner-linux-arm64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA linux-arm64_noruntime_noexternals --><LINUX_ARM64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA linux-arm64_noruntime_noexternals -->
- actions-runner-linux-arm-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA linux-arm_noruntime_noexternals --><LINUX_ARM_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA linux-arm_noruntime_noexternals --> - actions-runner-linux-arm-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA linux-arm_noruntime_noexternals --><LINUX_ARM_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA linux-arm_noruntime_noexternals -->

View File

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

View File

@@ -25,12 +25,9 @@
<DefineConstants>$(DefineConstants);X86</DefineConstants> <DefineConstants>$(DefineConstants);X86</DefineConstants>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(BUILD_OS)' == 'OSX' AND '$(PackageRuntime)' == 'osx-x64'"> <PropertyGroup Condition="'$(BUILD_OS)' == 'OSX'">
<DefineConstants>$(DefineConstants);X64</DefineConstants> <DefineConstants>$(DefineConstants);X64</DefineConstants>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(BUILD_OS)' == 'OSX' AND '$(PackageRuntime)' == 'osx-arm64'">
<DefineConstants>$(DefineConstants);ARM64</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(BUILD_OS)' == 'Linux' AND ('$(PackageRuntime)' == 'linux-x64' OR '$(PackageRuntime)' == '')"> <PropertyGroup Condition="'$(BUILD_OS)' == 'Linux' AND ('$(PackageRuntime)' == 'linux-x64' OR '$(PackageRuntime)' == '')">
<DefineConstants>$(DefineConstants);X64</DefineConstants> <DefineConstants>$(DefineConstants);X64</DefineConstants>
@@ -50,6 +47,11 @@
<DefineConstants>$(DefineConstants);DEBUG</DefineConstants> <DefineConstants>$(DefineConstants);DEBUG</DefineConstants>
</PropertyGroup> </PropertyGroup>
<!-- Set USE_BROKER vars -->
<PropertyGroup Condition="'$(USE_BROKER)' == 'true'">
<DefineConstants>$(DefineConstants);USE_BROKER</DefineConstants>
</PropertyGroup>
<!-- Set Treat tarnings as errors --> <!-- Set Treat tarnings as errors -->
<PropertyGroup> <PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>

View File

@@ -1 +1 @@
1d709d93e5d3c6c6c656a61aa6c1781050224788a05b0e6ecc4c3c0408bdf89c de62d296708908cfd1236e58869aebbc2bae8a8c3d629276968542626c508e37

View File

@@ -1 +1 @@
b92a47cfeaad02255b1f7a377060651b73ae5e5db22a188dbbcb4183ab03a03d 44fcd0422dd98ed17d2c8e9057ff2260c50165f20674236a4ae7d2645a07df25

View File

@@ -1 +1 @@
68a9a8ef0843a8bb74241894f6f63fd76241a82295c5337d3cc7a940a314c78e e57652cf322ee16ce3af4f9e58f80858746b9e1e60279e991a3b3d9a6baf8d79

View File

@@ -1 +0,0 @@
02c7126ff4d63ee2a0ae390c81434c125630522aadf35903bbeebb1a99d8af99

View File

@@ -1 +1 @@
c9d5a542f8d765168855a89e83ae0a8970d00869041c4f9a766651c04c72b212 bdd247b2ff3f51095524412e2ac588e7a87af805e114d6caf2368366ee7be1ea

View File

@@ -1 +1 @@
d94f2fbaf210297162bc9f3add819d73682c3aa6899e321c3872412b924d5504 d23a0cb9f20c0aa1cddb7a39567cd097020cdeb06a1e952940601d1a405c53b8

View File

@@ -1 +0,0 @@
cc4708962a80325de0baa5ae8484e0cb9ae976ac6a4178c1c0d448b8c52bd7f7

View File

@@ -140,11 +140,6 @@ if [[ "$PACKAGERUNTIME" == "osx-x64" ]]; then
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-darwin-x64.tar.gz" node16 fix_nested_dir acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-darwin-x64.tar.gz" node16 fix_nested_dir
fi fi
if [[ "$PACKAGERUNTIME" == "osx-arm64" ]]; then
# node.js v12 doesn't support macOS on arm64.
acquireExternalTool "$NODE_URL/v${NODE16_VERSION}/node-v${NODE16_VERSION}-darwin-arm64.tar.gz" node16 fix_nested_dir
fi
# Download the external tools for Linux PACKAGERUNTIMEs. # Download the external tools for Linux PACKAGERUNTIMEs.
if [[ "$PACKAGERUNTIME" == "linux-x64" ]]; then if [[ "$PACKAGERUNTIME" == "linux-x64" ]]; then
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-x64.tar.gz" node12 fix_nested_dir acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-x64.tar.gz" node12 fix_nested_dir

View File

@@ -3,7 +3,6 @@ api-ms-win-core-console-l1-2-0.dll
api-ms-win-core-datetime-l1-1-0.dll api-ms-win-core-datetime-l1-1-0.dll
api-ms-win-core-debug-l1-1-0.dll api-ms-win-core-debug-l1-1-0.dll
api-ms-win-core-errorhandling-l1-1-0.dll api-ms-win-core-errorhandling-l1-1-0.dll
api-ms-win-core-fibers-l1-1-0.dll
api-ms-win-core-file-l1-1-0.dll api-ms-win-core-file-l1-1-0.dll
api-ms-win-core-file-l1-2-0.dll api-ms-win-core-file-l1-2-0.dll
api-ms-win-core-file-l2-1-0.dll api-ms-win-core-file-l2-1-0.dll
@@ -71,7 +70,7 @@ 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.21.52210.dll
mscordbi.dll mscordbi.dll
mscorlib.dll mscorlib.dll
mscorrc.debug.dll mscorrc.debug.dll

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using GitHub.DistributedTask.WebApi;
using System.Threading;
using System.Threading.Tasks;
using GitHub.Runner.Common.Util;
using GitHub.Services.WebApi;
using GitHub.Services.Common;
using GitHub.Runner.Sdk;
using System.Net;
using System.Net.Http;
namespace GitHub.Runner.Common
{
[ServiceLocator(Default = typeof(BrokerServer))]
public interface IBrokerServer : IRunnerService
{
Task ConnectAsync(Uri serverUrl, CancellationToken cancellationToken);
Task<string> GetMessageAsync(TaskAgentSession session, RunnerSettings settings, long? lastMessageId, CancellationToken cancellationToken);
}
public sealed class BrokerServer : RunnerService, IBrokerServer
{
private HttpClient _httpClient;
public async Task ConnectAsync(Uri serverUrl, CancellationToken cancellationToken)
{
_httpClient = new HttpClient();
_httpClient.BaseAddress = serverUrl;
_httpClient.Timeout = TimeSpan.FromSeconds(100);
await _httpClient.GetAsync("health", cancellationToken);
}
public async Task<string> GetMessageAsync(TaskAgentSession session, RunnerSettings settings, long? lastMessageId, CancellationToken cancellationToken)
{
var response = await _httpClient.GetAsync($"message?tenant=org:github&root_tenant=org:github&group_id={settings.PoolId}&group_name={settings.PoolName}&runner_id={settings.AgentId}&runner_name={settings.AgentName}&labels=self-hosted,linux", cancellationToken);
if (!response.IsSuccessStatusCode)
{
var content = default(string);
try
{
content = await response.Content.ReadAsStringAsync();
}
catch
{
}
var error = $"HTTP {(int)response.StatusCode} {Enum.GetName(typeof(HttpStatusCode), response.StatusCode)}";
if (!string.IsNullOrEmpty(content))
{
error = $"{error}: {content}";
}
throw new Exception(error);
}
return await response.Content.ReadAsStringAsync();
}
}
}

View File

@@ -86,7 +86,7 @@ namespace GitHub.Runner.Common
public static class CommandLine public static class CommandLine
{ {
//if you are adding a new arg, please make sure you update the //if you are adding a new arg, please make sure you update the
//validOptions dictionary as well present in the CommandSettings.cs //validArgs array as well present in the CommandSettings.cs
public static class Args public static class Args
{ {
public static readonly string Auth = "auth"; public static readonly string Auth = "auth";
@@ -121,7 +121,7 @@ namespace GitHub.Runner.Common
} }
//if you are adding a new flag, please make sure you update the //if you are adding a new flag, please make sure you update the
//validOptions dictionary as well present in the CommandSettings.cs //validFlags array as well present in the CommandSettings.cs
public static class Flags public static class Flags
{ {
public static readonly string Check = "check"; public static readonly string Check = "check";
@@ -150,7 +150,6 @@ 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 InternalTelemetryIssueDataKey = "_internal_telemetry"; public static readonly string InternalTelemetryIssueDataKey = "_internal_telemetry";

View File

@@ -1,4 +1,5 @@
using System; using GitHub.DistributedTask.WebApi;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -8,7 +9,6 @@ using System.Net.WebSockets;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using GitHub.DistributedTask.WebApi;
using GitHub.Runner.Sdk; using GitHub.Runner.Sdk;
using GitHub.Services.Common; using GitHub.Services.Common;
using GitHub.Services.WebApi; using GitHub.Services.WebApi;
@@ -140,8 +140,8 @@ namespace GitHub.Runner.Common
public void InitializeWebsocketClient(ServiceEndpoint serviceEndpoint) public void InitializeWebsocketClient(ServiceEndpoint serviceEndpoint)
{ {
this._serviceEndpoint = serviceEndpoint; this._serviceEndpoint = serviceEndpoint;
InitializeWebsocketClient(TimeSpan.Zero); InitializeWebsocketClient(TimeSpan.Zero);
} }
public ValueTask DisposeAsync() public ValueTask DisposeAsync()
@@ -163,9 +163,9 @@ namespace GitHub.Runner.Common
private void InitializeWebsocketClient(TimeSpan delay) private void InitializeWebsocketClient(TimeSpan delay)
{ {
if (_serviceEndpoint.Authorization != null && if (_serviceEndpoint.Authorization != null &&
_serviceEndpoint.Authorization.Parameters.TryGetValue(EndpointAuthorizationParameters.AccessToken, out var accessToken) && _serviceEndpoint.Authorization.Parameters.TryGetValue(EndpointAuthorizationParameters.AccessToken, out var accessToken) &&
!string.IsNullOrEmpty(accessToken)) !string.IsNullOrEmpty(accessToken))
{ {
if (_serviceEndpoint.Data.TryGetValue("FeedStreamUrl", out var feedStreamUrl) && !string.IsNullOrEmpty(feedStreamUrl)) if (_serviceEndpoint.Data.TryGetValue("FeedStreamUrl", out var feedStreamUrl) && !string.IsNullOrEmpty(feedStreamUrl))
{ {
@@ -177,7 +177,7 @@ namespace GitHub.Runner.Common
var userAgentValues = new List<ProductInfoHeaderValue>(); var userAgentValues = new List<ProductInfoHeaderValue>();
userAgentValues.AddRange(UserAgentUtility.GetDefaultRestUserAgent()); userAgentValues.AddRange(UserAgentUtility.GetDefaultRestUserAgent());
userAgentValues.AddRange(HostContext.UserAgents); userAgentValues.AddRange(HostContext.UserAgents);
this._websocketClient.Options.SetRequestHeader("User-Agent", string.Join(" ", userAgentValues.Select(x => x.ToString()))); this._websocketClient.Options.SetRequestHeader("User-Agent", string.Join(" ", userAgentValues.Select(x=>x.ToString())));
this._websocketConnectTask = ConnectWebSocketClient(feedStreamUrl, delay); this._websocketConnectTask = ConnectWebSocketClient(feedStreamUrl, delay);
} }
@@ -201,7 +201,7 @@ namespace GitHub.Runner.Common
await this._websocketClient.ConnectAsync(new Uri(feedStreamUrl), default(CancellationToken)); await this._websocketClient.ConnectAsync(new Uri(feedStreamUrl), default(CancellationToken));
Trace.Info($"Successfully started websocket client."); Trace.Info($"Successfully started websocket client.");
} }
catch (Exception ex) catch(Exception ex)
{ {
Trace.Info("Exception caught during websocket client connect, fallback of HTTP would be used now instead of websocket."); Trace.Info("Exception caught during websocket client connect, fallback of HTTP would be used now instead of websocket.");
Trace.Error(ex); Trace.Error(ex);
@@ -231,7 +231,7 @@ namespace GitHub.Runner.Common
// ...in other words, if websocket client is null, we will skip sending to websocket and just use rest api calls to send data // ...in other words, if websocket client is null, we will skip sending to websocket and just use rest api calls to send data
if (_websocketClient != null) if (_websocketClient != null)
{ {
var linesWrapper = startLine.HasValue ? new TimelineRecordFeedLinesWrapper(stepId, lines, startLine.Value) : new TimelineRecordFeedLinesWrapper(stepId, lines); var linesWrapper = startLine.HasValue? new TimelineRecordFeedLinesWrapper(stepId, lines, startLine.Value): new TimelineRecordFeedLinesWrapper(stepId, lines);
var jsonData = StringUtil.ConvertToJson(linesWrapper); var jsonData = StringUtil.ConvertToJson(linesWrapper);
try try
{ {
@@ -242,7 +242,7 @@ namespace GitHub.Runner.Common
{ {
var lastChunk = i + (1 * 1024) >= jsonDataBytes.Length; var lastChunk = i + (1 * 1024) >= jsonDataBytes.Length;
var chunk = new ArraySegment<byte>(jsonDataBytes, i, Math.Min(1 * 1024, jsonDataBytes.Length - i)); var chunk = new ArraySegment<byte>(jsonDataBytes, i, Math.Min(1 * 1024, jsonDataBytes.Length - i));
await _websocketClient.SendAsync(chunk, WebSocketMessageType.Text, endOfMessage: lastChunk, cancellationToken); await _websocketClient.SendAsync(chunk, WebSocketMessageType.Text, endOfMessage:lastChunk, cancellationToken);
} }
pushedLinesViaWebsocket = true; pushedLinesViaWebsocket = true;
@@ -274,7 +274,7 @@ namespace GitHub.Runner.Common
} }
} }
if (!pushedLinesViaWebsocket && !cancellationToken.IsCancellationRequested) if (!pushedLinesViaWebsocket)
{ {
if (startLine.HasValue) if (startLine.HasValue)
{ {

View File

@@ -299,11 +299,7 @@ namespace GitHub.Runner.Common
{ {
try try
{ {
// Give at most 60s for each request. await _jobServer.AppendTimelineRecordFeedAsync(_scopeIdentifier, _hubName, _planId, _jobTimelineId, _jobTimelineRecordId, stepRecordId, batch.Select(logLine => logLine.Line).ToList(), batch[0].LineNumber, default(CancellationToken));
using (var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(60)))
{
await _jobServer.AppendTimelineRecordFeedAsync(_scopeIdentifier, _hubName, _planId, _jobTimelineId, _jobTimelineRecordId, stepRecordId, batch.Select(logLine => logLine.Line).ToList(), batch[0].LineNumber, timeoutTokenSource.Token);
}
if (_firstConsoleOutputs) if (_firstConsoleOutputs)
{ {

View File

@@ -0,0 +1,120 @@
using GitHub.DistributedTask.WebApi;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using GitHub.Runner.Common.Util;
using GitHub.Services.WebApi;
using GitHub.Services.Common;
using GitHub.Runner.Sdk;
using GitHub.DistributedTask.Pipelines;
namespace GitHub.Runner.Common
{
[ServiceLocator(Default = typeof(RunServer))]
public interface IRunServer : IRunnerService
{
Task ConnectAsync(Uri serverUrl, VssCredentials credentials);
Task<AgentJobRequestMessage> GetJobMessageAsync(Guid scopeId, Guid hostId, string planType, string planGroup, Guid planId, IList<InstanceRef> instanceRefsJson);
}
public sealed class RunServer : RunnerService, IRunServer
{
private bool _hasConnection;
private VssConnection _connection;
private TaskAgentHttpClient _taskAgentClient;
public async Task ConnectAsync(Uri serverUrl, VssCredentials credentials)
{
// System.Console.WriteLine("RunServer.ConnectAsync");
_connection = await EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(100));
_taskAgentClient = _connection.GetClient<TaskAgentHttpClient>();
_hasConnection = true;
}
private async Task<VssConnection> EstablishVssConnection(Uri serverUrl, VssCredentials credentials, TimeSpan timeout)
{
// System.Console.WriteLine("EstablishVssConnection");
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()
{
if (!_hasConnection)
{
throw new InvalidOperationException($"SetConnection");
}
}
public Task<AgentJobRequestMessage> GetJobMessageAsync(
Guid scopeId,
Guid hostId,
string planType,
string planGroup,
Guid planId,
IList<InstanceRef> instanceRefsJson)
{
// System.Console.WriteLine("RunServer.GetMessageAsync");
CheckConnection();
return _taskAgentClient.GetJobMessageAsync(scopeId, hostId, planType, planGroup, planId, StringUtil.ConvertToJson(instanceRefsJson, Newtonsoft.Json.Formatting.None));
}
}
// todo: move to SDK?
[DataContract]
public sealed class MessageRef
{
[DataMember(Name = "url")]
public string Url { get; set; }
[DataMember(Name = "token")]
public string Token { get; set; }
[DataMember(Name = "scopeId")]
public Guid ScopeId { get; set; }
[DataMember(Name = "hostId")]
public Guid HostId { get; set; }
[DataMember(Name = "planType")]
public string PlanType { get; set; }
[DataMember(Name = "planGroup")]
public string PlanGroup { get; set; }
[DataMember(Name = "planId")]
public Guid PlanId { get; set; }
[DataMember(Name = "instanceRefs")]
public InstanceRef[] InstanceRefs { get; set; }
[DataMember(Name = "labels")]
public string[] Labels { get; set; }
}
[DataContract]
public sealed class InstanceRef
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "instanceType")]
public string InstanceType { get; set; }
[DataMember(Name = "attempt")]
public int Attempt { get; set; }
}
}

View File

@@ -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</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch> <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<NoWarn>NU1701;NU1603</NoWarn> <NoWarn>NU1701;NU1603</NoWarn>
<Version>$(Version)</Version> <Version>$(Version)</Version>

View File

@@ -44,7 +44,7 @@ namespace GitHub.Runner.Common
// job request // job request
Task<TaskAgentJobRequest> GetAgentRequestAsync(int poolId, long requestId, CancellationToken cancellationToken); Task<TaskAgentJobRequest> GetAgentRequestAsync(int poolId, long requestId, CancellationToken cancellationToken);
Task<TaskAgentJobRequest> RenewAgentRequestAsync(int poolId, long requestId, Guid lockToken, string orchestrationId, CancellationToken cancellationToken); Task<TaskAgentJobRequest> RenewAgentRequestAsync(int poolId, long requestId, Guid lockToken, string orchestrationId, CancellationToken cancellationToken);
Task<TaskAgentJobRequest> FinishAgentRequestAsync(int poolId, long requestId, Guid lockToken, DateTime finishTime, TaskResult result, CancellationToken cancellationToken); Task<TaskAgentJobRequest> FinishAgentRequestAsync(int poolId, long requestId, Guid lockToken, DateTime finishTime, TaskResult result, Guid targetHostId, CancellationToken cancellationToken);
// agent package // agent package
Task<List<PackageMetadata>> GetPackagesAsync(string packageType, string platform, int top, bool includeToken, CancellationToken cancellationToken); Task<List<PackageMetadata>> GetPackagesAsync(string packageType, string platform, int top, bool includeToken, CancellationToken cancellationToken);
@@ -68,11 +68,23 @@ namespace GitHub.Runner.Common
public async Task ConnectAsync(Uri serverUrl, VssCredentials credentials) public async Task ConnectAsync(Uri serverUrl, VssCredentials credentials)
{ {
var createGenericConnection = EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(100)); // System.Console.WriteLine("RunnerServer.ConnectAsync: Create message connection");
var createMessageConnection = EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(60)); var createMessageConnection = EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(60));
var createRequestConnection = EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(60)); await Task.WhenAll(createMessageConnection);
await Task.WhenAll(createGenericConnection, createMessageConnection, createRequestConnection); // System.Console.WriteLine("RunnerServer.ConnectAsync: Create generic connection");
var createGenericConnection = EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(100));
await Task.WhenAll(createGenericConnection);
// System.Console.WriteLine("RunnerServer.ConnectAsync: Create request connection");
var createRequestConnection = EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(60));
await Task.WhenAll(createRequestConnection);
// var createGenericConnection = EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(100));
// var createMessageConnection = EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(60));
// var createRequestConnection = EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(60));
// await Task.WhenAll(createGenericConnection, createMessageConnection, createRequestConnection);
_genericConnection = await createGenericConnection; _genericConnection = await createGenericConnection;
_messageConnection = await createMessageConnection; _messageConnection = await createMessageConnection;
@@ -182,6 +194,8 @@ namespace GitHub.Runner.Common
private async Task<VssConnection> EstablishVssConnection(Uri serverUrl, VssCredentials credentials, TimeSpan timeout) private async Task<VssConnection> EstablishVssConnection(Uri serverUrl, VssCredentials credentials, TimeSpan timeout)
{ {
// System.Console.WriteLine("EstablishVssConnection");
Trace.Info($"EstablishVssConnection");
Trace.Info($"Establish connection with {timeout.TotalSeconds} seconds timeout."); Trace.Info($"Establish connection with {timeout.TotalSeconds} seconds timeout.");
int attemptCount = 5; int attemptCount = 5;
while (attemptCount-- > 0) while (attemptCount-- > 0)
@@ -238,41 +252,48 @@ namespace GitHub.Runner.Common
public Task<List<TaskAgentPool>> GetAgentPoolsAsync(string agentPoolName = null, TaskAgentPoolType poolType = TaskAgentPoolType.Automation) public Task<List<TaskAgentPool>> GetAgentPoolsAsync(string agentPoolName = null, TaskAgentPoolType poolType = TaskAgentPoolType.Automation)
{ {
// System.Console.WriteLine("RunnerServer.GetAgentPoolsAsync");
CheckConnection(RunnerConnectionType.Generic); CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.GetAgentPoolsAsync(agentPoolName, poolType: poolType); return _genericTaskAgentClient.GetAgentPoolsAsync(agentPoolName, poolType: poolType);
} }
public Task<TaskAgent> AddAgentAsync(Int32 agentPoolId, TaskAgent agent) public Task<TaskAgent> AddAgentAsync(Int32 agentPoolId, TaskAgent agent)
{ {
// System.Console.WriteLine("RunnerServer.AddAgentAsync");
CheckConnection(RunnerConnectionType.Generic); CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.AddAgentAsync(agentPoolId, agent); return _genericTaskAgentClient.AddAgentAsync(agentPoolId, agent);
} }
public Task<List<TaskAgent>> GetAgentsAsync(int agentPoolId, string agentName = null) public Task<List<TaskAgent>> GetAgentsAsync(int agentPoolId, string agentName = null)
{ {
// System.Console.WriteLine("RunnerServer.GetAgentsAsync 1");
CheckConnection(RunnerConnectionType.Generic); CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.GetAgentsAsync(agentPoolId, agentName, false); return _genericTaskAgentClient.GetAgentsAsync(agentPoolId, agentName, false);
} }
public Task<List<TaskAgent>> GetAgentsAsync(string agentName) public Task<List<TaskAgent>> GetAgentsAsync(string agentName)
{ {
// System.Console.WriteLine("RunnerServer.GetAgentsAsync 2");
return GetAgentsAsync(0, agentName); // search in all all agentPools return GetAgentsAsync(0, agentName); // search in all all agentPools
} }
public Task<TaskAgent> ReplaceAgentAsync(int agentPoolId, TaskAgent agent) public Task<TaskAgent> ReplaceAgentAsync(int agentPoolId, TaskAgent agent)
{ {
// System.Console.WriteLine("RunnerServer.ReplaceAgentAsync");
CheckConnection(RunnerConnectionType.Generic); CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.ReplaceAgentAsync(agentPoolId, agent); return _genericTaskAgentClient.ReplaceAgentAsync(agentPoolId, agent);
} }
public Task DeleteAgentAsync(int agentPoolId, int agentId) public Task DeleteAgentAsync(int agentPoolId, int agentId)
{ {
// System.Console.WriteLine("RunnerServer.DeleteAgentAsync");
CheckConnection(RunnerConnectionType.Generic); CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.DeleteAgentAsync(agentPoolId, agentId); return _genericTaskAgentClient.DeleteAgentAsync(agentPoolId, agentId);
} }
public Task DeleteAgentAsync(int agentId) public Task DeleteAgentAsync(int agentId)
{ {
// System.Console.WriteLine("RunnerServer.DeleteAgentAsync");
return DeleteAgentAsync(0, agentId); // agentPool is ignored server side return DeleteAgentAsync(0, agentId); // agentPool is ignored server side
} }
@@ -282,24 +303,28 @@ namespace GitHub.Runner.Common
public Task<TaskAgentSession> CreateAgentSessionAsync(Int32 poolId, TaskAgentSession session, CancellationToken cancellationToken) public Task<TaskAgentSession> CreateAgentSessionAsync(Int32 poolId, TaskAgentSession session, CancellationToken cancellationToken)
{ {
// System.Console.WriteLine("RunnerServer.CreateAgentSessionAsync");
CheckConnection(RunnerConnectionType.MessageQueue); CheckConnection(RunnerConnectionType.MessageQueue);
return _messageTaskAgentClient.CreateAgentSessionAsync(poolId, session, cancellationToken: cancellationToken); return _messageTaskAgentClient.CreateAgentSessionAsync(poolId, session, cancellationToken: cancellationToken);
} }
public Task DeleteAgentMessageAsync(Int32 poolId, Int64 messageId, Guid sessionId, CancellationToken cancellationToken) public Task DeleteAgentMessageAsync(Int32 poolId, Int64 messageId, Guid sessionId, CancellationToken cancellationToken)
{ {
// System.Console.WriteLine("RunnerServer.DeleteAgentMessageAsync");
CheckConnection(RunnerConnectionType.MessageQueue); CheckConnection(RunnerConnectionType.MessageQueue);
return _messageTaskAgentClient.DeleteMessageAsync(poolId, messageId, sessionId, cancellationToken: cancellationToken); return _messageTaskAgentClient.DeleteMessageAsync(poolId, messageId, sessionId, cancellationToken: cancellationToken);
} }
public Task DeleteAgentSessionAsync(Int32 poolId, Guid sessionId, CancellationToken cancellationToken) public Task DeleteAgentSessionAsync(Int32 poolId, Guid sessionId, CancellationToken cancellationToken)
{ {
// System.Console.WriteLine("RunnerServer.DeleteAgentSessionAsync");
CheckConnection(RunnerConnectionType.MessageQueue); CheckConnection(RunnerConnectionType.MessageQueue);
return _messageTaskAgentClient.DeleteAgentSessionAsync(poolId, sessionId, cancellationToken: cancellationToken); return _messageTaskAgentClient.DeleteAgentSessionAsync(poolId, sessionId, cancellationToken: cancellationToken);
} }
public Task<TaskAgentMessage> GetAgentMessageAsync(Int32 poolId, Guid sessionId, Int64? lastMessageId, CancellationToken cancellationToken) public Task<TaskAgentMessage> GetAgentMessageAsync(Int32 poolId, Guid sessionId, Int64? lastMessageId, CancellationToken cancellationToken)
{ {
// System.Console.WriteLine("RunnerServer.GetAgentMessageAsync");
CheckConnection(RunnerConnectionType.MessageQueue); CheckConnection(RunnerConnectionType.MessageQueue);
return _messageTaskAgentClient.GetMessageAsync(poolId, sessionId, lastMessageId, cancellationToken: cancellationToken); return _messageTaskAgentClient.GetMessageAsync(poolId, sessionId, lastMessageId, cancellationToken: cancellationToken);
} }
@@ -310,18 +335,21 @@ namespace GitHub.Runner.Common
public Task<TaskAgentJobRequest> RenewAgentRequestAsync(int poolId, long requestId, Guid lockToken, string orchestrationId = null, CancellationToken cancellationToken = default(CancellationToken)) public Task<TaskAgentJobRequest> RenewAgentRequestAsync(int poolId, long requestId, Guid lockToken, string orchestrationId = null, CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("RunnerServer.RenewAgentRequestAsync");
CheckConnection(RunnerConnectionType.JobRequest); CheckConnection(RunnerConnectionType.JobRequest);
return _requestTaskAgentClient.RenewAgentRequestAsync(poolId, requestId, lockToken, orchestrationId: orchestrationId, cancellationToken: cancellationToken); return _requestTaskAgentClient.RenewAgentRequestAsync(poolId, requestId, lockToken, orchestrationId: orchestrationId, cancellationToken: cancellationToken);
} }
public Task<TaskAgentJobRequest> FinishAgentRequestAsync(int poolId, long requestId, Guid lockToken, DateTime finishTime, TaskResult result, CancellationToken cancellationToken = default(CancellationToken)) public Task<TaskAgentJobRequest> FinishAgentRequestAsync(int poolId, long requestId, Guid lockToken, DateTime finishTime, TaskResult result, Guid targetHostId, CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("RunnerServer.FinishAgentRequestAsync");
CheckConnection(RunnerConnectionType.JobRequest); CheckConnection(RunnerConnectionType.JobRequest);
return _requestTaskAgentClient.FinishAgentRequestAsync(poolId, requestId, lockToken, finishTime, result, cancellationToken: cancellationToken); return _requestTaskAgentClient.FinishAgentRequestAsync(poolId, requestId, lockToken, finishTime, result, targetHostId, cancellationToken: cancellationToken);
} }
public Task<TaskAgentJobRequest> GetAgentRequestAsync(int poolId, long requestId, CancellationToken cancellationToken = default(CancellationToken)) public Task<TaskAgentJobRequest> GetAgentRequestAsync(int poolId, long requestId, CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("RunnerServer.GetAgentRequestAsync");
CheckConnection(RunnerConnectionType.JobRequest); CheckConnection(RunnerConnectionType.JobRequest);
return _requestTaskAgentClient.GetAgentRequestAsync(poolId, requestId, cancellationToken: cancellationToken); return _requestTaskAgentClient.GetAgentRequestAsync(poolId, requestId, cancellationToken: cancellationToken);
} }
@@ -331,18 +359,21 @@ namespace GitHub.Runner.Common
//----------------------------------------------------------------- //-----------------------------------------------------------------
public Task<List<PackageMetadata>> GetPackagesAsync(string packageType, string platform, int top, bool includeToken, CancellationToken cancellationToken) public Task<List<PackageMetadata>> GetPackagesAsync(string packageType, string platform, int top, bool includeToken, CancellationToken cancellationToken)
{ {
// System.Console.WriteLine("RunnerServer.GetPackagesAsync");
CheckConnection(RunnerConnectionType.Generic); CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.GetPackagesAsync(packageType, platform, top, includeToken, cancellationToken: cancellationToken); return _genericTaskAgentClient.GetPackagesAsync(packageType, platform, top, includeToken, cancellationToken: cancellationToken);
} }
public Task<PackageMetadata> GetPackageAsync(string packageType, string platform, string version, bool includeToken, CancellationToken cancellationToken) public Task<PackageMetadata> GetPackageAsync(string packageType, string platform, string version, bool includeToken, CancellationToken cancellationToken)
{ {
// System.Console.WriteLine("RunnerServer.GetPackageAsync");
CheckConnection(RunnerConnectionType.Generic); CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.GetPackageAsync(packageType, platform, version, includeToken, cancellationToken: cancellationToken); return _genericTaskAgentClient.GetPackageAsync(packageType, platform, version, includeToken, cancellationToken: cancellationToken);
} }
public Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, int agentId, string currentState, string trace) public Task<TaskAgent> UpdateAgentUpdateStateAsync(int agentPoolId, int agentId, string currentState, string trace)
{ {
// System.Console.WriteLine("RunnerServer.UpdateAgentUpdateStateAsync");
CheckConnection(RunnerConnectionType.Generic); CheckConnection(RunnerConnectionType.Generic);
return _genericTaskAgentClient.UpdateAgentUpdateStateAsync(agentPoolId, agentId, currentState, trace); return _genericTaskAgentClient.UpdateAgentUpdateStateAsync(agentPoolId, agentId, currentState, trace);
} }

View File

@@ -6,13 +6,7 @@ namespace GitHub.Runner.Common.Util
public static class NodeUtil public static class NodeUtil
{ {
private const string _defaultNodeVersion = "node16"; private const string _defaultNodeVersion = "node16";
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] {"node12", "node16"});
#if OS_OSX && ARM64
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node16" });
#else
public static readonly ReadOnlyCollection<string> BuiltInNodeVersions = new(new[] { "node12", "node16" });
#endif
public static string GetInternalNodeVersion() public static string GetInternalNodeVersion()
{ {
var forcedNodeVersion = Environment.GetEnvironmentVariable(Constants.Variables.Agent.ForcedInternalNodeVersion); var forcedNodeVersion = Environment.GetEnvironmentVariable(Constants.Variables.Agent.ForcedInternalNodeVersion);

View File

@@ -17,57 +17,43 @@ namespace GitHub.Runner.Listener
private readonly IPromptManager _promptManager; private readonly IPromptManager _promptManager;
private readonly Tracing _trace; private readonly Tracing _trace;
// Valid flags for all commands private readonly string[] validCommands =
private readonly string[] genericOptions =
{ {
Constants.Runner.CommandLine.Flags.Help, Constants.Runner.CommandLine.Commands.Configure,
Constants.Runner.CommandLine.Flags.Version, Constants.Runner.CommandLine.Commands.Remove,
Constants.Runner.CommandLine.Flags.Commit, Constants.Runner.CommandLine.Commands.Run,
Constants.Runner.CommandLine.Flags.Check Constants.Runner.CommandLine.Commands.Warmup,
}; };
// Valid flags and args for specific command - key: command, value: array of valid flags and args private readonly string[] validFlags =
private readonly Dictionary<string, string[]> validOptions = new Dictionary<string, string[]>
{ {
// Valid configure flags and args Constants.Runner.CommandLine.Flags.Check,
[Constants.Runner.CommandLine.Commands.Configure] = Constants.Runner.CommandLine.Flags.Commit,
new string[] Constants.Runner.CommandLine.Flags.DisableUpdate,
{ Constants.Runner.CommandLine.Flags.Ephemeral,
Constants.Runner.CommandLine.Flags.DisableUpdate, Constants.Runner.CommandLine.Flags.Help,
Constants.Runner.CommandLine.Flags.Ephemeral, Constants.Runner.CommandLine.Flags.Once,
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,
Constants.Runner.CommandLine.Args.Auth, Constants.Runner.CommandLine.Flags.Version
Constants.Runner.CommandLine.Args.Labels, };
Constants.Runner.CommandLine.Args.MonitorSocketAddress,
Constants.Runner.CommandLine.Args.Name, private readonly string[] validArgs =
Constants.Runner.CommandLine.Args.PAT, {
Constants.Runner.CommandLine.Args.RunnerGroup, Constants.Runner.CommandLine.Args.Auth,
Constants.Runner.CommandLine.Args.Token, Constants.Runner.CommandLine.Args.Labels,
Constants.Runner.CommandLine.Args.Url, Constants.Runner.CommandLine.Args.MonitorSocketAddress,
Constants.Runner.CommandLine.Args.UserName, Constants.Runner.CommandLine.Args.Name,
Constants.Runner.CommandLine.Args.WindowsLogonAccount, Constants.Runner.CommandLine.Args.PAT,
Constants.Runner.CommandLine.Args.WindowsLogonPassword, Constants.Runner.CommandLine.Args.RunnerGroup,
Constants.Runner.CommandLine.Args.Work Constants.Runner.CommandLine.Args.StartupType,
}, Constants.Runner.CommandLine.Args.Token,
// Valid remove flags and args Constants.Runner.CommandLine.Args.Url,
[Constants.Runner.CommandLine.Commands.Remove] = Constants.Runner.CommandLine.Args.UserName,
new string[] Constants.Runner.CommandLine.Args.WindowsLogonAccount,
{ Constants.Runner.CommandLine.Args.WindowsLogonPassword,
Constants.Runner.CommandLine.Args.Token, Constants.Runner.CommandLine.Args.Work
Constants.Runner.CommandLine.Args.PAT
},
// Valid run flags and args
[Constants.Runner.CommandLine.Commands.Run] =
new string[]
{
Constants.Runner.CommandLine.Flags.Once,
Constants.Runner.CommandLine.Args.StartupType
},
// valid warmup flags and args
[Constants.Runner.CommandLine.Commands.Warmup] =
new string[] { }
}; };
// Commands. // Commands.
@@ -140,48 +126,17 @@ namespace GitHub.Runner.Listener
List<string> unknowns = new List<string>(); 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 => !validCommands.Contains(x, StringComparer.OrdinalIgnoreCase)));
if (unknowns.Count == 0) // detect unknown flags
{ unknowns.AddRange(_parser.Flags.Where(x => !validFlags.Contains(x, StringComparer.OrdinalIgnoreCase)));
// detect unknown flags and args for valid commands
foreach (var command in _parser.Commands) // detect unknown args
{ unknowns.AddRange(_parser.Args.Keys.Where(x => !validArgs.Contains(x, StringComparer.OrdinalIgnoreCase)));
if (validOptions.TryGetValue(command, out string[] options))
{
unknowns.AddRange(_parser.Flags.Where(x => !options.Contains(x, StringComparer.OrdinalIgnoreCase) && !genericOptions.Contains(x, StringComparer.OrdinalIgnoreCase)));
unknowns.AddRange(_parser.Args.Keys.Where(x => !options.Contains(x, StringComparer.OrdinalIgnoreCase)));
}
}
}
return unknowns; return unknowns;
} }
public string GetCommandName()
{
string command = string.Empty;
if (Configure)
{
command = Constants.Runner.CommandLine.Commands.Configure;
}
else if (Remove)
{
command = Constants.Runner.CommandLine.Commands.Remove;
}
else if (Run)
{
command = Constants.Runner.CommandLine.Commands.Run;
}
else if (Warmup)
{
command = Constants.Runner.CommandLine.Commands.Warmup;
}
return command;
}
// //
// Interactive flags. // Interactive flags.
// //

View File

@@ -40,6 +40,12 @@ namespace GitHub.Runner.Listener.Configuration
return creds; return creds;
} }
#if USE_BROKER
public VssCredentials LoadCredentials()
{
return new VssCredentials();
}
#else
public VssCredentials LoadCredentials() public VssCredentials LoadCredentials()
{ {
IConfigurationStore store = HostContext.GetService<IConfigurationStore>(); IConfigurationStore store = HostContext.GetService<IConfigurationStore>();
@@ -69,6 +75,7 @@ namespace GitHub.Runner.Listener.Configuration
return creds; return creds;
} }
#endif
} }
[DataContract] [DataContract]

View File

@@ -23,7 +23,7 @@ namespace GitHub.Runner.Listener
{ {
bool Busy { get; } bool Busy { get; }
TaskCompletionSource<bool> RunOnceJobCompleted { get; } TaskCompletionSource<bool> RunOnceJobCompleted { get; }
void Run(Pipelines.AgentJobRequestMessage message, bool runOnce = false); void Run(Guid targetHostId, Pipelines.AgentJobRequestMessage message, bool runOnce = false);
bool Cancel(JobCancelMessage message); bool Cancel(JobCancelMessage message);
Task WaitAsync(CancellationToken token); Task WaitAsync(CancellationToken token);
Task ShutdownAsync(); Task ShutdownAsync();
@@ -79,7 +79,7 @@ namespace GitHub.Runner.Listener
public bool Busy { get; private set; } public bool Busy { get; private set; }
public void Run(Pipelines.AgentJobRequestMessage jobRequestMessage, bool runOnce = false) public void Run(Guid targetHostId, Pipelines.AgentJobRequestMessage jobRequestMessage, bool runOnce = false)
{ {
Trace.Info($"Job request {jobRequestMessage.RequestId} for plan {jobRequestMessage.Plan.PlanId} job {jobRequestMessage.JobId} received."); Trace.Info($"Job request {jobRequestMessage.RequestId} for plan {jobRequestMessage.Plan.PlanId} job {jobRequestMessage.JobId} received.");
@@ -112,11 +112,11 @@ namespace GitHub.Runner.Listener
if (runOnce) if (runOnce)
{ {
Trace.Info("Start dispatcher for one time used runner."); Trace.Info("Start dispatcher for one time used runner.");
newDispatch.WorkerDispatch = RunOnceAsync(jobRequestMessage, orchestrationId, currentDispatch, newDispatch.WorkerCancellationTokenSource.Token, newDispatch.WorkerCancelTimeoutKillTokenSource.Token); newDispatch.WorkerDispatch = RunOnceAsync(targetHostId, jobRequestMessage, orchestrationId, currentDispatch, newDispatch.WorkerCancellationTokenSource.Token, newDispatch.WorkerCancelTimeoutKillTokenSource.Token);
} }
else else
{ {
newDispatch.WorkerDispatch = RunAsync(jobRequestMessage, orchestrationId, currentDispatch, newDispatch.WorkerCancellationTokenSource.Token, newDispatch.WorkerCancelTimeoutKillTokenSource.Token); newDispatch.WorkerDispatch = RunAsync(targetHostId, jobRequestMessage, orchestrationId, currentDispatch, newDispatch.WorkerCancellationTokenSource.Token, newDispatch.WorkerCancelTimeoutKillTokenSource.Token);
} }
_jobInfos.TryAdd(newDispatch.JobId, newDispatch); _jobInfos.TryAdd(newDispatch.JobId, newDispatch);
@@ -317,11 +317,11 @@ namespace GitHub.Runner.Listener
} }
} }
private async Task RunOnceAsync(Pipelines.AgentJobRequestMessage message, string orchestrationId, WorkerDispatcher previousJobDispatch, CancellationToken jobRequestCancellationToken, CancellationToken workerCancelTimeoutKillToken) private async Task RunOnceAsync(Guid targetHostId, Pipelines.AgentJobRequestMessage message, string orchestrationId, WorkerDispatcher previousJobDispatch, CancellationToken jobRequestCancellationToken, CancellationToken workerCancelTimeoutKillToken)
{ {
try try
{ {
await RunAsync(message, orchestrationId, previousJobDispatch, jobRequestCancellationToken, workerCancelTimeoutKillToken); await RunAsync(targetHostId, message, orchestrationId, previousJobDispatch, jobRequestCancellationToken, workerCancelTimeoutKillToken);
} }
finally finally
{ {
@@ -330,7 +330,7 @@ namespace GitHub.Runner.Listener
} }
} }
private async Task RunAsync(Pipelines.AgentJobRequestMessage message, string orchestrationId, WorkerDispatcher previousJobDispatch, CancellationToken jobRequestCancellationToken, CancellationToken workerCancelTimeoutKillToken) private async Task RunAsync(Guid targetHostId, Pipelines.AgentJobRequestMessage message, string orchestrationId, WorkerDispatcher previousJobDispatch, CancellationToken jobRequestCancellationToken, CancellationToken workerCancelTimeoutKillToken)
{ {
Busy = true; Busy = true;
try try
@@ -383,7 +383,7 @@ namespace GitHub.Runner.Listener
await renewJobRequest; await renewJobRequest;
// complete job request with result Cancelled // complete job request with result Cancelled
await CompleteJobRequestAsync(_poolId, message, lockToken, TaskResult.Canceled); await CompleteJobRequestAsync(targetHostId, _poolId, message, lockToken, TaskResult.Canceled);
return; return;
} }
@@ -540,7 +540,7 @@ namespace GitHub.Runner.Listener
await renewJobRequest; await renewJobRequest;
// complete job request // complete job request
await CompleteJobRequestAsync(_poolId, message, lockToken, result, detailInfo); await CompleteJobRequestAsync(targetHostId, _poolId, message, lockToken, result, detailInfo);
// print out unhandled exception happened in worker after we complete job request. // print out unhandled exception happened in worker after we complete job request.
// when we run out of disk space, report back to server has higher priority. // when we run out of disk space, report back to server has higher priority.
@@ -637,7 +637,7 @@ namespace GitHub.Runner.Listener
await renewJobRequest; await renewJobRequest;
// complete job request // complete job request
await CompleteJobRequestAsync(_poolId, message, lockToken, resultOnAbandonOrCancel); await CompleteJobRequestAsync(targetHostId, _poolId, message, lockToken, resultOnAbandonOrCancel);
} }
finally finally
{ {
@@ -666,17 +666,25 @@ namespace GitHub.Runner.Listener
{ {
try try
{ {
request = await runnerServer.RenewAgentRequestAsync(poolId, requestId, lockToken, orchestrationId, token); // #if USE_BROKER
Trace.Info($"Successfully renew job request {requestId}, job is valid till {request.LockedUntil.Value}");
if (!firstJobRequestRenewed.Task.IsCompleted) if (!firstJobRequestRenewed.Task.IsCompleted)
{ {
// fire first renew succeed event. // fire first renew succeed event.
firstJobRequestRenewed.TrySetResult(0); firstJobRequestRenewed.TrySetResult(0);
// Update settings if the runner name has been changed server-side
UpdateAgentNameIfNeeded(request.ReservedAgent?.Name);
} }
// #else
// request = await runnerServer.RenewAgentRequestAsync(poolId, requestId, lockToken, orchestrationId, token);
// Trace.Info($"Successfully renew job request {requestId}, job is valid till {request?.LockedUntil.Value}");
// if (!firstJobRequestRenewed.Task.IsCompleted)
// {
// // fire first renew succeed event.
// firstJobRequestRenewed.TrySetResult(0);
// // Update settings if the runner name has been changed server-side
// UpdateAgentNameIfNeeded(request.ReservedAgent?.Name);
// }
// #endif
if (encounteringError > 0) if (encounteringError > 0)
{ {
@@ -911,7 +919,7 @@ namespace GitHub.Runner.Listener
} }
} }
private async Task CompleteJobRequestAsync(int poolId, Pipelines.AgentJobRequestMessage message, Guid lockToken, TaskResult result, string detailInfo = null) private async Task CompleteJobRequestAsync(Guid targetHostId, int poolId, Pipelines.AgentJobRequestMessage message, Guid lockToken, TaskResult result, string detailInfo = null)
{ {
Trace.Entering(); Trace.Entering();
@@ -928,7 +936,7 @@ namespace GitHub.Runner.Listener
{ {
try try
{ {
await runnerServer.FinishAgentRequestAsync(poolId, message.RequestId, lockToken, DateTime.UtcNow, result, CancellationToken.None); await runnerServer.FinishAgentRequestAsync(poolId, message.RequestId, lockToken, DateTime.UtcNow, result, targetHostId, CancellationToken.None);
return; return;
} }
catch (TaskAgentJobNotFoundException) catch (TaskAgentJobNotFoundException)

View File

@@ -2,7 +2,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@@ -27,10 +31,13 @@ namespace GitHub.Runner.Listener
public sealed class MessageListener : RunnerService, IMessageListener public sealed class MessageListener : RunnerService, IMessageListener
{ {
#if !USE_BROKER
private long? _lastMessageId; private long? _lastMessageId;
#endif
private RunnerSettings _settings; private RunnerSettings _settings;
private ITerminal _term; private ITerminal _term;
private IRunnerServer _runnerServer; private IRunnerServer _runnerServer;
private IBrokerServer _brokerServer;
private TaskAgentSession _session; private TaskAgentSession _session;
private TimeSpan _getNextMessageRetryInterval; private TimeSpan _getNextMessageRetryInterval;
private bool _accessTokenRevoked = false; private bool _accessTokenRevoked = false;
@@ -45,8 +52,44 @@ namespace GitHub.Runner.Listener
_term = HostContext.GetService<ITerminal>(); _term = HostContext.GetService<ITerminal>();
_runnerServer = HostContext.GetService<IRunnerServer>(); _runnerServer = HostContext.GetService<IRunnerServer>();
_brokerServer = HostContext.GetService<IBrokerServer>();
} }
#if USE_BROKER
public async Task<Boolean> CreateSessionAsync(CancellationToken token)
{
Trace.Entering();
// Settings
var configManager = HostContext.GetService<IConfigurationManager>();
_settings = configManager.LoadSettings();
var serverUrl = _settings.ServerUrl;
Trace.Info(_settings);
// Connect
token.ThrowIfCancellationRequested();
Trace.Info($"Attempt to create session.");
Trace.Info("Connecting to the Runner Server...");
_term.WriteLine($"Connecting to {new Uri(serverUrl)}");
await _brokerServer.ConnectAsync(new Uri(serverUrl), token);
_term.WriteLine();
_term.WriteSuccessMessage("Connected to GitHub");
_term.WriteLine();
// Session info
var agent = new TaskAgentReference
{
Id = _settings.AgentId,
Name = _settings.AgentName,
Version = BuildConstants.RunnerPackage.Version,
OSDescription = RuntimeInformation.OSDescription,
};
string sessionName = $"{Environment.MachineName ?? "RUNNER"}";
_session = new TaskAgentSession(sessionName, agent);
return true;
}
#else
public async Task<Boolean> CreateSessionAsync(CancellationToken token) public async Task<Boolean> CreateSessionAsync(CancellationToken token)
{ {
Trace.Entering(); Trace.Entering();
@@ -81,6 +124,7 @@ namespace GitHub.Runner.Listener
Trace.Info($"Attempt to create session."); Trace.Info($"Attempt to create session.");
try try
{ {
Trace.Info("Connecting to the Runner Server...");
Trace.Info("Connecting to the Runner Server..."); Trace.Info("Connecting to the Runner Server...");
await _runnerServer.ConnectAsync(new Uri(serverUrl), creds); await _runnerServer.ConnectAsync(new Uri(serverUrl), creds);
Trace.Info("VssConnection created"); Trace.Info("VssConnection created");
@@ -151,6 +195,7 @@ namespace GitHub.Runner.Listener
} }
} }
} }
#endif
public async Task DeleteSessionAsync() public async Task DeleteSessionAsync()
{ {
@@ -170,6 +215,167 @@ namespace GitHub.Runner.Listener
} }
} }
#if USE_BROKER
[DataContract]
public sealed class MessageRef
{
[DataMember(Name = "url")]
public string Url { get; set; }
[DataMember(Name = "token")]
public string Token { get; set; }
[DataMember(Name = "scopeId")]
public string ScopeId { get; set; }
[DataMember(Name = "planType")]
public string PlanType { get; set; }
[DataMember(Name = "planGroup")]
public string PlanGroup { get; set; }
[DataMember(Name = "instanceRefs")]
public InstanceRef[] InstanceRefs { get; set; }
[DataMember(Name = "labels")]
public string[] Labels { get; set; }
}
[DataContract]
public sealed class InstanceRef
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "instanceType")]
public string InstanceType { get; set; }
[DataMember(Name = "attempt")]
public int Attempt { get; set; }
}
public async Task<TaskAgentMessage> GetNextMessageAsync(CancellationToken token)
{
Trace.Entering();
ArgUtil.NotNull(_session, nameof(_session));
ArgUtil.NotNull(_settings, nameof(_settings));
bool encounteringError = false;
int continuousError = 0;
string errorMessage = string.Empty;
Stopwatch heartbeat = new Stopwatch();
heartbeat.Restart();
while (true)
{
token.ThrowIfCancellationRequested();
string message = null;
try
{
message = await _brokerServer.GetMessageAsync(_session, _settings, null/*_lastMessageId*/, token);
_term.WriteLine($"{DateTime.UtcNow:u}: {message}");
if (!string.IsNullOrEmpty(message))
{
var messageRef = StringUtil.ConvertFromJson<MessageRef>(message);
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", messageRef.Token);
var response = await client.GetAsync(messageRef.Url, token);
if (!response.IsSuccessStatusCode)
{
var content = default(string);
try
{
content = await response.Content.ReadAsStringAsync();
}
catch
{
}
var error = $"HTTP {(int)response.StatusCode} {Enum.GetName(typeof(HttpStatusCode), response.StatusCode)}";
if (!string.IsNullOrEmpty(content))
{
error = $"{error}: {content}";
}
throw new Exception(error);
}
var fullMessage = await response.Content.ReadAsStringAsync();
return StringUtil.ConvertFromJson<TaskAgentMessage>(fullMessage);
}
if (encounteringError) //print the message once only if there was an error
{
_term.WriteLine($"{DateTime.UtcNow:u}: Runner reconnected.");
encounteringError = false;
continuousError = 0;
}
}
catch (OperationCanceledException) when (token.IsCancellationRequested)
{
Trace.Info("Get next message has been cancelled.");
throw;
}
catch (TaskAgentAccessTokenExpiredException)
{
Trace.Info("Runner OAuth token has been revoked. Unable to pull message.");
_accessTokenRevoked = true;
throw;
}
catch (Exception ex)
{
Trace.Error("Catch exception during get next message.");
Trace.Error(ex);
// don't retry if SkipSessionRecover = true, DT service will delete agent session to stop agent from taking more jobs.
if (ex is TaskAgentSessionExpiredException && !_settings.SkipSessionRecover && await CreateSessionAsync(token))
{
Trace.Info($"{nameof(TaskAgentSessionExpiredException)} received, recovered by recreate session.");
}
else if (!IsGetNextMessageExceptionRetriable(ex))
{
throw;
}
else
{
continuousError++;
//retry after a random backoff to avoid service throttling
//in case of there is a service error happened and all agents get kicked off of the long poll and all agent try to reconnect back at the same time.
if (continuousError <= 5)
{
// random backoff [15, 30]
_getNextMessageRetryInterval = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(30), _getNextMessageRetryInterval);
}
else
{
// more aggressive backoff [30, 60]
_getNextMessageRetryInterval = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(60), _getNextMessageRetryInterval);
}
if (!encounteringError)
{
//print error only on the first consecutive error
_term.WriteError($"{DateTime.UtcNow:u}: Runner connect error: {ex.Message}. Retrying until reconnected.");
encounteringError = true;
}
// re-create VssConnection before next retry
await _runnerServer.RefreshConnectionAsync(RunnerConnectionType.MessageQueue, TimeSpan.FromSeconds(60));
Trace.Info("Sleeping for {0} seconds before retrying.", _getNextMessageRetryInterval.TotalSeconds);
await HostContext.Delay(_getNextMessageRetryInterval, token);
}
}
// if (message == null)
// {
// if (heartbeat.Elapsed > TimeSpan.FromMinutes(30))
// {
// Trace.Info($"No message retrieved from session '{_session.SessionId}' within last 30 minutes.");
// heartbeat.Restart();
// }
// else
// {
// Trace.Verbose($"No message retrieved from session '{_session.SessionId}'.");
// }
// continue;
// }
// Trace.Info($"Message '{message.MessageId}' received from session '{_session.SessionId}'.");
// return message;
}
}
#else
public async Task<TaskAgentMessage> GetNextMessageAsync(CancellationToken token) public async Task<TaskAgentMessage> GetNextMessageAsync(CancellationToken token)
{ {
Trace.Entering(); Trace.Entering();
@@ -281,6 +487,7 @@ namespace GitHub.Runner.Listener
return message; return message;
} }
} }
#endif
public async Task DeleteMessageAsync(TaskAgentMessage message) public async Task DeleteMessageAsync(TaskAgentMessage message)
{ {

View File

@@ -95,15 +95,7 @@ namespace GitHub.Runner.Listener
var unknownCommandlines = command.Validate(); var unknownCommandlines = command.Validate();
if (unknownCommandlines.Count > 0) if (unknownCommandlines.Count > 0)
{ {
string commandName = command.GetCommandName(); terminal.WriteError($"Unrecognized command-line input arguments: '{string.Join(", ", unknownCommandlines)}'. For usage refer to: .\\config.cmd --help or ./config.sh --help");
if (string.IsNullOrEmpty(commandName))
{
terminal.WriteError($"This command does not recognize the command-line input arguments: '{string.Join(", ", unknownCommandlines)}'. For usage refer to: .\\config.cmd --help or ./config.sh --help");
}
else
{
terminal.WriteError($"Unrecognized command-line input arguments for command {commandName}: '{string.Join(", ", unknownCommandlines)}'. For usage refer to: .\\config.cmd --help or ./config.sh --help");
}
} }
// Defer to the Runner class to execute the command. // Defer to the Runner class to execute the command.

View File

@@ -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</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch> <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<NoWarn>NU1701;NU1603</NoWarn> <NoWarn>NU1701;NU1603</NoWarn>
<Version>$(Version)</Version> <Version>$(Version)</Version>

View File

@@ -13,6 +13,10 @@ using GitHub.Runner.Sdk;
using System.Linq; using System.Linq;
using GitHub.Runner.Listener.Check; using GitHub.Runner.Listener.Check;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
namespace GitHub.Runner.Listener namespace GitHub.Runner.Listener
{ {
@@ -449,7 +453,37 @@ namespace GitHub.Runner.Listener
{ {
Trace.Info($"Received job message of length {message.Body.Length} from service, with hash '{IOUtil.GetSha256Hash(message.Body)}'"); Trace.Info($"Received job message of length {message.Body.Length} from service, with hash '{IOUtil.GetSha256Hash(message.Body)}'");
var jobMessage = StringUtil.ConvertFromJson<Pipelines.AgentJobRequestMessage>(message.Body); var jobMessage = StringUtil.ConvertFromJson<Pipelines.AgentJobRequestMessage>(message.Body);
jobDispatcher.Run(jobMessage, runOnce); jobDispatcher.Run(Guid.Empty, jobMessage, runOnce);
if (runOnce)
{
Trace.Info("One time used runner received job message.");
runOnceJobReceived = true;
}
}
}
// Broker flow
else if (string.Equals(message.MessageType, JobRequestMessageTypes.RunnerJobRequest, StringComparison.OrdinalIgnoreCase))
{
if (autoUpdateInProgress || runOnceJobReceived)
{
skipMessageDeletion = true;
Trace.Info($"Skip message deletion for job request message '{message.MessageId}'.");
}
else
{
var messageRef = StringUtil.ConvertFromJson<MessageRef>(message.Body);
// Create connection
var credMgr = HostContext.GetService<ICredentialManager>();
var creds = credMgr.LoadCredentials();
// todo: add retries
var runServer = HostContext.CreateService<IRunServer>();
await runServer.ConnectAsync(new Uri(settings.ServerUrl), creds);
var jobMessage = await runServer.GetJobMessageAsync(messageRef.ScopeId, messageRef.HostId, messageRef.PlanType, messageRef.PlanGroup, messageRef.PlanId, messageRef.InstanceRefs);
// todo: Trace.Info($"Received job message of length {message.Body.Length} from service, with hash '{IOUtil.GetSha256Hash(message.Body)}'");
jobDispatcher.Run(messageRef.HostId, jobMessage, runOnce);
if (runOnce) if (runOnce)
{ {
Trace.Info("One time used runner received job message."); Trace.Info("One time used runner received job message.");

View File

@@ -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</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch> <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<NoWarn>NU1701;NU1603</NoWarn> <NoWarn>NU1701;NU1603</NoWarn>
<Version>$(Version)</Version> <Version>$(Version)</Version>

View File

@@ -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</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch> <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<NoWarn>NU1701;NU1603</NoWarn> <NoWarn>NU1701;NU1603</NoWarn>
<Version>$(Version)</Version> <Version>$(Version)</Version>

View File

@@ -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</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch> <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<NoWarn>NU1701;NU1603</NoWarn> <NoWarn>NU1701;NU1603</NoWarn>
<Version>$(Version)</Version> <Version>$(Version)</Version>

View File

@@ -36,6 +36,7 @@ namespace GitHub.Runner.Sdk
public static VssConnection CreateConnection(Uri serverUri, VssCredentials credentials, IEnumerable<DelegatingHandler> additionalDelegatingHandler = null, TimeSpan? timeout = null) public static VssConnection CreateConnection(Uri serverUri, VssCredentials credentials, IEnumerable<DelegatingHandler> additionalDelegatingHandler = null, TimeSpan? timeout = null)
{ {
// System.Console.WriteLine("VssUtil.CreateConnection");
VssClientHttpRequestSettings settings = VssClientHttpRequestSettings.Default.Clone(); VssClientHttpRequestSettings settings = VssClientHttpRequestSettings.Default.Clone();
int maxRetryRequest; int maxRetryRequest;

View File

@@ -817,6 +817,7 @@ namespace GitHub.Runner.Worker
{ {
// Something else bad happened, let's go to our retry logic // Something else bad happened, let's go to our retry logic
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
throw new Exception("Unexpected response code: " + response.StatusCode);
} }
} }
} }

View File

@@ -1,6 +1,5 @@
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;
@@ -10,6 +9,7 @@ using GitHub.DistributedTask.Pipelines.ObjectTemplating;
using GitHub.Runner.Common; using GitHub.Runner.Common;
using GitHub.Runner.Common.Util; using GitHub.Runner.Common.Util;
using GitHub.Runner.Sdk; using GitHub.Runner.Sdk;
using GitHub.Runner.Worker;
using GitHub.Runner.Worker.Handlers; using GitHub.Runner.Worker.Handlers;
using Pipelines = GitHub.DistributedTask.Pipelines; using Pipelines = GitHub.DistributedTask.Pipelines;
@@ -171,16 +171,8 @@ namespace GitHub.Runner.Worker
// Load the inputs. // Load the inputs.
ExecutionContext.Debug("Loading inputs"); ExecutionContext.Debug("Loading inputs");
Dictionary<string, string> inputs; var templateEvaluator = ExecutionContext.ToPipelineTemplateEvaluator();
if (ExecutionContext.Global.Variables.GetBoolean(Constants.Runner.Features.UseContainerPathForTemplate) ?? false) var inputs = templateEvaluator.EvaluateStepInputs(Action.Inputs, ExecutionContext.ExpressionValues, ExecutionContext.ExpressionFunctions);
{
inputs = EvaluateStepInputs(stepHost);
}
else
{
var templateEvaluator = ExecutionContext.ToPipelineTemplateEvaluator();
inputs = templateEvaluator.EvaluateStepInputs(Action.Inputs, ExecutionContext.ExpressionValues, ExecutionContext.ExpressionFunctions);
}
var userInputs = new HashSet<string>(StringComparer.OrdinalIgnoreCase); var userInputs = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (KeyValuePair<string, string> input in inputs) foreach (KeyValuePair<string, string> input in inputs)
@@ -307,15 +299,6 @@ namespace GitHub.Runner.Worker
return didFullyEvaluate; return didFullyEvaluate;
} }
private Dictionary<String, String> EvaluateStepInputs(IStepHost stepHost)
{
DictionaryContextData expressionValues = ExecutionContext.GetExpressionValues(stepHost);
var templateEvaluator = ExecutionContext.ToPipelineTemplateEvaluator();
var inputs = templateEvaluator.EvaluateStepInputs(Action.Inputs, expressionValues, ExecutionContext.ExpressionFunctions);
return inputs;
}
private string GenerateDisplayName(ActionStep action, DictionaryContextData contextData, IExecutionContext context, out bool didFullyEvaluate) private string GenerateDisplayName(ActionStep action, DictionaryContextData contextData, IExecutionContext context, out bool didFullyEvaluate)
{ {
ArgUtil.NotNull(context, nameof(context)); ArgUtil.NotNull(context, nameof(context));

View File

@@ -1,16 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using GitHub.Runner.Common.Util;
using GitHub.Runner.Common; using GitHub.Runner.Common;
using GitHub.Runner.Sdk; using GitHub.Runner.Sdk;
using Pipelines = GitHub.DistributedTask.Pipelines; using Pipelines = GitHub.DistributedTask.Pipelines;
using System.Collections.ObjectModel;
using System.Linq;
namespace GitHub.Runner.Worker.Container namespace GitHub.Runner.Worker.Container
{ {
public class ContainerInfo public class ContainerInfo
{ {
private IDictionary<string, string> _userMountVolumes;
private List<MountVolume> _mountVolumes; private List<MountVolume> _mountVolumes;
private IDictionary<string, string> _userPortMappings; private IDictionary<string, string> _userPortMappings;
private List<PortMapping> _portMappings; private List<PortMapping> _portMappings;
@@ -68,7 +68,8 @@ namespace GitHub.Runner.Worker.Container
{ {
foreach (var volume in container.Volumes) foreach (var volume in container.Volumes)
{ {
MountVolumes.Add(new MountVolume(volume, isUserProvided: true)); UserMountVolumes[volume] = volume;
MountVolumes.Add(new MountVolume(volume));
} }
} }
@@ -103,20 +104,19 @@ namespace GitHub.Runner.Worker.Container
return _environmentVariables; return _environmentVariables;
} }
} }
public ReadOnlyCollection<MountVolume> UserMountVolumes
public IDictionary<string, string> UserMountVolumes
{ {
get get
{ {
return MountVolumes.Where(v => !string.IsNullOrEmpty(v.UserProvidedValue)).ToList().AsReadOnly(); if (_userMountVolumes == null)
} {
} _userMountVolumes = new Dictionary<string, string>();
public ReadOnlyCollection<MountVolume> SystemMountVolumes }
{ return _userMountVolumes;
get
{
return MountVolumes.Where(v => string.IsNullOrEmpty(v.UserProvidedValue)).ToList().AsReadOnly();
} }
} }
public List<MountVolume> MountVolumes public List<MountVolume> MountVolumes
{ {
get get
@@ -260,27 +260,18 @@ namespace GitHub.Runner.Worker.Container
public class MountVolume public class MountVolume
{ {
public string UserProvidedValue { get; set; }
public MountVolume(string sourceVolumePath, string targetVolumePath, bool readOnly = false) public MountVolume(string sourceVolumePath, string targetVolumePath, bool readOnly = false)
{ {
this.SourceVolumePath = sourceVolumePath; this.SourceVolumePath = sourceVolumePath;
this.TargetVolumePath = targetVolumePath; this.TargetVolumePath = targetVolumePath;
this.ReadOnly = readOnly; this.ReadOnly = readOnly;
} }
public MountVolume(string fromString) public MountVolume(string fromString)
{ {
ParseVolumeString(fromString); ParseVolumeString(fromString);
} }
public MountVolume(string fromString, bool isUserProvided)
{
ParseVolumeString(fromString);
if (isUserProvided)
{
UserProvidedValue = fromString;
}
}
private void ParseVolumeString(string volume) private void ParseVolumeString(string volume)
{ {
var volumeSplit = volume.Split(":"); var volumeSplit = volume.Split(":");

View File

@@ -192,12 +192,13 @@ namespace GitHub.Runner.Worker
{ {
Trace.Info($"User provided port: {port.Value}"); Trace.Info($"User provided port: {port.Value}");
} }
foreach (var mount in container.UserMountVolumes) foreach (var volume in container.UserMountVolumes)
{ {
Trace.Info($"User provided volume: {mount.UserProvidedValue}"); Trace.Info($"User provided volume: {volume.Value}");
var mount = new MountVolume(volume.Value);
if (string.Equals(mount.SourceVolumePath, "/", StringComparison.OrdinalIgnoreCase)) if (string.Equals(mount.SourceVolumePath, "/", StringComparison.OrdinalIgnoreCase))
{ {
executionContext.Warning($"Volume mount {mount.UserProvidedValue} is going to mount '/' into the container which may cause file ownership change in the entire file system and cause Actions Runner to lose permission to access the disk."); executionContext.Warning($"Volume mount {volume.Value} is going to mount '/' into the container which may cause file ownership change in the entire file system and cause Actions Runner to lose permission to access the disk.");
} }
} }

View File

@@ -1,13 +1,18 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web;
using GitHub.DistributedTask.Expressions2; using GitHub.DistributedTask.Expressions2;
using GitHub.DistributedTask.ObjectTemplating.Tokens; using GitHub.DistributedTask.ObjectTemplating.Tokens;
using GitHub.DistributedTask.Pipelines;
using GitHub.DistributedTask.Pipelines.ContextData; using GitHub.DistributedTask.Pipelines.ContextData;
using GitHub.DistributedTask.Pipelines.ObjectTemplating; using GitHub.DistributedTask.Pipelines.ObjectTemplating;
using GitHub.DistributedTask.WebApi; using GitHub.DistributedTask.WebApi;
@@ -15,7 +20,7 @@ using GitHub.Runner.Common;
using GitHub.Runner.Common.Util; using GitHub.Runner.Common.Util;
using GitHub.Runner.Sdk; using GitHub.Runner.Sdk;
using GitHub.Runner.Worker.Container; using GitHub.Runner.Worker.Container;
using GitHub.Runner.Worker.Handlers; using GitHub.Services.WebApi;
using Newtonsoft.Json; using Newtonsoft.Json;
using ObjectTemplating = GitHub.DistributedTask.ObjectTemplating; using ObjectTemplating = GitHub.DistributedTask.ObjectTemplating;
using Pipelines = GitHub.DistributedTask.Pipelines; using Pipelines = GitHub.DistributedTask.Pipelines;
@@ -110,6 +115,7 @@ namespace GitHub.Runner.Worker
void UpdateGlobalStepsContext(); void UpdateGlobalStepsContext();
void WriteWebhookPayload(); void WriteWebhookPayload();
} }
public sealed class ExecutionContext : RunnerService, IExecutionContext public sealed class ExecutionContext : RunnerService, IExecutionContext
@@ -1193,66 +1199,6 @@ namespace GitHub.Runner.Worker
{ {
return new TemplateTraceWriter(context); return new TemplateTraceWriter(context);
} }
public static DictionaryContextData GetExpressionValues(this IExecutionContext context, IStepHost stepHost)
{
if (stepHost is ContainerStepHost)
{
var expressionValues = context.ExpressionValues.Clone() as DictionaryContextData;
context.UpdatePathsInExpressionValues("github", expressionValues, stepHost);
context.UpdatePathsInExpressionValues("runner", expressionValues, stepHost);
return expressionValues;
}
else
{
return context.ExpressionValues.Clone() as DictionaryContextData;
}
}
private static void UpdatePathsInExpressionValues(this IExecutionContext context, string contextName, DictionaryContextData expressionValues, IStepHost stepHost)
{
var dict = expressionValues[contextName].AssertDictionary($"expected context {contextName} to be a dictionary");
context.ResolvePathsInExpressionValuesDictionary(dict, stepHost);
expressionValues[contextName] = dict;
}
private static void ResolvePathsInExpressionValuesDictionary(this IExecutionContext context, DictionaryContextData dict, IStepHost stepHost)
{
foreach (var key in dict.Keys.ToList())
{
if (dict[key] is StringContextData)
{
var value = dict[key].ToString();
if (!string.IsNullOrEmpty(value))
{
dict[key] = new StringContextData(stepHost.ResolvePathForStepHost(value));
}
}
else if (dict[key] is DictionaryContextData)
{
var innerDict = dict[key].AssertDictionary("expected dictionary");
context.ResolvePathsInExpressionValuesDictionary(innerDict, stepHost);
var updatedDict = new DictionaryContextData();
foreach (var k in innerDict.Keys.ToList())
{
updatedDict[k] = innerDict[k];
}
dict[key] = updatedDict;
}
else if (dict[key] is CaseSensitiveDictionaryContextData)
{
var innerDict = dict[key].AssertDictionary("expected dictionary");
context.ResolvePathsInExpressionValuesDictionary(innerDict, stepHost);
var updatedDict = new CaseSensitiveDictionaryContextData();
foreach (var k in innerDict.Keys.ToList())
{
updatedDict[k] = innerDict[k];
}
dict[key] = updatedDict;
}
}
}
} }
internal sealed class TemplateTraceWriter : ObjectTemplating.ITraceWriter internal sealed class TemplateTraceWriter : ObjectTemplating.ITraceWriter

View File

@@ -15,7 +15,7 @@ namespace GitHub.Runner.Worker
{ {
void InitializeFiles(IExecutionContext context, ContainerInfo container); void InitializeFiles(IExecutionContext context, ContainerInfo container);
void ProcessFiles(IExecutionContext context, ContainerInfo container); void ProcessFiles(IExecutionContext context, ContainerInfo container);
} }
public sealed class FileCommandManager : RunnerService, IFileCommandManager public sealed class FileCommandManager : RunnerService, IFileCommandManager
@@ -57,7 +57,7 @@ namespace GitHub.Runner.Worker
TryDeleteFile(newPath); TryDeleteFile(newPath);
File.Create(newPath).Dispose(); File.Create(newPath).Dispose();
var pathToSet = container != null ? container.TranslateToContainerPath(newPath) : newPath; var pathToSet = container != null ? container.TranslateToContainerPath(newPath) : newPath;
context.SetGitHubContext(fileCommand.ContextName, pathToSet); context.SetGitHubContext(fileCommand.ContextName, pathToSet);
} }
} }
@@ -66,7 +66,7 @@ namespace GitHub.Runner.Worker
{ {
foreach (var fileCommand in _commandExtensions) foreach (var fileCommand in _commandExtensions)
{ {
try try
{ {
fileCommand.ProcessCommand(context, Path.Combine(_fileCommandDirectory, fileCommand.FilePrefix + _fileSuffix),container); fileCommand.ProcessCommand(context, Path.Combine(_fileCommandDirectory, fileCommand.FilePrefix + _fileSuffix),container);
} }
@@ -266,7 +266,7 @@ namespace GitHub.Runner.Worker
public sealed class CreateStepSummaryCommand : RunnerService, IFileCommandExtension public sealed class CreateStepSummaryCommand : RunnerService, IFileCommandExtension
{ {
public const int AttachmentSizeLimit = 1024 * 1024; private const int _attachmentSizeLimit = 128 * 1024;
public string ContextName => "step_summary"; public string ContextName => "step_summary";
public string FilePrefix => "step_summary_"; public string FilePrefix => "step_summary_";
@@ -296,9 +296,9 @@ namespace GitHub.Runner.Worker
return; return;
} }
if (fileSize > AttachmentSizeLimit) if (fileSize > _attachmentSizeLimit)
{ {
context.Error(String.Format(Constants.Runner.UnsupportedSummarySize, AttachmentSizeLimit / 1024, fileSize / 1024)); context.Error(String.Format(Constants.Runner.UnsupportedSummarySize, _attachmentSizeLimit / 1024, fileSize / 1024));
Trace.Info($"Step Summary file ({filePath}) is too large ({fileSize} bytes); skipping attachment upload"); Trace.Info($"Step Summary file ({filePath}) is too large ({fileSize} bytes); skipping attachment upload");
return; return;

View File

@@ -94,14 +94,6 @@ namespace GitHub.Runner.Worker.Handlers
workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work);
} }
#if OS_OSX
if (string.Equals(Data.NodeVersion, "node12", StringComparison.OrdinalIgnoreCase) &&
Constants.Runner.PlatformArchitecture.Equals(Constants.Architecture.Arm64))
{
ExecutionContext.Output($"The node12 is not supported on macOS ARM64 platform. Use node16 instead.");
Data.NodeVersion = "node16";
}
#endif
var nodeRuntimeVersion = await StepHost.DetermineNodeRuntimeVersion(ExecutionContext, Data.NodeVersion); var nodeRuntimeVersion = await StepHost.DetermineNodeRuntimeVersion(ExecutionContext, Data.NodeVersion);
string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), nodeRuntimeVersion, "bin", $"node{IOUtil.ExeExtension}"); string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), nodeRuntimeVersion, "bin", $"node{IOUtil.ExeExtension}");

View File

@@ -151,11 +151,6 @@ namespace GitHub.Runner.Worker.Handlers
} }
} }
if (line.Contains("fatal: unsafe repository", StringComparison.OrdinalIgnoreCase))
{
_executionContext.StepTelemetry.ErrorMessages.Add(line);
}
// Regular output // Regular output
_executionContext.Output(line); _executionContext.Output(line);
} }

View File

@@ -1,13 +1,18 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks; using System.Threading.Tasks;
using GitHub.DistributedTask.WebApi;
using GitHub.Runner.Common.Util;
using GitHub.Runner.Worker.Container; using GitHub.Runner.Worker.Container;
using GitHub.Services.WebApi;
using Newtonsoft.Json;
using GitHub.Runner.Common; using GitHub.Runner.Common;
using GitHub.Runner.Sdk; using GitHub.Runner.Sdk;
using System.Linq; using System.Linq;
using GitHub.DistributedTask.Pipelines.ContextData;
namespace GitHub.Runner.Worker.Handlers namespace GitHub.Runner.Worker.Handlers
{ {

View File

@@ -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</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch> <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<NoWarn>NU1701;NU1603</NoWarn> <NoWarn>NU1701;NU1603</NoWarn>
<Version>$(Version)</Version> <Version>$(Version)</Version>

View File

@@ -132,7 +132,7 @@
"continue-on-error": "boolean-steps-context", "continue-on-error": "boolean-steps-context",
"working-directory": "string-steps-context", "working-directory": "string-steps-context",
"shell": { "shell": {
"type": "string-steps-context", "type": "non-empty-string",
"required": true "required": true
} }
} }

View File

@@ -18,6 +18,7 @@ namespace GitHub.Services.Common
public override bool IsAuthenticationChallenge(IHttpResponse webResponse) public override bool IsAuthenticationChallenge(IHttpResponse webResponse)
{ {
// System.Console.WriteLine($"FederatedCredential.IsAuthenticationChallenge");
if (webResponse == null) if (webResponse == null)
{ {
return false; return false;

View File

@@ -88,6 +88,7 @@ namespace GitHub.Services.Common
IHttpResponse response, IHttpResponse response,
IssuedToken failedToken) IssuedToken failedToken)
{ {
// System.Console.WriteLine("IssuedTokenCredential.CreateTokenProvider");
if (response != null && !IsAuthenticationChallenge(response)) if (response != null && !IsAuthenticationChallenge(response))
{ {
throw new InvalidOperationException(); throw new InvalidOperationException();
@@ -99,12 +100,14 @@ namespace GitHub.Services.Common
{ {
throw new InvalidOperationException($"The {nameof(TokenStorageUrl)} property must have a value if the {nameof(Storage)} property is set on this instance of {GetType().Name}."); throw new InvalidOperationException($"The {nameof(TokenStorageUrl)} property must have a value if the {nameof(Storage)} property is set on this instance of {GetType().Name}.");
} }
// System.Console.WriteLine($"IssuedTokenCredential.CreateTokenProvider: TokenStorageUrl: {TokenStorageUrl}");
InitialToken = Storage.RetrieveToken(TokenStorageUrl, CredentialType); InitialToken = Storage.RetrieveToken(TokenStorageUrl, CredentialType);
} }
IssuedTokenProvider provider = OnCreateTokenProvider(serverUrl, response); IssuedTokenProvider provider = OnCreateTokenProvider(serverUrl, response);
if (provider != null) if (provider != null)
{ {
// System.Console.WriteLine($"IssuedTokenCredential.CreateTokenProvider: provider: {provider}");
provider.TokenStorageUrl = TokenStorageUrl; provider.TokenStorageUrl = TokenStorageUrl;
} }
@@ -123,6 +126,7 @@ namespace GitHub.Services.Common
internal virtual string GetAuthenticationChallenge(IHttpResponse webResponse) internal virtual string GetAuthenticationChallenge(IHttpResponse webResponse)
{ {
// System.Console.WriteLine($"IssuedTokenCredential.GetAuthenticationChallenge");
IEnumerable<String> values; IEnumerable<String> values;
if (!webResponse.Headers.TryGetValues(Internal.HttpHeaders.WwwAuthenticate, out values)) if (!webResponse.Headers.TryGetValues(Internal.HttpHeaders.WwwAuthenticate, out values))
{ {

View File

@@ -108,6 +108,7 @@ namespace GitHub.Services.Common
TaskScheduler scheduler, TaskScheduler scheduler,
IVssCredentialPrompt credentialPrompt) IVssCredentialPrompt credentialPrompt)
{ {
// System.Console.WriteLine($"VssCredentials.ctor");
this.PromptType = promptType; this.PromptType = promptType;
if (promptType == CredentialPromptType.PromptIfNeeded && scheduler == null) if (promptType == CredentialPromptType.PromptIfNeeded && scheduler == null)
@@ -150,6 +151,7 @@ namespace GitHub.Services.Common
{ {
get get
{ {
// System.Console.WriteLine($"VssCredentials.get_PromptType");
return m_promptType; return m_promptType;
} }
set set
@@ -170,6 +172,7 @@ namespace GitHub.Services.Common
{ {
get get
{ {
// System.Console.WriteLine($"VssCredentials.get_Federated");
return m_federatedCredential; return m_federatedCredential;
} }
} }
@@ -184,6 +187,7 @@ namespace GitHub.Services.Common
{ {
get get
{ {
// System.Console.WriteLine($"VssCredentials.get_Storage");
return m_credentialStorage; return m_credentialStorage;
} }
set set
@@ -203,6 +207,7 @@ namespace GitHub.Services.Common
/// </summary> /// </summary>
internal virtual bool TryGetValidAdalToken(IVssCredentialPrompt prompt) internal virtual bool TryGetValidAdalToken(IVssCredentialPrompt prompt)
{ {
// System.Console.WriteLine($"VssCredentials.TryGetValidAdalToken");
return false; return false;
} }
@@ -218,6 +223,7 @@ namespace GitHub.Services.Common
IHttpResponse webResponse, IHttpResponse webResponse,
IssuedToken failedToken) IssuedToken failedToken)
{ {
// System.Console.WriteLine("VssCredential.CreateTokenProvider");
ArgumentUtility.CheckForNull(serverUrl, "serverUrl"); ArgumentUtility.CheckForNull(serverUrl, "serverUrl");
IssuedTokenProvider tokenProvider = null; IssuedTokenProvider tokenProvider = null;
@@ -263,6 +269,7 @@ namespace GitHub.Services.Common
Uri serverUrl, Uri serverUrl,
out IssuedTokenProvider provider) out IssuedTokenProvider provider)
{ {
// System.Console.WriteLine($"VssCredentials.TryGetTokenProvider");
ArgumentUtility.CheckForNull(serverUrl, "serverUrl"); ArgumentUtility.CheckForNull(serverUrl, "serverUrl");
lock (m_thisLock) lock (m_thisLock)
@@ -272,11 +279,13 @@ namespace GitHub.Services.Common
{ {
if (m_federatedCredential != null) if (m_federatedCredential != null)
{ {
// System.Console.WriteLine($"VssCredentials.TryGetTokenProvider: Using federated credential");
m_currentProvider = m_federatedCredential.CreateTokenProvider(serverUrl, null, null); m_currentProvider = m_federatedCredential.CreateTokenProvider(serverUrl, null, null);
} }
if (m_currentProvider != null) if (m_currentProvider != null)
{ {
// System.Console.WriteLine($"VssCredentials.TryGetTokenProvider: Issued token provider created");
VssHttpEventSource.Log.IssuedTokenProviderCreated(VssTraceActivity.Current, m_currentProvider); VssHttpEventSource.Log.IssuedTokenProviderCreated(VssTraceActivity.Current, m_currentProvider);
} }
} }
@@ -294,6 +303,7 @@ namespace GitHub.Services.Common
/// <returns>True if this is an token authentication redirect, false otherwise</returns> /// <returns>True if this is an token authentication redirect, false otherwise</returns>
internal bool IsAuthenticationChallenge(IHttpResponse webResponse) internal bool IsAuthenticationChallenge(IHttpResponse webResponse)
{ {
// System.Console.WriteLine($"VssCredentials.IsAuthenticationChallenge");
if (webResponse == null) if (webResponse == null)
{ {
return false; return false;
@@ -313,6 +323,7 @@ namespace GitHub.Services.Common
Uri serviceLocation, Uri serviceLocation,
string identityProvider) string identityProvider)
{ {
// System.Console.WriteLine($"VssCredentials.SignOut");
// Remove the token in the storage and the current token provider. Note that we don't // Remove the token in the storage and the current token provider. Note that we don't
// call InvalidateToken here because we want to remove the whole token not just its value // call InvalidateToken here because we want to remove the whole token not just its value
if ((m_currentProvider != null) && (m_currentProvider.CurrentToken != null)) if ((m_currentProvider != null) && (m_currentProvider.CurrentToken != null))
@@ -349,6 +360,7 @@ namespace GitHub.Services.Common
string token, string token,
IDictionary<string, string> attributes) IDictionary<string, string> attributes)
{ {
// System.Console.WriteLine($"VssCredentials.WriteAuthorizationToken");
int i = 0; int i = 0;
for (int j = 0; j < token.Length; i++, j += 128) for (int j = 0; j < token.Length; i++, j += 128)
{ {
@@ -360,6 +372,7 @@ namespace GitHub.Services.Common
protected static string ReadAuthorizationToken(IDictionary<string, string> attributes) protected static string ReadAuthorizationToken(IDictionary<string, string> attributes)
{ {
// System.Console.WriteLine($"VssCredentials.ReadAuthorizationToken");
string authTokenCountValue; string authTokenCountValue;
if (attributes.TryGetValue("AuthTokenSegmentCount", out authTokenCountValue)) if (attributes.TryGetValue("AuthTokenSegmentCount", out authTokenCountValue))
{ {

View File

@@ -23,6 +23,7 @@ namespace GitHub.Services.Common.ClientStorage
private readonly string m_filePath; private readonly string m_filePath;
private readonly VssFileStorageReader m_reader; private readonly VssFileStorageReader m_reader;
private readonly IVssClientStorageWriter m_writer; private readonly IVssClientStorageWriter m_writer;
private const char c_defaultPathSeparator = '\\'; private const char c_defaultPathSeparator = '\\';
private const bool c_defaultIgnoreCaseInPaths = false; private const bool c_defaultIgnoreCaseInPaths = false;
@@ -191,7 +192,7 @@ namespace GitHub.Services.Common.ClientStorage
// Windows Impersonation is being used. // Windows Impersonation is being used.
// Check to see if we can find the user's local application data directory. // Check to see if we can find the user's local application data directory.
string subDir = Path.Combine("GitHub", "ActionsService"); string subDir = "GitHub\\ActionsService";
string path = Environment.GetEnvironmentVariable("localappdata"); string path = Environment.GetEnvironmentVariable("localappdata");
SafeGetFolderPath(Environment.SpecialFolder.LocalApplicationData); SafeGetFolderPath(Environment.SpecialFolder.LocalApplicationData);
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))

View File

@@ -49,6 +49,7 @@ namespace GitHub.Services.Common
VssHttpRequestSettings settings, VssHttpRequestSettings settings,
HttpMessageHandler innerHandler) HttpMessageHandler innerHandler)
{ {
// System.Console.WriteLine("VssHttpMessageHandler.ctor");
this.Credentials = credentials; this.Credentials = credentials;
this.Settings = settings; this.Settings = settings;
this.ExpectContinue = settings.ExpectContinue; this.ExpectContinue = settings.ExpectContinue;
@@ -122,6 +123,7 @@ namespace GitHub.Services.Common
HttpRequestMessage request, HttpRequestMessage request,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
// System.Console.WriteLine("VssHttpMessageHandler.SendAsync");
VssTraceActivity traceActivity = VssTraceActivity.Current; VssTraceActivity traceActivity = VssTraceActivity.Current;
var traceInfo = VssHttpMessageHandlerTraceInfo.GetTraceInfo(request); var traceInfo = VssHttpMessageHandlerTraceInfo.GetTraceInfo(request);
@@ -130,6 +132,7 @@ namespace GitHub.Services.Common
if (!m_appliedClientCertificatesToTransportHandler && if (!m_appliedClientCertificatesToTransportHandler &&
request.RequestUri.Scheme == "https") request.RequestUri.Scheme == "https")
{ {
// System.Console.WriteLine("VssHttpMessageHandler.SendAsync: !appliedClientCertificatesToTransportHandler");
HttpClientHandler httpClientHandler = m_transportHandler as HttpClientHandler; HttpClientHandler httpClientHandler = m_transportHandler as HttpClientHandler;
if (httpClientHandler != null && if (httpClientHandler != null &&
this.Settings.ClientCertificateManager != null && this.Settings.ClientCertificateManager != null &&
@@ -144,6 +147,7 @@ namespace GitHub.Services.Common
if (!m_appliedServerCertificateValidationCallbackToTransportHandler && if (!m_appliedServerCertificateValidationCallbackToTransportHandler &&
request.RequestUri.Scheme == "https") request.RequestUri.Scheme == "https")
{ {
// System.Console.WriteLine("VssHttpMessageHandler.SendAsync: !appliedServerCertificateValidationCallbackToTransportHandler");
HttpClientHandler httpClientHandler = m_transportHandler as HttpClientHandler; HttpClientHandler httpClientHandler = m_transportHandler as HttpClientHandler;
if (httpClientHandler != null && if (httpClientHandler != null &&
this.Settings.ServerCertificateValidationCallback != null) this.Settings.ServerCertificateValidationCallback != null)
@@ -165,6 +169,7 @@ namespace GitHub.Services.Common
IssuedTokenProvider provider; IssuedTokenProvider provider;
if (this.Credentials.TryGetTokenProvider(request.RequestUri, out provider)) if (this.Credentials.TryGetTokenProvider(request.RequestUri, out provider))
{ {
// System.Console.WriteLine("VssHttpMessageHandler.SendAsync: Got token provider from credentials");
token = provider.CurrentToken; token = provider.CurrentToken;
} }
@@ -225,6 +230,7 @@ namespace GitHub.Services.Common
traceInfo?.TraceResponseContentTime(); traceInfo?.TraceResponseContentTime();
// System.Console.WriteLine($"VssHttpMessageHandler.SendAsync: Creating response wrapper");
responseWrapper = new HttpResponseMessageWrapper(response); responseWrapper = new HttpResponseMessageWrapper(response);
if (!this.Credentials.IsAuthenticationChallenge(responseWrapper)) if (!this.Credentials.IsAuthenticationChallenge(responseWrapper))
@@ -232,6 +238,7 @@ namespace GitHub.Services.Common
// Validate the token after it has been successfully authenticated with the server. // Validate the token after it has been successfully authenticated with the server.
if (provider != null) if (provider != null)
{ {
// System.Console.WriteLine("VssHttpMessageHandler.SendAsync: Validating token");
provider.ValidateToken(token, responseWrapper); provider.ValidateToken(token, responseWrapper);
} }
@@ -243,6 +250,7 @@ namespace GitHub.Services.Common
} }
else else
{ {
// System.Console.WriteLine($"VssHttpMessageHandler.SendAsync: Auth challenge. Response status code {response.StatusCode}; headers {response.Headers}");
// In the case of a Windows token, only apply it to the web proxy if it // In the case of a Windows token, only apply it to the web proxy if it
// returned a 407 Proxy Authentication Required. If we didn't get this // returned a 407 Proxy Authentication Required. If we didn't get this
// status code back, then the proxy (if there is one) is clearly working fine, // status code back, then the proxy (if there is one) is clearly working fine,
@@ -288,6 +296,7 @@ namespace GitHub.Services.Common
} }
// Now invoke the provider and await the result // Now invoke the provider and await the result
// System.Console.WriteLine($"VssHttpMessageHandler.SendAsync: Calling GetTokenAsync");
token = await provider.GetTokenAsync(token, tokenSource.Token).ConfigureAwait(false); token = await provider.GetTokenAsync(token, tokenSource.Token).ConfigureAwait(false);
// I always see 0 here, but the method above could take more time so keep for now // I always see 0 here, but the method above could take more time so keep for now
@@ -432,6 +441,7 @@ namespace GitHub.Services.Common
activity != VssTraceActivity.Empty && activity != VssTraceActivity.Empty &&
!request.Headers.Contains(HttpHeaders.TfsSessionHeader)) !request.Headers.Contains(HttpHeaders.TfsSessionHeader))
{ {
// System.Console.WriteLine($"VssHttpMessageHandler.ApplyHeaders: Activity ID {activity.Id}");
request.Headers.Add(HttpHeaders.TfsSessionHeader, activity.Id.ToString("D")); request.Headers.Add(HttpHeaders.TfsSessionHeader, activity.Id.ToString("D"));
} }
@@ -452,13 +462,16 @@ namespace GitHub.Services.Common
ICredentials credentialsToken = token as ICredentials; ICredentials credentialsToken = token as ICredentials;
if (credentialsToken != null) if (credentialsToken != null)
{ {
// System.Console.WriteLine("VssHttpMessageHandler.ApplyToken: Credentials token != null");
if (applyICredentialsToWebProxy) if (applyICredentialsToWebProxy)
{ {
// System.Console.WriteLine("VssHttpMessageHandler.ApplyToken: Apply credentials to web proxy");
HttpClientHandler httpClientHandler = m_transportHandler as HttpClientHandler; HttpClientHandler httpClientHandler = m_transportHandler as HttpClientHandler;
if (httpClientHandler != null && if (httpClientHandler != null &&
httpClientHandler.Proxy != null) httpClientHandler.Proxy != null)
{ {
// System.Console.WriteLine("VssHttpMessageHandler.ApplyToken: Setting proxy crednetials");
httpClientHandler.Proxy.Credentials = credentialsToken; httpClientHandler.Proxy.Credentials = credentialsToken;
} }
} }
@@ -467,6 +480,7 @@ namespace GitHub.Services.Common
} }
else else
{ {
// System.Console.WriteLine("VssHttpMessageHandler.ApplyToken: Applying credentials to request");
token.ApplyTo(new HttpRequestMessageWrapper(request)); token.ApplyTo(new HttpRequestMessageWrapper(request));
} }
} }
@@ -479,7 +493,8 @@ namespace GitHub.Services.Common
HttpClientHandler httpClientHandler = handler as HttpClientHandler; HttpClientHandler httpClientHandler = handler as HttpClientHandler;
if (httpClientHandler != null) if (httpClientHandler != null)
{ {
httpClientHandler.AllowAutoRedirect = settings.AllowAutoRedirect; // System.Console.WriteLine($"VssHttpMessageHandler.ApplySettings: Default credentials = {defaultCredentials} AllowAutoRedirect = {settings.AllowAutoRedirect}");
httpClientHandler.AllowAutoRedirect = true; //settings.AllowAutoRedirect;
httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual; httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
//Setting httpClientHandler.UseDefaultCredentials to false in .Net Core, clears httpClientHandler.Credentials if //Setting httpClientHandler.UseDefaultCredentials to false in .Net Core, clears httpClientHandler.Credentials if
//credentials is already set to defaultcredentials. Therefore httpClientHandler.Credentials must be //credentials is already set to defaultcredentials. Therefore httpClientHandler.Credentials must be
@@ -550,6 +565,7 @@ namespace GitHub.Services.Common
Uri uri, Uri uri,
String authType) String authType)
{ {
// System.Console.WriteLine($"CredentialWrapper.GetCredential: InnerCredentials = {InnerCredentials}");
return InnerCredentials != null ? InnerCredentials.GetCredential(uri, authType) : null; return InnerCredentials != null ? InnerCredentials.GetCredential(uri, authType) : null;
} }
} }

View File

@@ -27,6 +27,7 @@ using System.Net.Http.Headers;
using System.Net.Http.Formatting; using System.Net.Http.Formatting;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using GitHub.DistributedTask.Pipelines;
using GitHub.Services.Common; using GitHub.Services.Common;
using GitHub.Services.WebApi; using GitHub.Services.WebApi;
@@ -378,6 +379,7 @@ namespace GitHub.DistributedTask.WebApi
/// <param name="requestId"></param> /// <param name="requestId"></param>
/// <param name="lockToken"></param> /// <param name="lockToken"></param>
/// <param name="request"></param> /// <param name="request"></param>
/// <param name="targetHostId"></param>
/// <param name="userState"></param> /// <param name="userState"></param>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param> /// <param name="cancellationToken">The cancellation token to cancel operation.</param>
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
@@ -386,6 +388,7 @@ namespace GitHub.DistributedTask.WebApi
long requestId, long requestId,
Guid lockToken, Guid lockToken,
TaskAgentJobRequest request, TaskAgentJobRequest request,
Guid targetHostId,
object userState = null, object userState = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
@@ -396,6 +399,7 @@ namespace GitHub.DistributedTask.WebApi
List<KeyValuePair<string, string>> queryParams = new List<KeyValuePair<string, string>>(); List<KeyValuePair<string, string>> queryParams = new List<KeyValuePair<string, string>>();
queryParams.Add("lockToken", lockToken.ToString()); queryParams.Add("lockToken", lockToken.ToString());
queryParams.Add("targetHostId", targetHostId.ToString());
return SendAsync<TaskAgentJobRequest>( return SendAsync<TaskAgentJobRequest>(
httpMethod, httpMethod,
@@ -703,6 +707,47 @@ namespace GitHub.DistributedTask.WebApi
cancellationToken: cancellationToken); cancellationToken: cancellationToken);
} }
/// <summary>
/// [Preview API]
/// </summary>
/// <param name="scopeId"></param>
/// <param name="planType"></param>
/// <param name="planGroup"></param>
/// <param name="planId"></param>
/// <param name="instanceRefsJson"></param>
/// <param name="userState"></param>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual Task<Pipelines.AgentJobRequestMessage> GetJobMessageAsync(
Guid scopeId,
Guid hostId,
string planType,
string planGroup,
Guid planId,
string instanceRefsJson,
object userState = null,
CancellationToken cancellationToken = default)
{
HttpMethod httpMethod = new HttpMethod("GET");
Guid locationId = new Guid("25adab70-1379-4186-be8e-b643061ebe3a");
List<KeyValuePair<string, string>> queryParams = new List<KeyValuePair<string, string>>();
queryParams.Add("scopeId", scopeId.ToString());
queryParams.Add("hostId", hostId.ToString());
queryParams.Add("planType", planType);
queryParams.Add("planGroup", planGroup);
queryParams.Add("planId", planId.ToString());
queryParams.Add("instanceRefsJson", instanceRefsJson);
return SendAsync<Pipelines.AgentJobRequestMessage>(
httpMethod,
locationId,
version: new ApiResourceVersion(6.0, 1),
queryParameters: queryParams,
userState: userState,
cancellationToken: cancellationToken);
}
/// <summary> /// <summary>
/// [Preview API] /// [Preview API]
/// </summary> /// </summary>
@@ -717,6 +762,7 @@ namespace GitHub.DistributedTask.WebApi
object userState = null, object userState = null,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
// System.Console.WriteLine("TaskAgentHttpClientBase.CreateAgentSessionAsync");
HttpMethod httpMethod = new HttpMethod("POST"); HttpMethod httpMethod = new HttpMethod("POST");
Guid locationId = new Guid("134e239e-2df3-4794-a6f6-24f1f19ec8dc"); Guid locationId = new Guid("134e239e-2df3-4794-a6f6-24f1f19ec8dc");
object routeValues = new { poolId = poolId }; object routeValues = new { poolId = poolId };

View File

@@ -5,5 +5,6 @@ namespace GitHub.DistributedTask.WebApi
public static class JobRequestMessageTypes public static class JobRequestMessageTypes
{ {
public const String PipelineAgentJobRequest = "PipelineAgentJobRequest"; public const String PipelineAgentJobRequest = "PipelineAgentJobRequest";
public const String RunnerJobRequest = "RunnerJobRequest";
} }
} }

View File

@@ -64,6 +64,7 @@ namespace GitHub.DistributedTask.WebApi
Guid lockToken, Guid lockToken,
DateTime finishTime, DateTime finishTime,
TaskResult result, TaskResult result,
Guid targetHostId,
Object userState = null, Object userState = null,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
@@ -74,7 +75,7 @@ namespace GitHub.DistributedTask.WebApi
Result = result, Result = result,
}; };
return UpdateAgentRequestAsync(poolId, requestId, lockToken, request, userState, cancellationToken); return UpdateAgentRequestAsync(poolId, requestId, lockToken, request, targetHostId, userState, cancellationToken);
} }
public Task<List<TaskAgent>> GetAgentsAsync( public Task<List<TaskAgent>> GetAgentsAsync(
@@ -152,6 +153,7 @@ namespace GitHub.DistributedTask.WebApi
CancellationToken cancellationToken = default(CancellationToken), CancellationToken cancellationToken = default(CancellationToken),
Func<HttpResponseMessage, CancellationToken, Task<T>> processResponse = null) Func<HttpResponseMessage, CancellationToken, Task<T>> processResponse = null)
{ {
// System.Console.WriteLine("TaskAgentHttpClient.SendAsync 1");
return SendAsync<T>(method, null, locationId, routeValues, version, content, queryParameters, userState, cancellationToken, processResponse); return SendAsync<T>(method, null, locationId, routeValues, version, content, queryParameters, userState, cancellationToken, processResponse);
} }
@@ -170,6 +172,7 @@ namespace GitHub.DistributedTask.WebApi
using (VssTraceActivity.GetOrCreate().EnterCorrelationScope()) using (VssTraceActivity.GetOrCreate().EnterCorrelationScope())
using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, additionalHeaders, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false)) using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, additionalHeaders, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false))
{ {
// System.Console.WriteLine("TaskAgentHttpClient.SendAsync 2");
return await SendAsync<T>(requestMessage, userState, cancellationToken, processResponse).ConfigureAwait(false); return await SendAsync<T>(requestMessage, userState, cancellationToken, processResponse).ConfigureAwait(false);
} }
} }
@@ -180,6 +183,7 @@ namespace GitHub.DistributedTask.WebApi
CancellationToken cancellationToken = default(CancellationToken), CancellationToken cancellationToken = default(CancellationToken),
Func<HttpResponseMessage, CancellationToken, Task<T>> processResponse = null) Func<HttpResponseMessage, CancellationToken, Task<T>> processResponse = null)
{ {
// System.Console.WriteLine("TaskAgentHttpClient.SendAsync 3");
if (processResponse == null) if (processResponse == null)
{ {
processResponse = ReadContentAsAsync<T>; processResponse = ReadContentAsAsync<T>;

View File

@@ -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</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch> <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<NoWarn>NU1701;NU1603</NoWarn> <NoWarn>NU1701;NU1603</NoWarn>
<Version>$(Version)</Version> <Version>$(Version)</Version>

View File

@@ -801,6 +801,7 @@ namespace GitHub.Services.WebApi.Location
private async Task<ConnectionData> GetConnectionDataAsync(ConnectOptions connectOptions, int lastChangeId, CancellationToken cancellationToken) private async Task<ConnectionData> GetConnectionDataAsync(ConnectOptions connectOptions, int lastChangeId, CancellationToken cancellationToken)
{ {
// System.Console.WriteLine("ServerDataProvider.GetConnectionDataAsync");
int timeoutRetries = 1; int timeoutRetries = 1;
while (true) while (true)

View File

@@ -75,6 +75,7 @@ namespace GitHub.Services.OAuth
internal override void ApplyTo(IHttpRequest request) internal override void ApplyTo(IHttpRequest request)
{ {
// System.Console.WriteLine($"VssOAuthAccessToken.ApplyTo: Bearer {m_value}");
request.Headers.SetValue(Common.Internal.HttpHeaders.Authorization, $"Bearer {m_value}"); request.Headers.SetValue(Common.Internal.HttpHeaders.Authorization, $"Bearer {m_value}");
} }

View File

@@ -60,6 +60,7 @@ namespace GitHub.Services.OAuth
Uri serverUrl, Uri serverUrl,
IHttpResponse response) IHttpResponse response)
{ {
// System.Console.WriteLine($"VssOAuthAccessTokenCredential.OnCreateTokenProvider");
return new VssOAuthAccessTokenProvider(this, serverUrl, null); return new VssOAuthAccessTokenProvider(this, serverUrl, null);
} }
@@ -71,6 +72,7 @@ namespace GitHub.Services.OAuth
Uri signInUrl) Uri signInUrl)
: base(credential, serverUrl, signInUrl) : base(credential, serverUrl, signInUrl)
{ {
// System.Console.WriteLine($"VssOAuthAccessTokenProvider.ctor");
} }
public override Boolean GetTokenIsInteractive public override Boolean GetTokenIsInteractive

View File

@@ -103,17 +103,23 @@ namespace GitHub.Services.OAuth
/// <returns>True if the web response indicates an authorization challenge; otherwise, false</returns> /// <returns>True if the web response indicates an authorization challenge; otherwise, false</returns>
public override Boolean IsAuthenticationChallenge(IHttpResponse webResponse) public override Boolean IsAuthenticationChallenge(IHttpResponse webResponse)
{ {
// System.Console.WriteLine($"VssOAuthCredential.IsAuthenticationChallenge");
if (webResponse == null) if (webResponse == null)
{ {
// System.Console.WriteLine($"VssOAuthCredential.IsAuthenticationChallenge: webResponse is null");
return false; return false;
} }
if (webResponse.StatusCode == HttpStatusCode.Found || if (webResponse.StatusCode == HttpStatusCode.Found ||
webResponse.StatusCode == HttpStatusCode.Unauthorized) webResponse.StatusCode == HttpStatusCode.Unauthorized)
{ {
return webResponse.Headers.GetValues(Common.Internal.HttpHeaders.WwwAuthenticate).Any(x => x.IndexOf("Bearer", StringComparison.OrdinalIgnoreCase) >= 0); // System.Console.WriteLine($"VssOAuthCredential.IsAuthenticationChallenge: found or unauthorized");
var result = webResponse.Headers.GetValues(Common.Internal.HttpHeaders.WwwAuthenticate).Any(x => x.IndexOf("Bearer", StringComparison.OrdinalIgnoreCase) >= 0);
// System.Console.WriteLine($"VssOAuthCredential.IsAuthenticationChallenge: {result}");
return result;
} }
// System.Console.WriteLine($"VssOAuthCredential.IsAuthenticationChallenge: false");
return false; return false;
} }
@@ -121,6 +127,7 @@ namespace GitHub.Services.OAuth
Uri serverUrl, Uri serverUrl,
IHttpResponse response) IHttpResponse response)
{ {
// System.Console.WriteLine($"VssOAuthCredential.OnCreateTokenProvider");
return new VssOAuthTokenProvider(this, serverUrl); return new VssOAuthTokenProvider(this, serverUrl);
} }

View File

@@ -54,6 +54,7 @@ namespace GitHub.Services.OAuth
VssOAuthTokenParameters tokenParameters = null, VssOAuthTokenParameters tokenParameters = null,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
// todo: qqq
VssTraceActivity traceActivity = VssTraceActivity.Current; VssTraceActivity traceActivity = VssTraceActivity.Current;
using (HttpClient client = new HttpClient(CreateMessageHandler(this.AuthorizationUrl))) using (HttpClient client = new HttpClient(CreateMessageHandler(this.AuthorizationUrl)))
{ {

View File

@@ -47,6 +47,7 @@ namespace GitHub.Services.OAuth
VssOAuthTokenParameters tokenParameters) VssOAuthTokenParameters tokenParameters)
: base(credential, serverUrl, authorizationUrl) : base(credential, serverUrl, authorizationUrl)
{ {
// System.Console.WriteLine($"VssOAuthTokenProvider.ctor");
m_grant = grant; m_grant = grant;
m_tokenParameters = tokenParameters; m_tokenParameters = tokenParameters;
m_clientCredential = clientCrential; m_clientCredential = clientCrential;
@@ -59,6 +60,7 @@ namespace GitHub.Services.OAuth
{ {
get get
{ {
// System.Console.WriteLine($"VssOAuthTokenProvider.get_Grant");
return m_grant; return m_grant;
} }
} }
@@ -70,6 +72,7 @@ namespace GitHub.Services.OAuth
{ {
get get
{ {
// System.Console.WriteLine($"VssOAuthTokenProvider.get_ClientCredential");
return m_clientCredential; return m_clientCredential;
} }
} }
@@ -81,6 +84,7 @@ namespace GitHub.Services.OAuth
{ {
get get
{ {
// System.Console.WriteLine($"VssOAuthTokenProvider.get_TokenParameters");
return m_tokenParameters; return m_tokenParameters;
} }
} }
@@ -92,6 +96,7 @@ namespace GitHub.Services.OAuth
{ {
get get
{ {
// System.Console.WriteLine($"VssOAuthTokenProvider.get_GetTokenIsInteractive");
return false; return false;
} }
} }
@@ -100,6 +105,7 @@ namespace GitHub.Services.OAuth
{ {
get get
{ {
// System.Console.WriteLine($"VssOAuthTokenProvider.get_AuthenticationParameter");
if (this.ClientCredential == null) if (this.ClientCredential == null)
{ {
return null; return null;
@@ -115,12 +121,14 @@ namespace GitHub.Services.OAuth
{ {
get get
{ {
// System.Console.WriteLine($"VssOAuthTokenProvider.get_AuthenticationScheme");
return "Bearer"; return "Bearer";
} }
} }
public async Task<string> ValidateCredentialAsync(CancellationToken cancellationToken) public async Task<string> ValidateCredentialAsync(CancellationToken cancellationToken)
{ {
// System.Console.WriteLine($"VssOAuthTokenProvider.ValidateCredentialAsync: Calling VssOAuthTokenHttpClient.GetTokenAsync");
var tokenHttpClient = new VssOAuthTokenHttpClient(this.SignInUrl); var tokenHttpClient = new VssOAuthTokenHttpClient(this.SignInUrl);
var tokenResponse = await tokenHttpClient.GetTokenAsync(this.Grant, this.ClientCredential, this.TokenParameters, cancellationToken); var tokenResponse = await tokenHttpClient.GetTokenAsync(this.Grant, this.ClientCredential, this.TokenParameters, cancellationToken);
@@ -139,6 +147,7 @@ namespace GitHub.Services.OAuth
IssuedToken failedToken, IssuedToken failedToken,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
// System.Console.WriteLine($"VssOAuthTokenProvider.OnGetTokenAsync");
if (this.SignInUrl == null || if (this.SignInUrl == null ||
this.Grant == null || this.Grant == null ||
this.ClientCredential == null) this.ClientCredential == null)
@@ -151,6 +160,7 @@ namespace GitHub.Services.OAuth
try try
{ {
var tokenHttpClient = new VssOAuthTokenHttpClient(this.SignInUrl); var tokenHttpClient = new VssOAuthTokenHttpClient(this.SignInUrl);
// System.Console.WriteLine($"VssOAuthTokenProvider.OnGetTokenAsync: Calling VssOAuthTokenHttpClient.GetTokenAsync; sign-in url {this.SignInUrl.AbsoluteUri}");
var tokenResponse = await tokenHttpClient.GetTokenAsync(this.Grant, this.ClientCredential, this.TokenParameters, cancellationToken).ConfigureAwait(false); var tokenResponse = await tokenHttpClient.GetTokenAsync(this.Grant, this.ClientCredential, this.TokenParameters, cancellationToken).ConfigureAwait(false);
if (!String.IsNullOrEmpty(tokenResponse.AccessToken)) if (!String.IsNullOrEmpty(tokenResponse.AccessToken))
{ {
@@ -197,6 +207,7 @@ namespace GitHub.Services.OAuth
protected virtual IssuedToken CreateIssuedToken(VssOAuthTokenResponse tokenResponse) protected virtual IssuedToken CreateIssuedToken(VssOAuthTokenResponse tokenResponse)
{ {
// System.Console.WriteLine($"VssOAuthTokenProvider.CreateIssuedToken");
if (tokenResponse.ExpiresIn > 0) if (tokenResponse.ExpiresIn > 0)
{ {
return new VssOAuthAccessToken(tokenResponse.AccessToken, DateTime.UtcNow.AddSeconds(tokenResponse.ExpiresIn)); return new VssOAuthAccessToken(tokenResponse.AccessToken, DateTime.UtcNow.AddSeconds(tokenResponse.ExpiresIn));

View File

@@ -100,6 +100,7 @@ namespace GitHub.Services.WebApi
IDictionary<String, String> parameters, IDictionary<String, String> parameters,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("VssConnection.ConnectAsync");
CheckForDisposed(); CheckForDisposed();
// Set the connectMode on the credential's FederatedPrompt // Set the connectMode on the credential's FederatedPrompt
if (Credentials.Federated != null && Credentials.Federated.Prompt != null) if (Credentials.Federated != null && Credentials.Federated.Prompt != null)

View File

@@ -390,6 +390,7 @@ namespace GitHub.Services.WebApi
Object userState = null, Object userState = null,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("VssHttpClientBase.SendAsync 1");
return SendAsync<T>(method, null, locationId, routeValues, version, content, queryParameters, userState, cancellationToken); return SendAsync<T>(method, null, locationId, routeValues, version, content, queryParameters, userState, cancellationToken);
} }
@@ -404,6 +405,7 @@ namespace GitHub.Services.WebApi
Object userState = null, Object userState = null,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("VssHttpClientBase.SendAsync 2");
using (VssTraceActivity.GetOrCreate().EnterCorrelationScope()) using (VssTraceActivity.GetOrCreate().EnterCorrelationScope())
using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, additionalHeaders, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false)) using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, additionalHeaders, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false))
{ {
@@ -422,6 +424,7 @@ namespace GitHub.Services.WebApi
Object userState = null, Object userState = null,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("VssHttpClientBase.SendAsync 3");
using (VssTraceActivity.GetOrCreate().EnterCorrelationScope()) using (VssTraceActivity.GetOrCreate().EnterCorrelationScope())
using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, additionalHeaders, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false)) using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, additionalHeaders, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false))
{ {
@@ -455,6 +458,7 @@ namespace GitHub.Services.WebApi
Object userState = null, Object userState = null,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("VssHttpClientBase.SendAsync 4");
using (VssTraceActivity.GetOrCreate().EnterCorrelationScope()) using (VssTraceActivity.GetOrCreate().EnterCorrelationScope())
using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false)) using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false))
{ {
@@ -473,6 +477,7 @@ namespace GitHub.Services.WebApi
Object userState = null, Object userState = null,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("VssHttpClientBase.SendAsync 5");
using (VssTraceActivity.GetOrCreate().EnterCorrelationScope()) using (VssTraceActivity.GetOrCreate().EnterCorrelationScope())
using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false)) using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false))
{ {
@@ -501,6 +506,7 @@ namespace GitHub.Services.WebApi
CancellationToken cancellationToken = default(CancellationToken), CancellationToken cancellationToken = default(CancellationToken),
String mediaType = c_jsonMediaType) String mediaType = c_jsonMediaType)
{ {
// System.Console.WriteLine("VssHttpClientBase.CreateRequestMessageAsync 1");
return CreateRequestMessageAsync(method, null, locationId, routeValues, version, content, queryParameters, userState, cancellationToken, mediaType); return CreateRequestMessageAsync(method, null, locationId, routeValues, version, content, queryParameters, userState, cancellationToken, mediaType);
} }
@@ -526,6 +532,7 @@ namespace GitHub.Services.WebApi
CancellationToken cancellationToken = default(CancellationToken), CancellationToken cancellationToken = default(CancellationToken),
String mediaType = c_jsonMediaType) String mediaType = c_jsonMediaType)
{ {
// System.Console.WriteLine("VssHttpClientBase.CreateRequestMessageAsync 2");
// Lookup the location // Lookup the location
ApiResourceLocation location = await GetResourceLocationAsync(locationId, userState, cancellationToken).ConfigureAwait(false); ApiResourceLocation location = await GetResourceLocationAsync(locationId, userState, cancellationToken).ConfigureAwait(false);
if (location == null) if (location == null)
@@ -555,6 +562,7 @@ namespace GitHub.Services.WebApi
IEnumerable<KeyValuePair<String, String>> queryParameters = null, IEnumerable<KeyValuePair<String, String>> queryParameters = null,
String mediaType = c_jsonMediaType) String mediaType = c_jsonMediaType)
{ {
// System.Console.WriteLine("VssHttpClientBase.CreateRequestMessageAsync 3");
return CreateRequestMessage(method, null, location, routeValues, version, content, queryParameters, mediaType); return CreateRequestMessage(method, null, location, routeValues, version, content, queryParameters, mediaType);
} }
@@ -578,6 +586,7 @@ namespace GitHub.Services.WebApi
IEnumerable<KeyValuePair<String, String>> queryParameters = null, IEnumerable<KeyValuePair<String, String>> queryParameters = null,
String mediaType = c_jsonMediaType) String mediaType = c_jsonMediaType)
{ {
// System.Console.WriteLine("VssHttpClientBase.CreateRequestMessageAsync 4");
CheckForDisposed(); CheckForDisposed();
// Negotiate the request version to send // Negotiate the request version to send
ApiResourceVersion requestVersion = NegotiateRequestVersion(location, version); ApiResourceVersion requestVersion = NegotiateRequestVersion(location, version);
@@ -749,12 +758,14 @@ namespace GitHub.Services.WebApi
//from deadlocking... //from deadlocking...
using (HttpResponseMessage response = await this.SendAsync(message, userState, cancellationToken).ConfigureAwait(false)) using (HttpResponseMessage response = await this.SendAsync(message, userState, cancellationToken).ConfigureAwait(false))
{ {
// System.Console.WriteLine("VssHttpClientBase.SendAsync 6");
return await ReadContentAsAsync<T>(response, cancellationToken).ConfigureAwait(false); return await ReadContentAsAsync<T>(response, cancellationToken).ConfigureAwait(false);
} }
} }
protected async Task<T> ReadContentAsAsync<T>(HttpResponseMessage response, CancellationToken cancellationToken = default(CancellationToken)) protected async Task<T> ReadContentAsAsync<T>(HttpResponseMessage response, CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine($"VssHttpClientBase.ReadContentAsAsync {response.Headers}");
CheckForDisposed(); CheckForDisposed();
Boolean isJson = IsJsonResponse(response); Boolean isJson = IsJsonResponse(response);
bool mismatchContentType = false; bool mismatchContentType = false;
@@ -766,17 +777,20 @@ namespace GitHub.Services.WebApi
!typeof(Byte[]).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()) && !typeof(Byte[]).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()) &&
!typeof(JObject).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())) !typeof(JObject).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()))
{ {
// System.Console.WriteLine("VssHttpClientBase.ReadContentAsAsync: isJson 1");
// expect it to come back wrapped, if it isn't it is a bug! // expect it to come back wrapped, if it isn't it is a bug!
var wrapper = await ReadJsonContentAsync<VssJsonCollectionWrapper<T>>(response, cancellationToken).ConfigureAwait(false); var wrapper = await ReadJsonContentAsync<VssJsonCollectionWrapper<T>>(response, cancellationToken).ConfigureAwait(false);
return wrapper.Value; return wrapper.Value;
} }
else if (isJson) else if (isJson)
{ {
// System.Console.WriteLine("VssHttpClientBase.ReadContentAsAsync: isJson 2");
return await ReadJsonContentAsync<T>(response, cancellationToken).ConfigureAwait(false); return await ReadJsonContentAsync<T>(response, cancellationToken).ConfigureAwait(false);
} }
} }
catch (JsonReaderException) catch (JsonReaderException)
{ {
// System.Console.WriteLine("VssHttpClientBase.ReadContentAsAsync: mismatchContentType");
// We thought the content was JSON but failed to parse. // We thought the content was JSON but failed to parse.
// In this case, do nothing and utilize the HandleUnknownContentType call below // In this case, do nothing and utilize the HandleUnknownContentType call below
mismatchContentType = true; mismatchContentType = true;
@@ -802,6 +816,7 @@ namespace GitHub.Services.WebApi
Object userState = null, Object userState = null,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("VssHttpClientBase.SendAsync 7");
// the default in httpClient for HttpCompletionOption is ResponseContentRead so that is what we do here // the default in httpClient for HttpCompletionOption is ResponseContentRead so that is what we do here
return this.SendAsync( return this.SendAsync(
message, message,
@@ -816,6 +831,7 @@ namespace GitHub.Services.WebApi
Object userState = null, Object userState = null,
CancellationToken cancellationToken = default(CancellationToken)) CancellationToken cancellationToken = default(CancellationToken))
{ {
// System.Console.WriteLine("VssHttpClientBase.SendAsync 8");
CheckForDisposed(); CheckForDisposed();
if (message.Headers.UserAgent != null) if (message.Headers.UserAgent != null)
{ {
@@ -851,6 +867,7 @@ namespace GitHub.Services.WebApi
//ConfigureAwait(false) enables the continuation to be run outside //ConfigureAwait(false) enables the continuation to be run outside
//any captured SyncronizationContext (such as ASP.NET's) which keeps things //any captured SyncronizationContext (such as ASP.NET's) which keeps things
//from deadlocking... //from deadlocking...
// System.Console.WriteLine($"VssHttpClientBase.SendAsync 8: Calling Client.SendAsync {message}");
HttpResponseMessage response = await Client.SendAsync(message, completionOption, cancellationToken).ConfigureAwait(false); HttpResponseMessage response = await Client.SendAsync(message, completionOption, cancellationToken).ConfigureAwait(false);
// Inject delay or failure for testing // Inject delay or failure for testing
@@ -868,6 +885,7 @@ namespace GitHub.Services.WebApi
[Obsolete("Use VssHttpClientBase.HandleResponseAsync instead")] [Obsolete("Use VssHttpClientBase.HandleResponseAsync instead")]
protected virtual void HandleResponse(HttpResponseMessage response) protected virtual void HandleResponse(HttpResponseMessage response)
{ {
// System.Console.WriteLine("VssHttpClientBase.HandleResponse 1");
} }
@@ -875,6 +893,7 @@ namespace GitHub.Services.WebApi
HttpResponseMessage response, HttpResponseMessage response,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
// System.Console.WriteLine($"VssHttpClientBase.HandleResponse 2 status code {response.StatusCode} headers {response.Headers}");
response.Trace(); response.Trace();
VssHttpEventSource.Log.HttpRequestStop(VssTraceActivity.Current, response); VssHttpEventSource.Log.HttpRequestStop(VssTraceActivity.Current, response);
@@ -886,6 +905,7 @@ namespace GitHub.Services.WebApi
} }
else if (ShouldThrowError(response)) else if (ShouldThrowError(response))
{ {
// System.Console.WriteLine("VssHttpClientBase.HandleResponse: Should throw error");
Exception exToThrow = null; Exception exToThrow = null;
if (IsJsonResponse(response)) if (IsJsonResponse(response))
{ {
@@ -909,6 +929,7 @@ namespace GitHub.Services.WebApi
{ {
message = response.ReasonPhrase; message = response.ReasonPhrase;
} }
// System.Console.WriteLine($"VssHttpClientBase.HandleResponse: Exception message {message}");
exToThrow = new VssServiceResponseException(response.StatusCode, message, exToThrow); exToThrow = new VssServiceResponseException(response.StatusCode, message, exToThrow);
} }

View File

@@ -19,8 +19,7 @@ namespace GitHub.Runner.Common.Tests
"linux-x64", "linux-x64",
"linux-arm", "linux-arm",
"linux-arm64", "linux-arm64",
"osx-x64", "osx-x64"
"osx-arm64"
}; };
Assert.True(BuildConstants.Source.CommitHash.Length == 40, $"CommitHash should be SHA-1 hash {BuildConstants.Source.CommitHash}"); Assert.True(BuildConstants.Source.CommitHash.Length == 40, $"CommitHash should be SHA-1 hash {BuildConstants.Source.CommitHash}");

View File

@@ -708,85 +708,33 @@ namespace GitHub.Runner.Common.Tests
} }
} }
[Theory] [Fact]
[InlineData("configure", "once")]
[InlineData("remove", "disableupdate")]
[InlineData("remove", "ephemeral")]
[InlineData("remove", "once")]
[InlineData("remove", "replace")]
[InlineData("remove", "runasservice")]
[InlineData("remove", "unattended")]
[InlineData("run", "disableupdate")]
[InlineData("run", "ephemeral")]
[InlineData("run", "replace")]
[InlineData("run", "runasservice")]
[InlineData("run", "unattended")]
[InlineData("warmup", "disableupdate")]
[InlineData("warmup", "ephemeral")]
[InlineData("warmup", "once")]
[InlineData("warmup", "replace")]
[InlineData("warmup", "runasservice")]
[InlineData("warmup", "unattended")]
[Trait("Level", "L0")] [Trait("Level", "L0")]
[Trait("Category", nameof(CommandSettings))] [Trait("Category", nameof(CommandSettings))]
public void ValidateInvalidFlagCommandCombination(string validCommand, string flag) public void ValidateFlags()
{ {
using (TestHostContext hc = CreateTestContext()) using (TestHostContext hc = CreateTestContext())
{ {
// Arrange. // Arrange.
var command = new CommandSettings(hc, args: new string[] { validCommand, $"--{flag}" }); var command = new CommandSettings(hc, args: new string[] { "--badflag" });
// Assert. // Assert.
Assert.Contains(flag, command.Validate()); Assert.Contains("badflag", command.Validate());
} }
} }
[Theory] [Fact]
[InlineData("remove", "auth", "bar arg value")]
[InlineData("remove", "labels", "bar arg value")]
[InlineData("remove", "monitorsocketaddress", "bar arg value")]
[InlineData("remove", "name", "bar arg value")]
[InlineData("remove", "runnergroup", "bar arg value")]
[InlineData("remove", "url", "bar arg value")]
[InlineData("remove", "username", "bar arg value")]
[InlineData("remove", "windowslogonaccount", "bar arg value")]
[InlineData("remove", "windowslogonpassword", "bar arg value")]
[InlineData("remove", "work", "bar arg value")]
[InlineData("run", "auth", "bad arg value")]
[InlineData("run", "labels", "bad arg value")]
[InlineData("run", "monitorsocketaddress", "bad arg value")]
[InlineData("run", "name", "bad arg value")]
[InlineData("run", "pat", "bad arg value")]
[InlineData("run", "runnergroup", "bad arg value")]
[InlineData("run", "token", "bad arg value")]
[InlineData("run", "url", "bad arg value")]
[InlineData("run", "username", "bad arg value")]
[InlineData("run", "windowslogonaccount", "bad arg value")]
[InlineData("run", "windowslogonpassword", "bad arg value")]
[InlineData("run", "work", "bad arg value")]
[InlineData("warmup", "auth", "bad arg value")]
[InlineData("warmup", "labels", "bad arg value")]
[InlineData("warmup", "monitorsocketaddress", "bad arg value")]
[InlineData("warmup", "name", "bad arg value")]
[InlineData("warmup", "pat", "bad arg value")]
[InlineData("warmup", "runnergroup", "bad arg value")]
[InlineData("warmup", "token", "bad arg value")]
[InlineData("warmup", "url", "bad arg value")]
[InlineData("warmup", "username", "bad arg value")]
[InlineData("warmup", "windowslogonaccount", "bad arg value")]
[InlineData("warmup", "windowslogonpassword", "bad arg value")]
[InlineData("warmup", "work", "bad arg value")]
[Trait("Level", "L0")] [Trait("Level", "L0")]
[Trait("Category", nameof(CommandSettings))] [Trait("Category", nameof(CommandSettings))]
public void ValidateInvalidArgCommandCombination(string validCommand, string arg, string argValue) public void ValidateArgs()
{ {
using (TestHostContext hc = CreateTestContext()) using (TestHostContext hc = CreateTestContext())
{ {
// Arrange. // Arrange.
var command = new CommandSettings(hc, args: new string[] { validCommand, $"--{arg}", argValue }); var command = new CommandSettings(hc, args: new string[] { "--badargname", "bad arg value" });
// Assert. // Assert.
Assert.Contains(arg, command.Validate()); Assert.Contains("badargname", command.Validate());
} }
} }
@@ -810,73 +758,6 @@ namespace GitHub.Runner.Common.Tests
} }
} }
[Theory]
[InlineData("configure", "help")]
[InlineData("configure", "version")]
[InlineData("configure", "commit")]
[InlineData("configure", "check")]
[InlineData("configure", "disableupdate")]
[InlineData("configure", "ephemeral")]
[InlineData("configure", "replace")]
[InlineData("configure", "runasservice")]
[InlineData("configure", "unattended")]
[InlineData("remove", "help")]
[InlineData("remove", "version")]
[InlineData("remove", "commit")]
[InlineData("remove", "check")]
[InlineData("run", "help")]
[InlineData("run", "version")]
[InlineData("run", "commit")]
[InlineData("run", "check")]
[InlineData("run", "once")]
[InlineData("warmup", "help")]
[InlineData("warmup", "version")]
[InlineData("warmup", "commit")]
[InlineData("warmup", "check")]
[Trait("Level", "L0")]
[Trait("Category", nameof(CommandSettings))]
public void ValidateGoodFlagCommandCombination(string validCommand, string flag)
{
using (TestHostContext hc = CreateTestContext())
{
// Arrange.
var command = new CommandSettings(hc, args: new string[] { validCommand, $"--{flag}" });
// Assert.
Assert.True(command.Validate().Count == 0);
}
}
[Theory]
[InlineData("configure", "auth", "good arg value")]
[InlineData("configure", "labels", "good arg value")]
[InlineData("configure", "monitorsocketaddress", "good arg value")]
[InlineData("configure", "name", "good arg value")]
[InlineData("configure", "pat", "good arg value")]
[InlineData("configure", "runnergroup", "good arg value")]
[InlineData("configure", "token", "good arg value")]
[InlineData("configure", "url", "good arg value")]
[InlineData("configure", "username", "good arg value")]
[InlineData("configure", "windowslogonaccount", "good arg value")]
[InlineData("configure", "windowslogonpassword", "good arg value")]
[InlineData("configure", "work", "good arg value")]
[InlineData("remove", "token", "good arg value")]
[InlineData("remove", "pat", "good arg value")]
[InlineData("run", "startuptype", "good arg value")]
[Trait("Level", "L0")]
[Trait("Category", nameof(CommandSettings))]
public void ValidateGoodArgCommandCombination(string validCommand, string arg, string argValue)
{
using (TestHostContext hc = CreateTestContext())
{
// Arrange.
var command = new CommandSettings(hc, args: new string[] { validCommand, $"--{arg}", argValue });
// Assert.
Assert.True(command.Validate().Count == 0);
}
}
private TestHostContext CreateTestContext([CallerMemberName] string testName = "") private TestHostContext CreateTestContext([CallerMemberName] string testName = "")
{ {
TestHostContext hc = new TestHostContext(this, testName); TestHostContext hc = new TestHostContext(this, testName);

View File

@@ -1,5 +1,4 @@
#if !(OS_OSX && ARM64) using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -51,9 +50,9 @@ namespace GitHub.Runner.Common.Tests.Listener
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://github.com/actions/runner/releases/latest")); var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://github.com/actions/runner/releases/latest"));
if (response.StatusCode == System.Net.HttpStatusCode.Redirect) if (response.StatusCode == System.Net.HttpStatusCode.Redirect)
{ {
var redirectUrl = response.Headers.Location.ToString(); var redirect = await response.Content.ReadAsStringAsync();
Regex regex = new Regex(@"/runner/releases/tag/v(?<version>\d+\.\d+\.\d+)"); Regex regex = new Regex(@"/runner/releases/tag/v(?<version>\d+\.\d+\.\d+)");
var match = regex.Match(redirectUrl); var match = regex.Match(redirect);
if (match.Success) if (match.Success)
{ {
latestVersion = match.Groups["version"].Value; latestVersion = match.Groups["version"].Value;
@@ -64,10 +63,6 @@ namespace GitHub.Runner.Common.Tests.Listener
_packageUrl = $"https://github.com/actions/runner/releases/download/v{latestVersion}/actions-runner-{BuildConstants.RunnerPackage.PackageName}-{latestVersion}.zip"; _packageUrl = $"https://github.com/actions/runner/releases/download/v{latestVersion}/actions-runner-{BuildConstants.RunnerPackage.PackageName}-{latestVersion}.zip";
#endif #endif
} }
else
{
throw new Exception("The latest runner version could not be determined so a download URL could not be generated for it. Please check the location header of the redirect response of 'https://github.com/actions/runner/releases/latest'");
}
} }
} }
@@ -796,4 +791,3 @@ namespace GitHub.Runner.Common.Tests.Listener
} }
} }
} }
#endif

View File

@@ -166,9 +166,9 @@ namespace GitHub.Runner.Common.Tests
string binDir = Path.Combine(TestUtil.GetSrcPath(), @"../_layout/bin"); string binDir = Path.Combine(TestUtil.GetSrcPath(), @"../_layout/bin");
#if OS_WINDOWS #if OS_WINDOWS
string node = Path.Combine(TestUtil.GetSrcPath(), @"..\_layout\externals\node16\bin\node"); string node = Path.Combine(TestUtil.GetSrcPath(), @"..\_layout\externals\node12\bin\node");
#else #else
string node = Path.Combine(TestUtil.GetSrcPath(), @"../_layout/externals/node16/bin/node"); string node = Path.Combine(TestUtil.GetSrcPath(), @"../_layout/externals/node12/bin/node");
#endif #endif
string hashFilesScript = Path.Combine(binDir, "hashFiles"); string hashFilesScript = Path.Combine(binDir, "hashFiles");
var hashResult = string.Empty; var hashResult = string.Empty;
@@ -228,9 +228,9 @@ namespace GitHub.Runner.Common.Tests
string binDir = Path.Combine(TestUtil.GetSrcPath(), @"../_layout/bin"); string binDir = Path.Combine(TestUtil.GetSrcPath(), @"../_layout/bin");
#if OS_WINDOWS #if OS_WINDOWS
string node = Path.Combine(TestUtil.GetSrcPath(), @"..\_layout\externals\node16\bin\node"); string node = Path.Combine(TestUtil.GetSrcPath(), @"..\_layout\externals\node12\bin\node");
#else #else
string node = Path.Combine(TestUtil.GetSrcPath(), @"../_layout/externals/node16/bin/node"); string node = Path.Combine(TestUtil.GetSrcPath(), @"../_layout/externals/node12/bin/node");
#endif #endif
string hashFilesScript = Path.Combine(binDir, "hashFiles"); string hashFilesScript = Path.Combine(binDir, "hashFiles");
var hashResult = string.Empty; var hashResult = string.Empty;

View File

@@ -27,9 +27,9 @@ namespace GitHub.Runner.Common.Tests
try try
{ {
#if OS_WINDOWS #if OS_WINDOWS
string node = Path.Combine(TestUtil.GetSrcPath(), @"..\_layout\externals\node16\bin\node"); string node = Path.Combine(TestUtil.GetSrcPath(), @"..\_layout\externals\node12\bin\node");
#else #else
string node = Path.Combine(TestUtil.GetSrcPath(), @"../_layout/externals/node16/bin/node"); string node = Path.Combine(TestUtil.GetSrcPath(), @"../_layout/externals/node12/bin/node");
hc.EnqueueInstance<IProcessInvoker>(new ProcessInvokerWrapper()); hc.EnqueueInstance<IProcessInvoker>(new ProcessInvokerWrapper());
#endif #endif
var startInfo = new ProcessStartInfo(node, "-e \"setTimeout(function(){{}}, 15 * 1000);\""); var startInfo = new ProcessStartInfo(node, "-e \"setTimeout(function(){{}}, 15 * 1000);\"");

View File

@@ -33,7 +33,7 @@ namespace GitHub.Runner.Common.Tests.Worker
using (var hostContext = Setup(featureFlagState: "false")) using (var hostContext = Setup(featureFlagState: "false"))
{ {
var stepSummaryFile = Path.Combine(_rootDirectory, "feature-off"); var stepSummaryFile = Path.Combine(_rootDirectory, "feature-off");
_createStepCommand.ProcessCommand(_executionContext.Object, stepSummaryFile, null); _createStepCommand.ProcessCommand(_executionContext.Object, stepSummaryFile, null);
_jobExecutionContext.Complete(); _jobExecutionContext.Complete();
@@ -117,7 +117,7 @@ namespace GitHub.Runner.Common.Tests.Worker
using (var hostContext = Setup()) using (var hostContext = Setup())
{ {
var stepSummaryFile = Path.Combine(_rootDirectory, "empty-file"); var stepSummaryFile = Path.Combine(_rootDirectory, "empty-file");
File.WriteAllBytes(stepSummaryFile, new byte[CreateStepSummaryCommand.AttachmentSizeLimit + 1]); File.WriteAllBytes(stepSummaryFile, new byte[128 * 1024 + 1]);
_createStepCommand.ProcessCommand(_executionContext.Object, stepSummaryFile, null); _createStepCommand.ProcessCommand(_executionContext.Object, stepSummaryFile, null);
_jobExecutionContext.Complete(); _jobExecutionContext.Complete();

View File

@@ -6,8 +6,6 @@ using System.Threading;
using GitHub.DistributedTask.Pipelines.ContextData; using GitHub.DistributedTask.Pipelines.ContextData;
using GitHub.DistributedTask.WebApi; using GitHub.DistributedTask.WebApi;
using GitHub.Runner.Worker; using GitHub.Runner.Worker;
using GitHub.Runner.Worker.Container;
using GitHub.Runner.Worker.Handlers;
using Moq; using Moq;
using Xunit; using Xunit;
using GitHub.DistributedTask.ObjectTemplating.Tokens; using GitHub.DistributedTask.ObjectTemplating.Tokens;
@@ -726,149 +724,5 @@ namespace GitHub.Runner.Common.Tests.Worker
return hc; return hc;
} }
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void GetExpressionValues_ContainerStepHost()
{
using (TestHostContext hc = CreateTestContext())
{
const string source = "/home/username/Projects/work/runner/_layout";
var containerInfo = new ContainerInfo();
containerInfo.ContainerId = "test";
containerInfo.AddPathTranslateMapping($"{source}/_work", "/__w");
containerInfo.AddPathTranslateMapping($"{source}/_temp", "/__t");
containerInfo.AddPathTranslateMapping($"{source}/externals", "/__e");
containerInfo.AddPathTranslateMapping($"{source}/_work/_temp/_github_home", "/github/home");
containerInfo.AddPathTranslateMapping($"{source}/_work/_temp/_github_workflow", "/github/workflow");
foreach (var v in new List<string>() {
$"{source}/_work",
$"{source}/externals",
$"{source}/_work/_temp",
$"{source}/_work/_actions",
$"{source}/_work/_tool",
})
{
containerInfo.MountVolumes.Add(new MountVolume(v, containerInfo.TranslateToContainerPath(v)));
};
var stepHost = new ContainerStepHost();
stepHost.Container = containerInfo;
var ec = new Runner.Worker.ExecutionContext();
ec.Initialize(hc);
var inputGithubContext = new GitHubContext();
var inputeRunnerContext = new RunnerContext();
// string context data
inputGithubContext["action_path"] = new StringContextData("/home/username/Projects/work/runner/_layout/_work/_actions/owner/composite/main");
inputGithubContext["action"] = new StringContextData("__owner_composite");
inputGithubContext["api_url"] = new StringContextData("https://api.github.com/custom/path");
inputGithubContext["env"] = new StringContextData("/home/username/Projects/work/runner/_layout/_work/_temp/_runner_file_commands/set_env_265698aa-7f38-40f5-9316-5c01a3153672");
inputGithubContext["path"] = new StringContextData("/home/username/Projects/work/runner/_layout/_work/_temp/_runner_file_commands/add_path_265698aa-7f38-40f5-9316-5c01a3153672");
inputGithubContext["event_path"] = new StringContextData("/home/username/Projects/work/runner/_layout/_work/_temp/_github_workflow/event.json");
inputGithubContext["repository"] = new StringContextData("owner/repo-name");
inputGithubContext["run_id"] = new StringContextData("2033211332");
inputGithubContext["workflow"] = new StringContextData("Name of Workflow");
inputGithubContext["workspace"] = new StringContextData("/home/username/Projects/work/runner/_layout/_work/step-order/step-order");
inputeRunnerContext["temp"] = new StringContextData("/home/username/Projects/work/runner/_layout/_work/_temp");
inputeRunnerContext["tool_cache"] = new StringContextData("/home/username/Projects/work/runner/_layout/_work/_tool");
// dictionary context data
var githubEvent = new DictionaryContextData();
githubEvent["inputs"] = null;
githubEvent["ref"] = new StringContextData("refs/heads/main");
githubEvent["repository"] = new DictionaryContextData();
githubEvent["sender"] = new DictionaryContextData();
githubEvent["workflow"] = new StringContextData(".github/workflows/composite_step_host_translate.yaml");
inputGithubContext["event"] = githubEvent;
ec.ExpressionValues["github"] = inputGithubContext;
ec.ExpressionValues["runner"] = inputeRunnerContext;
var ecExpect = new Runner.Worker.ExecutionContext();
ecExpect.Initialize(hc);
var expectedGithubEvent = new DictionaryContextData();
expectedGithubEvent["inputs"] = null;
expectedGithubEvent["ref"] = new StringContextData("refs/heads/main");
expectedGithubEvent["repository"] = new DictionaryContextData();
expectedGithubEvent["sender"] = new DictionaryContextData();
expectedGithubEvent["workflow"] = new StringContextData(".github/workflows/composite_step_host_translate.yaml");
var expectedGithubContext = new GitHubContext();
var expectedRunnerContext = new RunnerContext();
expectedGithubContext["action_path"] = new StringContextData("/__w/_actions/owner/composite/main");
expectedGithubContext["action"] = new StringContextData("__owner_composite");
expectedGithubContext["api_url"] = new StringContextData("https://api.github.com/custom/path");
expectedGithubContext["env"] = new StringContextData("/__w/_temp/_runner_file_commands/set_env_265698aa-7f38-40f5-9316-5c01a3153672");
expectedGithubContext["path"] = new StringContextData("/__w/_temp/_runner_file_commands/add_path_265698aa-7f38-40f5-9316-5c01a3153672");
expectedGithubContext["event_path"] = new StringContextData("/github/workflow/event.json");
expectedGithubContext["repository"] = new StringContextData("owner/repo-name");
expectedGithubContext["run_id"] = new StringContextData("2033211332");
expectedGithubContext["workflow"] = new StringContextData("Name of Workflow");
expectedGithubContext["workspace"] = new StringContextData("/__w/step-order/step-order");
expectedGithubContext["event"] = expectedGithubEvent;
expectedRunnerContext["temp"] = new StringContextData("/__w/_temp");
expectedRunnerContext["tool_cache"] = new StringContextData("/__w/_tool");
ecExpect.ExpressionValues["github"] = expectedGithubContext;
ecExpect.ExpressionValues["runner"] = expectedRunnerContext;
var translatedExpressionValues = ec.GetExpressionValues(stepHost);
foreach (var contextName in new string[] { "github", "runner" })
{
var dict = translatedExpressionValues[contextName].AssertDictionary($"expected context github to be a dictionary");
var expectedExpressionValues = ecExpect.ExpressionValues[contextName].AssertDictionary("expect dict");
foreach (var key in dict.Keys.ToList())
{
if (dict[key] is StringContextData)
{
var expect = dict[key].AssertString("expect string");
var outcome = expectedExpressionValues[key].AssertString("expect string");
Assert.Equal(expect.Value, outcome.Value);
}
else if (dict[key] is DictionaryContextData || dict[key] is CaseSensitiveDictionaryContextData)
{
var expectDict = dict[key].AssertDictionary("expect dict");
var actualDict = expectedExpressionValues[key].AssertDictionary("expect dict");
Assert.True(ExpressionValuesAssertEqual(expectDict, actualDict));
}
}
}
}
}
private bool ExpressionValuesAssertEqual(DictionaryContextData expect, DictionaryContextData actual)
{
foreach (var key in expect.Keys.ToList())
{
if (expect[key] is StringContextData)
{
var expectValue = expect[key].AssertString("expect string");
var actualValue = actual[key].AssertString("expect string");
if (expectValue.Equals(actualValue))
{
return false;
}
}
else if (expect[key] is DictionaryContextData || expect[key] is CaseSensitiveDictionaryContextData)
{
var expectDict = expect[key].AssertDictionary("expect dict");
var actualDict = actual[key].AssertDictionary("expect dict");
if (!ExpressionValuesAssertEqual(expectDict, actualDict))
{
return false;
}
}
}
return true;
}
} }
} }

View File

@@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using GitHub.Runner.Sdk; using GitHub.Runner.Sdk;
using GitHub.Runner.Worker; using GitHub.Runner.Worker;
using GitHub.Runner.Worker.Container; using GitHub.Runner.Worker.Container;
@@ -937,19 +937,6 @@ namespace GitHub.Runner.Common.Tests.Worker
} }
} }
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public void CaptureTelemetryForGitUnsafeRepository()
{
using (Setup())
using (_outputManager)
{
Process("fatal: unsafe repository ('/github/workspace' is owned by someone else)");
Assert.Contains("fatal: unsafe repository ('/github/workspace' is owned by someone else)", _executionContext.Object.StepTelemetry.ErrorMessages);
}
}
private TestHostContext Setup( private TestHostContext Setup(
[CallerMemberName] string name = "", [CallerMemberName] string name = "",
IssueMatchersConfig matchers = null, IssueMatchersConfig matchers = null,
@@ -975,8 +962,6 @@ namespace GitHub.Runner.Common.Tests.Worker
Variables = _variables, Variables = _variables,
WriteDebug = true, WriteDebug = true,
}); });
_executionContext.Setup(x => x.StepTelemetry)
.Returns(new DTWebApi.ActionsStepTelemetry());
_executionContext.Setup(x => x.GetMatchers()) _executionContext.Setup(x => x.GetMatchers())
.Returns(matchers?.Matchers ?? new List<IssueMatcherConfig>()); .Returns(matchers?.Matchers ?? new List<IssueMatcherConfig>());
_executionContext.Setup(x => x.Add(It.IsAny<OnMatcherChanged>())) _executionContext.Setup(x => x.Add(It.IsAny<OnMatcherChanged>()))

View File

@@ -7,9 +7,6 @@ using Xunit;
using GitHub.Runner.Worker; using GitHub.Runner.Worker;
using GitHub.Runner.Worker.Handlers; using GitHub.Runner.Worker.Handlers;
using GitHub.Runner.Worker.Container; using GitHub.Runner.Worker.Container;
using GitHub.DistributedTask.Pipelines.ContextData;
using System.Linq;
using GitHub.DistributedTask.Pipelines;
namespace GitHub.Runner.Common.Tests.Worker namespace GitHub.Runner.Common.Tests.Worker
{ {
@@ -32,7 +29,6 @@ namespace GitHub.Runner.Common.Tests.Worker
return hc; return hc;
} }
#if OS_LINUX
[Fact] [Fact]
[Trait("Level", "L0")] [Trait("Level", "L0")]
[Trait("Category", "Worker")] [Trait("Category", "Worker")]
@@ -109,6 +105,5 @@ namespace GitHub.Runner.Common.Tests.Worker
Assert.Equal("node16", nodeVersion); Assert.Equal("node16", nodeVersion);
} }
} }
#endif
} }
} }

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64</RuntimeIdentifiers> <RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch> <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<NoWarn>NU1701;NU1603;NU1603;xUnit2013;</NoWarn> <NoWarn>NU1701;NU1603;NU1603;xUnit2013;</NoWarn>
</PropertyGroup> </PropertyGroup>

View File

@@ -2,7 +2,7 @@
############################################################################### ###############################################################################
# #
# ./dev.sh build/layout/test/package [Debug/Release] # ./dev.sh build/layout/test/package [Debug/Release] [linux-x64|linux-x86|linux-arm64|linux-arm|osx-x64|win-x64|win-x86] [use-broker]
# #
############################################################################### ###############################################################################
@@ -11,6 +11,7 @@ set -e
DEV_CMD=$1 DEV_CMD=$1
DEV_CONFIG=$2 DEV_CONFIG=$2
DEV_TARGET_RUNTIME=$3 DEV_TARGET_RUNTIME=$3
DEV_USE_BROKER=$4
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LAYOUT_DIR="$SCRIPT_DIR/../_layout" LAYOUT_DIR="$SCRIPT_DIR/../_layout"
@@ -22,7 +23,7 @@ DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
PACKAGE_DIR="$SCRIPT_DIR/../_package" PACKAGE_DIR="$SCRIPT_DIR/../_package"
PACKAGE_TRIMS_DIR="$SCRIPT_DIR/../_package_trims" PACKAGE_TRIMS_DIR="$SCRIPT_DIR/../_package_trims"
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk" DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
DOTNETSDK_VERSION="6.0.300" DOTNETSDK_VERSION="6.0.100"
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION" DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
RUNNER_VERSION=$(cat runnerversion) RUNNER_VERSION=$(cat runnerversion)
@@ -54,12 +55,6 @@ elif [[ "$CURRENT_PLATFORM" == 'linux' ]]; then
fi fi
elif [[ "$CURRENT_PLATFORM" == 'darwin' ]]; then elif [[ "$CURRENT_PLATFORM" == 'darwin' ]]; then
RUNTIME_ID='osx-x64' RUNTIME_ID='osx-x64'
if command -v uname > /dev/null; then
CPU_NAME=$(uname -m)
case $CPU_NAME in
arm64) RUNTIME_ID="osx-arm64";;
esac
fi
fi fi
if [[ -n "$DEV_TARGET_RUNTIME" ]]; then if [[ -n "$DEV_TARGET_RUNTIME" ]]; then
@@ -69,7 +64,7 @@ fi
# Make sure current platform support publish the dotnet runtime # Make sure current platform support publish the dotnet runtime
# Windows can publish win-x86/x64 # Windows can publish win-x86/x64
# Linux can publish linux-x64/arm/arm64 # Linux can publish linux-x64/arm/arm64
# OSX can publish osx-x64/arm64 # OSX can publish osx-x64
if [[ "$CURRENT_PLATFORM" == 'windows' ]]; then if [[ "$CURRENT_PLATFORM" == 'windows' ]]; then
if [[ ("$RUNTIME_ID" != 'win-x86') && ("$RUNTIME_ID" != 'win-x64') ]]; then if [[ ("$RUNTIME_ID" != 'win-x86') && ("$RUNTIME_ID" != 'win-x64') ]]; then
echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2 echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2
@@ -81,12 +76,19 @@ elif [[ "$CURRENT_PLATFORM" == 'linux' ]]; then
exit 1 exit 1
fi fi
elif [[ "$CURRENT_PLATFORM" == 'darwin' ]]; then elif [[ "$CURRENT_PLATFORM" == 'darwin' ]]; then
if [[ ("$RUNTIME_ID" != 'osx-x64') && ("$RUNTIME_ID" != 'osx-arm64') ]]; then if [[ ("$RUNTIME_ID" != 'osx-x64') ]]; then
echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2 echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2
exit 1 exit 1
fi fi
fi fi
if [ -n "$DEV_USE_BROKER" ]; then
USE_BROKER='-p:USE_BROKER="true"'
else
USE_BROKER=''
fi
function failed() function failed()
{ {
local error=${1:-Undefined error} local error=${1:-Undefined error}
@@ -120,13 +122,13 @@ function heading()
function build () function build ()
{ {
heading "Building ..." heading "Building ..."
dotnet msbuild -t:Build -p:PackageRuntime="${RUNTIME_ID}" -p:BUILDCONFIG="${BUILD_CONFIG}" -p:RunnerVersion="${RUNNER_VERSION}" ./dir.proj || failed build dotnet msbuild -t:Build -p:PackageRuntime="${RUNTIME_ID}" -p:BUILDCONFIG="${BUILD_CONFIG}" -p:RunnerVersion="${RUNNER_VERSION}" $USE_BROKER ./dir.proj || failed build
} }
function layout () function layout ()
{ {
heading "Create layout ..." heading "Create layout ..."
dotnet msbuild -t:layout -p:PackageRuntime="${RUNTIME_ID}" -p:BUILDCONFIG="${BUILD_CONFIG}" -p:RunnerVersion="${RUNNER_VERSION}" ./dir.proj || failed build dotnet msbuild -t:layout -p:PackageRuntime="${RUNTIME_ID}" -p:BUILDCONFIG="${BUILD_CONFIG}" -p:RunnerVersion="${RUNNER_VERSION}" $USE_BROKER ./dir.proj || failed build
#change execution flag to allow running with sudo #change execution flag to allow running with sudo
if [[ ("$CURRENT_PLATFORM" == "linux") || ("$CURRENT_PLATFORM" == "darwin") ]]; then if [[ ("$CURRENT_PLATFORM" == "linux") || ("$CURRENT_PLATFORM" == "darwin") ]]; then

View File

@@ -48,7 +48,7 @@
<Target Name="Test" DependsOnTargets="GenerateConstant"> <Target Name="Test" DependsOnTargets="GenerateConstant">
<Exec Command="dotnet build Test/Test.csproj -c $(BUILDCONFIG) /p:PackageRuntime=$(PackageRuntime)" ConsoleToMSBuild="true" /> <Exec Command="dotnet build Test/Test.csproj -c $(BUILDCONFIG) /p:PackageRuntime=$(PackageRuntime)" ConsoleToMSBuild="true" />
<Exec Command="dotnet test Test/Test.csproj -c $(BUILDCONFIG) --no-build --logger:trx" ConsoleToMSBuild="true" /> <Exec Command="dotnet test Test/Test.csproj --no-build --logger:trx" ConsoleToMSBuild="true" />
</Target> </Target>
<Target Name="Layout" DependsOnTargets="Clean;Build"> <Target Name="Layout" DependsOnTargets="Clean;Build">

View File

@@ -1,5 +1,5 @@
{ {
"sdk": { "sdk": {
"version": "6.0.300" "version": "6.0.100"
} }
} }

View File

@@ -1 +1 @@
2.292.0 2.289.2