mirror of
https://github.com/actions/runner.git
synced 2025-12-10 20:36:49 +00:00
Compare commits
2 Commits
v2.301.1
...
thboop/upd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62036ccdc0 | ||
|
|
82a4ca9a6b |
@@ -1,27 +0,0 @@
|
|||||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
|
||||||
{
|
|
||||||
"name": "Actions Runner Devcontainer",
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:focal",
|
|
||||||
"features": {
|
|
||||||
"ghcr.io/devcontainers/features/docker-in-docker:1": {},
|
|
||||||
"ghcr.io/devcontainers/features/dotnet": {
|
|
||||||
"version": "6.0.300"
|
|
||||||
},
|
|
||||||
"ghcr.io/devcontainers/features/node:1": {
|
|
||||||
"version": "16"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-azuretools.vscode-docker",
|
|
||||||
"ms-dotnettools.csharp",
|
|
||||||
"eamodio.gitlens"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// dotnet restore to install dependencies so OmniSharp works out of the box
|
|
||||||
// src/Test restores all other projects it references, src/Runner.PluginHost is not one of them
|
|
||||||
"postCreateCommand": "dotnet restore src/Test && dotnet restore src/Runner.PluginHost",
|
|
||||||
"remoteUser": "vscode"
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
# https://editorconfig.org/
|
# https://editorconfig.org/
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8 # Set default charset to utf-8
|
|
||||||
insert_final_newline = true # ensure all files end with a single newline
|
insert_final_newline = true # ensure all files end with a single newline
|
||||||
trim_trailing_whitespace = true # attempt to remove trailing whitespace on save
|
trim_trailing_whitespace = true # attempt to remove trailing whitespace on save
|
||||||
|
|
||||||
|
|||||||
3
.github/ISSUE_TEMPLATE/config.yml
vendored
3
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,5 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: 🛑 Request a feature in the runner application
|
|
||||||
url: https://github.com/orgs/community/discussions/categories/actions-and-packages
|
|
||||||
about: If you have feature requests for GitHub Actions, please use the Actions and Packages section on the Github Product Feedback page.
|
|
||||||
- name: ✅ Support for GitHub Actions
|
- name: ✅ Support for GitHub Actions
|
||||||
url: https://github.community/c/code-to-cloud/52
|
url: https://github.community/c/code-to-cloud/52
|
||||||
about: If you have questions about GitHub Actions or need support writing workflows, please ask in the GitHub Community Support forum.
|
about: If you have questions about GitHub Actions or need support writing workflows, please ask in the GitHub Community Support forum.
|
||||||
|
|||||||
32
.github/ISSUE_TEMPLATE/enhancement_request.md
vendored
Normal file
32
.github/ISSUE_TEMPLATE/enhancement_request.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: 🛑 Request a feature in the runner application
|
||||||
|
about: If you have feature requests for GitHub Actions, please use the "feedback and suggestions for GitHub Actions" link below.
|
||||||
|
title: ''
|
||||||
|
labels: enhancement
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
👋 You're opening a request for an enhancement in the GitHub Actions **runner application**.
|
||||||
|
|
||||||
|
🛑 Please stop if you're not certain that the feature you want is in the runner application - if you have a suggestion for improving GitHub Actions, please see the [GitHub Actions Feedback](https://github.com/github/feedback/discussions/categories/actions-and-packages-feedback) discussion forum which is actively monitored. Using the forum ensures that we route your problem to the correct team. 😃
|
||||||
|
|
||||||
|
Some additional useful links:
|
||||||
|
* If you have found a security issue [please submit it here](https://hackerone.com/github)
|
||||||
|
* If you have questions or issues with the service, writing workflows or actions, then please [visit the GitHub Community Forum's Actions Board](https://github.community/t5/GitHub-Actions/bd-p/actions)
|
||||||
|
* If you are having an issue or have a question about GitHub Actions then please [contact customer support](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-github-actions#contacting-support)
|
||||||
|
|
||||||
|
If you have a feature request that is relevant to this repository, the runner, then please include the information below:
|
||||||
|
-->
|
||||||
|
|
||||||
|
**Describe the enhancement**
|
||||||
|
A clear and concise description of what the features or enhancement you need.
|
||||||
|
|
||||||
|
**Code Snippet**
|
||||||
|
If applicable, add a code snippet.
|
||||||
|
|
||||||
|
**Additional information**
|
||||||
|
Add any other context about the feature here.
|
||||||
|
|
||||||
|
NOTE: if the feature request has been agreed upon then the assignee will create an ADR. See docs/adrs/README.md
|
||||||
16
.github/workflows/build.yml
vendored
16
.github/workflows/build.yml
vendored
@@ -10,7 +10,7 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- '**'
|
- '*'
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, win-arm64, osx-x64, osx-arm64 ]
|
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64 ]
|
||||||
include:
|
include:
|
||||||
- runtime: linux-x64
|
- runtime: linux-x64
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
@@ -36,21 +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
|
||||||
|
|
||||||
- runtime: win-arm64
|
|
||||||
os: windows-latest
|
|
||||||
devScript: ./dev
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
# Build runner layout
|
# Build runner layout
|
||||||
- name: Build & Layout Release
|
- name: Build & Layout Release
|
||||||
@@ -86,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' && matrix.runtime != 'win-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
|
||||||
|
|||||||
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@@ -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
|
||||||
|
|||||||
25
.github/workflows/lint.yml
vendored
25
.github/workflows/lint.yml
vendored
@@ -1,25 +0,0 @@
|
|||||||
name: Lint
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [ main ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Lint
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
# Ensure full list of changed files within `super-linter`
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Run linters
|
|
||||||
uses: github/super-linter@v4
|
|
||||||
env:
|
|
||||||
DEFAULT_BRANCH: ${{ github.base_ref }}
|
|
||||||
DISABLE_ERRORS: true
|
|
||||||
EDITORCONFIG_FILE_NAME: .editorconfig
|
|
||||||
LINTER_RULES_PATH: /src/
|
|
||||||
VALIDATE_ALL_CODEBASE: false
|
|
||||||
VALIDATE_CSHARP: true
|
|
||||||
65
.github/workflows/publish-image.yml
vendored
65
.github/workflows/publish-image.yml
vendored
@@ -1,65 +0,0 @@
|
|||||||
name: Publish Runner Image
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
runnerVersion:
|
|
||||||
type: string
|
|
||||||
description: Version of the runner being installed
|
|
||||||
|
|
||||||
env:
|
|
||||||
REGISTRY: ghcr.io
|
|
||||||
IMAGE_NAME: ${{ github.repository_owner }}/actions-runner
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Compute image version
|
|
||||||
id: image
|
|
||||||
uses: actions/github-script@v6
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const fs = require('fs');
|
|
||||||
const inputRunnerVersion = "${{ github.event.inputs.runnerVersion }}"
|
|
||||||
if (inputRunnerVersion) {
|
|
||||||
console.log(`Using input runner version ${inputRunnerVersion}`)
|
|
||||||
core.setOutput('version', inputRunnerVersion);
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const runnerVersion = fs.readFileSync('${{ github.workspace }}/src/runnerversion', 'utf8').replace(/\n$/g, '')
|
|
||||||
console.log(`Using runner version ${runnerVersion}`)
|
|
||||||
core.setOutput('version', runnerVersion);
|
|
||||||
|
|
||||||
- name: Setup Docker buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
|
|
||||||
- name: Log into registry ${{ env.REGISTRY }}
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
registry: ${{ env.REGISTRY }}
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Build and push Docker image
|
|
||||||
id: build-and-push
|
|
||||||
uses: docker/build-push-action@v3
|
|
||||||
with:
|
|
||||||
context: ./images
|
|
||||||
tags: |
|
|
||||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.image.outputs.version }}
|
|
||||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
|
||||||
build-args: |
|
|
||||||
RUNNER_VERSION=${{ steps.image.outputs.version }}
|
|
||||||
push: true
|
|
||||||
labels: |
|
|
||||||
org.opencontainers.image.source=${{github.server_url}}/${{github.repository}}
|
|
||||||
org.opencontainers.image.description=https://github.com/actions/runner/releases/tag/v${{ steps.image.outputs.version }}
|
|
||||||
org.opencontainers.image.licenses=MIT
|
|
||||||
198
.github/workflows/release.yml
vendored
198
.github/workflows/release.yml
vendored
@@ -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
|
||||||
@@ -50,33 +50,25 @@ jobs:
|
|||||||
linux-arm64-sha: ${{ steps.sha.outputs.linux-arm64-sha256 }}
|
linux-arm64-sha: ${{ steps.sha.outputs.linux-arm64-sha256 }}
|
||||||
linux-arm-sha: ${{ steps.sha.outputs.linux-arm-sha256 }}
|
linux-arm-sha: ${{ steps.sha.outputs.linux-arm-sha256 }}
|
||||||
win-x64-sha: ${{ steps.sha.outputs.win-x64-sha256 }}
|
win-x64-sha: ${{ steps.sha.outputs.win-x64-sha256 }}
|
||||||
win-arm64-sha: ${{ steps.sha.outputs.win-arm64-sha256 }}
|
|
||||||
osx-x64-sha: ${{ steps.sha.outputs.osx-x64-sha256 }}
|
osx-x64-sha: ${{ steps.sha.outputs.osx-x64-sha256 }}
|
||||||
osx-arm64-sha: ${{ steps.sha.outputs.osx-arm64-sha256 }}
|
|
||||||
linux-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-x64-sha256 }}
|
linux-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-x64-sha256 }}
|
||||||
linux-arm64-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-arm64-sha256 }}
|
linux-arm64-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-arm64-sha256 }}
|
||||||
linux-arm-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-arm-sha256 }}
|
linux-arm-sha-noexternals: ${{ steps.sha_noexternals.outputs.linux-arm-sha256 }}
|
||||||
win-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.win-x64-sha256 }}
|
win-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.win-x64-sha256 }}
|
||||||
win-arm64-sha-noexternals: ${{ steps.sha_noexternals.outputs.win-arm64-sha256 }}
|
|
||||||
osx-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.osx-x64-sha256 }}
|
osx-x64-sha-noexternals: ${{ steps.sha_noexternals.outputs.osx-x64-sha256 }}
|
||||||
osx-arm64-sha-noexternals: ${{ steps.sha_noexternals.outputs.osx-arm64-sha256 }}
|
|
||||||
linux-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-x64-sha256 }}
|
linux-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-x64-sha256 }}
|
||||||
linux-arm64-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-arm64-sha256 }}
|
linux-arm64-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-arm64-sha256 }}
|
||||||
linux-arm-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-arm-sha256 }}
|
linux-arm-sha-noruntime: ${{ steps.sha_noruntime.outputs.linux-arm-sha256 }}
|
||||||
win-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.win-x64-sha256 }}
|
win-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.win-x64-sha256 }}
|
||||||
win-arm64-sha-noruntime: ${{ steps.sha_noruntime.outputs.win-arm64-sha256 }}
|
|
||||||
osx-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.osx-x64-sha256 }}
|
osx-x64-sha-noruntime: ${{ steps.sha_noruntime.outputs.osx-x64-sha256 }}
|
||||||
osx-arm64-sha-noruntime: ${{ steps.sha_noruntime.outputs.osx-arm64-sha256 }}
|
|
||||||
linux-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-x64-sha256 }}
|
linux-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-x64-sha256 }}
|
||||||
linux-arm64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-arm64-sha256 }}
|
linux-arm64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-arm64-sha256 }}
|
||||||
linux-arm-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-arm-sha256 }}
|
linux-arm-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.linux-arm-sha256 }}
|
||||||
win-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.win-x64-sha256 }}
|
win-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.win-x64-sha256 }}
|
||||||
win-arm64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.win-arm64-sha256 }}
|
|
||||||
osx-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.osx-x64-sha256 }}
|
osx-x64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.osx-x64-sha256 }}
|
||||||
osx-arm64-sha-noruntime-noexternals: ${{ steps.sha_noruntime_noexternals.outputs.osx-arm64-sha256 }}
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64, osx-arm64, win-arm64 ]
|
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64 ]
|
||||||
include:
|
include:
|
||||||
- runtime: linux-x64
|
- runtime: linux-x64
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
@@ -94,21 +86,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
|
||||||
|
|
||||||
- runtime: win-arm64
|
|
||||||
os: windows-latest
|
|
||||||
devScript: ./dev
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
# Build runner layout
|
# Build runner layout
|
||||||
- name: Build & Layout Release
|
- name: Build & Layout Release
|
||||||
@@ -116,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'
|
||||||
@@ -168,7 +159,7 @@ jobs:
|
|||||||
working-directory: _package_trims/trim_runtime_externals
|
working-directory: _package_trims/trim_runtime_externals
|
||||||
|
|
||||||
- name: Create trimmedpackages.json for ${{ matrix.runtime }}
|
- name: Create trimmedpackages.json for ${{ matrix.runtime }}
|
||||||
if: matrix.runtime == 'win-x64' || matrix.runtime == 'win-arm64'
|
if: matrix.runtime == 'win-x64'
|
||||||
uses: actions/github-script@0.3.0
|
uses: actions/github-script@0.3.0
|
||||||
with:
|
with:
|
||||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||||
@@ -188,7 +179,7 @@ jobs:
|
|||||||
fs.writeFileSync('${{ matrix.runtime }}-trimmedpackages.json', trimmedPackages)
|
fs.writeFileSync('${{ matrix.runtime }}-trimmedpackages.json', trimmedPackages)
|
||||||
|
|
||||||
- name: Create trimmedpackages.json for ${{ matrix.runtime }}
|
- name: Create trimmedpackages.json for ${{ matrix.runtime }}
|
||||||
if: matrix.runtime != 'win-x64' && matrix.runtime != 'win-arm64'
|
if: matrix.runtime != 'win-x64'
|
||||||
uses: actions/github-script@0.3.0
|
uses: actions/github-script@0.3.0
|
||||||
with:
|
with:
|
||||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||||
@@ -226,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
|
||||||
@@ -247,30 +238,22 @@ jobs:
|
|||||||
const runnerVersion = fs.readFileSync('${{ github.workspace }}/src/runnerversion', 'utf8').replace(/\n$/g, '')
|
const runnerVersion = fs.readFileSync('${{ github.workspace }}/src/runnerversion', 'utf8').replace(/\n$/g, '')
|
||||||
var releaseNote = fs.readFileSync('${{ github.workspace }}/releaseNote.md', 'utf8').replace(/<RUNNER_VERSION>/g, runnerVersion)
|
var releaseNote = fs.readFileSync('${{ github.workspace }}/releaseNote.md', 'utf8').replace(/<RUNNER_VERSION>/g, runnerVersion)
|
||||||
releaseNote = releaseNote.replace(/<WIN_X64_SHA>/g, '${{needs.build.outputs.win-x64-sha}}')
|
releaseNote = releaseNote.replace(/<WIN_X64_SHA>/g, '${{needs.build.outputs.win-x64-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA>/g, '${{needs.build.outputs.win-arm64-sha}}')
|
|
||||||
releaseNote = releaseNote.replace(/<OSX_X64_SHA>/g, '${{needs.build.outputs.osx-x64-sha}}')
|
releaseNote = releaseNote.replace(/<OSX_X64_SHA>/g, '${{needs.build.outputs.osx-x64-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA>/g, '${{needs.build.outputs.osx-arm64-sha}}')
|
|
||||||
releaseNote = releaseNote.replace(/<LINUX_X64_SHA>/g, '${{needs.build.outputs.linux-x64-sha}}')
|
releaseNote = releaseNote.replace(/<LINUX_X64_SHA>/g, '${{needs.build.outputs.linux-x64-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA>/g, '${{needs.build.outputs.linux-arm-sha}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA>/g, '${{needs.build.outputs.linux-arm-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA>/g, '${{needs.build.outputs.linux-arm64-sha}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA>/g, '${{needs.build.outputs.linux-arm64-sha}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.win-x64-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.win-x64-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.win-arm64-sha-noexternals}}')
|
|
||||||
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.osx-x64-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.osx-x64-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.osx-arm64-sha-noexternals}}')
|
|
||||||
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-x64-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-x64-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm64-sha-noexternals}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NOEXTERNALS>/g, '${{needs.build.outputs.linux-arm64-sha-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.win-x64-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.win-x64-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.win-arm64-sha-noruntime}}')
|
|
||||||
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.osx-x64-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.osx-x64-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.osx-arm64-sha-noruntime}}')
|
|
||||||
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-x64-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<LINUX_X64_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-x64-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-arm-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-arm-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-arm64-sha-noruntime}}')
|
releaseNote = releaseNote.replace(/<LINUX_ARM64_SHA_NORUNTIME>/g, '${{needs.build.outputs.linux-arm64-sha-noruntime}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.win-x64-sha-noruntime-noexternals}}')
|
releaseNote = releaseNote.replace(/<WIN_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.win-x64-sha-noruntime-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<WIN_ARM64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.win-arm64-sha-noruntime-noexternals}}')
|
|
||||||
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.osx-x64-sha-noruntime-noexternals}}')
|
releaseNote = releaseNote.replace(/<OSX_X64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.osx-x64-sha-noruntime-noexternals}}')
|
||||||
releaseNote = releaseNote.replace(/<OSX_ARM64_SHA_NORUNTIME_NOEXTERNALS>/g, '${{needs.build.outputs.osx-arm64-sha-noruntime-noexternals}}')
|
|
||||||
releaseNote = releaseNote.replace(/<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}}')
|
||||||
@@ -283,9 +266,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
ls -l
|
ls -l
|
||||||
echo "${{needs.build.outputs.win-x64-sha}} actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip" | shasum -a 256 -c
|
echo "${{needs.build.outputs.win-x64-sha}} actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip" | shasum -a 256 -c
|
||||||
echo "${{needs.build.outputs.win-arm64-sha}} actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}.zip" | shasum -a 256 -c
|
|
||||||
echo "${{needs.build.outputs.osx-x64-sha}} actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
|
echo "${{needs.build.outputs.osx-x64-sha}} actions-runner-osx-x64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
|
||||||
echo "${{needs.build.outputs.osx-arm64-sha}} actions-runner-osx-arm64-${{ steps.releaseNote.outputs.version }}.tar.gz" | shasum -a 256 -c
|
|
||||||
echo "${{needs.build.outputs.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
|
||||||
@@ -313,16 +294,6 @@ jobs:
|
|||||||
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip
|
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}.zip
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
- name: Upload Release Asset (win-arm64)
|
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/_package/actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}.zip
|
|
||||||
asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}.zip
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Release Asset (linux-x64)
|
- name: Upload Release Asset (linux-x64)
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
env:
|
env:
|
||||||
@@ -343,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:
|
||||||
@@ -384,17 +345,6 @@ jobs:
|
|||||||
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noexternals.zip
|
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noexternals.zip
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
# Upload release assets (trim externals)
|
|
||||||
- name: Upload Release Asset (win-arm64-noexternals)
|
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/_package_trims/trim_externals/actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noexternals.zip
|
|
||||||
asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noexternals.zip
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Release Asset (linux-x64-noexternals)
|
- name: Upload Release Asset (linux-x64-noexternals)
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
env:
|
env:
|
||||||
@@ -415,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:
|
||||||
@@ -456,17 +396,6 @@ jobs:
|
|||||||
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noruntime.zip
|
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noruntime.zip
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
# Upload release assets (trim runtime)
|
|
||||||
- name: Upload Release Asset (win-arm64-noruntime)
|
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/_package_trims/trim_runtime/actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noruntime.zip
|
|
||||||
asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noruntime.zip
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Release Asset (linux-x64-noruntime)
|
- name: Upload Release Asset (linux-x64-noruntime)
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
env:
|
env:
|
||||||
@@ -487,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:
|
||||||
@@ -528,17 +447,6 @@ jobs:
|
|||||||
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.zip
|
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.zip
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
# Upload release assets (trim runtime and externals)
|
|
||||||
- name: Upload Release Asset (win-arm64-noruntime-noexternals)
|
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/_package_trims/trim_runtime_externals/actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.zip
|
|
||||||
asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-noruntime-noexternals.zip
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Release Asset (linux-x64-noruntime-noexternals)
|
- name: Upload Release Asset (linux-x64-noruntime-noexternals)
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
env:
|
env:
|
||||||
@@ -559,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:
|
||||||
@@ -600,17 +498,6 @@ jobs:
|
|||||||
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json
|
asset_name: actions-runner-win-x64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
# Upload release assets (trimmedpackages.json)
|
|
||||||
- name: Upload Release Asset (win-arm64-trimmedpackages.json)
|
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.createRelease.outputs.upload_url }}
|
|
||||||
asset_path: ${{ github.workspace }}/win-arm64-trimmedpackages.json
|
|
||||||
asset_name: actions-runner-win-arm64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json
|
|
||||||
asset_content_type: application/octet-stream
|
|
||||||
|
|
||||||
- name: Upload Release Asset (linux-x64-trimmedpackages.json)
|
- name: Upload Release Asset (linux-x64-trimmedpackages.json)
|
||||||
uses: actions/upload-release-asset@v1.0.1
|
uses: actions/upload-release-asset@v1.0.1
|
||||||
env:
|
env:
|
||||||
@@ -631,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:
|
||||||
@@ -660,52 +537,3 @@ jobs:
|
|||||||
asset_path: ${{ github.workspace }}/linux-arm64-trimmedpackages.json
|
asset_path: ${{ github.workspace }}/linux-arm64-trimmedpackages.json
|
||||||
asset_name: actions-runner-linux-arm64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json
|
asset_name: actions-runner-linux-arm64-${{ steps.releaseNote.outputs.version }}-trimmedpackages.json
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
|
|
||||||
publish-image:
|
|
||||||
needs: release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
env:
|
|
||||||
REGISTRY: ghcr.io
|
|
||||||
IMAGE_NAME: ${{ github.repository_owner }}/actions-runner
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Compute image version
|
|
||||||
id: image
|
|
||||||
uses: actions/github-script@v6
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const fs = require('fs');
|
|
||||||
const runnerVersion = fs.readFileSync('${{ github.workspace }}/releaseVersion', 'utf8').replace(/\n$/g, '')
|
|
||||||
console.log(`Using runner version ${runnerVersion}`)
|
|
||||||
core.setOutput('version', runnerVersion);
|
|
||||||
|
|
||||||
- name: Setup Docker buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
|
|
||||||
- name: Log into registry ${{ env.REGISTRY }}
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
registry: ${{ env.REGISTRY }}
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Build and push Docker image
|
|
||||||
id: build-and-push
|
|
||||||
uses: docker/build-push-action@v3
|
|
||||||
with:
|
|
||||||
context: ./images
|
|
||||||
tags: |
|
|
||||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.image.outputs.version }}
|
|
||||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
|
||||||
build-args: |
|
|
||||||
RUNNER_VERSION=${{ steps.image.outputs.version }}
|
|
||||||
push: true
|
|
||||||
labels: |
|
|
||||||
org.opencontainers.image.source=${{github.server_url}}/${{github.repository}}
|
|
||||||
org.opencontainers.image.description=https://github.com/actions/runner/releases/tag/v${{ steps.image.outputs.version }}
|
|
||||||
org.opencontainers.image.licenses=MIT
|
|
||||||
|
|||||||
15
.vscode/launch.json
vendored
15
.vscode/launch.json
vendored
@@ -12,7 +12,8 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceFolder}/src",
|
"cwd": "${workspaceFolder}/src",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"requireExactSource": false
|
"requireExactSource": false,
|
||||||
|
"targetArchitecture": "x86_64"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Run",
|
"name": "Run",
|
||||||
@@ -24,7 +25,8 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceFolder}/src",
|
"cwd": "${workspaceFolder}/src",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"requireExactSource": false
|
"requireExactSource": false,
|
||||||
|
"targetArchitecture": "x86_64"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Configure",
|
"name": "Configure",
|
||||||
@@ -37,21 +39,24 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceFolder}/src",
|
"cwd": "${workspaceFolder}/src",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"requireExactSource": false
|
"requireExactSource": false,
|
||||||
|
"targetArchitecture": "x86_64"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Debug Worker",
|
"name": "Debug Worker",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "attach",
|
"request": "attach",
|
||||||
"processName": "Runner.Worker",
|
"processName": "Runner.Worker",
|
||||||
"requireExactSource": false
|
"requireExactSource": false,
|
||||||
|
"targetArchitecture": "x86_64"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Attach Debugger",
|
"name": "Attach Debugger",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "attach",
|
"request": "attach",
|
||||||
"processId": "${command:pickProcess}",
|
"processId": "${command:pickProcess}",
|
||||||
"requireExactSource": false
|
"requireExactSource": false,
|
||||||
|
"targetArchitecture": "x86_64"
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,4 +22,4 @@ Runner releases:
|
|||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
We accept contributions in the form of issues and pull requests. The runner typically requires changes across the entire system and we aim for issues in the runner to be entirely self contained and fixable here. Therefore, we will primarily handle bug issues opened in this repo and we kindly request you to create all feature and enhancement requests on the [GitHub Feedback](https://github.com/community/community/discussions/categories/actions-and-packages) page. [Read more about our guidelines here](docs/contribute.md) before contributing.
|
We accept contributions in the form of issues and pull requests. [Read more here](docs/contribute.md) before contributing.
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -1,596 +0,0 @@
|
|||||||
# ADR 0000: Container Hooks
|
|
||||||
|
|
||||||
**Date**: 2022-05-12
|
|
||||||
|
|
||||||
**Status**: Accepted
|
|
||||||
|
|
||||||
# Background
|
|
||||||
|
|
||||||
[Job Hooks](https://github.com/actions/runner/blob/main/docs/adrs/1751-runner-job-hooks.md) have given users the ability to customize how their self hosted runners run a job.
|
|
||||||
Users also want the ability to customize how they run containers during the scope of the job, rather then being locked into the docker implementation we have in the runner. They may want to use podman, kubernetes, or even change the docker commands we run.
|
|
||||||
We should give them that option, and publish examples how how they can create their own hooks.
|
|
||||||
|
|
||||||
# Guiding Principles
|
|
||||||
- **Extensibility** is the focus, we need to make sure we are flexible enough to cover current and future scenarios, even at the cost of making it harder to utilize these hooks
|
|
||||||
- Args should map **directly** to yaml values provided by the user.
|
|
||||||
- For example, the current runner overrides `HOME`, we can do that in the hook, but we shouldn't pass that hook as an ENV with the other env's the user has set, as that is not user input, it is how the runner invokes containers
|
|
||||||
|
|
||||||
## Interface
|
|
||||||
- You will set the variable `ACTIONS_RUNNER_CONTAINER_HOOKS=/Users/foo/runner/hooks.js` which is the entrypoint to your hook handler.
|
|
||||||
- There is no partial opt in, you must handle every hook
|
|
||||||
- We will pass a command and some args via `stdin`
|
|
||||||
- An exit code of 0 is a success, every other exit code is a failure
|
|
||||||
- We will support the same runner commands we support in [Job Hooks](https://github.com/actions/runner/blob/main/docs/adrs/1751-runner-job-hooks.md)
|
|
||||||
- On timeout, we will send a sigint to your process. If you fail to terminate within a reasonable amount of time, we will send a sigkill, and eventually kill the process tree.
|
|
||||||
|
|
||||||
An example input looks like
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"command": "job_cleanup",
|
|
||||||
"responseFile": "/users/thboop/runner/_work/{guid}.json",
|
|
||||||
"args": {},
|
|
||||||
"state":
|
|
||||||
{
|
|
||||||
"id": "82e8219701fe096a35941d869cf8d71af1d943b5d3bdd718850fb87ac3042480"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`command` is the command we expect you to invoke
|
|
||||||
`responseFile` is the file you need to write your output to, if the command has output
|
|
||||||
`args` are the specific arguments the command needs
|
|
||||||
`state` is a json blog you can pass around to maintain your state, this is covered in more details below.
|
|
||||||
|
|
||||||
### Writing responses to a file
|
|
||||||
All text written to stdout or stderr should appear in the job or step logs. With that in mind, we support a few ways to actually return data:
|
|
||||||
1. Wrapping the json in some unique tag and processing it like we do commands
|
|
||||||
2. Writing to a file
|
|
||||||
|
|
||||||
For 1, users typically view logging information as a safe action, so we worry someone accidentialy logging unsantized information and causing unexpected or un-secure behavior. We eventually plan to move off of stdout/stderr style commands in favor of a runner cli.
|
|
||||||
Investing in this area doesn't make a lot of sense at this time.
|
|
||||||
|
|
||||||
While writing to a file to communicate isn't the most ideal pattern, its an existing pattern in the runner and serves us well, so lets reuse it.
|
|
||||||
|
|
||||||
### Output
|
|
||||||
Your output must be correctly formatted json. An example output looks like:
|
|
||||||
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"state": {},
|
|
||||||
"context"
|
|
||||||
{
|
|
||||||
"container" :
|
|
||||||
{
|
|
||||||
"id": "82e8219701fe096a35941d869cf8d71af1d943b5d3bdd718850fb87ac3042480"
|
|
||||||
"network": "github_network_53269bd575974817b43f4733536b200c"
|
|
||||||
}
|
|
||||||
"services": {
|
|
||||||
"redis": {
|
|
||||||
"id": "60972d9aa486605e66b0dad4abb638dc3d9116f566579e418166eedb8abb9105",
|
|
||||||
"ports": {
|
|
||||||
"8080": "8080"
|
|
||||||
},
|
|
||||||
"network": "github_network_53269bd575974817b43f4733536b200c"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"alpine: true,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`state` is a unique field any command can return. If it is not empty, we will store the state for you and pass it into all future commands. You can overwrite it by having the next hook invoked return a unique state.
|
|
||||||
|
|
||||||
Other fields are dependent upon the command being run.
|
|
||||||
|
|
||||||
### Versioning
|
|
||||||
We will not version these hooks at launch. If needed, we can always major version split these hooks in the future. We will ship in Beta to allow for breaking changes for a few months.
|
|
||||||
|
|
||||||
### The Job Context
|
|
||||||
The [job context](https://docs.github.com/en/actions/learn-github-actions/contexts#example-contents-of-the-job-context) currently has a variety of fields that correspond to containers. We should consider allowing hooks to populate new fields in the job context. That is out of scope for this original release however.
|
|
||||||
|
|
||||||
## Hooks
|
|
||||||
Hooks are to be implemented at a very high level, and map to actions the runner does, rather then specific docker actions like `docker build` or `docker create`. By mapping to runner actions, we create a very extensible framework that is flexible enough to solve any user concerns in the future. By providing first party implementations, we give users easy starting points to customize specific hooks (like `docker build`) without having to write full blown solutions.
|
|
||||||
|
|
||||||
The other would be to provide hooks that mirror every docker call we make, and expose more hooks to help support k8s users, with the expectation that users may have to no-op on multiple hooks if they don't correspond to our use case.
|
|
||||||
|
|
||||||
Why we don't want to go that way
|
|
||||||
- It feels clunky, users need to understand which hooks they need to implement and which they can ignore, which isn't a great UX
|
|
||||||
- It doesn't scale well, I don't want to build a solution where we may need to add more hooks, by mapping to runner actions, updating hooks is a painful experience for users
|
|
||||||
- Its overwhelming, its easier to tell users to build 4 hooks and track data themselves, rather then 16 hooks where the runner needs certain information and then needs to provide that information back into each hook. If we expose `Container Create`, you need to return the container you created, then we do `container run` which uses that container. If we just give you an image and say create and run this container, you don't need to store the container id in the runner, and it maps better to k8s scenarios where we don't really have container ids.
|
|
||||||
|
|
||||||
### Prepare_job hook
|
|
||||||
The `prepare_job` hook is called when a job is started. We pass in any job or service containers the job has. We expect that you:
|
|
||||||
- Prune anything from previous jobs if needed
|
|
||||||
- Create a network if needed
|
|
||||||
- Pull the job and service containers
|
|
||||||
- Start the job container
|
|
||||||
- Start the service containers
|
|
||||||
- Write to the response file some information we need
|
|
||||||
- Required: if the container is alpine, otherwise x64
|
|
||||||
- Optional: any context fields you want to set on the job context, otherwise they will be unavailable for users to use
|
|
||||||
- Return 0 when the health checks have succeeded and the job/service containers are started
|
|
||||||
|
|
||||||
This hook will **always** be called if you have container hooks enabled, even if no service or job containers exist in the job. This allows you to fail the job or implement a default job container if you want to and no job container has been provided.
|
|
||||||
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Example Input</summary>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"command": "prepare_job",
|
|
||||||
"responseFile": "/users/thboop/runner/_work/{guid}.json",
|
|
||||||
"state": {},
|
|
||||||
"args":
|
|
||||||
{
|
|
||||||
"jobContainer": {
|
|
||||||
"image": "node:14.16",
|
|
||||||
"workingDirectory": "/__w/thboop-test2/thboop-test2",
|
|
||||||
"createOptions": "--cpus 1",
|
|
||||||
"environmentVariables": {
|
|
||||||
"NODE_ENV": "development"
|
|
||||||
},
|
|
||||||
"userMountVolumes:[
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "my_docker_volume",
|
|
||||||
"targetVolumePath": "/volume_mount",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"mountVolumes": [
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work",
|
|
||||||
"targetVolumePath": "/__w",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/externals",
|
|
||||||
"targetVolumePath": "/__e",
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_temp",
|
|
||||||
"targetVolumePath": "/__w/_temp",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_actions",
|
|
||||||
"targetVolumePath": "/__w/_actions",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_tool",
|
|
||||||
"targetVolumePath": "/__w/_tool",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_temp/_github_home",
|
|
||||||
"targetVolumePath": "/github/home",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_temp/_github_workflow",
|
|
||||||
"targetVolumePath": "/github/workflow",
|
|
||||||
"readOnly": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"registry": {
|
|
||||||
"username": "foo",
|
|
||||||
"password": "bar",
|
|
||||||
"serverUrl": "https://index.docker.io/v1"
|
|
||||||
},
|
|
||||||
"portMappings": [ "8080:80/tcp", "8080:80/udp" ]
|
|
||||||
},
|
|
||||||
"services": [
|
|
||||||
{
|
|
||||||
"contextName": "redis",
|
|
||||||
"image": "redis",
|
|
||||||
"createOptions": "--cpus 1",
|
|
||||||
"environmentVariables": {},
|
|
||||||
"mountVolumes": [],
|
|
||||||
"portMappings": [ "8080:80/tcp", "8080:80/udp" ]
|
|
||||||
"registry": {
|
|
||||||
"username": "foo",
|
|
||||||
"password": "bar",
|
|
||||||
"serverUrl": "https://index.docker.io/v1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Field Descriptions</summary>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
```
|
|
||||||
Arg Fields:
|
|
||||||
|
|
||||||
jobContainer: **Optional** An Object containing information about the specified job container
|
|
||||||
"image": **Required** A string containing the docker image
|
|
||||||
"workingDirectory": **Required** A string containing the absolute path of the working directory
|
|
||||||
"createOptions": **Optional** The optional create options specified in the [YAML](https://docs.github.com/en/actions/using-jobs/running-jobs-in-a-container#example-running-a-job-within-a-container)
|
|
||||||
"environmentVariables": **Optional** A map of key value env's to set
|
|
||||||
"userMountVolumes: ** Optional** an array of user mount volumes set in the [YAML](https://docs.github.com/en/actions/using-jobs/running-jobs-in-a-container#example-running-a-job-within-a-container)
|
|
||||||
"sourceVolumePath": **Required** The source path to the volume to be mounted into the docker container
|
|
||||||
"targetVolumePath": **Required** The target path to the volume to be mounted into the docker container
|
|
||||||
"readOnly": false **Required** whether or not the mount should be read only
|
|
||||||
"mountVolumes": **Required** an array of mounts to mount into the container, same fields as above
|
|
||||||
"sourceVolumePath": **Required** The source path to the volume to be mounted into the docker container
|
|
||||||
"targetVolumePath": **Required** The target path to the volume to be mounted into the docker container
|
|
||||||
"readOnly": false **Required** whether or not the mount should be read only
|
|
||||||
"registry" **Optional** docker registry credentials to use when using a private container registry
|
|
||||||
"username": **Optional** the username
|
|
||||||
"password": **Optional** the password
|
|
||||||
"serverUrl": **Optional** the registry url
|
|
||||||
"portMappings": **Optional** an array of source:target ports to map into the container
|
|
||||||
|
|
||||||
"services": an array of service containers to spin up
|
|
||||||
"contextName": **Required** the name of the service in the Job context
|
|
||||||
"image": **Required** A string containing the docker image
|
|
||||||
"createOptions": **Optional** The optional create options specified in the [YAML](https://docs.github.com/en/actions/using-jobs/running-jobs-in-a-container#example-running-a-job-within-a-container)
|
|
||||||
"environmentVariables": **Optional** A map of key value env's to set
|
|
||||||
"mountVolumes": **Required** an array of mounts to mount into the container, same fields as above
|
|
||||||
"sourceVolumePath": **Required** The source path to the volume to be mounted into the docker container
|
|
||||||
"targetVolumePath": **Required** The target path to the volume to be mounted into the docker container
|
|
||||||
"readOnly": false **Required** whether or not the mount should be read only
|
|
||||||
"registry" **Optional** docker registry credentials to use when using a private container registry
|
|
||||||
"username": **Optional** the username
|
|
||||||
"password": **Optional** the password
|
|
||||||
"serverUrl": **Optional** the registry url
|
|
||||||
"portMappings": **Optional** an array of source:target ports to map into the container
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Example Output</summary>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"state":
|
|
||||||
{
|
|
||||||
"network": "github_network_53269bd575974817b43f4733536b200c",
|
|
||||||
"jobContainer" : "82e8219701fe096a35941d869cf8d71af1d943b5d3bdd718850fb87ac3042480",
|
|
||||||
"serviceContainers":
|
|
||||||
{
|
|
||||||
"redis": "60972d9aa486605e66b0dad4abb638dc3d9116f566579e418166eedb8abb9105"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"context"
|
|
||||||
{
|
|
||||||
"container" :
|
|
||||||
{
|
|
||||||
"id": "82e8219701fe096a35941d869cf8d71af1d943b5d3bdd718850fb87ac3042480"
|
|
||||||
"network": "github_network_53269bd575974817b43f4733536b200c"
|
|
||||||
}
|
|
||||||
"services": {
|
|
||||||
"redis": {
|
|
||||||
"id": "60972d9aa486605e66b0dad4abb638dc3d9116f566579e418166eedb8abb9105",
|
|
||||||
"ports": {
|
|
||||||
"8080": "8080"
|
|
||||||
},
|
|
||||||
"network": "github_network_53269bd575974817b43f4733536b200c"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"alpine: true,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
### Cleanup Job
|
|
||||||
The `cleanup_job` hook is called at the end of a job and expects you to:
|
|
||||||
- Stop any running service or job containers (or the equiavalent pod)
|
|
||||||
- Stop the network (if one exists)
|
|
||||||
- Delete any job or service containers (or the equiavalent pod)
|
|
||||||
- Delete the network (if one exists)
|
|
||||||
- Cleanup anything else that was created for the run
|
|
||||||
|
|
||||||
Its input looks like
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Example Input</summary>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
```
|
|
||||||
"command": "cleanup_job",
|
|
||||||
"responseFile": null,
|
|
||||||
"state":
|
|
||||||
{
|
|
||||||
"network": "github_network_53269bd575974817b43f4733536b200c",
|
|
||||||
"jobContainer" : "82e8219701fe096a35941d869cf8d71af1d943b5d3bdd718850fb87ac3042480",
|
|
||||||
"serviceContainers":
|
|
||||||
{
|
|
||||||
"redis": "60972d9aa486605e66b0dad4abb638dc3d9116f566579e418166eedb8abb9105"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"args": {}
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
No args are provided.
|
|
||||||
|
|
||||||
No output is expected.
|
|
||||||
|
|
||||||
|
|
||||||
### Run Container Step
|
|
||||||
The `run_container_step` is called once per container action in your job and expects you to:
|
|
||||||
- Pull or build the required container (or fail if you cannot)
|
|
||||||
- Run the container action and return the exit code of the container
|
|
||||||
- Stream any step logs output to stdout and stderr
|
|
||||||
- Cleanup the container after it executes
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Example Input for Image</summary>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
```
|
|
||||||
"command": "run_container_step",
|
|
||||||
"responseFile": null,
|
|
||||||
"state":
|
|
||||||
{
|
|
||||||
"network": "github_network_53269bd575974817b43f4733536b200c",
|
|
||||||
"jobContainer" : "82e8219701fe096a35941d869cf8d71af1d943b5d3bdd718850fb87ac3042480",
|
|
||||||
"serviceContainers":
|
|
||||||
{
|
|
||||||
"redis": "60972d9aa486605e66b0dad4abb638dc3d9116f566579e418166eedb8abb9105"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"args":
|
|
||||||
{
|
|
||||||
"image": "node:14.16",
|
|
||||||
"dockerfile": null,
|
|
||||||
"entryPointArgs": ["-f", "/dev/null"],
|
|
||||||
"entryPoint": "tail",
|
|
||||||
"workingDirectory": "/__w/thboop-test2/thboop-test2",
|
|
||||||
"createOptions": "--cpus 1",
|
|
||||||
"environmentVariables": {
|
|
||||||
"NODE_ENV": "development"
|
|
||||||
},
|
|
||||||
"prependPath":["/foo/bar", "bar/foo"]
|
|
||||||
"userMountVolumes:[
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "my_docker_volume",
|
|
||||||
"targetVolumePath": "/volume_mount",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"mountVolumes": [
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work",
|
|
||||||
"targetVolumePath": "/__w",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/externals",
|
|
||||||
"targetVolumePath": "/__e",
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_temp",
|
|
||||||
"targetVolumePath": "/__w/_temp",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_actions",
|
|
||||||
"targetVolumePath": "/__w/_actions",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_tool",
|
|
||||||
"targetVolumePath": "/__w/_tool",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_temp/_github_home",
|
|
||||||
"targetVolumePath": "/github/home",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_temp/_github_workflow",
|
|
||||||
"targetVolumePath": "/github/workflow",
|
|
||||||
"readOnly": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"registry": null,
|
|
||||||
"portMappings": { "80": "801" }
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Example Input for dockerfile</summary>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
```
|
|
||||||
"command": "run_container_step",
|
|
||||||
"responseFile": null,
|
|
||||||
"state":
|
|
||||||
{
|
|
||||||
"network": "github_network_53269bd575974817b43f4733536b200c",
|
|
||||||
"jobContainer" : "82e8219701fe096a35941d869cf8d71af1d943b5d3bdd718850fb87ac3042480",
|
|
||||||
"services":
|
|
||||||
{
|
|
||||||
"redis": "60972d9aa486605e66b0dad4abb638dc3d9116f566579e418166eedb8abb9105"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"args":
|
|
||||||
{
|
|
||||||
"image": null,
|
|
||||||
"dockerfile": /__w/_actions/foo/dockerfile,
|
|
||||||
"entryPointArgs": ["hello world"],
|
|
||||||
"entryPoint": "echo",
|
|
||||||
"workingDirectory": "/__w/thboop-test2/thboop-test2",
|
|
||||||
"createOptions": "--cpus 1",
|
|
||||||
"environmentVariables": {
|
|
||||||
"NODE_ENV": "development"
|
|
||||||
},
|
|
||||||
"prependPath":["/foo/bar", "bar/foo"]
|
|
||||||
"userMountVolumes:[
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "my_docker_volume",
|
|
||||||
"targetVolumePath": "/volume_mount",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"mountVolumes": [
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "my_docker_volume",
|
|
||||||
"targetVolumePath": "/volume_mount",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work",
|
|
||||||
"targetVolumePath": "/__w",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/externals",
|
|
||||||
"targetVolumePath": "/__e",
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_temp",
|
|
||||||
"targetVolumePath": "/__w/_temp",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_actions",
|
|
||||||
"targetVolumePath": "/__w/_actions",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_tool",
|
|
||||||
"targetVolumePath": "/__w/_tool",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_temp/_github_home",
|
|
||||||
"targetVolumePath": "/github/home",
|
|
||||||
"readOnly": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"sourceVolumePath": "/home/thomas/git/runner/_layout/_work/_temp/_github_workflow",
|
|
||||||
"targetVolumePath": "/github/workflow",
|
|
||||||
"readOnly": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"registry": null,
|
|
||||||
"portMappings": [ "8080:80/tcp", "8080:80/udp" ]
|
|
||||||
},
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Field Descriptions</summary>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
```
|
|
||||||
Arg Fields:
|
|
||||||
|
|
||||||
|
|
||||||
"image": **Optional** A string containing the docker image. Otherwise a dockerfile must be provided
|
|
||||||
"dockerfile": **Optional** A string containing the path to the dockerfile, otherwise an image must be provided
|
|
||||||
"entryPointArgs": **Optional** A list containing the entry point args
|
|
||||||
"entryPoint": **Optional** The container entry point to use if the default image entrypoint should be overwritten
|
|
||||||
"workingDirectory": **Required** A string containing the absolute path of the working directory
|
|
||||||
"createOptions": **Optional** The optional create options specified in the [YAML](https://docs.github.com/en/actions/using-jobs/running-jobs-in-a-container#example-running-a-job-within-a-container)
|
|
||||||
"environmentVariables": **Optional** A map of key value env's to set
|
|
||||||
"prependPath": **Optional** an array of additional paths to prepend to the $PATH variable
|
|
||||||
"userMountVolumes: ** Optional** an array of user mount volumes set in the [YAML](https://docs.github.com/en/actions/using-jobs/running-jobs-in-a-container#example-running-a-job-within-a-container)
|
|
||||||
"sourceVolumePath": **Required** The source path to the volume to be mounted into the docker container
|
|
||||||
"targetVolumePath": **Required** The target path to the volume to be mounted into the docker container
|
|
||||||
"readOnly": false **Required** whether or not the mount should be read only
|
|
||||||
"mountVolumes": **Required** an array of mounts to mount into the container, same fields as above
|
|
||||||
"sourceVolumePath": **Required** The source path to the volume to be mounted into the docker container
|
|
||||||
"targetVolumePath": **Required** The target path to the volume to be mounted into the docker container
|
|
||||||
"readOnly": false **Required** whether or not the mount should be read only
|
|
||||||
"registry" **Optional** docker registry credentials to use when using a private container registry
|
|
||||||
"username": **Optional** the username
|
|
||||||
"password": **Optional** the password
|
|
||||||
"serverUrl": **Optional** the registry url
|
|
||||||
"portMappings": **Optional** an array of source:target ports to map into the container
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
No output is expected
|
|
||||||
|
|
||||||
Currently we build all container actions at the start of the job. By doing it during the hook, we move this to just in time building for hooks. We could expose a hook to build/pull a container action, and have those called at the start of a job, but doing so would require hook authors to track the build containers in the state, which could be painful.
|
|
||||||
|
|
||||||
### Run Script Step
|
|
||||||
The `run_script_step` expects you to:
|
|
||||||
- Invoke the provided script inside the job container and return the exit code
|
|
||||||
- Stream any step log output to stdout and stderr
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Example Input</summary>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
"command": "run_script_step",
|
|
||||||
"responseFile": null,
|
|
||||||
"state":
|
|
||||||
{
|
|
||||||
"network": "github_network_53269bd575974817b43f4733536b200c",
|
|
||||||
"jobContainer" : "82e8219701fe096a35941d869cf8d71af1d943b5d3bdd718850fb87ac3042480",
|
|
||||||
"serviceContainers":
|
|
||||||
{
|
|
||||||
"redis": "60972d9aa486605e66b0dad4abb638dc3d9116f566579e418166eedb8abb9105"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"args":
|
|
||||||
{
|
|
||||||
"entryPointArgs": ["-e", "/runner/temp/abc123.sh"],
|
|
||||||
"entryPoint": "bash",
|
|
||||||
"environmentVariables": {
|
|
||||||
"NODE_ENV": "development"
|
|
||||||
},
|
|
||||||
"prependPath": ["/foo/bar", "bar/foo"],
|
|
||||||
"workingDirectory": "/__w/thboop-test2/thboop-test2"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary>Field Descriptions</summary>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
```
|
|
||||||
Arg Fields:
|
|
||||||
|
|
||||||
|
|
||||||
"entryPointArgs": **Optional** A list containing the entry point args
|
|
||||||
"entryPoint": **Optional** The container entry point to use if the default image entrypoint should be overwritten
|
|
||||||
"prependPath": **Optional** an array of additional paths to prepend to the $PATH variable
|
|
||||||
"workingDirectory": **Required** A string containing the absolute path of the working directory
|
|
||||||
"environmentVariables": **Optional** A map of key value env's to set
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
No output is expected
|
|
||||||
|
|
||||||
|
|
||||||
## Limitations
|
|
||||||
- We will only support linux on launch
|
|
||||||
- Hooks are set by the runner admin, and thus are only supported on self hosted runners
|
|
||||||
|
|
||||||
## Consequences
|
|
||||||
- We support non docker scenarios for self hosted runners and allow customers to customize their docker invocations
|
|
||||||
- We ship/maintain docs on docker hooks and an open source repo with examples
|
|
||||||
- We support these hooks and add enough telemetry to be able to troubleshoot support issues as they come in.
|
|
||||||
@@ -15,7 +15,7 @@ Make sure the runner has access to actions service for GitHub.com or GitHub Ente
|
|||||||
```
|
```
|
||||||
curl -v https://api.github.com/api/v3/zen
|
curl -v https://api.github.com/api/v3/zen
|
||||||
curl -v https://vstoken.actions.githubusercontent.com/_apis/health
|
curl -v https://vstoken.actions.githubusercontent.com/_apis/health
|
||||||
curl -v https://pipelines.actions.githubusercontent.com/_apis/health
|
curl -v https://pipelines.actions.githubusercontent/_apis/health
|
||||||
```
|
```
|
||||||
|
|
||||||
- For GitHub Enterprise Server
|
- For GitHub Enterprise Server
|
||||||
@@ -64,4 +64,4 @@ Make sure the runner has access to actions service for GitHub.com or GitHub Ente
|
|||||||
|
|
||||||
## Still not working?
|
## Still not working?
|
||||||
|
|
||||||
Contact [GitHub Support](https://support.github.com) if you have further questuons, or log an issue at https://github.com/actions/runner if you think it's a runner issue.
|
Contact [GitHub Support](https://support.github.com] if you have further questuons, or log an issue at https://github.com/actions/runner if you think it's a runner issue.
|
||||||
|
|||||||
@@ -20,30 +20,11 @@ The test also set environment variable `GIT_TRACE=1` and `GIT_CURL_VERBOSE=1` be
|
|||||||
|
|
||||||
## How to fix the issue?
|
## How to fix the issue?
|
||||||
|
|
||||||
### 1. Check global and system git config
|
### 1. Check the common network issue
|
||||||
|
|
||||||
If you are having issues connecting to the server, check your global and system git config for any unexpected authentication headers. You might be seeing an error like:
|
|
||||||
|
|
||||||
```
|
|
||||||
fatal: unable to access 'https://github.com/actions/checkout/': The requested URL returned error: 400
|
|
||||||
```
|
|
||||||
|
|
||||||
The following commands can be used to check for unexpected authentication headers:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ git config --global --list | grep extraheader
|
|
||||||
http.extraheader=AUTHORIZATION: unexpected_auth_header
|
|
||||||
|
|
||||||
$ git config --system --list | grep extraheader
|
|
||||||
```
|
|
||||||
|
|
||||||
The following command can be used to remove the above value: `git config --global --unset http.extraheader`
|
|
||||||
|
|
||||||
### 2. Check the common network issue
|
|
||||||
|
|
||||||
> Please check the [network doc](./network.md)
|
> Please check the [network doc](./network.md)
|
||||||
|
|
||||||
### 3. SSL certificate related issue
|
### 2. SSL certificate related issue
|
||||||
|
|
||||||
If you are seeing `SSL Certificate problem:` in the log, it means the `git` can't connect to the GitHub server due to SSL handshake failure.
|
If you are seeing `SSL Certificate problem:` in the log, it means the `git` can't connect to the GitHub server due to SSL handshake failure.
|
||||||
> Please check the [SSL cert doc](./sslcert.md)
|
> Please check the [SSL cert doc](./sslcert.md)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Contributions
|
# Contributions
|
||||||
|
|
||||||
We welcome contributions in the form of issues and pull requests. We view the contributions and the process as the same for github and external contributors.Please note the runner typically requires changes across the entire system and we aim for issues in the runner to be entirely self contained and fixable here. Therefore, we will primarily handle bug issues opened in this repo and we kindly request you to create all feature and enhancement requests on the [GitHub Feedback](https://github.com/community/community/discussions/categories/actions-and-packages) page.
|
We welcome contributions in the form of issues and pull requests. We view the contributions and the process as the same for github and external contributors.
|
||||||
|
|
||||||
> IMPORTANT: Building your own runner is critical for the dev inner loop process when contributing changes. However, only runners built and distributed by GitHub (releases) are supported in production. Be aware that workflows and orchestrations run service side with the runner being a remote process to run steps. For that reason, the service can pull the runner forward so customizations can be lost.
|
> IMPORTANT: Building your own runner is critical for the dev inner loop process when contributing changes. However, only runners built and distributed by GitHub (releases) are supported in production. Be aware that workflows and orchestrations run service side with the runner being a remote process to run steps. For that reason, the service can pull the runner forward so customizations can be lost.
|
||||||
|
|
||||||
@@ -27,8 +27,6 @@ An ADR is an Architectural Decision Record. This allows consensus on the direct
|
|||||||
|
|
||||||
 Visual Studio 2017 or newer [Install here](https://visualstudio.microsoft.com) (needed for dev sh script)
|
 Visual Studio 2017 or newer [Install here](https://visualstudio.microsoft.com) (needed for dev sh script)
|
||||||
|
|
||||||
 Visual Studio 2022 17.3 Preview or later. [Install here](https://docs.microsoft.com/en-us/visualstudio/releases/2022/release-notes-preview)
|
|
||||||
|
|
||||||
## Quickstart: Run a job from a real repository
|
## Quickstart: Run a job from a real repository
|
||||||
|
|
||||||
If you just want to get from building the sourcecode to using it to execute an action, you will need:
|
If you just want to get from building the sourcecode to using it to execute an action, you will need:
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ All the configs below can be found in `.vscode/launch.json`.
|
|||||||
If you launch `Run` or `Run [build]`, it starts a process called `Runner.Listener`.
|
If you launch `Run` or `Run [build]`, it starts a process called `Runner.Listener`.
|
||||||
This process will receive any job queued on this repository if the job runs on matching labels (e.g `runs-on: self-hosted`).
|
This process will receive any job queued on this repository if the job runs on matching labels (e.g `runs-on: self-hosted`).
|
||||||
Once a job is received, a `Runner.Listener` starts a new process of `Runner.Worker`.
|
Once a job is received, a `Runner.Listener` starts a new process of `Runner.Worker`.
|
||||||
Since this is a different process, you can't use the same debugger session debug it.
|
Since this is a diferent process, you can't use the same debugger session debug it.
|
||||||
Instead, a parallel debugging session has to be started, using a different launch config.
|
Instead, a parallel debugging session has to be started, using a different launch config.
|
||||||
Luckily, VS Code supports multiple parallel debugging sessions.
|
Luckily, VS Code supports multiple parallel debugging sessions.
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ The `installdependencies.sh` script should install all required dependencies on
|
|||||||
|
|
||||||
Debian based OS (Debian, Ubuntu, Linux Mint)
|
Debian based OS (Debian, Ubuntu, Linux Mint)
|
||||||
|
|
||||||
- liblttng-ust1 or liblttng-ust0
|
- liblttng-ust0
|
||||||
- libkrb5-3
|
- libkrb5-3
|
||||||
- zlib1g
|
- zlib1g
|
||||||
- libssl1.1, libssl1.0.2 or libssl1.0.0
|
- libssl1.1, libssl1.0.2 or libssl1.0.0
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
FROM mcr.microsoft.com/dotnet/runtime-deps:6.0 as build
|
|
||||||
|
|
||||||
ARG RUNNER_VERSION
|
|
||||||
ARG RUNNER_ARCH="x64"
|
|
||||||
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.2.0
|
|
||||||
|
|
||||||
RUN apt update -y && apt install curl unzip -y
|
|
||||||
|
|
||||||
WORKDIR /actions-runner
|
|
||||||
RUN curl -f -L -o runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${RUNNER_ARCH}-${RUNNER_VERSION}.tar.gz \
|
|
||||||
&& tar xzf ./runner.tar.gz \
|
|
||||||
&& rm runner.tar.gz
|
|
||||||
|
|
||||||
RUN curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v${RUNNER_CONTAINER_HOOKS_VERSION}/actions-runner-hooks-k8s-${RUNNER_CONTAINER_HOOKS_VERSION}.zip \
|
|
||||||
&& unzip ./runner-container-hooks.zip -d ./k8s \
|
|
||||||
&& rm runner-container-hooks.zip
|
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/runtime-deps:6.0
|
|
||||||
|
|
||||||
ENV RUNNER_ALLOW_RUNASROOT=1
|
|
||||||
ENV RUNNER_MANUALLY_TRAP_SIG=1
|
|
||||||
ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1
|
|
||||||
|
|
||||||
WORKDIR /actions-runner
|
|
||||||
COPY --from=build /actions-runner .
|
|
||||||
@@ -1,23 +1,18 @@
|
|||||||
## Features
|
## Features
|
||||||
- Log GitHub RequestId for better traceability (#2332)
|
|
||||||
- Dual upload summary to Actions and Result service (#2334)
|
- Added `github.triggering_actor` to the `github` context (#1726)
|
||||||
- Allow providing extra User-Agent for better correlation (#2370)
|
- Save step information when creating annotations (#1744)
|
||||||
- Show more information in the runner log (#2377)
|
- Improved performance of live log streaming (#1730, #1755)
|
||||||
- New option to remove local config files (#2367)
|
- Added Beta support for job started and completed hooks (#1737)
|
||||||
|
|
||||||
## Bugs
|
## Bugs
|
||||||
- Treat jitconfig as secret (#2335)
|
|
||||||
- Add Header/Footer to multi-line message in StdoutTraceListener (#2336)
|
|
||||||
- Update Node dependencies (#2381)
|
|
||||||
|
|
||||||
## Misc
|
## Misc
|
||||||
- Make runner image print diag log to STDOUT (#2331)
|
|
||||||
- Update Node.js to 16.16.0 (#2371)
|
|
||||||
- Add a disclaimer for which runner version is available to a given tenant (#2362)
|
|
||||||
|
|
||||||
_Note: Actions Runner follows a progressive release policy, so the latest release might not be available to your enterprise, organization, or repository yet.
|
- Made some minor job telemetry improvements (#1747)
|
||||||
To confirm which version of the Actions Runner you should expect, please view the download instructions for your enterprise, organization, or repository.
|
- Added repository name and workflow file name to `run.sh` output (#1761)
|
||||||
See https://docs.github.com/en/enterprise-cloud@latest/actions/hosting-your-own-runners/adding-self-hosted-runners_
|
|
||||||
|
|
||||||
## 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.
|
||||||
@@ -33,23 +28,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")
|
||||||
```
|
```
|
||||||
|
|
||||||
## [Pre-release] Windows arm64
|
## OSX
|
||||||
**Warning:** Windows arm64 runners are currently in preview status and use [unofficial versions of nodejs](https://unofficial-builds.nodejs.org/). They are not intended for production workflows.
|
|
||||||
|
|
||||||
We recommend configuring the runner in a root folder of the Windows drive (e.g. "C:\actions-runner"). This will help avoid issues related to service identity folder permissions and long file path restrictions on Windows.
|
|
||||||
|
|
||||||
The following snipped needs to be run on `powershell`:
|
|
||||||
``` powershell
|
|
||||||
# Create a folder under the drive root
|
|
||||||
mkdir \actions-runner ; cd \actions-runner
|
|
||||||
# Download the latest runner package
|
|
||||||
Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-win-arm64-<RUNNER_VERSION>.zip -OutFile actions-runner-win-arm64-<RUNNER_VERSION>.zip
|
|
||||||
# Extract the installer
|
|
||||||
Add-Type -AssemblyName System.IO.Compression.FileSystem ;
|
|
||||||
[System.IO.Compression.ZipFile]::ExtractToDirectory("$PWD\actions-runner-win-arm64-<RUNNER_VERSION>.zip", "$PWD")
|
|
||||||
```
|
|
||||||
|
|
||||||
## OSX x64
|
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
# Create a folder
|
# Create a folder
|
||||||
@@ -60,17 +39,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
|
||||||
```
|
```
|
||||||
|
|
||||||
## 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
|
||||||
@@ -112,33 +80,25 @@ For additional details about configuring, running, or shutting down the runner p
|
|||||||
The SHA-256 checksums for the packages included in this build are shown below:
|
The SHA-256 checksums for the packages included in this build are shown below:
|
||||||
|
|
||||||
- actions-runner-win-x64-<RUNNER_VERSION>.zip <!-- BEGIN SHA win-x64 --><WIN_X64_SHA><!-- END SHA win-x64 -->
|
- actions-runner-win-x64-<RUNNER_VERSION>.zip <!-- BEGIN SHA win-x64 --><WIN_X64_SHA><!-- END SHA win-x64 -->
|
||||||
- actions-runner-win-arm64-<RUNNER_VERSION>.zip <!-- BEGIN SHA win-arm64 --><WIN_ARM64_SHA><!-- END SHA win-arm64 -->
|
|
||||||
- actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA osx-x64 --><OSX_X64_SHA><!-- END SHA osx-x64 -->
|
- actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA osx-x64 --><OSX_X64_SHA><!-- END SHA osx-x64 -->
|
||||||
- actions-runner-osx-arm64-<RUNNER_VERSION>.tar.gz <!-- BEGIN SHA osx-arm64 --><OSX_ARM64_SHA><!-- END SHA osx-arm64 -->
|
|
||||||
- actions-runner-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-win-arm64-<RUNNER_VERSION>-noexternals.zip <!-- BEGIN SHA win-arm64_noexternals --><WIN_ARM64_SHA_NOEXTERNALS><!-- END SHA win-arm64_noexternals -->
|
|
||||||
- actions-runner-osx-x64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA osx-x64_noexternals --><OSX_X64_SHA_NOEXTERNALS><!-- END SHA osx-x64_noexternals -->
|
- actions-runner-osx-x64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA osx-x64_noexternals --><OSX_X64_SHA_NOEXTERNALS><!-- END SHA osx-x64_noexternals -->
|
||||||
- actions-runner-osx-arm64-<RUNNER_VERSION>-noexternals.tar.gz <!-- BEGIN SHA osx-arm64_noexternals --><OSX_ARM64_SHA_NOEXTERNALS><!-- END SHA osx-arm64_noexternals -->
|
|
||||||
- actions-runner-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-win-arm64-<RUNNER_VERSION>-noruntime.zip <!-- BEGIN SHA win-arm64_noruntime --><WIN_ARM64_SHA_NORUNTIME><!-- END SHA win-arm64_noruntime -->
|
|
||||||
- actions-runner-osx-x64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA osx-x64_noruntime --><OSX_X64_SHA_NORUNTIME><!-- END SHA osx-x64_noruntime -->
|
- actions-runner-osx-x64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA osx-x64_noruntime --><OSX_X64_SHA_NORUNTIME><!-- END SHA osx-x64_noruntime -->
|
||||||
- actions-runner-osx-arm64-<RUNNER_VERSION>-noruntime.tar.gz <!-- BEGIN SHA osx-arm64_noruntime --><OSX_ARM64_SHA_NORUNTIME><!-- END SHA osx-arm64_noruntime -->
|
|
||||||
- actions-runner-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-win-arm64-<RUNNER_VERSION>-noruntime-noexternals.zip <!-- BEGIN SHA win-arm64_noruntime_noexternals --><WIN_ARM64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA win-arm64_noruntime_noexternals -->
|
|
||||||
- actions-runner-osx-x64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA osx-x64_noruntime_noexternals --><OSX_X64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA osx-x64_noruntime_noexternals -->
|
- actions-runner-osx-x64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA osx-x64_noruntime_noexternals --><OSX_X64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA osx-x64_noruntime_noexternals -->
|
||||||
- actions-runner-osx-arm64-<RUNNER_VERSION>-noruntime-noexternals.tar.gz <!-- BEGIN SHA osx-arm64_noruntime_noexternals --><OSX_ARM64_SHA_NORUNTIME_NOEXTERNALS><!-- END SHA osx-arm64_noruntime_noexternals -->
|
|
||||||
- actions-runner-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 -->
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.301.1
|
<Update to ./src/runnerversion when creating release>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ set -e
|
|||||||
|
|
||||||
flags_found=false
|
flags_found=false
|
||||||
|
|
||||||
while getopts 's:g:n:r:u:l:df' opt; do
|
while getopts 's:g:n:r:u:l:' opt; do
|
||||||
flags_found=true
|
flags_found=true
|
||||||
|
|
||||||
case $opt in
|
case $opt in
|
||||||
@@ -35,12 +35,6 @@ while getopts 's:g:n:r:u:l:df' opt; do
|
|||||||
l)
|
l)
|
||||||
labels=$OPTARG
|
labels=$OPTARG
|
||||||
;;
|
;;
|
||||||
f)
|
|
||||||
replace='true'
|
|
||||||
;;
|
|
||||||
d)
|
|
||||||
disableupdate='true'
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
echo "
|
echo "
|
||||||
Runner Service Installer
|
Runner Service Installer
|
||||||
@@ -55,9 +49,7 @@ Usage:
|
|||||||
-n optional name of the runner, defaults to hostname
|
-n optional name of the runner, defaults to hostname
|
||||||
-r optional name of the runner group to add the runner to, defaults to the Default group
|
-r optional name of the runner group to add the runner to, defaults to the Default group
|
||||||
-u optional user svc will run as, defaults to current
|
-u optional user svc will run as, defaults to current
|
||||||
-l optional list of labels (split by comma) applied on the runner
|
-l optional list of labels (split by comma) applied on the runner"
|
||||||
-d optional allow runner to remain on the current version for one month after the release of a newer version
|
|
||||||
-f optional replace any existing runner with the same name"
|
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -177,8 +169,8 @@ fi
|
|||||||
|
|
||||||
echo
|
echo
|
||||||
echo "Configuring ${runner_name} @ $runner_url"
|
echo "Configuring ${runner_name} @ $runner_url"
|
||||||
echo "./config.sh --unattended --url $runner_url --token *** --name $runner_name ${labels:+--labels $labels} ${runner_group:+--runnergroup \"$runner_group\"} ${disableupdate:+--disableupdate}"
|
echo "./config.sh --unattended --url $runner_url --token *** --name $runner_name ${labels:+--labels $labels} ${runner_group:+--runnergroup \"$runner_group\"}"
|
||||||
sudo -E -u ${svc_user} ./config.sh --unattended --url $runner_url --token $RUNNER_TOKEN ${replace:+--replace} --name $runner_name ${labels:+--labels $labels} ${runner_group:+--runnergroup "$runner_group"} ${disableupdate:+--disableupdate}
|
sudo -E -u ${svc_user} ./config.sh --unattended --url $runner_url --token $RUNNER_TOKEN --name $runner_name ${labels:+--labels $labels} ${runner_group:+--runnergroup "$runner_group"}
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
# Configuring as a service
|
# Configuring as a service
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#/bin/bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ set -e
|
|||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# export RUNNER_CFG_PAT=<yourPAT>
|
# export RUNNER_CFG_PAT=<yourPAT>
|
||||||
# ./delete.sh <scope> [<name>]
|
# ./delete.sh scope name
|
||||||
#
|
#
|
||||||
# scope required repo (:owner/:repo) or org (:organization)
|
# scope required repo (:owner/:repo) or org (:organization)
|
||||||
# name optional defaults to hostname. name to delete
|
# name optional defaults to hostname. name to delete
|
||||||
@@ -26,6 +26,8 @@ set -e
|
|||||||
runner_scope=${1}
|
runner_scope=${1}
|
||||||
runner_name=${2}
|
runner_name=${2}
|
||||||
|
|
||||||
|
echo "Deleting runner ${runner_name} @ ${runner_scope}"
|
||||||
|
|
||||||
function fatal()
|
function fatal()
|
||||||
{
|
{
|
||||||
echo "error: $1" >&2
|
echo "error: $1" >&2
|
||||||
@@ -33,10 +35,8 @@ function fatal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if [ -z "${runner_scope}" ]; then fatal "supply scope as argument 1"; fi
|
if [ -z "${runner_scope}" ]; then fatal "supply scope as argument 1"; fi
|
||||||
|
if [ -z "${runner_name}" ]; then fatal "supply name as argument 2"; fi
|
||||||
if [ -z "${RUNNER_CFG_PAT}" ]; then fatal "RUNNER_CFG_PAT must be set before calling"; fi
|
if [ -z "${RUNNER_CFG_PAT}" ]; then fatal "RUNNER_CFG_PAT must be set before calling"; fi
|
||||||
if [ -z "${runner_name}" ]; then runner_name=`hostname`; fi
|
|
||||||
|
|
||||||
echo "Deleting runner ${runner_name} @ ${runner_scope}"
|
|
||||||
|
|
||||||
which curl || fatal "curl required. Please install in PATH with apt-get, brew, etc"
|
which curl || fatal "curl required. Please install in PATH with apt-get, brew, etc"
|
||||||
which jq || fatal "jq required. Please install in PATH with apt-get, brew, etc"
|
which jq || fatal "jq required. Please install in PATH with apt-get, brew, etc"
|
||||||
|
|||||||
@@ -24,16 +24,10 @@
|
|||||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Windows' AND '$(PackageRuntime)' == 'win-x86'">
|
<PropertyGroup Condition="'$(BUILD_OS)' == 'Windows' AND '$(PackageRuntime)' == 'win-x86'">
|
||||||
<DefineConstants>$(DefineConstants);X86</DefineConstants>
|
<DefineConstants>$(DefineConstants);X86</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Windows' AND '$(PackageRuntime)' == 'win-arm64'">
|
|
||||||
<DefineConstants>$(DefineConstants);ARM64</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'OSX' AND '$(PackageRuntime)' == 'osx-x64'">
|
<PropertyGroup Condition="'$(BUILD_OS)' == 'OSX'">
|
||||||
<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>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1d709d93e5d3c6c6c656a61aa6c1781050224788a05b0e6ecc4c3c0408bdf89c
|
de62d296708908cfd1236e58869aebbc2bae8a8c3d629276968542626c508e37
|
||||||
@@ -1 +1 @@
|
|||||||
b92a47cfeaad02255b1f7a377060651b73ae5e5db22a188dbbcb4183ab03a03d
|
44fcd0422dd98ed17d2c8e9057ff2260c50165f20674236a4ae7d2645a07df25
|
||||||
@@ -1 +1 @@
|
|||||||
68a9a8ef0843a8bb74241894f6f63fd76241a82295c5337d3cc7a940a314c78e
|
e57652cf322ee16ce3af4f9e58f80858746b9e1e60279e991a3b3d9a6baf8d79
|
||||||
@@ -1 +0,0 @@
|
|||||||
02c7126ff4d63ee2a0ae390c81434c125630522aadf35903bbeebb1a99d8af99
|
|
||||||
@@ -1 +1 @@
|
|||||||
c9d5a542f8d765168855a89e83ae0a8970d00869041c4f9a766651c04c72b212
|
bdd247b2ff3f51095524412e2ac588e7a87af805e114d6caf2368366ee7be1ea
|
||||||
@@ -1 +0,0 @@
|
|||||||
39d0683f0f115a211cb10c473e9574c16549a19d4e9a6c637ded3d7022bf809f
|
|
||||||
@@ -1 +1 @@
|
|||||||
d94f2fbaf210297162bc9f3add819d73682c3aa6899e321c3872412b924d5504
|
d23a0cb9f20c0aa1cddb7a39567cd097020cdeb06a1e952940601d1a405c53b8
|
||||||
2
src/Misc/contentHash/externals/linux-arm
vendored
2
src/Misc/contentHash/externals/linux-arm
vendored
@@ -1 +1 @@
|
|||||||
3807dcbf947e840c33535fb466b096d76bf09e5c0254af8fc8cbbb24c6388222
|
6ed30a2c1ee403a610d63e82bb230b9ba846a9c25cec9e4ea8672fb6ed4e1a51
|
||||||
2
src/Misc/contentHash/externals/linux-arm64
vendored
2
src/Misc/contentHash/externals/linux-arm64
vendored
@@ -1 +1 @@
|
|||||||
ee01eee80cd8a460a4b9780ee13fdd20f25c59e754b4ccd99df55fbba2a85634
|
711c30c51ec52c9b7a9a2eb399d6ab2ab5ee1dc72de11879f2f36f919f163d78
|
||||||
2
src/Misc/contentHash/externals/linux-x64
vendored
2
src/Misc/contentHash/externals/linux-x64
vendored
@@ -1 +1 @@
|
|||||||
a9fb9c14e24e79aec97d4da197dd7bfc6364297d6fce573afb2df48cc9a931f8
|
a49479ca4b4988a06c097e8d22c51fd08a11c13f40807366236213d0e008cf6a
|
||||||
1
src/Misc/contentHash/externals/osx-arm64
vendored
1
src/Misc/contentHash/externals/osx-arm64
vendored
@@ -1 +0,0 @@
|
|||||||
a4e0e8fc62eba0967a39c7d693dcd0aeb8b2bed0765f9c38df80d42884f65341
|
|
||||||
2
src/Misc/contentHash/externals/osx-x64
vendored
2
src/Misc/contentHash/externals/osx-x64
vendored
@@ -1 +1 @@
|
|||||||
17ac17fbe785b3d6fa2868d8d17185ebfe0c90b4b0ddf6b67eac70e42bcd989b
|
8e97df75230b843462a9b4c578ccec604ee4b4a1066120c85b04374317fa372b
|
||||||
1
src/Misc/contentHash/externals/win-arm64
vendored
1
src/Misc/contentHash/externals/win-arm64
vendored
@@ -1 +0,0 @@
|
|||||||
89f24657a550f1e818b0e9975e5b80edcf4dd22b7d4bccbb9e48e37f45d30fb1
|
|
||||||
2
src/Misc/contentHash/externals/win-x64
vendored
2
src/Misc/contentHash/externals/win-x64
vendored
@@ -1 +1 @@
|
|||||||
24fd131b5dce33ef16038b771407bc0507da8682a72fb3b7780607235f76db0b
|
f75a671e5a188c76680739689aa75331a2c09d483dce9c80023518c48fd67a18
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"plugins": ["@typescript-eslint"],
|
"plugins": ["jest", "@typescript-eslint"],
|
||||||
"extends": ["plugin:github/recommended"],
|
"extends": ["plugin:github/es6"],
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 9,
|
"ecmaVersion": 9,
|
||||||
@@ -17,16 +17,13 @@
|
|||||||
"@typescript-eslint/no-require-imports": "error",
|
"@typescript-eslint/no-require-imports": "error",
|
||||||
"@typescript-eslint/array-type": "error",
|
"@typescript-eslint/array-type": "error",
|
||||||
"@typescript-eslint/await-thenable": "error",
|
"@typescript-eslint/await-thenable": "error",
|
||||||
"@typescript-eslint/naming-convention": [
|
"@typescript-eslint/ban-ts-ignore": "error",
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"selector": "default",
|
|
||||||
"format": ["camelCase"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"camelcase": "off",
|
"camelcase": "off",
|
||||||
|
"@typescript-eslint/camelcase": "error",
|
||||||
|
"@typescript-eslint/class-name-casing": "error",
|
||||||
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
|
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
|
||||||
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
||||||
|
"@typescript-eslint/generic-type-naming": ["error", "^[A-Z][A-Za-z]*$"],
|
||||||
"@typescript-eslint/no-array-constructor": "error",
|
"@typescript-eslint/no-array-constructor": "error",
|
||||||
"@typescript-eslint/no-empty-interface": "error",
|
"@typescript-eslint/no-empty-interface": "error",
|
||||||
"@typescript-eslint/no-explicit-any": "error",
|
"@typescript-eslint/no-explicit-any": "error",
|
||||||
@@ -36,6 +33,7 @@
|
|||||||
"@typescript-eslint/no-misused-new": "error",
|
"@typescript-eslint/no-misused-new": "error",
|
||||||
"@typescript-eslint/no-namespace": "error",
|
"@typescript-eslint/no-namespace": "error",
|
||||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||||
|
"@typescript-eslint/no-object-literal-type-assertion": "error",
|
||||||
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
||||||
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
||||||
"@typescript-eslint/no-useless-constructor": "error",
|
"@typescript-eslint/no-useless-constructor": "error",
|
||||||
@@ -43,19 +41,19 @@
|
|||||||
"@typescript-eslint/prefer-for-of": "warn",
|
"@typescript-eslint/prefer-for-of": "warn",
|
||||||
"@typescript-eslint/prefer-function-type": "warn",
|
"@typescript-eslint/prefer-function-type": "warn",
|
||||||
"@typescript-eslint/prefer-includes": "error",
|
"@typescript-eslint/prefer-includes": "error",
|
||||||
|
"@typescript-eslint/prefer-interface": "error",
|
||||||
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
||||||
"@typescript-eslint/promise-function-async": "error",
|
"@typescript-eslint/promise-function-async": "error",
|
||||||
"@typescript-eslint/require-array-sort-compare": "error",
|
"@typescript-eslint/require-array-sort-compare": "error",
|
||||||
"@typescript-eslint/restrict-plus-operands": "error",
|
"@typescript-eslint/restrict-plus-operands": "error",
|
||||||
|
"semi": "off",
|
||||||
"@typescript-eslint/semi": ["error", "never"],
|
"@typescript-eslint/semi": ["error", "never"],
|
||||||
"@typescript-eslint/type-annotation-spacing": "error",
|
"@typescript-eslint/type-annotation-spacing": "error",
|
||||||
"@typescript-eslint/unbound-method": "error",
|
"@typescript-eslint/unbound-method": "error"
|
||||||
"filenames/match-regex" : "off",
|
|
||||||
"github/no-then" : 1, // warning
|
|
||||||
"semi": "off"
|
|
||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"node": true,
|
"node": true,
|
||||||
"es6": true
|
"es6": true,
|
||||||
|
"jest/globals": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1 @@
|
|||||||
To compile this package (output will be stored in `Misc/layoutbin`) run `npm install && npm run all`.
|
To update hashFiles under `Misc/layoutbin` run `npm install && npm run all`
|
||||||
|
|
||||||
> Note: this package also needs to be recompiled for dependabot PRs updating one of
|
|
||||||
> its dependencies.
|
|
||||||
6266
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
6266
src/Misc/expressionFunc/hashFiles/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -25,10 +25,10 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^12.7.12",
|
"@types/node": "^12.7.12",
|
||||||
"@typescript-eslint/parser": "^5.15.0",
|
"@typescript-eslint/parser": "^2.8.0",
|
||||||
"@vercel/ncc": "^0.36.0",
|
"@zeit/ncc": "^0.20.5",
|
||||||
"eslint": "^8.11.0",
|
"eslint": "^6.8.0",
|
||||||
"eslint-plugin-github": "^4.3.5",
|
"eslint-plugin-github": "^2.0.0",
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^1.19.1",
|
||||||
"typescript": "^3.6.4"
|
"typescript": "^3.6.4"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import * as glob from '@actions/glob'
|
||||||
import * as crypto from 'crypto'
|
import * as crypto from 'crypto'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as glob from '@actions/glob'
|
|
||||||
import * as path from 'path'
|
|
||||||
import * as stream from 'stream'
|
import * as stream from 'stream'
|
||||||
import * as util from 'util'
|
import * as util from 'util'
|
||||||
|
import * as path from 'path'
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
// arg0 -> node
|
// arg0 -> node
|
||||||
|
|||||||
@@ -3,9 +3,8 @@ PACKAGERUNTIME=$1
|
|||||||
PRECACHE=$2
|
PRECACHE=$2
|
||||||
|
|
||||||
NODE_URL=https://nodejs.org/dist
|
NODE_URL=https://nodejs.org/dist
|
||||||
UNOFFICIAL_NODE_URL=https://unofficial-builds.nodejs.org/download/release
|
|
||||||
NODE12_VERSION="12.22.7"
|
NODE12_VERSION="12.22.7"
|
||||||
NODE16_VERSION="16.16.0"
|
NODE16_VERSION="16.13.0"
|
||||||
|
|
||||||
get_abs_path() {
|
get_abs_path() {
|
||||||
# exploits the fact that pwd will print abs path when no args
|
# exploits the fact that pwd will print abs path when no args
|
||||||
@@ -135,27 +134,12 @@ if [[ "$PACKAGERUNTIME" == "win-x64" || "$PACKAGERUNTIME" == "win-x86" ]]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Download the external tools only for Windows.
|
|
||||||
if [[ "$PACKAGERUNTIME" == "win-arm64" ]]; then
|
|
||||||
# todo: replace these with official release when available
|
|
||||||
acquireExternalTool "$UNOFFICIAL_NODE_URL/v${NODE16_VERSION}/$PACKAGERUNTIME/node.exe" node16/bin
|
|
||||||
acquireExternalTool "$UNOFFICIAL_NODE_URL/v${NODE16_VERSION}/$PACKAGERUNTIME/node.lib" node16/bin
|
|
||||||
if [[ "$PRECACHE" != "" ]]; then
|
|
||||||
acquireExternalTool "https://github.com/microsoft/vswhere/releases/download/2.6.7/vswhere.exe" vswhere
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Download the external tools only for OSX.
|
# Download the external tools only for OSX.
|
||||||
if [[ "$PACKAGERUNTIME" == "osx-x64" ]]; then
|
if [[ "$PACKAGERUNTIME" == "osx-x64" ]]; then
|
||||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-darwin-x64.tar.gz" node12 fix_nested_dir
|
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-darwin-x64.tar.gz" node12 fix_nested_dir
|
||||||
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
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -66,7 +66,7 @@ then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$apt_get update && $apt_get install -y libkrb5-3 zlib1g
|
$apt_get update && $apt_get install -y liblttng-ust0 libkrb5-3 zlib1g
|
||||||
if [ $? -ne 0 ]
|
if [ $? -ne 0 ]
|
||||||
then
|
then
|
||||||
echo "'$apt_get' failed with exit code '$?'"
|
echo "'$apt_get' failed with exit code '$?'"
|
||||||
@@ -94,14 +94,6 @@ then
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
apt_get_with_fallbacks liblttng-ust1 liblttng-ust0
|
|
||||||
if [ $? -ne 0 ]
|
|
||||||
then
|
|
||||||
echo "'$apt_get' failed with exit code '$?'"
|
|
||||||
print_errormessage
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
apt_get_with_fallbacks libssl1.1$ libssl1.0.2$ libssl1.0.0$
|
apt_get_with_fallbacks libssl1.1$ libssl1.0.2$ libssl1.0.0$
|
||||||
if [ $? -ne 0 ]
|
if [ $? -ne 0 ]
|
||||||
then
|
then
|
||||||
|
|||||||
@@ -120,9 +120,6 @@ if ERRORLEVEL 1 (
|
|||||||
|
|
||||||
echo [%date% %time%] Update succeed >> "%logfile%" 2>&1
|
echo [%date% %time%] Update succeed >> "%logfile%" 2>&1
|
||||||
|
|
||||||
type nul > update.finished
|
|
||||||
echo [%date% %time%] update.finished file creation succeed >> "%logfile%" 2>&1
|
|
||||||
|
|
||||||
rem rename the update log file with %logfile%.succeed/.failed/succeedneedrestart
|
rem rename the update log file with %logfile%.succeed/.failed/succeedneedrestart
|
||||||
rem runner service host can base on the log file name determin the result of the runner update
|
rem runner service host can base on the log file name determin the result of the runner update
|
||||||
echo [%date% %time%] Rename "%logfile%" to be "%logfile%.succeed" >> "%logfile%" 2>&1
|
echo [%date% %time%] Rename "%logfile%" to be "%logfile%.succeed" >> "%logfile%" 2>&1
|
||||||
|
|||||||
@@ -180,9 +180,6 @@ fi
|
|||||||
|
|
||||||
date "+[%F %T-%4N] Update succeed" >> "$logfile"
|
date "+[%F %T-%4N] Update succeed" >> "$logfile"
|
||||||
|
|
||||||
touch update.finished
|
|
||||||
date "+[%F %T-%4N] update.finished file creation succeed" >> "$logfile"
|
|
||||||
|
|
||||||
# rename the update log file with %logfile%.succeed/.failed/succeedneedrestart
|
# rename the update log file with %logfile%.succeed/.failed/succeedneedrestart
|
||||||
# runner service host can base on the log file name determin the result of the runner update
|
# runner service host can base on the log file name determin the result of the runner update
|
||||||
date "+[%F %T-%4N] Rename $logfile to be $logfile.succeed" >> "$logfile" 2>&1
|
date "+[%F %T-%4N] Rename $logfile to be $logfile.succeed" >> "$logfile" 2>&1
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@echo off
|
@echo off
|
||||||
SET UPDATEFILE=update.finished
|
|
||||||
"%~dp0\bin\Runner.Listener.exe" run %*
|
"%~dp0\bin\Runner.Listener.exe" run %*
|
||||||
|
|
||||||
rem using `if %ERRORLEVEL% EQU N` insterad of `if ERRORLEVEL N`
|
rem using `if %ERRORLEVEL% EQU N` insterad of `if ERRORLEVEL N`
|
||||||
@@ -22,30 +22,16 @@ if %ERRORLEVEL% EQU 2 (
|
|||||||
)
|
)
|
||||||
|
|
||||||
if %ERRORLEVEL% EQU 3 (
|
if %ERRORLEVEL% EQU 3 (
|
||||||
rem Wait for 30 seconds or for flag file to exists for the ephemeral runner update process finish
|
rem Sleep 5 seconds to wait for the runner update process finish
|
||||||
echo "Runner listener exit because of updating, re-launch runner after successful update"
|
echo "Runner listener exit because of updating, re-launch runner in 5 seconds"
|
||||||
FOR /L %%G IN (1,1,30) DO (
|
ping 127.0.0.1 -n 6 -w 1000 >NUL
|
||||||
IF EXIST %UPDATEFILE% (
|
|
||||||
echo "Update finished successfully."
|
|
||||||
del %FILE%
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
ping 127.0.0.1 -n 2 -w 1000 >NUL
|
|
||||||
)
|
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
if %ERRORLEVEL% EQU 4 (
|
if %ERRORLEVEL% EQU 4 (
|
||||||
rem Wait for 30 seconds or for flag file to exists for the runner update process finish
|
rem Sleep 5 seconds to wait for the ephemeral runner update process finish
|
||||||
echo "Runner listener exit because of updating, re-launch runner after successful update"
|
echo "Runner listener exit because of updating, re-launch ephemeral runner in 5 seconds"
|
||||||
FOR /L %%G IN (1,1,30) DO (
|
ping 127.0.0.1 -n 6 -w 1000 >NUL
|
||||||
IF EXIST %UPDATEFILE% (
|
|
||||||
echo "Update finished successfully."
|
|
||||||
del %FILE%
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
ping 127.0.0.1 -n 2 -w 1000 >NUL
|
|
||||||
)
|
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
|
|||||||
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||||
done
|
done
|
||||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
|
||||||
updateFile="update.finished"
|
|
||||||
"$DIR"/bin/Runner.Listener run $*
|
"$DIR"/bin/Runner.Listener run $*
|
||||||
|
|
||||||
returnCode=$?
|
returnCode=$?
|
||||||
@@ -33,28 +31,14 @@ elif [[ $returnCode == 2 ]]; then
|
|||||||
"$DIR"/safe_sleep.sh 5
|
"$DIR"/safe_sleep.sh 5
|
||||||
exit 2
|
exit 2
|
||||||
elif [[ $returnCode == 3 ]]; then
|
elif [[ $returnCode == 3 ]]; then
|
||||||
# Wait for 30 seconds or for flag file to exists for the runner update process finish
|
# Sleep 5 seconds to wait for the runner update process finish
|
||||||
echo "Runner listener exit because of updating, re-launch runner after successful update"
|
echo "Runner listener exit because of updating, re-launch runner in 5 seconds"
|
||||||
for i in {0..30}; do
|
"$DIR"/safe_sleep.sh 5
|
||||||
if test -f "$updateFile"; then
|
|
||||||
echo "Update finished successfully."
|
|
||||||
rm "$updateFile"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
"$DIR"/safe_sleep.sh 1
|
|
||||||
done
|
|
||||||
exit 2
|
exit 2
|
||||||
elif [[ $returnCode == 4 ]]; then
|
elif [[ $returnCode == 4 ]]; then
|
||||||
# Wait for 30 seconds or for flag file to exists for the ephemeral runner update process finish
|
# Sleep 5 seconds to wait for the ephemeral runner update process finish
|
||||||
echo "Runner listener exit because of updating, re-launch runner after successful update"
|
echo "Runner listener exit because of updating, re-launch ephemeral runner in 5 seconds"
|
||||||
for i in {0..30}; do
|
"$DIR"/safe_sleep.sh 5
|
||||||
if test -f "$updateFile"; then
|
|
||||||
echo "Update finished successfully."
|
|
||||||
rm "$updateFile"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
"$DIR"/safe_sleep.sh 1
|
|
||||||
done
|
|
||||||
exit 2
|
exit 2
|
||||||
else
|
else
|
||||||
echo "Exiting with unknown error code: ${returnCode}"
|
echo "Exiting with unknown error code: ${returnCode}"
|
||||||
|
|||||||
@@ -9,12 +9,10 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
|
|||||||
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||||
done
|
done
|
||||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
cp -f "$DIR"/run-helper.sh.template "$DIR"/run-helper.sh
|
||||||
run() {
|
# run the helper process which keep the listener alive
|
||||||
# run the helper process which keep the listener alive
|
while :;
|
||||||
while :;
|
do
|
||||||
do
|
|
||||||
cp -f "$DIR"/run-helper.sh.template "$DIR"/run-helper.sh
|
|
||||||
"$DIR"/run-helper.sh $*
|
"$DIR"/run-helper.sh $*
|
||||||
returnCode=$?
|
returnCode=$?
|
||||||
if [[ $returnCode -eq 2 ]]; then
|
if [[ $returnCode -eq 2 ]]; then
|
||||||
@@ -23,38 +21,4 @@ run() {
|
|||||||
echo "Exiting runner..."
|
echo "Exiting runner..."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
|
||||||
|
|
||||||
runWithManualTrap() {
|
|
||||||
# Set job control
|
|
||||||
set -m
|
|
||||||
|
|
||||||
trap 'kill -INT -$PID' INT TERM
|
|
||||||
|
|
||||||
# run the helper process which keep the listener alive
|
|
||||||
while :;
|
|
||||||
do
|
|
||||||
cp -f "$DIR"/run-helper.sh.template "$DIR"/run-helper.sh
|
|
||||||
"$DIR"/run-helper.sh $* &
|
|
||||||
PID=$!
|
|
||||||
wait -f $PID
|
|
||||||
returnCode=$?
|
|
||||||
if [[ $returnCode -eq 2 ]]; then
|
|
||||||
echo "Restarting runner..."
|
|
||||||
else
|
|
||||||
echo "Exiting runner..."
|
|
||||||
# Unregister signal handling before exit
|
|
||||||
trap - INT TERM
|
|
||||||
# wait for last parts to be logged
|
|
||||||
wait $PID
|
|
||||||
exit $returnCode
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
if [[ -z "$RUNNER_MANUALLY_TRAP_SIG" ]]; then
|
|
||||||
run $*
|
|
||||||
else
|
|
||||||
runWithManualTrap $*
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -66,14 +65,12 @@ libmscordbi.dylib
|
|||||||
libmscordbi.so
|
libmscordbi.so
|
||||||
Microsoft.CSharp.dll
|
Microsoft.CSharp.dll
|
||||||
Microsoft.DiaSymReader.Native.amd64.dll
|
Microsoft.DiaSymReader.Native.amd64.dll
|
||||||
Microsoft.DiaSymReader.Native.arm64.dll
|
|
||||||
Microsoft.VisualBasic.Core.dll
|
Microsoft.VisualBasic.Core.dll
|
||||||
Microsoft.VisualBasic.dll
|
Microsoft.VisualBasic.dll
|
||||||
Microsoft.Win32.Primitives.dll
|
Microsoft.Win32.Primitives.dll
|
||||||
Microsoft.Win32.Registry.dll
|
Microsoft.Win32.Registry.dll
|
||||||
mscordaccore.dll
|
mscordaccore.dll
|
||||||
mscordaccore_amd64_amd64_6.0.522.21309.dll
|
mscordaccore_amd64_amd64_6.0.21.52210.dll
|
||||||
mscordaccore_arm64_arm64_6.0.522.21309.dll
|
|
||||||
mscordbi.dll
|
mscordbi.dll
|
||||||
mscorlib.dll
|
mscorlib.dll
|
||||||
mscorrc.debug.dll
|
mscorrc.debug.dll
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -31,7 +32,7 @@ namespace GitHub.Runner.Common
|
|||||||
new EscapeMapping(token: "%", replacement: "%25"),
|
new EscapeMapping(token: "%", replacement: "%25"),
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly Dictionary<string, string> _properties = new(StringComparer.OrdinalIgnoreCase);
|
private readonly Dictionary<string, string> _properties = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
public const string Prefix = "##[";
|
public const string Prefix = "##[";
|
||||||
public const string _commandKey = "::";
|
public const string _commandKey = "::";
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
{
|
{
|
||||||
public enum ActionResult
|
public enum ActionResult
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using GitHub.DistributedTask.Pipelines;
|
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
using GitHub.Services.Common;
|
|
||||||
using GitHub.Services.WebApi;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
|
||||||
{
|
|
||||||
[ServiceLocator(Default = typeof(ActionsRunServer))]
|
|
||||||
public interface IActionsRunServer : IRunnerService
|
|
||||||
{
|
|
||||||
Task ConnectAsync(Uri serverUrl, VssCredentials credentials);
|
|
||||||
|
|
||||||
Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class ActionsRunServer : RunnerService, IActionsRunServer
|
|
||||||
{
|
|
||||||
private bool _hasConnection;
|
|
||||||
private VssConnection _connection;
|
|
||||||
private TaskAgentHttpClient _taskAgentClient;
|
|
||||||
|
|
||||||
public async Task ConnectAsync(Uri serverUrl, VssCredentials credentials)
|
|
||||||
{
|
|
||||||
_connection = await EstablishVssConnection(serverUrl, credentials, TimeSpan.FromSeconds(100));
|
|
||||||
_taskAgentClient = _connection.GetClient<TaskAgentHttpClient>();
|
|
||||||
_hasConnection = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckConnection()
|
|
||||||
{
|
|
||||||
if (!_hasConnection)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"SetConnection");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
CheckConnection();
|
|
||||||
var jobMessage = RetryRequest<AgentJobRequestMessage>(async () =>
|
|
||||||
{
|
|
||||||
return await _taskAgentClient.GetJobMessageAsync(id, cancellationToken);
|
|
||||||
}, cancellationToken);
|
|
||||||
|
|
||||||
return jobMessage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using GitHub.DistributedTask.Logging;
|
using GitHub.DistributedTask.Logging;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -74,18 +75,17 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Uri accountUri = new(this.ServerUrl);
|
Uri accountUri = new Uri(this.ServerUrl);
|
||||||
string repoOrOrgName = string.Empty;
|
string repoOrOrgName = string.Empty;
|
||||||
|
|
||||||
if (accountUri.Host.EndsWith(".githubusercontent.com", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(this.GitHubUrl))
|
if (accountUri.Host.EndsWith(".githubusercontent.com", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Uri gitHubUrl = new(this.GitHubUrl);
|
Uri gitHubUrl = new Uri(this.GitHubUrl);
|
||||||
|
|
||||||
// Use the "NWO part" from the GitHub URL path
|
// Use the "NWO part" from the GitHub URL path
|
||||||
repoOrOrgName = gitHubUrl.AbsolutePath.Trim('/');
|
repoOrOrgName = gitHubUrl.AbsolutePath.Trim('/');
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (string.IsNullOrEmpty(repoOrOrgName))
|
|
||||||
{
|
{
|
||||||
repoOrOrgName = accountUri.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
|
repoOrOrgName = accountUri.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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";
|
||||||
@@ -104,13 +104,11 @@ namespace GitHub.Runner.Common
|
|||||||
public static readonly string Token = "token";
|
public static readonly string Token = "token";
|
||||||
public static readonly string PAT = "pat";
|
public static readonly string PAT = "pat";
|
||||||
public static readonly string WindowsLogonPassword = "windowslogonpassword";
|
public static readonly string WindowsLogonPassword = "windowslogonpassword";
|
||||||
public static readonly string JitConfig = "jitconfig";
|
|
||||||
public static string[] Secrets => new[]
|
public static string[] Secrets => new[]
|
||||||
{
|
{
|
||||||
PAT,
|
PAT,
|
||||||
Token,
|
Token,
|
||||||
WindowsLogonPassword,
|
WindowsLogonPassword,
|
||||||
JitConfig,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,15 +121,13 @@ 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";
|
||||||
public static readonly string Commit = "commit";
|
public static readonly string Commit = "commit";
|
||||||
public static readonly string Ephemeral = "ephemeral";
|
public static readonly string Ephemeral = "ephemeral";
|
||||||
public static readonly string GenerateServiceConfig = "generateServiceConfig";
|
|
||||||
public static readonly string Help = "help";
|
public static readonly string Help = "help";
|
||||||
public static readonly string Local = "local";
|
|
||||||
public static readonly string Replace = "replace";
|
public static readonly string Replace = "replace";
|
||||||
public static readonly string DisableUpdate = "disableupdate";
|
public static readonly string DisableUpdate = "disableupdate";
|
||||||
public static readonly string Once = "once"; // Keep this around since customers still relies on it
|
public static readonly string Once = "once"; // Keep this around since customers still relies on it
|
||||||
@@ -153,23 +149,15 @@ namespace GitHub.Runner.Common
|
|||||||
public static class Features
|
public static class Features
|
||||||
{
|
{
|
||||||
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 UseContainerPathForTemplate = "DistributedTask.UseContainerPathForTemplate";
|
|
||||||
public static readonly string AllowRunnerContainerHooks = "DistributedTask.AllowRunnerContainerHooks";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly string InternalTelemetryIssueDataKey = "_internal_telemetry";
|
public static readonly string InternalTelemetryIssueDataKey = "_internal_telemetry";
|
||||||
public static readonly Guid TelemetryRecordId = new Guid("11111111-1111-1111-1111-111111111111");
|
|
||||||
public static readonly string WorkerCrash = "WORKER_CRASH";
|
public static readonly string WorkerCrash = "WORKER_CRASH";
|
||||||
public static readonly string LowDiskSpace = "LOW_DISK_SPACE";
|
public static readonly string LowDiskSpace = "LOW_DISK_SPACE";
|
||||||
public static readonly string UnsupportedCommand = "UNSUPPORTED_COMMAND";
|
public static readonly string UnsupportedCommand = "UNSUPPORTED_COMMAND";
|
||||||
public static readonly string ResultsUploadFailure = "RESULTS_UPLOAD_FAILURE";
|
|
||||||
public static readonly string UnsupportedCommandMessage = "The `{0}` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/";
|
|
||||||
public static readonly string UnsupportedCommandMessageDisabled = "The `{0}` command is disabled. Please upgrade to using Environment Files or opt into unsecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_COMMANDS` environment variable to `true`. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/";
|
public static readonly string UnsupportedCommandMessageDisabled = "The `{0}` command is disabled. Please upgrade to using Environment Files or opt into unsecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_COMMANDS` environment variable to `true`. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/";
|
||||||
public static readonly string UnsupportedStopCommandTokenDisabled = "You cannot use a endToken that is an empty string, the string 'pause-logging', or another workflow command. For more information see: https://docs.github.com/actions/learn-github-actions/workflow-commands-for-github-actions#example-stopping-and-starting-workflow-commands or opt into insecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_STOPCOMMAND_TOKENS` environment variable to `true`.";
|
public static readonly string UnsupportedStopCommandTokenDisabled = "You cannot use a endToken that is an empty string, the string 'pause-logging', or another workflow command. For more information see: https://docs.github.com/actions/learn-github-actions/workflow-commands-for-github-actions#example-stopping-and-starting-workflow-commands or opt into insecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_STOPCOMMAND_TOKENS` environment variable to `true`.";
|
||||||
public static readonly string UnsupportedSummarySize = "$GITHUB_STEP_SUMMARY upload aborted, supports content up to a size of {0}k, got {1}k. For more information see: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-markdown-summary";
|
public static readonly string UnsupportedSummarySize = "$GITHUB_STEP_SUMMARY upload aborted, supports content up to a size of {0}k, got {1}k. For more information see: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-markdown-summary";
|
||||||
public static readonly string SummaryUploadError = "$GITHUB_STEP_SUMMARY upload aborted, an error occurred when uploading the summary. For more information see: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-markdown-summary";
|
|
||||||
public static readonly string Node12DetectedAfterEndOfLife = "Node.js 12 actions are deprecated. Please update the following actions to use Node.js 16: {0}. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RunnerEvent
|
public static class RunnerEvent
|
||||||
@@ -205,7 +193,6 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
public static readonly string JobStartedStepName = "Set up runner";
|
public static readonly string JobStartedStepName = "Set up runner";
|
||||||
public static readonly string JobCompletedStepName = "Complete runner";
|
public static readonly string JobCompletedStepName = "Complete runner";
|
||||||
public static readonly string ContainerHooksPath = "ACTIONS_RUNNER_CONTAINER_HOOKS";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Path
|
public static class Path
|
||||||
@@ -237,7 +224,6 @@ namespace GitHub.Runner.Common
|
|||||||
//
|
//
|
||||||
public static readonly string AllowUnsupportedCommands = "ACTIONS_ALLOW_UNSECURE_COMMANDS";
|
public static readonly string AllowUnsupportedCommands = "ACTIONS_ALLOW_UNSECURE_COMMANDS";
|
||||||
public static readonly string AllowUnsupportedStopCommandTokens = "ACTIONS_ALLOW_UNSECURE_STOPCOMMAND_TOKENS";
|
public static readonly string AllowUnsupportedStopCommandTokens = "ACTIONS_ALLOW_UNSECURE_STOPCOMMAND_TOKENS";
|
||||||
public static readonly string RequireJobContainer = "ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER";
|
|
||||||
public static readonly string RunnerDebug = "ACTIONS_RUNNER_DEBUG";
|
public static readonly string RunnerDebug = "ACTIONS_RUNNER_DEBUG";
|
||||||
public static readonly string StepDebug = "ACTIONS_STEP_DEBUG";
|
public static readonly string StepDebug = "ACTIONS_STEP_DEBUG";
|
||||||
public static readonly string AllowActionsUseUnsecureNodeVersion = "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION";
|
public static readonly string AllowActionsUseUnsecureNodeVersion = "ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION";
|
||||||
@@ -249,8 +235,6 @@ namespace GitHub.Runner.Common
|
|||||||
|
|
||||||
// Set this env var to "node12" to downgrade the node version for internal functions (e.g hashfiles). This does NOT affect the version of node actions.
|
// Set this env var to "node12" to downgrade the node version for internal functions (e.g hashfiles). This does NOT affect the version of node actions.
|
||||||
public static readonly string ForcedInternalNodeVersion = "ACTIONS_RUNNER_FORCED_INTERNAL_NODE_VERSION";
|
public static readonly string ForcedInternalNodeVersion = "ACTIONS_RUNNER_FORCED_INTERNAL_NODE_VERSION";
|
||||||
public static readonly string ForcedActionsNodeVersion = "ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION";
|
|
||||||
public static readonly string PrintLogToStdout = "ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class System
|
public static class System
|
||||||
@@ -263,12 +247,5 @@ namespace GitHub.Runner.Common
|
|||||||
public static readonly string PhaseDisplayName = "system.phaseDisplayName";
|
public static readonly string PhaseDisplayName = "system.phaseDisplayName";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class OperatingSystem
|
|
||||||
{
|
|
||||||
public static readonly int Windows11BuildVersion = 22000;
|
|
||||||
// Both windows 10 and windows 11 share the same Major Version 10, need to use the build version to differentiate
|
|
||||||
public static readonly int Windows11MajorVersion = 10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
@@ -14,7 +15,7 @@ namespace GitHub.Runner.Common
|
|||||||
|
|
||||||
public sealed class ExtensionManager : RunnerService, IExtensionManager
|
public sealed class ExtensionManager : RunnerService, IExtensionManager
|
||||||
{
|
{
|
||||||
private readonly ConcurrentDictionary<Type, List<IExtension>> _cache = new();
|
private readonly ConcurrentDictionary<Type, List<IExtension>> _cache = new ConcurrentDictionary<Type, List<IExtension>>();
|
||||||
|
|
||||||
public List<T> GetExtensions<T>() where T : class, IExtension
|
public List<T> GetExtensions<T>() where T : class, IExtension
|
||||||
{
|
{
|
||||||
@@ -60,8 +61,6 @@ namespace GitHub.Runner.Common
|
|||||||
Add<T>(extensions, "GitHub.Runner.Worker.AddPathFileCommand, Runner.Worker");
|
Add<T>(extensions, "GitHub.Runner.Worker.AddPathFileCommand, Runner.Worker");
|
||||||
Add<T>(extensions, "GitHub.Runner.Worker.SetEnvFileCommand, Runner.Worker");
|
Add<T>(extensions, "GitHub.Runner.Worker.SetEnvFileCommand, Runner.Worker");
|
||||||
Add<T>(extensions, "GitHub.Runner.Worker.CreateStepSummaryCommand, Runner.Worker");
|
Add<T>(extensions, "GitHub.Runner.Worker.CreateStepSummaryCommand, Runner.Worker");
|
||||||
Add<T>(extensions, "GitHub.Runner.Worker.SaveStateFileCommand, Runner.Worker");
|
|
||||||
Add<T>(extensions, "GitHub.Runner.Worker.SetOutputFileCommand, Runner.Worker");
|
|
||||||
break;
|
break;
|
||||||
case "GitHub.Runner.Listener.Check.ICheckExtension":
|
case "GitHub.Runner.Listener.Check.ICheckExtension":
|
||||||
Add<T>(extensions, "GitHub.Runner.Listener.Check.InternetCheck, Runner.Listener");
|
Add<T>(extensions, "GitHub.Runner.Listener.Check.InternetCheck, Runner.Listener");
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ using System.Runtime.Loader;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.DistributedTask.Logging;
|
using GitHub.DistributedTask.Logging;
|
||||||
using GitHub.Runner.Common.Util;
|
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
@@ -51,12 +50,12 @@ namespace GitHub.Runner.Common
|
|||||||
private static int _defaultLogRetentionDays = 30;
|
private static int _defaultLogRetentionDays = 30;
|
||||||
private static int[] _vssHttpMethodEventIds = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 24 };
|
private static int[] _vssHttpMethodEventIds = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 24 };
|
||||||
private static int[] _vssHttpCredentialEventIds = new int[] { 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 27, 29 };
|
private static int[] _vssHttpCredentialEventIds = new int[] { 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 27, 29 };
|
||||||
private readonly ConcurrentDictionary<Type, object> _serviceInstances = new();
|
private readonly ConcurrentDictionary<Type, object> _serviceInstances = new ConcurrentDictionary<Type, object>();
|
||||||
private readonly ConcurrentDictionary<Type, Type> _serviceTypes = new();
|
private readonly ConcurrentDictionary<Type, Type> _serviceTypes = new ConcurrentDictionary<Type, Type>();
|
||||||
private readonly ISecretMasker _secretMasker = new SecretMasker();
|
private readonly ISecretMasker _secretMasker = new SecretMasker();
|
||||||
private readonly List<ProductInfoHeaderValue> _userAgents = new() { new ProductInfoHeaderValue($"GitHubActionsRunner-{BuildConstants.RunnerPackage.PackageName}", BuildConstants.RunnerPackage.Version) };
|
private readonly List<ProductInfoHeaderValue> _userAgents = new List<ProductInfoHeaderValue>() { new ProductInfoHeaderValue($"GitHubActionsRunner-{BuildConstants.RunnerPackage.PackageName}", BuildConstants.RunnerPackage.Version) };
|
||||||
private CancellationTokenSource _runnerShutdownTokenSource = new();
|
private CancellationTokenSource _runnerShutdownTokenSource = new CancellationTokenSource();
|
||||||
private object _perfLock = new();
|
private object _perfLock = new object();
|
||||||
private Tracing _trace;
|
private Tracing _trace;
|
||||||
private Tracing _actionsHttpTrace;
|
private Tracing _actionsHttpTrace;
|
||||||
private Tracing _netcoreHttpTrace;
|
private Tracing _netcoreHttpTrace;
|
||||||
@@ -66,7 +65,7 @@ namespace GitHub.Runner.Common
|
|||||||
private IDisposable _diagListenerSubscription;
|
private IDisposable _diagListenerSubscription;
|
||||||
private StartupType _startupType;
|
private StartupType _startupType;
|
||||||
private string _perfFile;
|
private string _perfFile;
|
||||||
private RunnerWebProxy _webProxy = new();
|
private RunnerWebProxy _webProxy = new RunnerWebProxy();
|
||||||
|
|
||||||
public event EventHandler Unloading;
|
public event EventHandler Unloading;
|
||||||
public CancellationToken RunnerShutdownToken => _runnerShutdownTokenSource.Token;
|
public CancellationToken RunnerShutdownToken => _runnerShutdownTokenSource.Token;
|
||||||
@@ -94,13 +93,6 @@ namespace GitHub.Runner.Common
|
|||||||
this.SecretMasker.AddValueEncoder(ValueEncoders.PowerShellPreAmpersandEscape);
|
this.SecretMasker.AddValueEncoder(ValueEncoders.PowerShellPreAmpersandEscape);
|
||||||
this.SecretMasker.AddValueEncoder(ValueEncoders.PowerShellPostAmpersandEscape);
|
this.SecretMasker.AddValueEncoder(ValueEncoders.PowerShellPostAmpersandEscape);
|
||||||
|
|
||||||
// Create StdoutTraceListener if ENV is set
|
|
||||||
StdoutTraceListener stdoutTraceListener = null;
|
|
||||||
if (StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable(Constants.Variables.Agent.PrintLogToStdout)))
|
|
||||||
{
|
|
||||||
stdoutTraceListener = new StdoutTraceListener(hostType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the trace manager.
|
// Create the trace manager.
|
||||||
if (string.IsNullOrEmpty(logFile))
|
if (string.IsNullOrEmpty(logFile))
|
||||||
{
|
{
|
||||||
@@ -120,11 +112,11 @@ namespace GitHub.Runner.Common
|
|||||||
|
|
||||||
// this should give us _diag folder under runner root directory
|
// this should give us _diag folder under runner root directory
|
||||||
string diagLogDirectory = Path.Combine(new DirectoryInfo(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)).Parent.FullName, Constants.Path.DiagDirectory);
|
string diagLogDirectory = Path.Combine(new DirectoryInfo(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)).Parent.FullName, Constants.Path.DiagDirectory);
|
||||||
_traceManager = new TraceManager(new HostTraceListener(diagLogDirectory, hostType, logPageSize, logRetentionDays), stdoutTraceListener, this.SecretMasker);
|
_traceManager = new TraceManager(new HostTraceListener(diagLogDirectory, hostType, logPageSize, logRetentionDays), this.SecretMasker);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_traceManager = new TraceManager(new HostTraceListener(logFile), stdoutTraceListener, this.SecretMasker);
|
_traceManager = new TraceManager(new HostTraceListener(logFile), this.SecretMasker);
|
||||||
}
|
}
|
||||||
|
|
||||||
_trace = GetTrace(nameof(HostContext));
|
_trace = GetTrace(nameof(HostContext));
|
||||||
@@ -226,20 +218,6 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
|
|
||||||
_userAgents.Add(new ProductInfoHeaderValue("CommitSHA", BuildConstants.Source.CommitHash));
|
_userAgents.Add(new ProductInfoHeaderValue("CommitSHA", BuildConstants.Source.CommitHash));
|
||||||
|
|
||||||
var extraUserAgent = Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT");
|
|
||||||
if (!string.IsNullOrEmpty(extraUserAgent))
|
|
||||||
{
|
|
||||||
var extraUserAgentSplit = extraUserAgent.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (extraUserAgentSplit.Length != 2)
|
|
||||||
{
|
|
||||||
_trace.Error($"GITHUB_ACTIONS_RUNNER_EXTRA_USER_AGENT is not in the format of 'name/version'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var extraUserAgentHeader = new ProductInfoHeaderValue(extraUserAgentSplit[0], extraUserAgentSplit[1]);
|
|
||||||
_trace.Info($"Adding extra user agent '{extraUserAgentHeader}' to all HTTP requests.");
|
|
||||||
_userAgents.Add(extraUserAgentHeader);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetDirectory(WellKnownDirectory directory)
|
public string GetDirectory(WellKnownDirectory directory)
|
||||||
@@ -663,31 +641,6 @@ namespace GitHub.Runner.Common
|
|||||||
var handlerFactory = context.GetService<IHttpClientHandlerFactory>();
|
var handlerFactory = context.GetService<IHttpClientHandlerFactory>();
|
||||||
return handlerFactory.CreateClientHandler(context.WebProxy);
|
return handlerFactory.CreateClientHandler(context.WebProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetDefaultShellForScript(this IHostContext hostContext, string path, string prependPath)
|
|
||||||
{
|
|
||||||
var trace = hostContext.GetTrace(nameof(GetDefaultShellForScript));
|
|
||||||
switch (Path.GetExtension(path))
|
|
||||||
{
|
|
||||||
case ".sh":
|
|
||||||
// use 'sh' args but prefer bash
|
|
||||||
if (WhichUtil.Which("bash", false, trace, prependPath) != null)
|
|
||||||
{
|
|
||||||
return "bash";
|
|
||||||
}
|
|
||||||
return "sh";
|
|
||||||
case ".ps1":
|
|
||||||
if (WhichUtil.Which("pwsh", false, trace, prependPath) != null)
|
|
||||||
{
|
|
||||||
return "pwsh";
|
|
||||||
}
|
|
||||||
return "powershell";
|
|
||||||
case ".js":
|
|
||||||
return Path.Combine(hostContext.GetDirectory(WellKnownDirectory.Externals), NodeUtil.GetInternalNodeVersion(), "bin", $"node{IOUtil.ExeExtension}") + " {0}";
|
|
||||||
default:
|
|
||||||
throw new ArgumentException($"{path} is not a valid path to a script. Make sure it ends in '.sh', '.ps1' or '.js'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ShutdownReason
|
public enum ShutdownReason
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -164,7 +165,7 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
if (_enableLogRetention)
|
if (_enableLogRetention)
|
||||||
{
|
{
|
||||||
DirectoryInfo diags = new(_logFileDirectory);
|
DirectoryInfo diags = new DirectoryInfo(_logFileDirectory);
|
||||||
var logs = diags.GetFiles($"{_logFilePrefix}*.log");
|
var logs = diags.GetFiles($"{_logFilePrefix}*.log");
|
||||||
foreach (var log in logs)
|
foreach (var log in logs)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Pipes;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
|
using GitHub.DistributedTask.WebApi;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Net.WebSockets;
|
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;
|
||||||
using GitHub.Services.WebApi.Utilities.Internal;
|
using Newtonsoft.Json;
|
||||||
using GitHub.Services.Results.Client;
|
|
||||||
using GitHub.Services.OAuth;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
{
|
{
|
||||||
@@ -24,13 +20,11 @@ namespace GitHub.Runner.Common
|
|||||||
Task ConnectAsync(VssConnection jobConnection);
|
Task ConnectAsync(VssConnection jobConnection);
|
||||||
|
|
||||||
void InitializeWebsocketClient(ServiceEndpoint serviceEndpoint);
|
void InitializeWebsocketClient(ServiceEndpoint serviceEndpoint);
|
||||||
void InitializeResultsClient(Uri uri, string token);
|
|
||||||
|
|
||||||
// logging and console
|
// logging and console
|
||||||
Task<TaskLog> AppendLogContentAsync(Guid scopeIdentifier, string hubName, Guid planId, int logId, Stream uploadStream, CancellationToken cancellationToken);
|
Task<TaskLog> AppendLogContentAsync(Guid scopeIdentifier, string hubName, Guid planId, int logId, Stream uploadStream, CancellationToken cancellationToken);
|
||||||
Task AppendTimelineRecordFeedAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, Guid timelineRecordId, Guid stepId, IList<string> lines, long? startLine, CancellationToken cancellationToken);
|
Task AppendTimelineRecordFeedAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, Guid timelineRecordId, Guid stepId, IList<string> lines, long? startLine, CancellationToken cancellationToken);
|
||||||
Task<TaskAttachment> CreateAttachmentAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, Guid timelineRecordId, String type, String name, Stream uploadStream, CancellationToken cancellationToken);
|
Task<TaskAttachment> CreateAttachmentAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, Guid timelineRecordId, String type, String name, Stream uploadStream, CancellationToken cancellationToken);
|
||||||
Task CreateStepSymmaryAsync(string planId, string jobId, string stepId, string file, CancellationToken cancellationToken);
|
|
||||||
Task<TaskLog> CreateLogAsync(Guid scopeIdentifier, string hubName, Guid planId, TaskLog log, CancellationToken cancellationToken);
|
Task<TaskLog> CreateLogAsync(Guid scopeIdentifier, string hubName, Guid planId, TaskLog log, CancellationToken cancellationToken);
|
||||||
Task<Timeline> CreateTimelineAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, CancellationToken cancellationToken);
|
Task<Timeline> CreateTimelineAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, CancellationToken cancellationToken);
|
||||||
Task<List<TimelineRecord>> UpdateTimelineRecordsAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, IEnumerable<TimelineRecord> records, CancellationToken cancellationToken);
|
Task<List<TimelineRecord>> UpdateTimelineRecordsAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, IEnumerable<TimelineRecord> records, CancellationToken cancellationToken);
|
||||||
@@ -44,7 +38,6 @@ namespace GitHub.Runner.Common
|
|||||||
private bool _hasConnection;
|
private bool _hasConnection;
|
||||||
private VssConnection _connection;
|
private VssConnection _connection;
|
||||||
private TaskHttpClient _taskClient;
|
private TaskHttpClient _taskClient;
|
||||||
private ResultsHttpClient _resultsClient;
|
|
||||||
private ClientWebSocket _websocketClient;
|
private ClientWebSocket _websocketClient;
|
||||||
|
|
||||||
private ServiceEndpoint _serviceEndpoint;
|
private ServiceEndpoint _serviceEndpoint;
|
||||||
@@ -148,18 +141,10 @@ namespace GitHub.Runner.Common
|
|||||||
InitializeWebsocketClient(TimeSpan.Zero);
|
InitializeWebsocketClient(TimeSpan.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeResultsClient(Uri uri, string token)
|
|
||||||
{
|
|
||||||
var httpMessageHandler = HostContext.CreateHttpClientHandler();
|
|
||||||
this._resultsClient = new ResultsHttpClient(uri, httpMessageHandler, token, disposeHandler: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueTask DisposeAsync()
|
public ValueTask DisposeAsync()
|
||||||
{
|
{
|
||||||
CloseWebSocket(WebSocketCloseStatus.NormalClosure, CancellationToken.None);
|
_websocketClient?.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Shutdown", CancellationToken.None);
|
||||||
|
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
|
|
||||||
return ValueTask.CompletedTask;
|
return ValueTask.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,11 +169,6 @@ namespace GitHub.Runner.Common
|
|||||||
Trace.Info($"Creating websocket client ..." + feedStreamUrl);
|
Trace.Info($"Creating websocket client ..." + feedStreamUrl);
|
||||||
this._websocketClient = new ClientWebSocket();
|
this._websocketClient = new ClientWebSocket();
|
||||||
this._websocketClient.Options.SetRequestHeader("Authorization", $"Bearer {accessToken}");
|
this._websocketClient.Options.SetRequestHeader("Authorization", $"Bearer {accessToken}");
|
||||||
var userAgentValues = new List<ProductInfoHeaderValue>();
|
|
||||||
userAgentValues.AddRange(UserAgentUtility.GetDefaultRestUserAgent());
|
|
||||||
userAgentValues.AddRange(HostContext.UserAgents);
|
|
||||||
this._websocketClient.Options.SetRequestHeader("User-Agent", string.Join(" ", userAgentValues.Select(x => x.ToString())));
|
|
||||||
|
|
||||||
this._websocketConnectTask = ConnectWebSocketClient(feedStreamUrl, delay);
|
this._websocketConnectTask = ConnectWebSocketClient(feedStreamUrl, delay);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -211,7 +191,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);
|
||||||
@@ -241,7 +221,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
|
||||||
{
|
{
|
||||||
@@ -252,7 +232,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;
|
||||||
@@ -268,8 +248,7 @@ namespace GitHub.Runner.Common
|
|||||||
if (failedAttemptsToPostBatchedLinesByWebsocket * 100 / totalBatchedLinesAttemptedByWebsocket > _minWebsocketFailurePercentageAllowed)
|
if (failedAttemptsToPostBatchedLinesByWebsocket * 100 / totalBatchedLinesAttemptedByWebsocket > _minWebsocketFailurePercentageAllowed)
|
||||||
{
|
{
|
||||||
Trace.Info($"Exhausted websocket allowed retries, we will not attempt websocket connection for this job to post lines again.");
|
Trace.Info($"Exhausted websocket allowed retries, we will not attempt websocket connection for this job to post lines again.");
|
||||||
CloseWebSocket(WebSocketCloseStatus.InternalServerError, cancellationToken);
|
_websocketClient?.CloseOutputAsync(WebSocketCloseStatus.InternalServerError, "Shutdown due to failures", cancellationToken);
|
||||||
|
|
||||||
// By setting it to null, we will ensure that we never try websocket path again for this job
|
// By setting it to null, we will ensure that we never try websocket path again for this job
|
||||||
_websocketClient = null;
|
_websocketClient = null;
|
||||||
}
|
}
|
||||||
@@ -284,7 +263,7 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pushedLinesViaWebsocket && !cancellationToken.IsCancellationRequested)
|
if (!pushedLinesViaWebsocket)
|
||||||
{
|
{
|
||||||
if (startLine.HasValue)
|
if (startLine.HasValue)
|
||||||
{
|
{
|
||||||
@@ -297,35 +276,12 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseWebSocket(WebSocketCloseStatus closeStatus, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_websocketClient?.CloseOutputAsync(closeStatus, "Closing websocket", cancellationToken);
|
|
||||||
}
|
|
||||||
catch (Exception websocketEx)
|
|
||||||
{
|
|
||||||
// In some cases this might be okay since the websocket might be open yet, so just close and don't trace exceptions
|
|
||||||
Trace.Info($"Failed to close websocket gracefully {websocketEx.GetType().Name}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<TaskAttachment> CreateAttachmentAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, Guid timelineRecordId, string type, string name, Stream uploadStream, CancellationToken cancellationToken)
|
public Task<TaskAttachment> CreateAttachmentAsync(Guid scopeIdentifier, string hubName, Guid planId, Guid timelineId, Guid timelineRecordId, string type, string name, Stream uploadStream, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
CheckConnection();
|
CheckConnection();
|
||||||
return _taskClient.CreateAttachmentAsync(scopeIdentifier, hubName, planId, timelineId, timelineRecordId, type, name, uploadStream, cancellationToken: cancellationToken);
|
return _taskClient.CreateAttachmentAsync(scopeIdentifier, hubName, planId, timelineId, timelineRecordId, type, name, uploadStream, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task CreateStepSymmaryAsync(string planId, string jobId, string stepId, string file, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
if (_resultsClient != null)
|
|
||||||
{
|
|
||||||
return _resultsClient.UploadStepSummaryAsync(planId, jobId, stepId, file, cancellationToken: cancellationToken);
|
|
||||||
}
|
|
||||||
throw new InvalidOperationException("Results client is not initialized.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Task<TaskLog> CreateLogAsync(Guid scopeIdentifier, string hubName, Guid planId, TaskLog log, CancellationToken cancellationToken)
|
public Task<TaskLog> CreateLogAsync(Guid scopeIdentifier, string hubName, Guid planId, TaskLog log, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
CheckConnection();
|
CheckConnection();
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ namespace GitHub.Runner.Common
|
|||||||
void Start(Pipelines.AgentJobRequestMessage jobRequest);
|
void Start(Pipelines.AgentJobRequestMessage jobRequest);
|
||||||
void QueueWebConsoleLine(Guid stepRecordId, string line, long? lineNumber = null);
|
void QueueWebConsoleLine(Guid stepRecordId, string line, long? lineNumber = null);
|
||||||
void QueueFileUpload(Guid timelineId, Guid timelineRecordId, string type, string name, string path, bool deleteSource);
|
void QueueFileUpload(Guid timelineId, Guid timelineRecordId, string type, string name, string path, bool deleteSource);
|
||||||
void QueueSummaryUpload(Guid stepRecordId, string name, string path, bool deleteSource);
|
|
||||||
void QueueTimelineRecordUpdate(Guid timelineId, TimelineRecord timelineRecord);
|
void QueueTimelineRecordUpdate(Guid timelineId, TimelineRecord timelineRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +30,6 @@ namespace GitHub.Runner.Common
|
|||||||
private static readonly TimeSpan _delayForWebConsoleLineDequeue = TimeSpan.FromMilliseconds(500);
|
private static readonly TimeSpan _delayForWebConsoleLineDequeue = TimeSpan.FromMilliseconds(500);
|
||||||
private static readonly TimeSpan _delayForTimelineUpdateDequeue = TimeSpan.FromMilliseconds(500);
|
private static readonly TimeSpan _delayForTimelineUpdateDequeue = TimeSpan.FromMilliseconds(500);
|
||||||
private static readonly TimeSpan _delayForFileUploadDequeue = TimeSpan.FromMilliseconds(1000);
|
private static readonly TimeSpan _delayForFileUploadDequeue = TimeSpan.FromMilliseconds(1000);
|
||||||
private static readonly TimeSpan _delayForSummaryUploadDequeue = TimeSpan.FromMilliseconds(1000);
|
|
||||||
|
|
||||||
// Job message information
|
// Job message information
|
||||||
private Guid _scopeIdentifier;
|
private Guid _scopeIdentifier;
|
||||||
@@ -41,33 +39,30 @@ namespace GitHub.Runner.Common
|
|||||||
private Guid _jobTimelineRecordId;
|
private Guid _jobTimelineRecordId;
|
||||||
|
|
||||||
// queue for web console line
|
// queue for web console line
|
||||||
private readonly ConcurrentQueue<ConsoleLineInfo> _webConsoleLineQueue = new();
|
private readonly ConcurrentQueue<ConsoleLineInfo> _webConsoleLineQueue = new ConcurrentQueue<ConsoleLineInfo>();
|
||||||
|
|
||||||
// queue for file upload (log file or attachment)
|
// queue for file upload (log file or attachment)
|
||||||
private readonly ConcurrentQueue<UploadFileInfo> _fileUploadQueue = new();
|
private readonly ConcurrentQueue<UploadFileInfo> _fileUploadQueue = new ConcurrentQueue<UploadFileInfo>();
|
||||||
|
|
||||||
private readonly ConcurrentQueue<SummaryUploadFileInfo> _summaryFileUploadQueue = new();
|
|
||||||
|
|
||||||
// queue for timeline or timeline record update (one queue per timeline)
|
// queue for timeline or timeline record update (one queue per timeline)
|
||||||
private readonly ConcurrentDictionary<Guid, ConcurrentQueue<TimelineRecord>> _timelineUpdateQueue = new();
|
private readonly ConcurrentDictionary<Guid, ConcurrentQueue<TimelineRecord>> _timelineUpdateQueue = new ConcurrentDictionary<Guid, ConcurrentQueue<TimelineRecord>>();
|
||||||
|
|
||||||
// indicate how many timelines we have, we will process _timelineUpdateQueue base on the order of timeline in this list
|
// indicate how many timelines we have, we will process _timelineUpdateQueue base on the order of timeline in this list
|
||||||
private readonly List<Guid> _allTimelines = new();
|
private readonly List<Guid> _allTimelines = new List<Guid>();
|
||||||
|
|
||||||
// bufferd timeline records that fail to update
|
// bufferd timeline records that fail to update
|
||||||
private readonly Dictionary<Guid, List<TimelineRecord>> _bufferedRetryRecords = new();
|
private readonly Dictionary<Guid, List<TimelineRecord>> _bufferedRetryRecords = new Dictionary<Guid, List<TimelineRecord>>();
|
||||||
|
|
||||||
// Task for each queue's dequeue process
|
// Task for each queue's dequeue process
|
||||||
private Task _webConsoleLineDequeueTask;
|
private Task _webConsoleLineDequeueTask;
|
||||||
private Task _fileUploadDequeueTask;
|
private Task _fileUploadDequeueTask;
|
||||||
private Task _summaryUploadDequeueTask;
|
|
||||||
private Task _timelineUpdateDequeueTask;
|
private Task _timelineUpdateDequeueTask;
|
||||||
|
|
||||||
// common
|
// common
|
||||||
private IJobServer _jobServer;
|
private IJobServer _jobServer;
|
||||||
private Task[] _allDequeueTasks;
|
private Task[] _allDequeueTasks;
|
||||||
private readonly TaskCompletionSource<int> _jobCompletionSource = new();
|
private readonly TaskCompletionSource<int> _jobCompletionSource = new TaskCompletionSource<int>();
|
||||||
private readonly TaskCompletionSource<int> _jobRecordUpdated = new();
|
private readonly TaskCompletionSource<int> _jobRecordUpdated = new TaskCompletionSource<int>();
|
||||||
private bool _queueInProcess = false;
|
private bool _queueInProcess = false;
|
||||||
|
|
||||||
public TaskCompletionSource<int> JobRecordUpdated => _jobRecordUpdated;
|
public TaskCompletionSource<int> JobRecordUpdated => _jobRecordUpdated;
|
||||||
@@ -98,20 +93,6 @@ namespace GitHub.Runner.Common
|
|||||||
|
|
||||||
_jobServer.InitializeWebsocketClient(serviceEndPoint);
|
_jobServer.InitializeWebsocketClient(serviceEndPoint);
|
||||||
|
|
||||||
// This code is usually wrapped by an instance of IExecutionContext which isn't available here.
|
|
||||||
jobRequest.Variables.TryGetValue("system.github.results_endpoint", out VariableValue resultsEndpointVariable);
|
|
||||||
var resultsReceiverEndpoint = resultsEndpointVariable?.Value;
|
|
||||||
|
|
||||||
if (serviceEndPoint?.Authorization != null &&
|
|
||||||
serviceEndPoint.Authorization.Parameters.TryGetValue("AccessToken", out var accessToken) &&
|
|
||||||
!string.IsNullOrEmpty(accessToken) &&
|
|
||||||
!string.IsNullOrEmpty(resultsReceiverEndpoint))
|
|
||||||
{
|
|
||||||
Trace.Info("Initializing results client");
|
|
||||||
_jobServer.InitializeResultsClient(new Uri(resultsReceiverEndpoint), accessToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (_queueInProcess)
|
if (_queueInProcess)
|
||||||
{
|
{
|
||||||
Trace.Info("No-opt, all queue process tasks are running.");
|
Trace.Info("No-opt, all queue process tasks are running.");
|
||||||
@@ -139,13 +120,10 @@ namespace GitHub.Runner.Common
|
|||||||
Trace.Info("Start process file upload queue.");
|
Trace.Info("Start process file upload queue.");
|
||||||
_fileUploadDequeueTask = ProcessFilesUploadQueueAsync();
|
_fileUploadDequeueTask = ProcessFilesUploadQueueAsync();
|
||||||
|
|
||||||
Trace.Info("Start results file upload queue.");
|
|
||||||
_summaryUploadDequeueTask = ProcessSummaryUploadQueueAsync();
|
|
||||||
|
|
||||||
Trace.Info("Start process timeline update queue.");
|
Trace.Info("Start process timeline update queue.");
|
||||||
_timelineUpdateDequeueTask = ProcessTimelinesUpdateQueueAsync();
|
_timelineUpdateDequeueTask = ProcessTimelinesUpdateQueueAsync();
|
||||||
|
|
||||||
_allDequeueTasks = new Task[] { _webConsoleLineDequeueTask, _fileUploadDequeueTask, _timelineUpdateDequeueTask, _summaryUploadDequeueTask };
|
_allDequeueTasks = new Task[] { _webConsoleLineDequeueTask, _fileUploadDequeueTask, _timelineUpdateDequeueTask };
|
||||||
_queueInProcess = true;
|
_queueInProcess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,10 +154,6 @@ namespace GitHub.Runner.Common
|
|||||||
await ProcessFilesUploadQueueAsync(runOnce: true);
|
await ProcessFilesUploadQueueAsync(runOnce: true);
|
||||||
Trace.Info("File upload queue drained.");
|
Trace.Info("File upload queue drained.");
|
||||||
|
|
||||||
Trace.Verbose("Draining results summary upload queue.");
|
|
||||||
await ProcessSummaryUploadQueueAsync(runOnce: true);
|
|
||||||
Trace.Info("Results summary upload queue drained.");
|
|
||||||
|
|
||||||
// ProcessTimelinesUpdateQueueAsync() will throw exception during shutdown
|
// ProcessTimelinesUpdateQueueAsync() will throw exception during shutdown
|
||||||
// if there is any timeline records that failed to update contains output variabls.
|
// if there is any timeline records that failed to update contains output variabls.
|
||||||
Trace.Verbose("Draining timeline update queue.");
|
Trace.Verbose("Draining timeline update queue.");
|
||||||
@@ -230,23 +204,6 @@ namespace GitHub.Runner.Common
|
|||||||
_fileUploadQueue.Enqueue(newFile);
|
_fileUploadQueue.Enqueue(newFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueSummaryUpload(Guid stepRecordId, string name, string path, bool deleteSource)
|
|
||||||
{
|
|
||||||
// all parameter not null, file path exist.
|
|
||||||
var newFile = new SummaryUploadFileInfo()
|
|
||||||
{
|
|
||||||
Name = name,
|
|
||||||
Path = path,
|
|
||||||
PlanId = _planId.ToString(),
|
|
||||||
JobId = _jobTimelineRecordId.ToString(),
|
|
||||||
StepId = stepRecordId.ToString(),
|
|
||||||
DeleteSource = deleteSource
|
|
||||||
};
|
|
||||||
|
|
||||||
Trace.Verbose("Enqueue results file upload queue: file '{0}' attach to job {1} step {2}", newFile.Path, _jobTimelineRecordId, stepRecordId);
|
|
||||||
_summaryFileUploadQueue.Enqueue(newFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void QueueTimelineRecordUpdate(Guid timelineId, TimelineRecord timelineRecord)
|
public void QueueTimelineRecordUpdate(Guid timelineId, TimelineRecord timelineRecord)
|
||||||
{
|
{
|
||||||
ArgUtil.NotEmpty(timelineId, nameof(timelineId));
|
ArgUtil.NotEmpty(timelineId, nameof(timelineId));
|
||||||
@@ -280,8 +237,8 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Group consolelines by timeline record of each step
|
// Group consolelines by timeline record of each step
|
||||||
Dictionary<Guid, List<TimelineRecordLogLine>> stepsConsoleLines = new();
|
Dictionary<Guid, List<TimelineRecordLogLine>> stepsConsoleLines = new Dictionary<Guid, List<TimelineRecordLogLine>>();
|
||||||
List<Guid> stepRecordIds = new(); // We need to keep lines in order
|
List<Guid> stepRecordIds = new List<Guid>(); // We need to keep lines in order
|
||||||
int linesCounter = 0;
|
int linesCounter = 0;
|
||||||
ConsoleLineInfo lineInfo;
|
ConsoleLineInfo lineInfo;
|
||||||
while (_webConsoleLineQueue.TryDequeue(out lineInfo))
|
while (_webConsoleLineQueue.TryDequeue(out lineInfo))
|
||||||
@@ -307,7 +264,7 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
// Split consolelines into batch, each batch will container at most 100 lines.
|
// Split consolelines into batch, each batch will container at most 100 lines.
|
||||||
int batchCounter = 0;
|
int batchCounter = 0;
|
||||||
List<List<TimelineRecordLogLine>> batchedLines = new();
|
List<List<TimelineRecordLogLine>> batchedLines = new List<List<TimelineRecordLogLine>>();
|
||||||
foreach (var line in stepsConsoleLines[stepRecordId])
|
foreach (var line in stepsConsoleLines[stepRecordId])
|
||||||
{
|
{
|
||||||
var currentBatch = batchedLines.ElementAtOrDefault(batchCounter);
|
var currentBatch = batchedLines.ElementAtOrDefault(batchCounter);
|
||||||
@@ -342,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)
|
||||||
{
|
{
|
||||||
@@ -381,7 +334,7 @@ namespace GitHub.Runner.Common
|
|||||||
{
|
{
|
||||||
while (!_jobCompletionSource.Task.IsCompleted || runOnce)
|
while (!_jobCompletionSource.Task.IsCompleted || runOnce)
|
||||||
{
|
{
|
||||||
List<UploadFileInfo> filesToUpload = new();
|
List<UploadFileInfo> filesToUpload = new List<UploadFileInfo>();
|
||||||
UploadFileInfo dequeueFile;
|
UploadFileInfo dequeueFile;
|
||||||
while (_fileUploadQueue.TryDequeue(out dequeueFile))
|
while (_fileUploadQueue.TryDequeue(out dequeueFile))
|
||||||
{
|
{
|
||||||
@@ -437,84 +390,17 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ProcessSummaryUploadQueueAsync(bool runOnce = false)
|
|
||||||
{
|
|
||||||
Trace.Info("Starting results-based upload queue...");
|
|
||||||
|
|
||||||
while (!_jobCompletionSource.Task.IsCompleted || runOnce)
|
|
||||||
{
|
|
||||||
List<SummaryUploadFileInfo> filesToUpload = new();
|
|
||||||
SummaryUploadFileInfo dequeueFile;
|
|
||||||
while (_summaryFileUploadQueue.TryDequeue(out dequeueFile))
|
|
||||||
{
|
|
||||||
filesToUpload.Add(dequeueFile);
|
|
||||||
// process at most 10 file upload.
|
|
||||||
if (!runOnce && filesToUpload.Count > 10)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filesToUpload.Count > 0)
|
|
||||||
{
|
|
||||||
if (runOnce)
|
|
||||||
{
|
|
||||||
Trace.Info($"Uploading {filesToUpload.Count} summary files in one shot through results service.");
|
|
||||||
}
|
|
||||||
|
|
||||||
int errorCount = 0;
|
|
||||||
foreach (var file in filesToUpload)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await UploadSummaryFile(file);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
var issue = new Issue() { Type = IssueType.Warning, Message = $"Caught exception during summary file upload to results. {ex.Message}" };
|
|
||||||
issue.Data[Constants.Runner.InternalTelemetryIssueDataKey] = Constants.Runner.ResultsUploadFailure;
|
|
||||||
|
|
||||||
var telemetryRecord = new TimelineRecord()
|
|
||||||
{
|
|
||||||
Id = Constants.Runner.TelemetryRecordId,
|
|
||||||
};
|
|
||||||
telemetryRecord.Issues.Add(issue);
|
|
||||||
QueueTimelineRecordUpdate(_jobTimelineId, telemetryRecord);
|
|
||||||
|
|
||||||
Trace.Info("Catch exception during summary file upload to results, keep going since the process is best effort.");
|
|
||||||
Trace.Error(ex);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
errorCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Trace.Info("Tried to upload {0} summary files to results, success rate: {1}/{0}.", filesToUpload.Count, filesToUpload.Count - errorCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (runOnce)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await Task.Delay(_delayForSummaryUploadDequeue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ProcessTimelinesUpdateQueueAsync(bool runOnce = false)
|
private async Task ProcessTimelinesUpdateQueueAsync(bool runOnce = false)
|
||||||
{
|
{
|
||||||
while (!_jobCompletionSource.Task.IsCompleted || runOnce)
|
while (!_jobCompletionSource.Task.IsCompleted || runOnce)
|
||||||
{
|
{
|
||||||
List<PendingTimelineRecord> pendingUpdates = new();
|
List<PendingTimelineRecord> pendingUpdates = new List<PendingTimelineRecord>();
|
||||||
foreach (var timeline in _allTimelines)
|
foreach (var timeline in _allTimelines)
|
||||||
{
|
{
|
||||||
ConcurrentQueue<TimelineRecord> recordQueue;
|
ConcurrentQueue<TimelineRecord> recordQueue;
|
||||||
if (_timelineUpdateQueue.TryGetValue(timeline, out recordQueue))
|
if (_timelineUpdateQueue.TryGetValue(timeline, out recordQueue))
|
||||||
{
|
{
|
||||||
List<TimelineRecord> records = new();
|
List<TimelineRecord> records = new List<TimelineRecord>();
|
||||||
TimelineRecord record;
|
TimelineRecord record;
|
||||||
while (recordQueue.TryDequeue(out record))
|
while (recordQueue.TryDequeue(out record))
|
||||||
{
|
{
|
||||||
@@ -536,7 +422,7 @@ namespace GitHub.Runner.Common
|
|||||||
// we need track whether we have new sub-timeline been created on the last run.
|
// we need track whether we have new sub-timeline been created on the last run.
|
||||||
// if so, we need continue update timeline record even we on the last run.
|
// if so, we need continue update timeline record even we on the last run.
|
||||||
bool pendingSubtimelineUpdate = false;
|
bool pendingSubtimelineUpdate = false;
|
||||||
List<Exception> mainTimelineRecordsUpdateErrors = new();
|
List<Exception> mainTimelineRecordsUpdateErrors = new List<Exception>();
|
||||||
if (pendingUpdates.Count > 0)
|
if (pendingUpdates.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var update in pendingUpdates)
|
foreach (var update in pendingUpdates)
|
||||||
@@ -639,7 +525,7 @@ namespace GitHub.Runner.Common
|
|||||||
return timelineRecords;
|
return timelineRecords;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<Guid, TimelineRecord> dict = new();
|
Dictionary<Guid, TimelineRecord> dict = new Dictionary<Guid, TimelineRecord>();
|
||||||
foreach (TimelineRecord rec in timelineRecords)
|
foreach (TimelineRecord rec in timelineRecords)
|
||||||
{
|
{
|
||||||
if (rec == null)
|
if (rec == null)
|
||||||
@@ -775,35 +661,6 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UploadSummaryFile(SummaryUploadFileInfo file)
|
|
||||||
{
|
|
||||||
bool uploadSucceed = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Upload the step summary
|
|
||||||
Trace.Info($"Starting to upload summary file to results service {file.Name}, {file.Path}");
|
|
||||||
var cancellationTokenSource = new CancellationTokenSource();
|
|
||||||
await _jobServer.CreateStepSymmaryAsync(file.PlanId, file.JobId, file.StepId, file.Path, cancellationTokenSource.Token);
|
|
||||||
|
|
||||||
uploadSucceed = true;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (uploadSucceed && file.DeleteSource)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.Delete(file.Path);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Trace.Info("Catch exception during delete success results uploaded summary file.");
|
|
||||||
Trace.Error(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class PendingTimelineRecord
|
internal class PendingTimelineRecord
|
||||||
@@ -822,17 +679,6 @@ namespace GitHub.Runner.Common
|
|||||||
public bool DeleteSource { get; set; }
|
public bool DeleteSource { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class SummaryUploadFileInfo
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string Path { get; set; }
|
|
||||||
public string PlanId { get; set; }
|
|
||||||
public string JobId { get; set; }
|
|
||||||
public string StepId { get; set; }
|
|
||||||
public bool DeleteSource { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal class ConsoleLineInfo
|
internal class ConsoleLineInfo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
|
||||||
{
|
|
||||||
public class JobStatusEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public JobStatusEventArgs(TaskAgentStatus status)
|
|
||||||
{
|
|
||||||
this.Status = status;
|
|
||||||
}
|
|
||||||
public TaskAgentStatus Status { get; private set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace GitHub.Runner.Common
|
|||||||
|
|
||||||
public async Task<WorkerMessage> ReceiveAsync(CancellationToken cancellationToken)
|
public async Task<WorkerMessage> ReceiveAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
WorkerMessage result = new(MessageType.NotInitialized, string.Empty);
|
WorkerMessage result = new WorkerMessage(MessageType.NotInitialized, string.Empty);
|
||||||
result.MessageType = (MessageType)await _readStream.ReadInt32Async(cancellationToken);
|
result.MessageType = (MessageType)await _readStream.ReadInt32Async(cancellationToken);
|
||||||
result.Body = await _readStream.ReadStringAsync(cancellationToken);
|
result.Body = await _readStream.ReadStringAsync(cancellationToken);
|
||||||
Trace.Info($"Receiving message of length {result.Body.Length}, with hash '{IOUtil.GetSha256Hash(result.Body)}'");
|
Trace.Info($"Receiving message of length {result.Body.Length}, with hash '{IOUtil.GetSha256Hash(result.Body)}'");
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ namespace GitHub.Runner.Common
|
|||||||
public static string GetEnvironmentVariable(this Process process, IHostContext hostContext, string variable)
|
public static string GetEnvironmentVariable(this Process process, IHostContext hostContext, string variable)
|
||||||
{
|
{
|
||||||
var trace = hostContext.GetTrace(nameof(LinuxProcessExtensions));
|
var trace = hostContext.GetTrace(nameof(LinuxProcessExtensions));
|
||||||
Dictionary<string, string> env = new();
|
Dictionary<string, string> env = new Dictionary<string, string>();
|
||||||
|
|
||||||
if (Directory.Exists("/proc"))
|
if (Directory.Exists("/proc"))
|
||||||
{
|
{
|
||||||
@@ -322,8 +322,8 @@ namespace GitHub.Runner.Common
|
|||||||
// It doesn't escape '=' or ' ', so we can't parse the output into a dictionary of all envs.
|
// It doesn't escape '=' or ' ', so we can't parse the output into a dictionary of all envs.
|
||||||
// So we only look for the env you request, in the format of variable=value. (it won't work if you variable contains = or space)
|
// So we only look for the env you request, in the format of variable=value. (it won't work if you variable contains = or space)
|
||||||
trace.Info($"Read env from output of `ps e -p {process.Id} -o command`");
|
trace.Info($"Read env from output of `ps e -p {process.Id} -o command`");
|
||||||
List<string> psOut = new();
|
List<string> psOut = new List<string>();
|
||||||
object outputLock = new();
|
object outputLock = new object();
|
||||||
using (var p = hostContext.CreateService<IProcessInvoker>())
|
using (var p = hostContext.CreateService<IProcessInvoker>())
|
||||||
{
|
{
|
||||||
p.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stdout)
|
p.OutputDataReceived += delegate (object sender, ProcessDataReceivedEventArgs stdout)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using GitHub.Runner.Common.Util;
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using GitHub.DistributedTask.Pipelines;
|
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
using GitHub.Runner.Sdk;
|
|
||||||
using GitHub.Services.Common;
|
|
||||||
using GitHub.Services.WebApi;
|
|
||||||
using Sdk.WebApi.WebApi.RawClient;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
|
||||||
{
|
|
||||||
[ServiceLocator(Default = typeof(RunServer))]
|
|
||||||
public interface IRunServer : IRunnerService
|
|
||||||
{
|
|
||||||
Task ConnectAsync(Uri serverUrl, VssCredentials credentials);
|
|
||||||
|
|
||||||
Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class RunServer : RunnerService, IRunServer
|
|
||||||
{
|
|
||||||
private bool _hasConnection;
|
|
||||||
private Uri requestUri;
|
|
||||||
private RawConnection _connection;
|
|
||||||
private RunServiceHttpClient _runServiceHttpClient;
|
|
||||||
|
|
||||||
public async Task ConnectAsync(Uri serverUri, VssCredentials credentials)
|
|
||||||
{
|
|
||||||
requestUri = serverUri;
|
|
||||||
|
|
||||||
_connection = VssUtil.CreateRawConnection(new Uri(serverUri.Authority), credentials);
|
|
||||||
_runServiceHttpClient = await _connection.GetClientAsync<RunServiceHttpClient>();
|
|
||||||
_hasConnection = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckConnection()
|
|
||||||
{
|
|
||||||
if (!_hasConnection)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"SetConnection");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<AgentJobRequestMessage> GetJobMessageAsync(string id, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
CheckConnection();
|
|
||||||
var jobMessage = RetryRequest<AgentJobRequestMessage>(
|
|
||||||
async () => await _runServiceHttpClient.GetJobMessageAsync(requestUri, id, cancellationToken), cancellationToken);
|
|
||||||
if (jobMessage == null)
|
|
||||||
{
|
|
||||||
throw new TaskOrchestrationJobNotFoundException(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return jobMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64;win-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
<NoWarn>NU1701;NU1603</NoWarn>
|
<NoWarn>NU1701;NU1603</NoWarn>
|
||||||
<Version>$(Version)</Version>
|
<Version>$(Version)</Version>
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Win32.Registry" Version="4.4.0" />
|
<PackageReference Include="Microsoft.Win32.Registry" Version="4.4.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.4.0" />
|
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.4.0" />
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.4.0" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.4.0" />
|
||||||
<PackageReference Include="System.Threading.Channels" Version="4.4.0" />
|
<PackageReference Include="System.Threading.Channels" Version="4.4.0" />
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Services.WebApi;
|
using GitHub.Services.WebApi;
|
||||||
using GitHub.Services.Common;
|
using GitHub.Services.Common;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
@@ -38,7 +39,7 @@ namespace GitHub.Runner.Common
|
|||||||
Task<TaskAgentSession> CreateAgentSessionAsync(Int32 poolId, TaskAgentSession session, CancellationToken cancellationToken);
|
Task<TaskAgentSession> CreateAgentSessionAsync(Int32 poolId, TaskAgentSession session, CancellationToken cancellationToken);
|
||||||
Task DeleteAgentMessageAsync(Int32 poolId, Int64 messageId, Guid sessionId, CancellationToken cancellationToken);
|
Task DeleteAgentMessageAsync(Int32 poolId, Int64 messageId, Guid sessionId, CancellationToken cancellationToken);
|
||||||
Task DeleteAgentSessionAsync(Int32 poolId, Guid sessionId, CancellationToken cancellationToken);
|
Task DeleteAgentSessionAsync(Int32 poolId, Guid sessionId, CancellationToken cancellationToken);
|
||||||
Task<TaskAgentMessage> GetAgentMessageAsync(Int32 poolId, Guid sessionId, Int64? lastMessageId, TaskAgentStatus status, string runnerVersion, CancellationToken cancellationToken);
|
Task<TaskAgentMessage> GetAgentMessageAsync(Int32 poolId, Guid sessionId, Int64? lastMessageId, CancellationToken cancellationToken);
|
||||||
|
|
||||||
// job request
|
// job request
|
||||||
Task<TaskAgentJobRequest> GetAgentRequestAsync(int poolId, long requestId, CancellationToken cancellationToken);
|
Task<TaskAgentJobRequest> GetAgentRequestAsync(int poolId, long requestId, CancellationToken cancellationToken);
|
||||||
@@ -179,6 +180,31 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<VssConnection> EstablishVssConnection(Uri serverUrl, VssCredentials credentials, TimeSpan timeout)
|
||||||
|
{
|
||||||
|
Trace.Info($"Establish connection with {timeout.TotalSeconds} seconds timeout.");
|
||||||
|
int attemptCount = 5;
|
||||||
|
while (attemptCount-- > 0)
|
||||||
|
{
|
||||||
|
var connection = VssUtil.CreateConnection(serverUrl, credentials, timeout: timeout);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await connection.ConnectAsync();
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (attemptCount > 0)
|
||||||
|
{
|
||||||
|
Trace.Info($"Catch exception during connect. {attemptCount} attempt left.");
|
||||||
|
Trace.Error(ex);
|
||||||
|
|
||||||
|
await HostContext.Delay(TimeSpan.FromMilliseconds(100), CancellationToken.None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// should never reach here.
|
||||||
|
throw new InvalidOperationException(nameof(EstablishVssConnection));
|
||||||
|
}
|
||||||
|
|
||||||
private void CheckConnection(RunnerConnectionType connectionType)
|
private void CheckConnection(RunnerConnectionType connectionType)
|
||||||
{
|
{
|
||||||
switch (connectionType)
|
switch (connectionType)
|
||||||
@@ -272,10 +298,10 @@ namespace GitHub.Runner.Common
|
|||||||
return _messageTaskAgentClient.DeleteAgentSessionAsync(poolId, sessionId, cancellationToken: cancellationToken);
|
return _messageTaskAgentClient.DeleteAgentSessionAsync(poolId, sessionId, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TaskAgentMessage> GetAgentMessageAsync(Int32 poolId, Guid sessionId, Int64? lastMessageId, TaskAgentStatus status, string runnerVersion, CancellationToken cancellationToken)
|
public Task<TaskAgentMessage> GetAgentMessageAsync(Int32 poolId, Guid sessionId, Int64? lastMessageId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
CheckConnection(RunnerConnectionType.MessageQueue);
|
CheckConnection(RunnerConnectionType.MessageQueue);
|
||||||
return _messageTaskAgentClient.GetMessageAsync(poolId, sessionId, lastMessageId, status, runnerVersion, cancellationToken: cancellationToken);
|
return _messageTaskAgentClient.GetMessageAsync(poolId, sessionId, lastMessageId, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using GitHub.Runner.Sdk;
|
|
||||||
using GitHub.Services.Common;
|
|
||||||
using GitHub.Services.WebApi;
|
|
||||||
using Sdk.WebApi.WebApi.RawClient;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
namespace GitHub.Runner.Common
|
||||||
{
|
{
|
||||||
@@ -41,57 +35,5 @@ namespace GitHub.Runner.Common
|
|||||||
Trace = HostContext.GetTrace(TraceName);
|
Trace = HostContext.GetTrace(TraceName);
|
||||||
Trace.Entering();
|
Trace.Entering();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task<VssConnection> EstablishVssConnection(Uri serverUrl, VssCredentials credentials, TimeSpan timeout)
|
|
||||||
{
|
|
||||||
Trace.Info($"EstablishVssConnection");
|
|
||||||
Trace.Info($"Establish connection with {timeout.TotalSeconds} seconds timeout.");
|
|
||||||
int attemptCount = 5;
|
|
||||||
while (attemptCount-- > 0)
|
|
||||||
{
|
|
||||||
var connection = VssUtil.CreateConnection(serverUrl, credentials, timeout: timeout);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await connection.ConnectAsync();
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
catch (Exception ex) when (attemptCount > 0)
|
|
||||||
{
|
|
||||||
Trace.Info($"Catch exception during connect. {attemptCount} attempt left.");
|
|
||||||
Trace.Error(ex);
|
|
||||||
|
|
||||||
await HostContext.Delay(TimeSpan.FromMilliseconds(100), CancellationToken.None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// should never reach here.
|
|
||||||
throw new InvalidOperationException(nameof(EstablishVssConnection));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async Task<T> RetryRequest<T>(Func<Task<T>> func,
|
|
||||||
CancellationToken cancellationToken,
|
|
||||||
int maxRetryAttemptsCount = 5
|
|
||||||
)
|
|
||||||
{
|
|
||||||
var retryCount = 0;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
retryCount++;
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return await func();
|
|
||||||
}
|
|
||||||
// TODO: Add handling of non-retriable exceptions: https://github.com/github/actions-broker/issues/122
|
|
||||||
catch (Exception ex) when (retryCount < maxRetryAttemptsCount)
|
|
||||||
{
|
|
||||||
Trace.Error("Catch exception during get full job message");
|
|
||||||
Trace.Error(ex);
|
|
||||||
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15));
|
|
||||||
Trace.Warning($"Back off {backOff.TotalSeconds} seconds before next retry. {maxRetryAttemptsCount - retryCount} attempt left.");
|
|
||||||
await Task.Delay(backOff, cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
|
||||||
using GitHub.Runner.Sdk;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Common
|
|
||||||
{
|
|
||||||
public sealed class StdoutTraceListener : ConsoleTraceListener
|
|
||||||
{
|
|
||||||
private readonly string _hostType;
|
|
||||||
|
|
||||||
public StdoutTraceListener(string hostType)
|
|
||||||
{
|
|
||||||
this._hostType = hostType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copied and modified slightly from .Net Core source code. Modification was required to make it compile.
|
|
||||||
// There must be some TraceFilter extension class that is missing in this source code.
|
|
||||||
public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
|
|
||||||
{
|
|
||||||
if (Filter != null && !Filter.ShouldTrace(eventCache, source, eventType, id, message, null, null, null))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(message))
|
|
||||||
{
|
|
||||||
var messageLines = message.Split(Environment.NewLine);
|
|
||||||
foreach (var messageLine in messageLines)
|
|
||||||
{
|
|
||||||
WriteHeader(source, eventType, id);
|
|
||||||
WriteLine(messageLine);
|
|
||||||
WriteFooter(eventCache);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal bool IsEnabled(TraceOptions opts)
|
|
||||||
{
|
|
||||||
return (opts & TraceOutputOptions) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Altered from the original .Net Core implementation.
|
|
||||||
private void WriteHeader(string source, TraceEventType eventType, int id)
|
|
||||||
{
|
|
||||||
string type = null;
|
|
||||||
switch (eventType)
|
|
||||||
{
|
|
||||||
case TraceEventType.Critical:
|
|
||||||
type = "CRIT";
|
|
||||||
break;
|
|
||||||
case TraceEventType.Error:
|
|
||||||
type = "ERR ";
|
|
||||||
break;
|
|
||||||
case TraceEventType.Warning:
|
|
||||||
type = "WARN";
|
|
||||||
break;
|
|
||||||
case TraceEventType.Information:
|
|
||||||
type = "INFO";
|
|
||||||
break;
|
|
||||||
case TraceEventType.Verbose:
|
|
||||||
type = "VERB";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
type = eventType.ToString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Write(StringUtil.Format("[{0} {1:u} {2} {3}] ", _hostType.ToUpperInvariant(), DateTime.UtcNow, type, source));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copied and modified slightly from .Net Core source code to make it compile. The original code
|
|
||||||
// accesses a private indentLevel field. In this code it has been modified to use the getter/setter.
|
|
||||||
private void WriteFooter(TraceEventCache eventCache)
|
|
||||||
{
|
|
||||||
if (eventCache == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
IndentLevel++;
|
|
||||||
if (IsEnabled(TraceOptions.ProcessId))
|
|
||||||
WriteLine("ProcessId=" + eventCache.ProcessId);
|
|
||||||
|
|
||||||
if (IsEnabled(TraceOptions.ThreadId))
|
|
||||||
WriteLine("ThreadId=" + eventCache.ThreadId);
|
|
||||||
|
|
||||||
if (IsEnabled(TraceOptions.DateTime))
|
|
||||||
WriteLine("DateTime=" + eventCache.DateTime.ToString("o", CultureInfo.InvariantCulture));
|
|
||||||
|
|
||||||
if (IsEnabled(TraceOptions.Timestamp))
|
|
||||||
WriteLine("Timestamp=" + eventCache.Timestamp);
|
|
||||||
|
|
||||||
IndentLevel--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,7 @@ namespace GitHub.Runner.Common
|
|||||||
string ReadSecret();
|
string ReadSecret();
|
||||||
void Write(string message, ConsoleColor? colorCode = null);
|
void Write(string message, ConsoleColor? colorCode = null);
|
||||||
void WriteLine();
|
void WriteLine();
|
||||||
void WriteLine(string line, ConsoleColor? colorCode = null, bool skipTracing = false);
|
void WriteLine(string line, ConsoleColor? colorCode = null);
|
||||||
void WriteError(Exception ex);
|
void WriteError(Exception ex);
|
||||||
void WriteError(string line);
|
void WriteError(string line);
|
||||||
void WriteSection(string message);
|
void WriteSection(string message);
|
||||||
@@ -81,7 +81,7 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trace whether a value was entered.
|
// Trace whether a value was entered.
|
||||||
string val = new(chars.ToArray());
|
string val = new String(chars.ToArray());
|
||||||
if (!string.IsNullOrEmpty(val))
|
if (!string.IsNullOrEmpty(val))
|
||||||
{
|
{
|
||||||
HostContext.SecretMasker.AddValue(val);
|
HostContext.SecretMasker.AddValue(val);
|
||||||
@@ -116,12 +116,9 @@ namespace GitHub.Runner.Common
|
|||||||
|
|
||||||
// Do not add a format string overload. Terminal messages are user facing and therefore
|
// Do not add a format string overload. Terminal messages are user facing and therefore
|
||||||
// should be localized. Use the Loc method in the StringUtil class.
|
// should be localized. Use the Loc method in the StringUtil class.
|
||||||
public void WriteLine(string line, ConsoleColor? colorCode = null, bool skipTracing = false)
|
public void WriteLine(string line, ConsoleColor? colorCode = null)
|
||||||
{
|
|
||||||
if (!skipTracing)
|
|
||||||
{
|
{
|
||||||
Trace.Info($"WRITE LINE: {line}");
|
Trace.Info($"WRITE LINE: {line}");
|
||||||
}
|
|
||||||
if (!Silent)
|
if (!Silent)
|
||||||
{
|
{
|
||||||
if (colorCode != null)
|
if (colorCode != null)
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using GitHub.Services.Common.Internal;
|
using GitHub.Services.Common.Internal;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -14,25 +15,23 @@ namespace GitHub.Runner.Common
|
|||||||
|
|
||||||
public sealed class TraceManager : ITraceManager
|
public sealed class TraceManager : ITraceManager
|
||||||
{
|
{
|
||||||
private readonly ConcurrentDictionary<string, Tracing> _sources = new(StringComparer.OrdinalIgnoreCase);
|
private readonly ConcurrentDictionary<string, Tracing> _sources = new ConcurrentDictionary<string, Tracing>(StringComparer.OrdinalIgnoreCase);
|
||||||
private readonly HostTraceListener _hostTraceListener;
|
private readonly HostTraceListener _hostTraceListener;
|
||||||
private readonly StdoutTraceListener _stdoutTraceListener;
|
|
||||||
private TraceSetting _traceSetting;
|
private TraceSetting _traceSetting;
|
||||||
private ISecretMasker _secretMasker;
|
private ISecretMasker _secretMasker;
|
||||||
|
|
||||||
public TraceManager(HostTraceListener traceListener, StdoutTraceListener stdoutTraceListener, ISecretMasker secretMasker)
|
public TraceManager(HostTraceListener traceListener, ISecretMasker secretMasker)
|
||||||
: this(traceListener, stdoutTraceListener, new TraceSetting(), secretMasker)
|
: this(traceListener, new TraceSetting(), secretMasker)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public TraceManager(HostTraceListener traceListener, StdoutTraceListener stdoutTraceListener, TraceSetting traceSetting, ISecretMasker secretMasker)
|
public TraceManager(HostTraceListener traceListener, TraceSetting traceSetting, ISecretMasker secretMasker)
|
||||||
{
|
{
|
||||||
// Validate and store params.
|
// Validate and store params.
|
||||||
ArgUtil.NotNull(traceListener, nameof(traceListener));
|
ArgUtil.NotNull(traceListener, nameof(traceListener));
|
||||||
ArgUtil.NotNull(traceSetting, nameof(traceSetting));
|
ArgUtil.NotNull(traceSetting, nameof(traceSetting));
|
||||||
ArgUtil.NotNull(secretMasker, nameof(secretMasker));
|
ArgUtil.NotNull(secretMasker, nameof(secretMasker));
|
||||||
_hostTraceListener = traceListener;
|
_hostTraceListener = traceListener;
|
||||||
_stdoutTraceListener = stdoutTraceListener;
|
|
||||||
_traceSetting = traceSetting;
|
_traceSetting = traceSetting;
|
||||||
_secretMasker = secretMasker;
|
_secretMasker = secretMasker;
|
||||||
|
|
||||||
@@ -83,7 +82,7 @@ namespace GitHub.Runner.Common
|
|||||||
Level = sourceTraceLevel.ToSourceLevels()
|
Level = sourceTraceLevel.ToSourceLevels()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return new Tracing(name, _secretMasker, sourceSwitch, _hostTraceListener, _stdoutTraceListener);
|
return new Tracing(name, _secretMasker, sourceSwitch, _hostTraceListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -12,7 +14,7 @@ namespace GitHub.Runner.Common
|
|||||||
private ISecretMasker _secretMasker;
|
private ISecretMasker _secretMasker;
|
||||||
private TraceSource _traceSource;
|
private TraceSource _traceSource;
|
||||||
|
|
||||||
public Tracing(string name, ISecretMasker secretMasker, SourceSwitch sourceSwitch, HostTraceListener traceListener, StdoutTraceListener stdoutTraceListener = null)
|
public Tracing(string name, ISecretMasker secretMasker, SourceSwitch sourceSwitch, HostTraceListener traceListener)
|
||||||
{
|
{
|
||||||
ArgUtil.NotNull(secretMasker, nameof(secretMasker));
|
ArgUtil.NotNull(secretMasker, nameof(secretMasker));
|
||||||
_secretMasker = secretMasker;
|
_secretMasker = secretMasker;
|
||||||
@@ -27,10 +29,6 @@ namespace GitHub.Runner.Common
|
|||||||
}
|
}
|
||||||
|
|
||||||
_traceSource.Listeners.Add(traceListener);
|
_traceSource.Listeners.Add(traceListener);
|
||||||
if (stdoutTraceListener != null)
|
|
||||||
{
|
|
||||||
_traceSource.Listeners.Add(stdoutTraceListener);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Info(string message)
|
public void Info(string message)
|
||||||
|
|||||||
@@ -6,23 +6,11 @@ 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 || OS_WINDOWS) && 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 forcedInternalNodeVersion = Environment.GetEnvironmentVariable(Constants.Variables.Agent.ForcedInternalNodeVersion);
|
var forcedNodeVersion = Environment.GetEnvironmentVariable(Constants.Variables.Agent.ForcedInternalNodeVersion);
|
||||||
var isForcedInternalNodeVersion = !string.IsNullOrEmpty(forcedInternalNodeVersion) && BuiltInNodeVersions.Contains(forcedInternalNodeVersion);
|
return !string.IsNullOrEmpty(forcedNodeVersion) && BuiltInNodeVersions.Contains(forcedNodeVersion) ? forcedNodeVersion : _defaultNodeVersion;
|
||||||
|
|
||||||
if (isForcedInternalNodeVersion)
|
|
||||||
{
|
|
||||||
return forcedInternalNodeVersion;
|
|
||||||
}
|
|
||||||
return _defaultNodeVersion;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using GitHub.Runner.Sdk;
|
||||||
|
|
||||||
namespace GitHub.Runner.Common.Util
|
namespace GitHub.Runner.Common.Util
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -347,8 +347,8 @@ namespace GitHub.Runner.Listener.Check
|
|||||||
public sealed class HttpEventSourceListener : EventListener
|
public sealed class HttpEventSourceListener : EventListener
|
||||||
{
|
{
|
||||||
private readonly List<string> _logs;
|
private readonly List<string> _logs;
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new object();
|
||||||
private readonly Dictionary<string, HashSet<string>> _ignoredEvent = new()
|
private readonly Dictionary<string, HashSet<string>> _ignoredEvent = new Dictionary<string, HashSet<string>>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"Microsoft-System-Net-Http",
|
"Microsoft-System-Net-Http",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
@@ -86,7 +87,7 @@ namespace GitHub.Runner.Listener.Check
|
|||||||
result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ***************************************************************************************************************");
|
result.Logs.Add($"{DateTime.UtcNow.ToString("O")} ***************************************************************************************************************");
|
||||||
|
|
||||||
// Request to github.com or ghes server
|
// Request to github.com or ghes server
|
||||||
Uri requestUrl = new(url);
|
Uri requestUrl = new Uri(url);
|
||||||
var env = new Dictionary<string, string>()
|
var env = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "HOSTNAME", requestUrl.Host },
|
{ "HOSTNAME", requestUrl.Host },
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using GitHub.DistributedTask.Logging;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
|
|
||||||
@@ -11,65 +12,48 @@ namespace GitHub.Runner.Listener
|
|||||||
{
|
{
|
||||||
public sealed class CommandSettings
|
public sealed class CommandSettings
|
||||||
{
|
{
|
||||||
private readonly Dictionary<string, string> _envArgs = new(StringComparer.OrdinalIgnoreCase);
|
private readonly Dictionary<string, string> _envArgs = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private readonly CommandLineParser _parser;
|
private readonly CommandLineParser _parser;
|
||||||
private readonly IPromptManager _promptManager;
|
private readonly IPromptManager _promptManager;
|
||||||
private readonly Tracing _trace;
|
private readonly Tracing _trace;
|
||||||
|
|
||||||
// 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()
|
|
||||||
{
|
|
||||||
// Valid configure flags and args
|
|
||||||
[Constants.Runner.CommandLine.Commands.Configure] =
|
|
||||||
new string[]
|
|
||||||
{
|
{
|
||||||
|
Constants.Runner.CommandLine.Flags.Check,
|
||||||
|
Constants.Runner.CommandLine.Flags.Commit,
|
||||||
Constants.Runner.CommandLine.Flags.DisableUpdate,
|
Constants.Runner.CommandLine.Flags.DisableUpdate,
|
||||||
Constants.Runner.CommandLine.Flags.Ephemeral,
|
Constants.Runner.CommandLine.Flags.Ephemeral,
|
||||||
Constants.Runner.CommandLine.Flags.GenerateServiceConfig,
|
Constants.Runner.CommandLine.Flags.Help,
|
||||||
|
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.Flags.Version
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly string[] validArgs =
|
||||||
|
{
|
||||||
Constants.Runner.CommandLine.Args.Auth,
|
Constants.Runner.CommandLine.Args.Auth,
|
||||||
Constants.Runner.CommandLine.Args.Labels,
|
Constants.Runner.CommandLine.Args.Labels,
|
||||||
Constants.Runner.CommandLine.Args.MonitorSocketAddress,
|
Constants.Runner.CommandLine.Args.MonitorSocketAddress,
|
||||||
Constants.Runner.CommandLine.Args.Name,
|
Constants.Runner.CommandLine.Args.Name,
|
||||||
Constants.Runner.CommandLine.Args.PAT,
|
Constants.Runner.CommandLine.Args.PAT,
|
||||||
Constants.Runner.CommandLine.Args.RunnerGroup,
|
Constants.Runner.CommandLine.Args.RunnerGroup,
|
||||||
|
Constants.Runner.CommandLine.Args.StartupType,
|
||||||
Constants.Runner.CommandLine.Args.Token,
|
Constants.Runner.CommandLine.Args.Token,
|
||||||
Constants.Runner.CommandLine.Args.Url,
|
Constants.Runner.CommandLine.Args.Url,
|
||||||
Constants.Runner.CommandLine.Args.UserName,
|
Constants.Runner.CommandLine.Args.UserName,
|
||||||
Constants.Runner.CommandLine.Args.WindowsLogonAccount,
|
Constants.Runner.CommandLine.Args.WindowsLogonAccount,
|
||||||
Constants.Runner.CommandLine.Args.WindowsLogonPassword,
|
Constants.Runner.CommandLine.Args.WindowsLogonPassword,
|
||||||
Constants.Runner.CommandLine.Args.Work
|
Constants.Runner.CommandLine.Args.Work
|
||||||
},
|
|
||||||
// Valid remove flags and args
|
|
||||||
[Constants.Runner.CommandLine.Commands.Remove] =
|
|
||||||
new string[]
|
|
||||||
{
|
|
||||||
Constants.Runner.CommandLine.Args.Token,
|
|
||||||
Constants.Runner.CommandLine.Args.PAT,
|
|
||||||
Constants.Runner.CommandLine.Flags.Local
|
|
||||||
},
|
|
||||||
// Valid run flags and args
|
|
||||||
[Constants.Runner.CommandLine.Commands.Run] =
|
|
||||||
new string[]
|
|
||||||
{
|
|
||||||
Constants.Runner.CommandLine.Flags.Once,
|
|
||||||
Constants.Runner.CommandLine.Args.JitConfig,
|
|
||||||
Constants.Runner.CommandLine.Args.StartupType
|
|
||||||
},
|
|
||||||
// valid warmup flags and args
|
|
||||||
[Constants.Runner.CommandLine.Commands.Warmup] =
|
|
||||||
new string[] { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Commands.
|
// Commands.
|
||||||
@@ -81,13 +65,11 @@ namespace GitHub.Runner.Listener
|
|||||||
// Flags.
|
// Flags.
|
||||||
public bool Check => TestFlag(Constants.Runner.CommandLine.Flags.Check);
|
public bool Check => TestFlag(Constants.Runner.CommandLine.Flags.Check);
|
||||||
public bool Commit => TestFlag(Constants.Runner.CommandLine.Flags.Commit);
|
public bool Commit => TestFlag(Constants.Runner.CommandLine.Flags.Commit);
|
||||||
public bool DisableUpdate => TestFlag(Constants.Runner.CommandLine.Flags.DisableUpdate);
|
|
||||||
public bool Ephemeral => TestFlag(Constants.Runner.CommandLine.Flags.Ephemeral);
|
|
||||||
public bool GenerateServiceConfig => TestFlag(Constants.Runner.CommandLine.Flags.GenerateServiceConfig);
|
|
||||||
public bool Help => TestFlag(Constants.Runner.CommandLine.Flags.Help);
|
public bool Help => TestFlag(Constants.Runner.CommandLine.Flags.Help);
|
||||||
public bool Unattended => TestFlag(Constants.Runner.CommandLine.Flags.Unattended);
|
public bool Unattended => TestFlag(Constants.Runner.CommandLine.Flags.Unattended);
|
||||||
public bool Version => TestFlag(Constants.Runner.CommandLine.Flags.Version);
|
public bool Version => TestFlag(Constants.Runner.CommandLine.Flags.Version);
|
||||||
public bool RemoveLocalConfig => TestFlag(Constants.Runner.CommandLine.Flags.Local);
|
public bool Ephemeral => TestFlag(Constants.Runner.CommandLine.Flags.Ephemeral);
|
||||||
|
public bool DisableUpdate => TestFlag(Constants.Runner.CommandLine.Flags.DisableUpdate);
|
||||||
|
|
||||||
// Keep this around since customers still relies on it
|
// Keep this around since customers still relies on it
|
||||||
public bool RunOnce => TestFlag(Constants.Runner.CommandLine.Flags.Once);
|
public bool RunOnce => TestFlag(Constants.Runner.CommandLine.Flags.Once);
|
||||||
@@ -141,51 +123,20 @@ namespace GitHub.Runner.Listener
|
|||||||
// Validate commandline parser result
|
// Validate commandline parser result
|
||||||
public List<string> Validate()
|
public List<string> Validate()
|
||||||
{
|
{
|
||||||
List<string> unknowns = new();
|
List<string> unknowns = new List<string>();
|
||||||
|
|
||||||
// detect unknown commands
|
// detect unknown commands
|
||||||
unknowns.AddRange(_parser.Commands.Where(x => !validOptions.Keys.Contains(x, StringComparer.OrdinalIgnoreCase)));
|
unknowns.AddRange(_parser.Commands.Where(x => !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.
|
||||||
//
|
//
|
||||||
@@ -217,12 +168,6 @@ namespace GitHub.Runner.Listener
|
|||||||
validator: Validators.AuthSchemeValidator);
|
validator: Validators.AuthSchemeValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetJitConfig()
|
|
||||||
{
|
|
||||||
return GetArg(
|
|
||||||
name: Constants.Runner.CommandLine.Args.JitConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRunnerName()
|
public string GetRunnerName()
|
||||||
{
|
{
|
||||||
return GetArgOrPrompt(
|
return GetArgOrPrompt(
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
using GitHub.DistributedTask.WebApi;
|
||||||
|
using GitHub.Runner.Common;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
|
using GitHub.Runner.Sdk;
|
||||||
|
using GitHub.Services.Common;
|
||||||
|
using GitHub.Services.OAuth;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -7,13 +13,6 @@ using System.Runtime.InteropServices;
|
|||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
using GitHub.Runner.Common;
|
|
||||||
using GitHub.Runner.Common.Util;
|
|
||||||
using GitHub.Runner.Sdk;
|
|
||||||
using GitHub.Services.Common;
|
|
||||||
using GitHub.Services.Common.Internal;
|
|
||||||
using GitHub.Services.OAuth;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Listener.Configuration
|
namespace GitHub.Runner.Listener.Configuration
|
||||||
{
|
{
|
||||||
@@ -81,33 +80,12 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
_term.WriteLine("--------------------------------------------------------------------------------");
|
_term.WriteLine("--------------------------------------------------------------------------------");
|
||||||
|
|
||||||
Trace.Info(nameof(ConfigureAsync));
|
Trace.Info(nameof(ConfigureAsync));
|
||||||
|
|
||||||
if (command.GenerateServiceConfig)
|
|
||||||
{
|
|
||||||
#if OS_LINUX
|
|
||||||
if (!IsConfigured())
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("--generateServiceConfig requires that the runner is already configured. For configuring a new runner as a service, run './config.sh'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerSettings settings = _store.GetSettings();
|
|
||||||
|
|
||||||
Trace.Info($"generate service config for runner: {settings.AgentId}");
|
|
||||||
var controlManager = HostContext.GetService<ILinuxServiceControlManager>();
|
|
||||||
controlManager.GenerateScripts(settings);
|
|
||||||
|
|
||||||
return;
|
|
||||||
#else
|
|
||||||
throw new NotSupportedException("--generateServiceConfig is only supported on Linux.");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsConfigured())
|
if (IsConfigured())
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Cannot configure the runner because it is already configured. To reconfigure the runner, run 'config.cmd remove' or './config.sh remove' first.");
|
throw new InvalidOperationException("Cannot configure the runner because it is already configured. To reconfigure the runner, run 'config.cmd remove' or './config.sh remove' first.");
|
||||||
}
|
}
|
||||||
|
|
||||||
RunnerSettings runnerSettings = new();
|
RunnerSettings runnerSettings = new RunnerSettings();
|
||||||
|
|
||||||
// Loop getting url and creds until you can connect
|
// Loop getting url and creds until you can connect
|
||||||
ICredentialProvider credProvider = null;
|
ICredentialProvider credProvider = null;
|
||||||
@@ -150,7 +128,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
// Example githubServerUrl is https://my-ghes
|
// Example githubServerUrl is https://my-ghes
|
||||||
var actionsServerUrl = new Uri(runnerSettings.ServerUrl);
|
var actionsServerUrl = new Uri(runnerSettings.ServerUrl);
|
||||||
var githubServerUrl = new Uri(runnerSettings.GitHubUrl);
|
var githubServerUrl = new Uri(runnerSettings.GitHubUrl);
|
||||||
if (!UriUtility.IsSubdomainOf(actionsServerUrl.Authority, githubServerUrl.Authority))
|
if (!string.Equals(actionsServerUrl.Authority, githubServerUrl.Authority, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"GitHub Actions is not properly configured in GHES. GHES url: {runnerSettings.GitHubUrl}, Actions url: {runnerSettings.ServerUrl}.");
|
throw new InvalidOperationException($"GitHub Actions is not properly configured in GHES. GHES url: {runnerSettings.GitHubUrl}, Actions url: {runnerSettings.ServerUrl}.");
|
||||||
}
|
}
|
||||||
@@ -542,7 +520,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
|
|
||||||
private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey, ISet<string> userLabels, bool ephemeral, bool disableUpdate)
|
private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey, ISet<string> userLabels, bool ephemeral, bool disableUpdate)
|
||||||
{
|
{
|
||||||
TaskAgent agent = new(agentName)
|
TaskAgent agent = new TaskAgent(agentName)
|
||||||
{
|
{
|
||||||
Authorization = new TaskAgentAuthorization
|
Authorization = new TaskAgentAuthorization
|
||||||
{
|
{
|
||||||
@@ -636,7 +614,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
}
|
}
|
||||||
|
|
||||||
int retryCount = 0;
|
int retryCount = 0;
|
||||||
while (retryCount < 3)
|
while(retryCount < 3)
|
||||||
{
|
{
|
||||||
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
|
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
|
||||||
using (var httpClient = new HttpClient(httpClientHandler))
|
using (var httpClient = new HttpClient(httpClientHandler))
|
||||||
@@ -646,37 +624,38 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("basic", base64EncodingToken);
|
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("basic", base64EncodingToken);
|
||||||
httpClient.DefaultRequestHeaders.UserAgent.AddRange(HostContext.UserAgents);
|
httpClient.DefaultRequestHeaders.UserAgent.AddRange(HostContext.UserAgents);
|
||||||
httpClient.DefaultRequestHeaders.Accept.ParseAdd("application/vnd.github.v3+json");
|
httpClient.DefaultRequestHeaders.Accept.ParseAdd("application/vnd.github.v3+json");
|
||||||
|
|
||||||
var responseStatus = System.Net.HttpStatusCode.OK;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = await httpClient.PostAsync(githubApiUrl, new StringContent(string.Empty));
|
var response = await httpClient.PostAsync(githubApiUrl, new StringContent(string.Empty));
|
||||||
responseStatus = response.StatusCode;
|
|
||||||
var githubRequestId = GetGitHubRequestId(response.Headers);
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' ({githubRequestId})");
|
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
|
||||||
var jsonResponse = await response.Content.ReadAsStringAsync();
|
var jsonResponse = await response.Content.ReadAsStringAsync();
|
||||||
return StringUtil.ConvertFromJson<GitHubRunnerRegisterToken>(jsonResponse);
|
return StringUtil.ConvertFromJson<GitHubRunnerRegisterToken>(jsonResponse);
|
||||||
}
|
}
|
||||||
|
else if(response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
|
// It doesn't make sense to retry in this case, so just stop
|
||||||
|
break;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' (Request Id: {githubRequestId})");
|
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
|
||||||
var errorResponse = await response.Content.ReadAsStringAsync();
|
var errorResponse = await response.Content.ReadAsStringAsync();
|
||||||
_term.WriteError(errorResponse);
|
_term.WriteError(errorResponse);
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex) when (retryCount < 2 && responseStatus != System.Net.HttpStatusCode.NotFound)
|
catch(Exception ex) when (retryCount < 2)
|
||||||
{
|
{
|
||||||
retryCount++;
|
retryCount++;
|
||||||
Trace.Error($"Failed to get JIT runner token -- Atempt: {retryCount}");
|
Trace.Error($"Failed to get JIT runner token -- Atempt: {retryCount}");
|
||||||
Trace.Error(ex);
|
Trace.Error(ex);
|
||||||
|
Trace.Info("Retrying in 5 seconds");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5));
|
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5));
|
||||||
Trace.Info($"Retrying in {backOff.Seconds} seconds");
|
|
||||||
await Task.Delay(backOff);
|
await Task.Delay(backOff);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -710,48 +689,42 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
{"runner_event", runnerEvent}
|
{"runner_event", runnerEvent}
|
||||||
};
|
};
|
||||||
|
|
||||||
var responseStatus = System.Net.HttpStatusCode.OK;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = await httpClient.PostAsync(githubApiUrl, new StringContent(StringUtil.ConvertToJson(bodyObject), null, "application/json"));
|
var response = await httpClient.PostAsync(githubApiUrl, new StringContent(StringUtil.ConvertToJson(bodyObject), null, "application/json"));
|
||||||
responseStatus = response.StatusCode;
|
|
||||||
var githubRequestId = GetGitHubRequestId(response.Headers);
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
if(response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' ({githubRequestId})");
|
Trace.Info($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
|
||||||
var jsonResponse = await response.Content.ReadAsStringAsync();
|
var jsonResponse = await response.Content.ReadAsStringAsync();
|
||||||
return StringUtil.ConvertFromJson<GitHubAuthResult>(jsonResponse);
|
return StringUtil.ConvertFromJson<GitHubAuthResult>(jsonResponse);
|
||||||
}
|
}
|
||||||
|
else if(response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
|
// It doesn't make sense to retry in this case, so just stop
|
||||||
|
break;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}' (Request Id: {githubRequestId})");
|
_term.WriteError($"Http response code: {response.StatusCode} from 'POST {githubApiUrl}'");
|
||||||
var errorResponse = await response.Content.ReadAsStringAsync();
|
var errorResponse = await response.Content.ReadAsStringAsync();
|
||||||
_term.WriteError(errorResponse);
|
_term.WriteError(errorResponse);
|
||||||
|
// Something else bad happened, let's go to our retry logic
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex) when (retryCount < 2 && responseStatus != System.Net.HttpStatusCode.NotFound)
|
catch(Exception ex) when (retryCount < 2)
|
||||||
{
|
{
|
||||||
retryCount++;
|
retryCount++;
|
||||||
Trace.Error($"Failed to get tenant credentials -- Atempt: {retryCount}");
|
Trace.Error($"Failed to get tenant credentials -- Atempt: {retryCount}");
|
||||||
Trace.Error(ex);
|
Trace.Error(ex);
|
||||||
|
Trace.Info("Retrying in 5 seconds");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5));
|
var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5));
|
||||||
Trace.Info($"Retrying in {backOff.Seconds} seconds");
|
|
||||||
await Task.Delay(backOff);
|
await Task.Delay(backOff);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetGitHubRequestId(HttpResponseHeaders headers)
|
|
||||||
{
|
|
||||||
if (headers.TryGetValues("x-github-request-id", out var headerValues))
|
|
||||||
{
|
|
||||||
return headerValues.FirstOrDefault();
|
|
||||||
}
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
|
|
||||||
public class CredentialManager : RunnerService, ICredentialManager
|
public class CredentialManager : RunnerService, ICredentialManager
|
||||||
{
|
{
|
||||||
public static readonly Dictionary<string, Type> CredentialTypes = new(StringComparer.OrdinalIgnoreCase)
|
public static readonly Dictionary<string, Type> CredentialTypes = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
{ Constants.Configuration.OAuth, typeof(OAuthCredential)},
|
{ Constants.Configuration.OAuth, typeof(OAuthCredential)},
|
||||||
{ Constants.Configuration.OAuthAccessToken, typeof(OAuthAccessTokenCredential)},
|
{ Constants.Configuration.OAuthAccessToken, typeof(OAuthAccessTokenCredential)},
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
ArgUtil.NotNullOrEmpty(token, nameof(token));
|
ArgUtil.NotNullOrEmpty(token, nameof(token));
|
||||||
|
|
||||||
trace.Info("token retrieved: {0} chars", token.Length);
|
trace.Info("token retrieved: {0} chars", token.Length);
|
||||||
VssCredentials creds = new(new VssOAuthAccessTokenCredential(token), CredentialPromptType.DoNotPrompt);
|
VssCredentials creds = new VssCredentials(new VssOAuthAccessTokenCredential(token), CredentialPromptType.DoNotPrompt);
|
||||||
trace.Info("cred created");
|
trace.Info("cred created");
|
||||||
|
|
||||||
return creds;
|
return creds;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
@@ -86,12 +87,11 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
// Write the message prompt.
|
// Write the message prompt.
|
||||||
_terminal.Write($"{description} ");
|
_terminal.Write($"{description} ");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(defaultValue))
|
if(!string.IsNullOrEmpty(defaultValue))
|
||||||
{
|
{
|
||||||
_terminal.Write($"[press Enter for {defaultValue}] ");
|
_terminal.Write($"[press Enter for {defaultValue}] ");
|
||||||
}
|
}
|
||||||
else if (isOptional)
|
else if (isOptional){
|
||||||
{
|
|
||||||
_terminal.Write($"[press Enter to skip] ");
|
_terminal.Write($"[press Enter to skip] ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace GitHub.Runner.Listener.Configuration
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For the service name, replace any characters outside of the alpha-numeric set and ".", "_", "-" with "-"
|
// For the service name, replace any characters outside of the alpha-numeric set and ".", "_", "-" with "-"
|
||||||
Regex regex = new(@"[^0-9a-zA-Z._\-]");
|
Regex regex = new Regex(@"[^0-9a-zA-Z._\-]");
|
||||||
string repoOrOrgName = regex.Replace(settings.RepoOrOrgName, "-");
|
string repoOrOrgName = regex.Replace(settings.RepoOrOrgName, "-");
|
||||||
|
|
||||||
serviceName = StringUtil.Format(serviceNamePattern, repoOrOrgName, settings.AgentName);
|
serviceName = StringUtil.Format(serviceNamePattern, repoOrOrgName, settings.AgentName);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#if OS_LINUX
|
#if OS_LINUX
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -6,6 +6,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using GitHub.Runner.Common.Util;
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
|
using GitHub.Runner.Sdk;
|
||||||
|
|
||||||
namespace GitHub.Runner.Listener.Configuration
|
namespace GitHub.Runner.Listener.Configuration
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace GitHub.Runner.Listener
|
|||||||
bool Cancel(JobCancelMessage message);
|
bool Cancel(JobCancelMessage message);
|
||||||
Task WaitAsync(CancellationToken token);
|
Task WaitAsync(CancellationToken token);
|
||||||
Task ShutdownAsync();
|
Task ShutdownAsync();
|
||||||
event EventHandler<JobStatusEventArgs> JobStatus;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This implementation of IJobDispatcher is not thread safe.
|
// This implementation of IJobDispatcher is not thread safe.
|
||||||
@@ -37,8 +36,8 @@ namespace GitHub.Runner.Listener
|
|||||||
// and the server will not send another job while this one is still running.
|
// and the server will not send another job while this one is still running.
|
||||||
public sealed class JobDispatcher : RunnerService, IJobDispatcher
|
public sealed class JobDispatcher : RunnerService, IJobDispatcher
|
||||||
{
|
{
|
||||||
private static Regex _invalidJsonRegex = new(@"invalid\ Json\ at\ position\ '(\d+)':", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static Regex _invalidJsonRegex = new Regex(@"invalid\ Json\ at\ position\ '(\d+)':", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
private readonly Lazy<Dictionary<long, TaskResult>> _localRunJobResult = new();
|
private readonly Lazy<Dictionary<long, TaskResult>> _localRunJobResult = new Lazy<Dictionary<long, TaskResult>>();
|
||||||
private int _poolId;
|
private int _poolId;
|
||||||
|
|
||||||
IConfigurationStore _configurationStore;
|
IConfigurationStore _configurationStore;
|
||||||
@@ -47,16 +46,14 @@ namespace GitHub.Runner.Listener
|
|||||||
private static readonly string _workerProcessName = $"Runner.Worker{IOUtil.ExeExtension}";
|
private static readonly string _workerProcessName = $"Runner.Worker{IOUtil.ExeExtension}";
|
||||||
|
|
||||||
// this is not thread-safe
|
// this is not thread-safe
|
||||||
private readonly Queue<Guid> _jobDispatchedQueue = new();
|
private readonly Queue<Guid> _jobDispatchedQueue = new Queue<Guid>();
|
||||||
private readonly ConcurrentDictionary<Guid, WorkerDispatcher> _jobInfos = new();
|
private readonly ConcurrentDictionary<Guid, WorkerDispatcher> _jobInfos = new ConcurrentDictionary<Guid, WorkerDispatcher>();
|
||||||
|
|
||||||
// allow up to 30sec for any data to be transmitted over the process channel
|
// allow up to 30sec for any data to be transmitted over the process channel
|
||||||
// timeout limit can be overwritten by environment GITHUB_ACTIONS_RUNNER_CHANNEL_TIMEOUT
|
// timeout limit can be overwritten by environment GITHUB_ACTIONS_RUNNER_CHANNEL_TIMEOUT
|
||||||
private TimeSpan _channelTimeout;
|
private TimeSpan _channelTimeout;
|
||||||
|
|
||||||
private TaskCompletionSource<bool> _runOnceJobCompleted = new();
|
private TaskCompletionSource<bool> _runOnceJobCompleted = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
public event EventHandler<JobStatusEventArgs> JobStatus;
|
|
||||||
|
|
||||||
public override void Initialize(IHostContext hostContext)
|
public override void Initialize(IHostContext hostContext)
|
||||||
{
|
{
|
||||||
@@ -111,7 +108,7 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkerDispatcher newDispatch = new(jobRequestMessage.JobId, jobRequestMessage.RequestId);
|
WorkerDispatcher newDispatch = new WorkerDispatcher(jobRequestMessage.JobId, jobRequestMessage.RequestId);
|
||||||
if (runOnce)
|
if (runOnce)
|
||||||
{
|
{
|
||||||
Trace.Info("Start dispatcher for one time used runner.");
|
Trace.Info("Start dispatcher for one time used runner.");
|
||||||
@@ -338,11 +335,6 @@ namespace GitHub.Runner.Listener
|
|||||||
Busy = true;
|
Busy = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (JobStatus != null)
|
|
||||||
{
|
|
||||||
JobStatus(this, new JobStatusEventArgs(TaskAgentStatus.Busy));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (previousJobDispatch != null)
|
if (previousJobDispatch != null)
|
||||||
{
|
{
|
||||||
Trace.Verbose($"Make sure the previous job request {previousJobDispatch.JobId} has successfully finished on worker.");
|
Trace.Verbose($"Make sure the previous job request {previousJobDispatch.JobId} has successfully finished on worker.");
|
||||||
@@ -354,10 +346,13 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
var term = HostContext.GetService<ITerminal>();
|
var term = HostContext.GetService<ITerminal>();
|
||||||
term.WriteLine($"{DateTime.UtcNow:u}: Running job: {message.JobDisplayName}");
|
|
||||||
|
string workflowName = message.Variables["system.workflowFilePath"].Value.Split('/').LastOrDefault();
|
||||||
|
string additionalInfo = string.IsNullOrEmpty(workflowName) ? $"(in repository \"{_runnerSettings.RepoOrOrgName}\")" : $"(workflow \"{workflowName}\" in repository \"{_runnerSettings.RepoOrOrgName}\")";
|
||||||
|
term.WriteLine($"{DateTime.UtcNow:u}: Running job: \"{message.JobDisplayName}\" {additionalInfo}");
|
||||||
|
|
||||||
// first job request renew succeed.
|
// first job request renew succeed.
|
||||||
TaskCompletionSource<int> firstJobRequestRenewed = new();
|
TaskCompletionSource<int> firstJobRequestRenewed = new TaskCompletionSource<int>();
|
||||||
var notification = HostContext.GetService<IJobNotification>();
|
var notification = HostContext.GetService<IJobNotification>();
|
||||||
|
|
||||||
// lock renew cancellation token.
|
// lock renew cancellation token.
|
||||||
@@ -398,9 +393,8 @@ namespace GitHub.Runner.Listener
|
|||||||
HostContext.WritePerfCounter($"JobRequestRenewed_{requestId.ToString()}");
|
HostContext.WritePerfCounter($"JobRequestRenewed_{requestId.ToString()}");
|
||||||
|
|
||||||
Task<int> workerProcessTask = null;
|
Task<int> workerProcessTask = null;
|
||||||
object _outputLock = new();
|
object _outputLock = new object();
|
||||||
List<string> workerOutput = new();
|
List<string> workerOutput = new List<string>();
|
||||||
bool printToStdout = StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable(Constants.Variables.Agent.PrintLogToStdout));
|
|
||||||
using (var processChannel = HostContext.CreateService<IProcessChannel>())
|
using (var processChannel = HostContext.CreateService<IProcessChannel>())
|
||||||
using (var processInvoker = HostContext.CreateService<IProcessInvoker>())
|
using (var processInvoker = HostContext.CreateService<IProcessInvoker>())
|
||||||
{
|
{
|
||||||
@@ -421,17 +415,9 @@ namespace GitHub.Runner.Listener
|
|||||||
if (!string.IsNullOrEmpty(stdout.Data))
|
if (!string.IsNullOrEmpty(stdout.Data))
|
||||||
{
|
{
|
||||||
lock (_outputLock)
|
lock (_outputLock)
|
||||||
{
|
|
||||||
if (!stdout.Data.StartsWith("[WORKER"))
|
|
||||||
{
|
{
|
||||||
workerOutput.Add(stdout.Data);
|
workerOutput.Add(stdout.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printToStdout)
|
|
||||||
{
|
|
||||||
term.WriteLine(stdout.Data, skipTracing: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -548,7 +534,7 @@ namespace GitHub.Runner.Listener
|
|||||||
|
|
||||||
TaskResult result = TaskResultUtil.TranslateFromReturnCode(returnCode);
|
TaskResult result = TaskResultUtil.TranslateFromReturnCode(returnCode);
|
||||||
Trace.Info($"finish job request for job {message.JobId} with result: {result}");
|
Trace.Info($"finish job request for job {message.JobId} with result: {result}");
|
||||||
term.WriteLine($"{DateTime.UtcNow:u}: Job {message.JobDisplayName} completed with result: {result}");
|
term.WriteLine($"{DateTime.UtcNow:u}: Job \"{message.JobDisplayName}\" {additionalInfo} completed with result: {result}");
|
||||||
|
|
||||||
Trace.Info($"Stop renew job request for job {message.JobId}.");
|
Trace.Info($"Stop renew job request for job {message.JobId}.");
|
||||||
// stop renew lock
|
// stop renew lock
|
||||||
@@ -644,7 +630,7 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
Trace.Info($"finish job request for job {message.JobId} with result: {resultOnAbandonOrCancel}");
|
Trace.Info($"finish job request for job {message.JobId} with result: {resultOnAbandonOrCancel}");
|
||||||
term.WriteLine($"{DateTime.UtcNow:u}: Job {message.JobDisplayName} completed with result: {resultOnAbandonOrCancel}");
|
term.WriteLine($"{DateTime.UtcNow:u}: Job \"{message.JobDisplayName}\" {additionalInfo} completed with result: {resultOnAbandonOrCancel}");
|
||||||
// complete job request with cancel result, stop renew lock, job has finished.
|
// complete job request with cancel result, stop renew lock, job has finished.
|
||||||
|
|
||||||
Trace.Info($"Stop renew job request for job {message.JobId}.");
|
Trace.Info($"Stop renew job request for job {message.JobId}.");
|
||||||
@@ -667,11 +653,6 @@ namespace GitHub.Runner.Listener
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Busy = false;
|
Busy = false;
|
||||||
|
|
||||||
if (JobStatus != null)
|
|
||||||
{
|
|
||||||
JobStatus(this, new JobStatusEventArgs(TaskAgentStatus.Online));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -945,7 +926,7 @@ namespace GitHub.Runner.Listener
|
|||||||
|
|
||||||
var runnerServer = HostContext.GetService<IRunnerServer>();
|
var runnerServer = HostContext.GetService<IRunnerServer>();
|
||||||
int completeJobRequestRetryLimit = 5;
|
int completeJobRequestRetryLimit = 5;
|
||||||
List<Exception> exceptions = new();
|
List<Exception> exceptions = new List<Exception>();
|
||||||
while (completeJobRequestRetryLimit-- > 0)
|
while (completeJobRequestRetryLimit-- > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -1048,7 +1029,7 @@ namespace GitHub.Runner.Listener
|
|||||||
public Task WorkerDispatch { get; set; }
|
public Task WorkerDispatch { get; set; }
|
||||||
public CancellationTokenSource WorkerCancellationTokenSource { get; private set; }
|
public CancellationTokenSource WorkerCancellationTokenSource { get; private set; }
|
||||||
public CancellationTokenSource WorkerCancelTimeoutKillTokenSource { get; private set; }
|
public CancellationTokenSource WorkerCancelTimeoutKillTokenSource { get; private set; }
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new object();
|
||||||
|
|
||||||
public WorkerDispatcher(Guid jobId, long requestId)
|
public WorkerDispatcher(Guid jobId, long requestId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ namespace GitHub.Runner.Listener
|
|||||||
Task DeleteSessionAsync();
|
Task DeleteSessionAsync();
|
||||||
Task<TaskAgentMessage> GetNextMessageAsync(CancellationToken token);
|
Task<TaskAgentMessage> GetNextMessageAsync(CancellationToken token);
|
||||||
Task DeleteMessageAsync(TaskAgentMessage message);
|
Task DeleteMessageAsync(TaskAgentMessage message);
|
||||||
void OnJobStatus(object sender, JobStatusEventArgs e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class MessageListener : RunnerService, IMessageListener
|
public sealed class MessageListener : RunnerService, IMessageListener
|
||||||
@@ -38,9 +37,7 @@ namespace GitHub.Runner.Listener
|
|||||||
private readonly TimeSpan _sessionCreationRetryInterval = TimeSpan.FromSeconds(30);
|
private readonly TimeSpan _sessionCreationRetryInterval = TimeSpan.FromSeconds(30);
|
||||||
private readonly TimeSpan _sessionConflictRetryLimit = TimeSpan.FromMinutes(4);
|
private readonly TimeSpan _sessionConflictRetryLimit = TimeSpan.FromMinutes(4);
|
||||||
private readonly TimeSpan _clockSkewRetryLimit = TimeSpan.FromMinutes(30);
|
private readonly TimeSpan _clockSkewRetryLimit = TimeSpan.FromMinutes(30);
|
||||||
private readonly Dictionary<string, int> _sessionCreationExceptionTracker = new();
|
private readonly Dictionary<string, int> _sessionCreationExceptionTracker = new Dictionary<string, int>();
|
||||||
private TaskAgentStatus runnerStatus = TaskAgentStatus.Online;
|
|
||||||
private CancellationTokenSource _getMessagesTokenSource;
|
|
||||||
|
|
||||||
public override void Initialize(IHostContext hostContext)
|
public override void Initialize(IHostContext hostContext)
|
||||||
{
|
{
|
||||||
@@ -173,23 +170,6 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnJobStatus(object sender, JobStatusEventArgs e)
|
|
||||||
{
|
|
||||||
if (StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("USE_BROKER_FLOW")))
|
|
||||||
{
|
|
||||||
Trace.Info("Received job status event. JobState: {0}", e.Status);
|
|
||||||
runnerStatus = e.Status;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_getMessagesTokenSource?.Cancel();
|
|
||||||
}
|
|
||||||
catch (ObjectDisposedException)
|
|
||||||
{
|
|
||||||
Trace.Info("_getMessagesTokenSource is already disposed.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TaskAgentMessage> GetNextMessageAsync(CancellationToken token)
|
public async Task<TaskAgentMessage> GetNextMessageAsync(CancellationToken token)
|
||||||
{
|
{
|
||||||
Trace.Entering();
|
Trace.Entering();
|
||||||
@@ -198,21 +178,18 @@ namespace GitHub.Runner.Listener
|
|||||||
bool encounteringError = false;
|
bool encounteringError = false;
|
||||||
int continuousError = 0;
|
int continuousError = 0;
|
||||||
string errorMessage = string.Empty;
|
string errorMessage = string.Empty;
|
||||||
Stopwatch heartbeat = new();
|
Stopwatch heartbeat = new Stopwatch();
|
||||||
heartbeat.Restart();
|
heartbeat.Restart();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
TaskAgentMessage message = null;
|
TaskAgentMessage message = null;
|
||||||
_getMessagesTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
message = await _runnerServer.GetAgentMessageAsync(_settings.PoolId,
|
message = await _runnerServer.GetAgentMessageAsync(_settings.PoolId,
|
||||||
_session.SessionId,
|
_session.SessionId,
|
||||||
_lastMessageId,
|
_lastMessageId,
|
||||||
runnerStatus,
|
token);
|
||||||
BuildConstants.RunnerPackage.Version,
|
|
||||||
_getMessagesTokenSource.Token);
|
|
||||||
|
|
||||||
// Decrypt the message body if the session is using encryption
|
// Decrypt the message body if the session is using encryption
|
||||||
message = DecryptMessage(message);
|
message = DecryptMessage(message);
|
||||||
@@ -229,11 +206,6 @@ namespace GitHub.Runner.Listener
|
|||||||
continuousError = 0;
|
continuousError = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException) when (_getMessagesTokenSource.Token.IsCancellationRequested && !token.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
Trace.Info("Get messages has been cancelled using local token source. Continue to get messages with new status.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException) when (token.IsCancellationRequested)
|
catch (OperationCanceledException) when (token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
Trace.Info("Get next message has been cancelled.");
|
Trace.Info("Get next message has been cancelled.");
|
||||||
@@ -289,10 +261,6 @@ namespace GitHub.Runner.Listener
|
|||||||
await HostContext.Delay(_getNextMessageRetryInterval, token);
|
await HostContext.Delay(_getNextMessageRetryInterval, token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
_getMessagesTokenSource.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message == null)
|
if (message == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using GitHub.Runner.Common;
|
using GitHub.Runner.Common;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace GitHub.Runner.Listener
|
namespace GitHub.Runner.Listener
|
||||||
@@ -16,7 +18,7 @@ namespace GitHub.Runner.Listener
|
|||||||
// Add environment variables from .env file
|
// Add environment variables from .env file
|
||||||
LoadAndSetEnv();
|
LoadAndSetEnv();
|
||||||
|
|
||||||
using (HostContext context = new("Runner"))
|
using (HostContext context = new HostContext("Runner"))
|
||||||
{
|
{
|
||||||
return MainAsync(context, args).GetAwaiter().GetResult();
|
return MainAsync(context, args).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
@@ -58,18 +60,6 @@ namespace GitHub.Runner.Listener
|
|||||||
terminal.WriteLine("This runner version is built for Windows. Please install a correct build for your OS.");
|
terminal.WriteLine("This runner version is built for Windows. Please install a correct build for your OS.");
|
||||||
return Constants.Runner.ReturnCode.TerminatedError;
|
return Constants.Runner.ReturnCode.TerminatedError;
|
||||||
}
|
}
|
||||||
#if ARM64
|
|
||||||
// A little hacky, but windows gives no way to differentiate between windows 10 and 11.
|
|
||||||
// By default only 11 supports native x64 app emulation on arm, so we only want to support windows 11
|
|
||||||
// https://docs.microsoft.com/en-us/windows/arm/overview#build-windows-apps-that-run-on-arm
|
|
||||||
// Windows 10 and 11 share a MajorVersion, so we also check the build version. Minor for both is 0, so doing < 0 doesn't really make a lot of sense.
|
|
||||||
if (Environment.OSVersion.Version.Major < Constants.OperatingSystem.Windows11MajorVersion ||
|
|
||||||
Environment.OSVersion.Version.Build < Constants.OperatingSystem.Windows11BuildVersion)
|
|
||||||
{
|
|
||||||
terminal.WriteLine("Win-arm64 runners require windows 11 or later. Please upgrade your operating system.");
|
|
||||||
return Constants.Runner.ReturnCode.TerminatedError;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
terminal.WriteLine($"Running the runner on this platform is not supported. The current platform is {RuntimeInformation.OSDescription} and it was built for {Constants.Runner.Platform.ToString()}.");
|
terminal.WriteLine($"Running the runner on this platform is not supported. The current platform is {RuntimeInformation.OSDescription} and it was built for {Constants.Runner.Platform.ToString()}.");
|
||||||
@@ -105,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.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64;win-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
<NoWarn>NU1701;NU1603</NoWarn>
|
<NoWarn>NU1701;NU1603</NoWarn>
|
||||||
<Version>$(Version)</Version>
|
<Version>$(Version)</Version>
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Win32.Registry" Version="4.4.0" />
|
<PackageReference Include="Microsoft.Win32.Registry" Version="4.4.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.4.0" />
|
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.4.0" />
|
||||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.4.0" />
|
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.4.0" />
|
||||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.4.0" />
|
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.4.0" />
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
|
using GitHub.DistributedTask.WebApi;
|
||||||
|
using GitHub.Runner.Listener.Configuration;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
using GitHub.Runner.Common;
|
|
||||||
using GitHub.Runner.Listener.Check;
|
|
||||||
using GitHub.Runner.Listener.Configuration;
|
|
||||||
using GitHub.Runner.Sdk;
|
|
||||||
using GitHub.Services.WebApi;
|
using GitHub.Services.WebApi;
|
||||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using GitHub.Runner.Common;
|
||||||
|
using GitHub.Runner.Sdk;
|
||||||
|
using System.Linq;
|
||||||
|
using GitHub.Runner.Listener.Check;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace GitHub.Runner.Listener
|
namespace GitHub.Runner.Listener
|
||||||
{
|
{
|
||||||
@@ -28,7 +27,7 @@ namespace GitHub.Runner.Listener
|
|||||||
private IMessageListener _listener;
|
private IMessageListener _listener;
|
||||||
private ITerminal _term;
|
private ITerminal _term;
|
||||||
private bool _inConfigStage;
|
private bool _inConfigStage;
|
||||||
private ManualResetEvent _completedCommand = new(false);
|
private ManualResetEvent _completedCommand = new ManualResetEvent(false);
|
||||||
|
|
||||||
public override void Initialize(IHostContext hostContext)
|
public override void Initialize(IHostContext hostContext)
|
||||||
{
|
{
|
||||||
@@ -135,12 +134,6 @@ namespace GitHub.Runner.Listener
|
|||||||
// remove config files, remove service, and exit
|
// remove config files, remove service, and exit
|
||||||
if (command.Remove)
|
if (command.Remove)
|
||||||
{
|
{
|
||||||
// only remove local config files and exit
|
|
||||||
if(command.RemoveLocalConfig)
|
|
||||||
{
|
|
||||||
configManager.DeleteLocalRunnerConfig();
|
|
||||||
return Constants.Runner.ReturnCode.Success;
|
|
||||||
}
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await configManager.UnconfigureAsync(command);
|
await configManager.UnconfigureAsync(command);
|
||||||
@@ -199,30 +192,6 @@ namespace GitHub.Runner.Listener
|
|||||||
return Constants.Runner.ReturnCode.Success;
|
return Constants.Runner.ReturnCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
var base64JitConfig = command.GetJitConfig();
|
|
||||||
if (!string.IsNullOrEmpty(base64JitConfig))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var decodedJitConfig = Encoding.UTF8.GetString(Convert.FromBase64String(base64JitConfig));
|
|
||||||
var jitConfig = StringUtil.ConvertFromJson<Dictionary<string, string>>(decodedJitConfig);
|
|
||||||
foreach (var config in jitConfig)
|
|
||||||
{
|
|
||||||
var configFile = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Root), config.Key);
|
|
||||||
var configContent = Encoding.UTF8.GetString(Convert.FromBase64String(config.Value));
|
|
||||||
File.WriteAllText(configFile, configContent, Encoding.UTF8);
|
|
||||||
File.SetAttributes(configFile, File.GetAttributes(configFile) | FileAttributes.Hidden);
|
|
||||||
Trace.Info($"Save {configContent.Length} chars to '{configFile}'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Trace.Error(ex);
|
|
||||||
_term.WriteError(ex.Message);
|
|
||||||
return Constants.Runner.ReturnCode.TerminatedError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerSettings settings = configManager.LoadSettings();
|
RunnerSettings settings = configManager.LoadSettings();
|
||||||
|
|
||||||
var store = HostContext.GetService<IConfigurationStore>();
|
var store = HostContext.GetService<IConfigurationStore>();
|
||||||
@@ -353,7 +322,6 @@ namespace GitHub.Runner.Listener
|
|||||||
|
|
||||||
// Should we try to cleanup ephemeral runners
|
// Should we try to cleanup ephemeral runners
|
||||||
bool runOnceJobCompleted = false;
|
bool runOnceJobCompleted = false;
|
||||||
bool skipSessionDeletion = false;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var notification = HostContext.GetService<IJobNotification>();
|
var notification = HostContext.GetService<IJobNotification>();
|
||||||
@@ -365,8 +333,6 @@ namespace GitHub.Runner.Listener
|
|||||||
bool runOnceJobReceived = false;
|
bool runOnceJobReceived = false;
|
||||||
jobDispatcher = HostContext.CreateService<IJobDispatcher>();
|
jobDispatcher = HostContext.CreateService<IJobDispatcher>();
|
||||||
|
|
||||||
jobDispatcher.JobStatus += _listener.OnJobStatus;
|
|
||||||
|
|
||||||
while (!HostContext.RunnerShutdownToken.IsCancellationRequested)
|
while (!HostContext.RunnerShutdownToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
TaskAgentMessage message = null;
|
TaskAgentMessage message = null;
|
||||||
@@ -436,22 +402,12 @@ namespace GitHub.Runner.Listener
|
|||||||
|
|
||||||
message = await getNextMessage; //get next message
|
message = await getNextMessage; //get next message
|
||||||
HostContext.WritePerfCounter($"MessageReceived_{message.MessageType}");
|
HostContext.WritePerfCounter($"MessageReceived_{message.MessageType}");
|
||||||
if (string.Equals(message.MessageType, AgentRefreshMessage.MessageType, StringComparison.OrdinalIgnoreCase) ||
|
if (string.Equals(message.MessageType, AgentRefreshMessage.MessageType, StringComparison.OrdinalIgnoreCase))
|
||||||
string.Equals(message.MessageType, RunnerRefreshMessage.MessageType, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
if (autoUpdateInProgress == false)
|
if (autoUpdateInProgress == false)
|
||||||
{
|
{
|
||||||
autoUpdateInProgress = true;
|
autoUpdateInProgress = true;
|
||||||
AgentRefreshMessage runnerUpdateMessage = null;
|
var runnerUpdateMessage = JsonUtility.FromString<AgentRefreshMessage>(message.Body);
|
||||||
if (string.Equals(message.MessageType, AgentRefreshMessage.MessageType, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
runnerUpdateMessage = JsonUtility.FromString<AgentRefreshMessage>(message.Body);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var brokerRunnerUpdateMessage = JsonUtility.FromString<RunnerRefreshMessage>(message.Body);
|
|
||||||
runnerUpdateMessage = new AgentRefreshMessage(brokerRunnerUpdateMessage.RunnerId, brokerRunnerUpdateMessage.TargetVersion, TimeSpan.FromSeconds(brokerRunnerUpdateMessage.TimeoutInSeconds));
|
|
||||||
}
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// Can mock the update for testing
|
// Can mock the update for testing
|
||||||
if (StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_IS_MOCK_UPDATE")))
|
if (StringUtil.ConvertToBoolean(Environment.GetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_IS_MOCK_UPDATE")))
|
||||||
@@ -501,44 +457,6 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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<RunnerJobRequestRef>(message.Body);
|
|
||||||
Pipelines.AgentJobRequestMessage jobRequestMessage = null;
|
|
||||||
|
|
||||||
// Create connection
|
|
||||||
var credMgr = HostContext.GetService<ICredentialManager>();
|
|
||||||
var creds = credMgr.LoadCredentials();
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(messageRef.RunServiceUrl))
|
|
||||||
{
|
|
||||||
var actionsRunServer = HostContext.CreateService<IActionsRunServer>();
|
|
||||||
await actionsRunServer.ConnectAsync(new Uri(settings.ServerUrl), creds);
|
|
||||||
jobRequestMessage = await actionsRunServer.GetJobMessageAsync(messageRef.RunnerRequestId, messageQueueLoopTokenSource.Token);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var runServer = HostContext.CreateService<IRunServer>();
|
|
||||||
await runServer.ConnectAsync(new Uri(messageRef.RunServiceUrl), creds);
|
|
||||||
jobRequestMessage = await runServer.GetJobMessageAsync(messageRef.RunnerRequestId, messageQueueLoopTokenSource.Token);
|
|
||||||
}
|
|
||||||
|
|
||||||
jobDispatcher.Run(jobRequestMessage, runOnce);
|
|
||||||
if (runOnce)
|
|
||||||
{
|
|
||||||
Trace.Info("One time used runner received job message.");
|
|
||||||
runOnceJobReceived = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (string.Equals(message.MessageType, JobCancelMessage.MessageType, StringComparison.OrdinalIgnoreCase))
|
else if (string.Equals(message.MessageType, JobCancelMessage.MessageType, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var cancelJobMessage = JsonUtility.FromString<JobCancelMessage>(message.Body);
|
var cancelJobMessage = JsonUtility.FromString<JobCancelMessage>(message.Body);
|
||||||
@@ -550,14 +468,6 @@ namespace GitHub.Runner.Listener
|
|||||||
Trace.Info($"Skip message deletion for cancellation message '{message.MessageId}'.");
|
Trace.Info($"Skip message deletion for cancellation message '{message.MessageId}'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (string.Equals(message.MessageType, Pipelines.HostedRunnerShutdownMessage.MessageType, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
var HostedRunnerShutdownMessage = JsonUtility.FromString<Pipelines.HostedRunnerShutdownMessage>(message.Body);
|
|
||||||
skipMessageDeletion = true;
|
|
||||||
skipSessionDeletion = true;
|
|
||||||
Trace.Info($"Service requests the hosted runner to shutdown. Reason: '{HostedRunnerShutdownMessage.Reason}'.");
|
|
||||||
return Constants.Runner.ReturnCode.Success;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Trace.Error($"Received message {message.MessageId} with unsupported message type {message.MessageType}.");
|
Trace.Error($"Received message {message.MessageId} with unsupported message type {message.MessageType}.");
|
||||||
@@ -588,12 +498,9 @@ namespace GitHub.Runner.Listener
|
|||||||
{
|
{
|
||||||
if (jobDispatcher != null)
|
if (jobDispatcher != null)
|
||||||
{
|
{
|
||||||
jobDispatcher.JobStatus -= _listener.OnJobStatus;
|
|
||||||
await jobDispatcher.ShutdownAsync();
|
await jobDispatcher.ShutdownAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skipSessionDeletion)
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _listener.DeleteSessionAsync();
|
await _listener.DeleteSessionAsync();
|
||||||
@@ -604,7 +511,6 @@ namespace GitHub.Runner.Listener
|
|||||||
// and the delete session call will ends up with 401.
|
// and the delete session call will ends up with 401.
|
||||||
Trace.Info($"Ignore any exception during DeleteSession for an ephemeral runner. {ex}");
|
Trace.Info($"Ignore any exception during DeleteSession for an ephemeral runner. {ex}");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
messageQueueLoopTokenSource.Dispose();
|
messageQueueLoopTokenSource.Dispose();
|
||||||
|
|
||||||
@@ -653,10 +559,9 @@ Config Options:
|
|||||||
--name string Name of the runner to configure (default {Environment.MachineName ?? "myrunner"})
|
--name string Name of the runner to configure (default {Environment.MachineName ?? "myrunner"})
|
||||||
--runnergroup string Name of the runner group to add this runner to (defaults to the default runner group)
|
--runnergroup string Name of the runner group to add this runner to (defaults to the default runner group)
|
||||||
--labels string Extra labels in addition to the default: 'self-hosted,{Constants.Runner.Platform},{Constants.Runner.PlatformArchitecture}'
|
--labels string Extra labels in addition to the default: 'self-hosted,{Constants.Runner.Platform},{Constants.Runner.PlatformArchitecture}'
|
||||||
--local Removes the runner config files from your local machine. Used as an option to the remove command
|
|
||||||
--work string Relative runner work directory (default {Constants.Path.WorkDirectory})
|
--work string Relative runner work directory (default {Constants.Path.WorkDirectory})
|
||||||
--replace Replace any existing runner with the same name (default false)
|
--replace Replace any existing runner with the same name (default false)
|
||||||
--pat GitHub personal access token with repo scope. Used for checking network connectivity when executing `.{separator}run.{ext} --check`
|
--pat GitHub personal access token used for checking network connectivity when executing `.{separator}run.{ext} --check`
|
||||||
--disableupdate Disable self-hosted runner automatic update to the latest released version`
|
--disableupdate Disable self-hosted runner automatic update to the latest released version`
|
||||||
--ephemeral Configure the runner to only take one job and then let the service un-configure the runner after the job finishes (default false)");
|
--ephemeral Configure the runner to only take one job and then let the service un-configure the runner after the job finishes (default false)");
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Listener
|
|
||||||
{
|
|
||||||
[DataContract]
|
|
||||||
public sealed class RunnerJobRequestRef
|
|
||||||
{
|
|
||||||
[DataMember(Name = "id")]
|
|
||||||
public string Id { get; set; }
|
|
||||||
[DataMember(Name = "runner_request_id")]
|
|
||||||
public string RunnerRequestId { get; set; }
|
|
||||||
[DataMember(Name = "run_service_url")]
|
|
||||||
public string RunServiceUrl { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -32,14 +32,14 @@ namespace GitHub.Runner.Listener
|
|||||||
private static string _platform = BuildConstants.RunnerPackage.PackageName;
|
private static string _platform = BuildConstants.RunnerPackage.PackageName;
|
||||||
private static string _dotnetRuntime = "dotnetRuntime";
|
private static string _dotnetRuntime = "dotnetRuntime";
|
||||||
private static string _externals = "externals";
|
private static string _externals = "externals";
|
||||||
private readonly Dictionary<string, string> _contentHashes = new();
|
private readonly Dictionary<string, string> _contentHashes = new Dictionary<string, string>();
|
||||||
|
|
||||||
private PackageMetadata _targetPackage;
|
private PackageMetadata _targetPackage;
|
||||||
private ITerminal _terminal;
|
private ITerminal _terminal;
|
||||||
private IRunnerServer _runnerServer;
|
private IRunnerServer _runnerServer;
|
||||||
private int _poolId;
|
private int _poolId;
|
||||||
private int _agentId;
|
private int _agentId;
|
||||||
private readonly ConcurrentQueue<string> _updateTrace = new();
|
private readonly ConcurrentQueue<string> _updateTrace = new ConcurrentQueue<string>();
|
||||||
private Task _cloneAndCalculateContentHashTask;
|
private Task _cloneAndCalculateContentHashTask;
|
||||||
private string _dotnetRuntimeCloneDirectory;
|
private string _dotnetRuntimeCloneDirectory;
|
||||||
private string _externalsCloneDirectory;
|
private string _externalsCloneDirectory;
|
||||||
@@ -131,10 +131,8 @@ namespace GitHub.Runner.Listener
|
|||||||
// For L0, we will skip execute update script.
|
// For L0, we will skip execute update script.
|
||||||
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GITHUB_ACTION_EXECUTE_UPDATE_SCRIPT")))
|
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_GITHUB_ACTION_EXECUTE_UPDATE_SCRIPT")))
|
||||||
{
|
{
|
||||||
string flagFile = "update.finished";
|
|
||||||
IOUtil.DeleteFile(flagFile);
|
|
||||||
// kick off update script
|
// kick off update script
|
||||||
Process invokeScript = new();
|
Process invokeScript = new Process();
|
||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
invokeScript.StartInfo.FileName = WhichUtil.Which("cmd.exe", trace: Trace);
|
invokeScript.StartInfo.FileName = WhichUtil.Which("cmd.exe", trace: Trace);
|
||||||
invokeScript.StartInfo.Arguments = $"/c \"{updateScript}\"";
|
invokeScript.StartInfo.Arguments = $"/c \"{updateScript}\"";
|
||||||
@@ -191,9 +189,9 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
Trace.Info($"Version '{_targetPackage.Version}' of '{_targetPackage.Type}' package available in server.");
|
Trace.Info($"Version '{_targetPackage.Version}' of '{_targetPackage.Type}' package available in server.");
|
||||||
PackageVersion serverVersion = new(_targetPackage.Version);
|
PackageVersion serverVersion = new PackageVersion(_targetPackage.Version);
|
||||||
Trace.Info($"Current running runner version is {BuildConstants.RunnerPackage.Version}");
|
Trace.Info($"Current running runner version is {BuildConstants.RunnerPackage.Version}");
|
||||||
PackageVersion runnerVersion = new(BuildConstants.RunnerPackage.Version);
|
PackageVersion runnerVersion = new PackageVersion(BuildConstants.RunnerPackage.Version);
|
||||||
|
|
||||||
return serverVersion.CompareTo(runnerVersion) > 0;
|
return serverVersion.CompareTo(runnerVersion) > 0;
|
||||||
}
|
}
|
||||||
@@ -476,7 +474,7 @@ namespace GitHub.Runner.Listener
|
|||||||
long downloadSize = 0;
|
long downloadSize = 0;
|
||||||
|
|
||||||
//open zip stream in async mode
|
//open zip stream in async mode
|
||||||
using (HttpClient httpClient = new(HostContext.CreateHttpClientHandler()))
|
using (HttpClient httpClient = new HttpClient(HostContext.CreateHttpClientHandler()))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_targetPackage.Token))
|
if (!string.IsNullOrEmpty(_targetPackage.Token))
|
||||||
{
|
{
|
||||||
@@ -486,7 +484,7 @@ namespace GitHub.Runner.Listener
|
|||||||
|
|
||||||
Trace.Info($"Downloading {packageDownloadUrl}");
|
Trace.Info($"Downloading {packageDownloadUrl}");
|
||||||
|
|
||||||
using (FileStream fs = new(archiveFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
|
using (FileStream fs = new FileStream(archiveFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
|
||||||
using (Stream result = await httpClient.GetStreamAsync(packageDownloadUrl))
|
using (Stream result = await httpClient.GetStreamAsync(packageDownloadUrl))
|
||||||
{
|
{
|
||||||
//81920 is the default used by System.IO.Stream.CopyTo and is under the large object heap threshold (85k).
|
//81920 is the default used by System.IO.Stream.CopyTo and is under the large object heap threshold (85k).
|
||||||
@@ -596,7 +594,7 @@ namespace GitHub.Runner.Listener
|
|||||||
int exitCode = await processInvoker.ExecuteAsync(extractDirectory, tar, $"-xzf \"{archiveFile}\"", null, token);
|
int exitCode = await processInvoker.ExecuteAsync(extractDirectory, tar, $"-xzf \"{archiveFile}\"", null, token);
|
||||||
if (exitCode != 0)
|
if (exitCode != 0)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException($"Can't use 'tar -xzf' to extract archive file: {archiveFile}. return code: {exitCode}.");
|
throw new NotSupportedException($"Can't use 'tar -xzf' extract archive file: {archiveFile}. return code: {exitCode}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Loader;
|
using System.Runtime.Loader;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using GitHub.Runner.Sdk;
|
using GitHub.Runner.Sdk;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
|
|
||||||
@@ -12,7 +15,7 @@ namespace GitHub.Runner.PluginHost
|
|||||||
{
|
{
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
private static CancellationTokenSource tokenSource = new();
|
private static CancellationTokenSource tokenSource = new CancellationTokenSource();
|
||||||
private static string executingAssemblyLocation = string.Empty;
|
private static string executingAssemblyLocation = string.Empty;
|
||||||
|
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user