mirror of
https://github.com/actions/runner.git
synced 2025-12-10 20:36:49 +00:00
Compare commits
35 Commits
v2.159.0
...
notarize-m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b10d8c0cf | ||
|
|
45c19eb7cb | ||
|
|
9ba971592b | ||
|
|
b27cfb18e6 | ||
|
|
ced4c2ca50 | ||
|
|
54f21c641f | ||
|
|
c5cbac9796 | ||
|
|
8911283cdb | ||
|
|
76078b5c44 | ||
|
|
ec9cb6c68d | ||
|
|
bcac4557a0 | ||
|
|
19580bdaf8 | ||
|
|
96d3288553 | ||
|
|
5b6f9d3b93 | ||
|
|
51581ac865 | ||
|
|
e7dd2c6cc2 | ||
|
|
08b9f6e045 | ||
|
|
0129e8111f | ||
|
|
ccca13ac07 | ||
|
|
82e9857d4f | ||
|
|
afd233b735 | ||
|
|
83be145bfd | ||
|
|
6e20aceaff | ||
|
|
e89148e33e | ||
|
|
f1c58c33b6 | ||
|
|
7b158fff05 | ||
|
|
6225b22870 | ||
|
|
53da198867 | ||
|
|
3a43d853be | ||
|
|
9d7b0a2405 | ||
|
|
05f0b938ac | ||
|
|
f5f14d4811 | ||
|
|
2f261f2c31 | ||
|
|
c3b11b36e9 | ||
|
|
8777686c11 |
42
.github/workflows/build.yml
vendored
42
.github/workflows/build.yml
vendored
@@ -1,33 +1,48 @@
|
||||
name: Runner CI
|
||||
|
||||
on:
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
branches:
|
||||
- master
|
||||
- releases/*
|
||||
pull_request:
|
||||
branches:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
runtime: [ linux-x64, linux-arm64, linux-arm, win-x64, osx-x64 ]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
- runtime: linux-x64
|
||||
os: ubuntu-latest
|
||||
devScript: ./dev.sh
|
||||
- os: macOS-latest
|
||||
|
||||
- runtime: linux-arm64
|
||||
os: ubuntu-latest
|
||||
devScript: ./dev.sh
|
||||
- os: windows-latest
|
||||
devScript: dev.cmd
|
||||
|
||||
- runtime: linux-arm
|
||||
os: ubuntu-latest
|
||||
devScript: ./dev.sh
|
||||
|
||||
- runtime: osx-x64
|
||||
os: macOS-latest
|
||||
devScript: ./dev.sh
|
||||
|
||||
- runtime: win-x64
|
||||
os: windows-latest
|
||||
devScript: ./dev
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
|
||||
# Build runner layout
|
||||
- name: Build & Layout Release
|
||||
run: |
|
||||
${{ matrix.devScript }} layout Release
|
||||
${{ matrix.devScript }} layout Release ${{ matrix.runtime }}
|
||||
working-directory: src
|
||||
|
||||
# Run tests
|
||||
@@ -35,18 +50,19 @@ jobs:
|
||||
run: |
|
||||
${{ matrix.devScript }} test
|
||||
working-directory: src
|
||||
|
||||
if: matrix.runtime != 'linux-arm64' && matrix.runtime != 'linux-arm'
|
||||
|
||||
# Create runner package tar.gz/zip
|
||||
- name: Package Release
|
||||
if: github.event_name != 'pull_request'
|
||||
run: |
|
||||
${{ matrix.devScript }} package Release
|
||||
working-directory: src
|
||||
|
||||
|
||||
# Upload runner package tar.gz/zip as artifact
|
||||
- name: Publish Artifact
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: runner-package-${{ matrix.os }}
|
||||
name: runner-package-${{ matrix.runtime }}
|
||||
path: _package
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,7 +3,6 @@
|
||||
**/libs
|
||||
**/*.xproj
|
||||
**/*.xproj.user
|
||||
**/*.sln
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.error
|
||||
|
||||
73
ActionsRunner.sln
Normal file
73
ActionsRunner.sln
Normal file
@@ -0,0 +1,73 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29411.138
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Runner.Common", "src\Runner.Common\Runner.Common.csproj", "{084289A3-CD7A-42E0-9219-4348B4B7E19B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Runner.Listener", "src\Runner.Listener\Runner.Listener.csproj", "{7D461AEE-BF2A-4855-BD96-56921160B36A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Runner.PluginHost", "src\Runner.PluginHost\Runner.PluginHost.csproj", "{D0320EB1-CB6D-4179-BFDC-2F2B664A370C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Runner.Plugins", "src\Runner.Plugins\Runner.Plugins.csproj", "{C23AFD6F-4DCD-4243-BC61-865BE31B9168}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Runner.Sdk", "src\Runner.Sdk\Runner.Sdk.csproj", "{D0484633-DA97-4C34-8E47-1DADE212A57A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RunnerService", "src\Runner.Service\Windows\RunnerService.csproj", "{D12EBD71-0464-46D0-8394-40BCFBA0A6F2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Runner.Worker", "src\Runner.Worker\Runner.Worker.csproj", "{C2F5B9FA-2621-411F-8EB2-273ED276F503}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sdk", "src\Sdk\Sdk.csproj", "{D2EE812B-E4DF-49BB-AE87-12BC49949B5F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "src\Test\Test.csproj", "{C932061F-F6A1-4F1E-B854-A6C6B30DC3EF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{084289A3-CD7A-42E0-9219-4348B4B7E19B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{084289A3-CD7A-42E0-9219-4348B4B7E19B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{084289A3-CD7A-42E0-9219-4348B4B7E19B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{084289A3-CD7A-42E0-9219-4348B4B7E19B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7D461AEE-BF2A-4855-BD96-56921160B36A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7D461AEE-BF2A-4855-BD96-56921160B36A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7D461AEE-BF2A-4855-BD96-56921160B36A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7D461AEE-BF2A-4855-BD96-56921160B36A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D0320EB1-CB6D-4179-BFDC-2F2B664A370C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D0320EB1-CB6D-4179-BFDC-2F2B664A370C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D0320EB1-CB6D-4179-BFDC-2F2B664A370C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D0320EB1-CB6D-4179-BFDC-2F2B664A370C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C23AFD6F-4DCD-4243-BC61-865BE31B9168}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C23AFD6F-4DCD-4243-BC61-865BE31B9168}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C23AFD6F-4DCD-4243-BC61-865BE31B9168}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C23AFD6F-4DCD-4243-BC61-865BE31B9168}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D0484633-DA97-4C34-8E47-1DADE212A57A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D0484633-DA97-4C34-8E47-1DADE212A57A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D0484633-DA97-4C34-8E47-1DADE212A57A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D0484633-DA97-4C34-8E47-1DADE212A57A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D12EBD71-0464-46D0-8394-40BCFBA0A6F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D12EBD71-0464-46D0-8394-40BCFBA0A6F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D12EBD71-0464-46D0-8394-40BCFBA0A6F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D12EBD71-0464-46D0-8394-40BCFBA0A6F2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C2F5B9FA-2621-411F-8EB2-273ED276F503}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C2F5B9FA-2621-411F-8EB2-273ED276F503}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C2F5B9FA-2621-411F-8EB2-273ED276F503}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C2F5B9FA-2621-411F-8EB2-273ED276F503}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D2EE812B-E4DF-49BB-AE87-12BC49949B5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D2EE812B-E4DF-49BB-AE87-12BC49949B5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D2EE812B-E4DF-49BB-AE87-12BC49949B5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D2EE812B-E4DF-49BB-AE87-12BC49949B5F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C932061F-F6A1-4F1E-B854-A6C6B30DC3EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C932061F-F6A1-4F1E-B854-A6C6B30DC3EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C932061F-F6A1-4F1E-B854-A6C6B30DC3EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C932061F-F6A1-4F1E-B854-A6C6B30DC3EF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4A831DDA-3860-45E5-930E-BB3A7833AE80}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
12
assets.json
12
assets.json
@@ -16,5 +16,17 @@
|
||||
"platform": "linux-x64",
|
||||
"version": "<RUNNER_VERSION>",
|
||||
"downloadUrl": "https://githubassets.azureedge.net/runners/<RUNNER_VERSION>/actions-runner-linux-x64-<RUNNER_VERSION>.tar.gz"
|
||||
},
|
||||
{
|
||||
"name": "actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz",
|
||||
"platform": "linux-arm64",
|
||||
"version": "<RUNNER_VERSION>",
|
||||
"downloadUrl": "https://githubassets.azureedge.net/runners/<RUNNER_VERSION>/actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz"
|
||||
},
|
||||
{
|
||||
"name": "actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz",
|
||||
"platform": "linux-arm",
|
||||
"version": "<RUNNER_VERSION>",
|
||||
"downloadUrl": "https://githubassets.azureedge.net/runners/<RUNNER_VERSION>/actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz"
|
||||
}
|
||||
]
|
||||
@@ -1,5 +1,5 @@
|
||||
stages:
|
||||
- stage: Build
|
||||
- stage: Build
|
||||
jobs:
|
||||
################################################################################
|
||||
- job: build_windows_agent_x64
|
||||
@@ -11,12 +11,14 @@ stages:
|
||||
|
||||
# Steps template for windows platform
|
||||
- template: windows.template.yml
|
||||
|
||||
parameters:
|
||||
targetRuntime: win-x64
|
||||
|
||||
# Package dotnet core windows dependency (VC++ Redistributable)
|
||||
- powershell: |
|
||||
Write-Host "Downloading 'VC++ Redistributable' package."
|
||||
$outDir = Join-Path -Path $env:TMP -ChildPath ([Guid]::NewGuid())
|
||||
New-Item -Path $outDir -ItemType directory
|
||||
New-Item -Path $outDir -ItemType directory
|
||||
$outFile = Join-Path -Path $outDir -ChildPath "ucrt.zip"
|
||||
Invoke-WebRequest -Uri https://vstsagenttools.blob.core.windows.net/tools/ucrt/ucrt_x64.zip -OutFile $outFile
|
||||
Write-Host "Unzipping 'VC++ Redistributable' package to agent layout."
|
||||
@@ -28,13 +30,13 @@ stages:
|
||||
displayName: Package UCRT
|
||||
|
||||
# Create agent package zip
|
||||
- script: dev.cmd package Release
|
||||
- script: dev.cmd package Release win-x64
|
||||
workingDirectory: src
|
||||
displayName: Package Release
|
||||
|
||||
# Upload agent package zip as build artifact
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (Windows)
|
||||
displayName: Publish Artifact (Windows x64)
|
||||
inputs:
|
||||
pathToPublish: _package
|
||||
artifactName: runners
|
||||
@@ -50,22 +52,76 @@ stages:
|
||||
|
||||
# Steps template for non-windows platform
|
||||
- template: nonwindows.template.yml
|
||||
parameters:
|
||||
targetRuntime: linux-x64
|
||||
|
||||
# Create agent package zip
|
||||
- script: ./dev.sh package Release
|
||||
- script: ./dev.sh package Release linux-x64
|
||||
workingDirectory: src
|
||||
displayName: Package Release
|
||||
displayName: Package Release
|
||||
|
||||
# Upload agent package zip as build artifact
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (Linux)
|
||||
displayName: Publish Artifact (Linux x64)
|
||||
inputs:
|
||||
pathToPublish: _package
|
||||
artifactName: runners
|
||||
artifactType: container
|
||||
|
||||
################################################################################
|
||||
- job: build_osx_agent
|
||||
- job: build_linux_agent_arm64
|
||||
################################################################################
|
||||
displayName: Linux Agent (arm64)
|
||||
pool:
|
||||
vmImage: ubuntu-16.04
|
||||
steps:
|
||||
|
||||
# Steps template for non-windows platform
|
||||
- template: nonwindows.template.yml
|
||||
parameters:
|
||||
targetRuntime: linux-arm64
|
||||
|
||||
# Create agent package zip
|
||||
- script: ./dev.sh package Release linux-arm64
|
||||
workingDirectory: src
|
||||
displayName: Package Release
|
||||
|
||||
# Upload agent package zip as build artifact
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (Linux ARM64)
|
||||
inputs:
|
||||
pathToPublish: _package
|
||||
artifactName: runners
|
||||
artifactType: container
|
||||
|
||||
################################################################################
|
||||
- job: build_linux_agent_arm
|
||||
################################################################################
|
||||
displayName: Linux Agent (arm)
|
||||
pool:
|
||||
vmImage: ubuntu-16.04
|
||||
steps:
|
||||
|
||||
# Steps template for non-windows platform
|
||||
- template: nonwindows.template.yml
|
||||
parameters:
|
||||
targetRuntime: linux-arm
|
||||
|
||||
# Create agent package zip
|
||||
- script: ./dev.sh package Release linux-arm
|
||||
workingDirectory: src
|
||||
displayName: Package Release
|
||||
|
||||
# Upload agent package zip as build artifact
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (Linux ARM)
|
||||
inputs:
|
||||
pathToPublish: _package
|
||||
artifactName: runners
|
||||
artifactType: container
|
||||
|
||||
################################################################################
|
||||
- job: build_osx_agent_x64
|
||||
################################################################################
|
||||
displayName: macOS Agent (x64)
|
||||
pool:
|
||||
@@ -74,15 +130,17 @@ stages:
|
||||
|
||||
# Steps template for non-windows platform
|
||||
- template: nonwindows.template.yml
|
||||
|
||||
parameters:
|
||||
targetRuntime: osx-x64
|
||||
|
||||
# Create agent package zip
|
||||
- script: ./dev.sh package Release
|
||||
- script: ./dev.sh package Release osx-x64
|
||||
workingDirectory: src
|
||||
displayName: Package Release
|
||||
displayName: Package Release
|
||||
|
||||
# Upload agent package zip as build artifact
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish Artifact (OSX)
|
||||
displayName: Publish Artifact (OSX x64)
|
||||
inputs:
|
||||
pathToPublish: _package
|
||||
artifactName: runners
|
||||
@@ -98,7 +156,7 @@ stages:
|
||||
pool:
|
||||
name: ProductionRMAgents
|
||||
steps:
|
||||
|
||||
|
||||
# Download all agent packages from all previous phases
|
||||
- task: DownloadBuildArtifacts@0
|
||||
displayName: Download Agent Packages
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Contribute (Dev)
|
||||
# Contribution guide for developers
|
||||
|
||||
## Dev Dependencies
|
||||
## Required Dev Dependencies
|
||||
|
||||
 Git for Windows [Install Here](https://git-scm.com/downloads) (needed for dev sh script)
|
||||
|
||||
## Build, Test, Layout
|
||||
## To Build, Test, Layout
|
||||
|
||||
From src:
|
||||
Navigate to the `src` directory and run the following command:
|
||||
|
||||
 `dev {command}`
|
||||
|
||||
@@ -14,13 +14,12 @@ From src:
|
||||
|
||||
**Commands:**
|
||||
|
||||
`layout` (`l`): Run first time to create a full agent layout in {root}/_layout
|
||||
* `layout` (`l`): Run first time to create a full agent layout in `{root}/_layout`
|
||||
* `build` (`b`): Build everything and update agent layout folder
|
||||
* `test` (`t`): Build agent binaries and run unit tests
|
||||
|
||||
`build` (`b`): build everything and update agent layout folder
|
||||
Sample developer flow:
|
||||
|
||||
`test` (`t`): build agent binaries and run unit tests
|
||||
|
||||
Normal dev flow:
|
||||
```bash
|
||||
git clone https://github.com/actions/runner
|
||||
cd ./src
|
||||
@@ -37,5 +36,5 @@ cd ./src
|
||||
|
||||
## Styling
|
||||
|
||||
We use the dotnet foundation and CoreCLR style guidelines [located here](
|
||||
We use the .NET Foundation and CoreCLR style guidelines [located here](
|
||||
https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md)
|
||||
|
||||
@@ -5,36 +5,55 @@
|
||||
## Supported Distributions and Versions
|
||||
|
||||
x64
|
||||
- Red Hat Enterprise Linux 6 (see note 1), 7
|
||||
- CentOS 6 (see note 1), 7
|
||||
- Red Hat Enterprise Linux 7
|
||||
- CentOS 7
|
||||
- Oracle Linux 7
|
||||
- Fedora 28, 27
|
||||
- Debian 9, 8.7 or later versions
|
||||
- Ubuntu 18.04, Ubuntu 16.04, Ubuntu 14.04
|
||||
- Linux Mint 18, 17
|
||||
- openSUSE 42.3 or later versions
|
||||
- SUSE Enterprise Linux (SLES) 12 SP2 or later versions
|
||||
- Fedora 29+
|
||||
- Debian 9+
|
||||
- Ubuntu 16.04+
|
||||
- Linux Mint 18+
|
||||
- openSUSE 15+
|
||||
- SUSE Enterprise Linux (SLES) 12 SP2+
|
||||
|
||||
ARM32 (see note 2)
|
||||
- Debian 9 or later versions
|
||||
- Ubuntu 18.04 or later versions
|
||||
## Install .Net Core 3.x Linux Dependencies
|
||||
|
||||
> Note 1: Red Hat Enterprise Linux 6 and CentOS 6 require installing the specialized "rhel.6-x64" agent package
|
||||
> Note 2: ARM instruction set [ARMv7](https://en.wikipedia.org/wiki/List_of_ARM_microarchitectures) or above is required, you can get your device's information by executing `uname -a`
|
||||
|
||||
## Install .Net Core 2.x Linux Dependencies
|
||||
|
||||
The `./config.sh` will check .Net Core 2.x dependencies during agent configuration.
|
||||
The `./config.sh` will check .Net Core 3.x dependencies during runner configuration.
|
||||
You might see something like this which indicate a dependency's missing.
|
||||
```bash
|
||||
./config.sh
|
||||
libunwind.so.8 => not found
|
||||
libunwind-x86_64.so.8 => not found
|
||||
Dependencies is missing for Dotnet Core 2.1
|
||||
Execute ./bin/installdependencies.sh to install any missing Dotnet Core 2.1 dependencies.
|
||||
Dependencies is missing for Dotnet Core 3.0
|
||||
Execute ./bin/installdependencies.sh to install any missing Dotnet Core 3.0 dependencies.
|
||||
```
|
||||
You can easily correct the problem by executing `./bin/installdependencies.sh`.
|
||||
The `installdependencies.sh` script should install all required dependencies on all supported Linux versions
|
||||
> Note: The `installdependencies.sh` script will try to use the default package management mechanism on your Linux flavor (ex. `yum`/`apt-get`/`apt`). You might need to deal with error coming from the package management mechanism related to your setup, like [#1353](https://github.com/Microsoft/vsts-agent/issues/1353)
|
||||
|
||||
### Full dependencies list
|
||||
|
||||
Debian based OS (Debian, Ubuntu, Linux Mint)
|
||||
|
||||
- liblttng-ust0
|
||||
- libkrb5-3
|
||||
- zlib1g
|
||||
- libssl1.1, libssl1.0.2 or libssl1.0.0
|
||||
- libicu63, libicu60, libicu57 or libicu55
|
||||
|
||||
Fedora based OS (Fedora, Redhat, Centos, Oracle Linux 7)
|
||||
|
||||
- lttng-ust
|
||||
- openssl-libs
|
||||
- krb5-libs
|
||||
- zlib
|
||||
- libicu
|
||||
|
||||
SUSE based OS (OpenSUSE, SUSE Enterprise)
|
||||
|
||||
- lttng-ust
|
||||
- libopenssl1_1
|
||||
- krb5
|
||||
- zlib
|
||||
- libicu60_2
|
||||
|
||||
## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites?tabs=netcore2x)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Supported Versions
|
||||
|
||||
- macOS Sierra (10.12) and later versions
|
||||
- macOS High Sierra (10.13) and later versions
|
||||
|
||||
|
||||
## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/macos-prerequisites?tabs=netcore2x)
|
||||
## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/macos-prerequisites?tabs=netcore30)
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
- Windows 7 64-bit
|
||||
- Windows 8.1 64-bit
|
||||
- Windows 10 64-bit
|
||||
- Windows Server 2008 R2 SP1 64-bit
|
||||
- Windows Server 2012 R2 64-bit
|
||||
- Windows Server 2016 64-bit
|
||||
- Windows Server 2019 64-bit
|
||||
|
||||
## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)
|
||||
## [More .Net Core Prerequisites Information](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore30)
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
parameters:
|
||||
targetRuntime: ''
|
||||
|
||||
steps:
|
||||
|
||||
# Build agent layout
|
||||
- script: ./dev.sh layout Release
|
||||
- script: ./dev.sh layout Release ${{ parameters.targetRuntime }}
|
||||
workingDirectory: src
|
||||
displayName: Build & Layout Release
|
||||
displayName: Build & Layout Release ${{ parameters.targetRuntime }}
|
||||
|
||||
# Run test
|
||||
- script: ./dev.sh test
|
||||
workingDirectory: src
|
||||
displayName: Test
|
||||
condition: and(ne('${{ parameters.targetRuntime }}', 'linux-arm64'), ne('${{ parameters.targetRuntime }}', 'linux-arm'))
|
||||
|
||||
# # Publish test results
|
||||
# - task: PublishTestResults@2
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
## Features
|
||||
- Runner config auth via GitHub.com. (#107) (#117)
|
||||
- Adding wrapper action to support post job cleanup, adding checkout v1.1 (#91)
|
||||
- Improving terminal experience (#110)
|
||||
- Add runner support for cache action. (#120)
|
||||
- Added packages for Linux ARM32 (linux-arm) and Linux ARM64 (linux-arm64) (#184)
|
||||
- Note that these packages are pre-release status and may not work with all existing actions
|
||||
|
||||
## Bugs
|
||||
- Set GITHUB_ACTIONS in containers. (#119)
|
||||
- Fix issue data column/col mismatch. (#122)
|
||||
- Fixed a bug where problem matchers were not treating FromPath as a file path (#183)
|
||||
|
||||
## Misc
|
||||
- Use GitHub actions for CI/PR (#112)
|
||||
- Code Cleanup (#123) (#124) (#125)
|
||||
- Fixed code warnings in the Runner (#174)
|
||||
- Fixed code warnings in the Runner tests (#178)
|
||||
- Added support for building the Runner in Visual Studio (#173)
|
||||
|
||||
## Agent Downloads
|
||||
|
||||
@@ -19,6 +17,8 @@
|
||||
| Windows x64 | [actions-runner-win-x64-<RUNNER_VERSION>.zip](https://githubassets.azureedge.net/runners/<RUNNER_VERSION>/actions-runner-win-x64-<RUNNER_VERSION>.zip) |
|
||||
| macOS | [actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz](https://githubassets.azureedge.net/runners/<RUNNER_VERSION>/actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz) |
|
||||
| Linux x64 | [actions-runner-linux-x64-<RUNNER_VERSION>.tar.gz](https://githubassets.azureedge.net/runners/<RUNNER_VERSION>/actions-runner-linux-x64-<RUNNER_VERSION>.tar.gz) |
|
||||
| Linux arm64 | [actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz](https://githubassets.azureedge.net/runners/<RUNNER_VERSION>/actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz) |
|
||||
| Linux arm | [actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz](https://githubassets.azureedge.net/runners/<RUNNER_VERSION>/actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz) |
|
||||
|
||||
After Download:
|
||||
|
||||
@@ -42,3 +42,17 @@ C:\myagent> Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO
|
||||
~/$ mkdir myagent && cd myagent
|
||||
~/myagent$ tar xzf ~/Downloads/actions-runner-linux-x64-<RUNNER_VERSION>.tar.gz
|
||||
```
|
||||
|
||||
## Linux arm64
|
||||
|
||||
``` bash
|
||||
~/$ mkdir myagent && cd myagent
|
||||
~/myagent$ tar xzf ~/Downloads/actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz
|
||||
```
|
||||
|
||||
## Linux arm
|
||||
|
||||
``` bash
|
||||
~/$ mkdir myagent && cd myagent
|
||||
~/myagent$ tar xzf ~/Downloads/actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz
|
||||
```
|
||||
54
src/Directory.Build.props
Normal file
54
src/Directory.Build.props
Normal file
@@ -0,0 +1,54 @@
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- Detect OS for build -->
|
||||
<PropertyGroup>
|
||||
<BUILD_OS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">Windows</BUILD_OS>
|
||||
<BUILD_OS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">OSX</BUILD_OS>
|
||||
<BUILD_OS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">Linux</BUILD_OS>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Set OS vars -->
|
||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Windows'">
|
||||
<DefineConstants>$(DefineConstants);OS_WINDOWS</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'OSX'">
|
||||
<DefineConstants>$(DefineConstants);OS_OSX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Linux'">
|
||||
<DefineConstants>$(DefineConstants);OS_LINUX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Set Platform/bitness vars -->
|
||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Windows' AND ('$(PackageRuntime)' == 'win-x64' OR '$(PackageRuntime)' == '')">
|
||||
<DefineConstants>$(DefineConstants);X64</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Windows' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>$(DefineConstants);X86</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'OSX'">
|
||||
<DefineConstants>$(DefineConstants);X64</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Linux' AND ('$(PackageRuntime)' == 'linux-x64' OR '$(PackageRuntime)' == '')">
|
||||
<DefineConstants>$(DefineConstants);X64</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Linux' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>$(DefineConstants);ARM</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'Linux' AND '$(PackageRuntime)' == 'linux-arm64'">
|
||||
<DefineConstants>$(DefineConstants);ARM64</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Set TRACE/DEBUG vars -->
|
||||
<PropertyGroup>
|
||||
<DefineConstants>$(DefineConstants);TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<DefineConstants>$(DefineConstants);DEBUG</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Set OS specific config -->
|
||||
<PropertyGroup Condition="'$(BUILD_OS)' == 'OSX'">
|
||||
<UseHardenedRuntime>true</UseHardenedRuntime>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
91
src/Misc/dotnet-install.ps1
vendored
91
src/Misc/dotnet-install.ps1
vendored
@@ -37,10 +37,7 @@
|
||||
.PARAMETER SharedRuntime
|
||||
This parameter is obsolete and may be removed in a future version of this script.
|
||||
The recommended alternative is '-Runtime dotnet'.
|
||||
|
||||
Default: false
|
||||
Installs just the shared runtime bits, not the entire SDK.
|
||||
This is equivalent to specifying `-Runtime dotnet`.
|
||||
.PARAMETER Runtime
|
||||
Installs just a shared runtime, not the entire SDK.
|
||||
Possible values:
|
||||
@@ -77,11 +74,15 @@
|
||||
Skips installing non-versioned files if they already exist, such as dotnet.exe.
|
||||
.PARAMETER NoCdn
|
||||
Disable downloading from the Azure CDN, and use the uncached feed directly.
|
||||
.PARAMETER JSonFile
|
||||
Determines the SDK version from a user specified global.json file
|
||||
Note: global.json must have a value for 'SDK:Version'
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
param(
|
||||
[string]$Channel="LTS",
|
||||
[string]$Version="Latest",
|
||||
[string]$JSonFile,
|
||||
[string]$InstallDir="<auto>",
|
||||
[string]$Architecture="<auto>",
|
||||
[ValidateSet("dotnet", "aspnetcore", "windowsdesktop", IgnoreCase = $false)]
|
||||
@@ -258,7 +259,6 @@ function GetHTTPResponse([Uri] $Uri)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Coherent) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
@@ -304,20 +304,64 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Co
|
||||
return $VersionInfo
|
||||
}
|
||||
|
||||
|
||||
function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel, [string]$Version) {
|
||||
function Parse-Jsonfile-For-Version([string]$JSonFile) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
switch ($Version.ToLower()) {
|
||||
{ $_ -eq "latest" } {
|
||||
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $False
|
||||
return $LatestVersionInfo.Version
|
||||
If (-Not (Test-Path $JSonFile)) {
|
||||
throw "Unable to find '$JSonFile'"
|
||||
exit 0
|
||||
}
|
||||
try {
|
||||
$JSonContent = Get-Content($JSonFile) -Raw | ConvertFrom-Json | Select-Object -expand "sdk" -ErrorAction SilentlyContinue
|
||||
}
|
||||
catch {
|
||||
throw "Json file unreadable: '$JSonFile'"
|
||||
exit 0
|
||||
}
|
||||
if ($JSonContent) {
|
||||
try {
|
||||
$JSonContent.PSObject.Properties | ForEach-Object {
|
||||
$PropertyName = $_.Name
|
||||
if ($PropertyName -eq "version") {
|
||||
$Version = $_.Value
|
||||
Say-Verbose "Version = $Version"
|
||||
}
|
||||
}
|
||||
}
|
||||
{ $_ -eq "coherent" } {
|
||||
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $True
|
||||
return $LatestVersionInfo.Version
|
||||
catch {
|
||||
throw "Unable to parse the SDK node in '$JSonFile'"
|
||||
exit 0
|
||||
}
|
||||
default { return $Version }
|
||||
}
|
||||
else {
|
||||
throw "Unable to find the SDK node in '$JSonFile'"
|
||||
exit 0
|
||||
}
|
||||
If ($Version -eq $null) {
|
||||
throw "Unable to find the SDK:version node in '$JSonFile'"
|
||||
exit 0
|
||||
}
|
||||
return $Version
|
||||
}
|
||||
|
||||
function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel, [string]$Version, [string]$JSonFile) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
if (-not $JSonFile) {
|
||||
switch ($Version.ToLower()) {
|
||||
{ $_ -eq "latest" } {
|
||||
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $False
|
||||
return $LatestVersionInfo.Version
|
||||
}
|
||||
{ $_ -eq "coherent" } {
|
||||
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $True
|
||||
return $LatestVersionInfo.Version
|
||||
}
|
||||
default { return $Version }
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Parse-Jsonfile-For-Version $JSonFile
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,23 +426,6 @@ function Resolve-Installation-Path([string]$InstallDir) {
|
||||
return $InstallDir
|
||||
}
|
||||
|
||||
function Get-Version-Info-From-Version-File([string]$InstallRoot, [string]$RelativePathToVersionFile) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
$VersionFile = Join-Path -Path $InstallRoot -ChildPath $RelativePathToVersionFile
|
||||
Say-Verbose "Local version file: $VersionFile"
|
||||
|
||||
if (Test-Path $VersionFile) {
|
||||
$VersionText = cat $VersionFile
|
||||
Say-Verbose "Local version file text: $VersionText"
|
||||
return Get-Version-Info-From-Version-Text $VersionText
|
||||
}
|
||||
|
||||
Say-Verbose "Local version file not found."
|
||||
|
||||
return $null
|
||||
}
|
||||
|
||||
function Is-Dotnet-Package-Installed([string]$InstallRoot, [string]$RelativePathToPackage, [string]$SpecificVersion) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
@@ -534,7 +561,7 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolde
|
||||
}
|
||||
|
||||
$CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture
|
||||
$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version
|
||||
$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version -JSonFile $JSonFile
|
||||
$DownloadLink = Get-Download-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
|
||||
$LegacyDownloadLink = Get-LegacyDownload-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
|
||||
|
||||
|
||||
125
src/Misc/dotnet-install.sh
vendored
125
src/Misc/dotnet-install.sh
vendored
@@ -435,11 +435,52 @@ get_latest_version_info() {
|
||||
return $?
|
||||
}
|
||||
|
||||
# args:
|
||||
# json_file - $1
|
||||
parse_jsonfile_for_version() {
|
||||
eval $invocation
|
||||
|
||||
local json_file="$1"
|
||||
if [ ! -f "$json_file" ]; then
|
||||
say_err "Unable to find \`$json_file\`"
|
||||
return 1
|
||||
fi
|
||||
|
||||
sdk_section=$(cat $json_file | awk '/"sdk"/,/}/')
|
||||
if [ -z "$sdk_section" ]; then
|
||||
say_err "Unable to parse the SDK node in \`$json_file\`"
|
||||
return 1
|
||||
fi
|
||||
|
||||
sdk_list=$(echo $sdk_section | awk -F"[{}]" '{print $2}')
|
||||
sdk_list=${sdk_list//[\" ]/}
|
||||
sdk_list=${sdk_list//,/$'\n'}
|
||||
sdk_list="$(echo -e "${sdk_list}" | tr -d '[[:space:]]')"
|
||||
|
||||
local version_info=""
|
||||
while read -r line; do
|
||||
IFS=:
|
||||
while read -r key value; do
|
||||
if [[ "$key" == "version" ]]; then
|
||||
version_info=$value
|
||||
fi
|
||||
done <<< "$line"
|
||||
done <<< "$sdk_list"
|
||||
if [ -z "$version_info" ]; then
|
||||
say_err "Unable to find the SDK:version node in \`$json_file\`"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$version_info"
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# azure_feed - $1
|
||||
# channel - $2
|
||||
# normalized_architecture - $3
|
||||
# version - $4
|
||||
# json_file - $5
|
||||
get_specific_version_from_version() {
|
||||
eval $invocation
|
||||
|
||||
@@ -447,27 +488,35 @@ get_specific_version_from_version() {
|
||||
local channel="$2"
|
||||
local normalized_architecture="$3"
|
||||
local version="$(to_lowercase "$4")"
|
||||
local json_file="$5"
|
||||
|
||||
case "$version" in
|
||||
latest)
|
||||
local version_info
|
||||
version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1
|
||||
say_verbose "get_specific_version_from_version: version_info=$version_info"
|
||||
echo "$version_info" | get_version_from_version_info
|
||||
return 0
|
||||
;;
|
||||
coherent)
|
||||
local version_info
|
||||
version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" true)" || return 1
|
||||
say_verbose "get_specific_version_from_version: version_info=$version_info"
|
||||
echo "$version_info" | get_version_from_version_info
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo "$version"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
if [ -z "$json_file" ]; then
|
||||
case "$version" in
|
||||
latest)
|
||||
local version_info
|
||||
version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1
|
||||
say_verbose "get_specific_version_from_version: version_info=$version_info"
|
||||
echo "$version_info" | get_version_from_version_info
|
||||
return 0
|
||||
;;
|
||||
coherent)
|
||||
local version_info
|
||||
version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" true)" || return 1
|
||||
say_verbose "get_specific_version_from_version: version_info=$version_info"
|
||||
echo "$version_info" | get_version_from_version_info
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo "$version"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
else
|
||||
local version_info
|
||||
version_info="$(parse_jsonfile_for_version "$json_file")" || return 1
|
||||
echo "$version_info"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# args:
|
||||
@@ -558,24 +607,6 @@ resolve_installation_path() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# install_root - $1
|
||||
get_installed_version_info() {
|
||||
eval $invocation
|
||||
|
||||
local install_root="$1"
|
||||
local version_file="$(combine_paths "$install_root" "$local_version_file_relative_path")"
|
||||
say_verbose "Local version file: $version_file"
|
||||
if [ ! -z "$version_file" ] | [ -r "$version_file" ]; then
|
||||
local version_info="$(cat "$version_file")"
|
||||
echo "$version_info"
|
||||
return 0
|
||||
fi
|
||||
|
||||
say_verbose "Local version file not found."
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# relative_or_absolute_path - $1
|
||||
get_absolute_path() {
|
||||
@@ -724,7 +755,7 @@ calculate_vars() {
|
||||
normalized_architecture="$(get_normalized_architecture_from_architecture "$architecture")"
|
||||
say_verbose "normalized_architecture=$normalized_architecture"
|
||||
|
||||
specific_version="$(get_specific_version_from_version "$azure_feed" "$channel" "$normalized_architecture" "$version")"
|
||||
specific_version="$(get_specific_version_from_version "$azure_feed" "$channel" "$normalized_architecture" "$version" "$json_file")"
|
||||
say_verbose "specific_version=$specific_version"
|
||||
if [ -z "$specific_version" ]; then
|
||||
say_err "Could not resolve version information."
|
||||
@@ -826,6 +857,7 @@ temporary_file_template="${TMPDIR:-/tmp}/dotnet.XXXXXXXXX"
|
||||
|
||||
channel="LTS"
|
||||
version="Latest"
|
||||
json_file=""
|
||||
install_dir="<auto>"
|
||||
architecture="<auto>"
|
||||
dry_run=false
|
||||
@@ -912,6 +944,10 @@ do
|
||||
runtime_id="$1"
|
||||
non_dynamic_parameters+=" $name "\""$1"\"""
|
||||
;;
|
||||
--jsonfile|-[Jj][Ss]on[Ff]ile)
|
||||
shift
|
||||
json_file="$1"
|
||||
;;
|
||||
--skip-non-versioned-files|-[Ss]kip[Nn]on[Vv]ersioned[Ff]iles)
|
||||
override_non_versioned_files=false
|
||||
non_dynamic_parameters+=" $name"
|
||||
@@ -953,22 +989,25 @@ do
|
||||
echo " Possible values:"
|
||||
echo " - dotnet - the Microsoft.NETCore.App shared runtime"
|
||||
echo " - aspnetcore - the Microsoft.AspNetCore.App shared runtime"
|
||||
echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable."
|
||||
echo " -SkipNonVersionedFiles"
|
||||
echo " --dry-run,-DryRun Do not perform installation. Display download link."
|
||||
echo " --no-path, -NoPath Do not set PATH for the current process."
|
||||
echo " --verbose,-Verbose Display diagnostics information."
|
||||
echo " --azure-feed,-AzureFeed Azure feed location. Defaults to $azure_feed, This parameter typically is not changed by the user."
|
||||
echo " --uncached-feed,-UncachedFeed Uncached feed location. This parameter typically is not changed by the user."
|
||||
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
|
||||
echo " --feed-credential,-FeedCredential Azure feed shared access token. This parameter typically is not specified."
|
||||
echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable."
|
||||
echo " -SkipNonVersionedFiles"
|
||||
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
|
||||
echo " --jsonfile <JSONFILE> Determines the SDK version from a user specified global.json file."
|
||||
echo " Note: global.json must have a value for 'SDK:Version'"
|
||||
echo " --runtime-id Installs the .NET Tools for the given platform (use linux-x64 for portable linux)."
|
||||
echo " -RuntimeId"
|
||||
echo " -?,--?,-h,--help,-Help Shows this help message"
|
||||
echo ""
|
||||
echo "Obsolete parameters:"
|
||||
echo " --shared-runtime The recommended alternative is '--runtime dotnet'."
|
||||
echo " -SharedRuntime Installs just the shared runtime bits, not the entire SDK."
|
||||
echo " This parameter is obsolete and may be removed in a future version of this script."
|
||||
echo " Installs just the shared runtime bits, not the entire SDK."
|
||||
echo ""
|
||||
echo "Install Location:"
|
||||
echo " Location is chosen in following order:"
|
||||
|
||||
@@ -123,9 +123,9 @@ function acquireExternalTool() {
|
||||
}
|
||||
|
||||
# Download the external tools only for Windows.
|
||||
if [[ "$PACKAGERUNTIME" == "win-x64" ]]; then
|
||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/win-x64/node.exe" node12/bin
|
||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/win-x64/node.lib" node12/bin
|
||||
if [[ "$PACKAGERUNTIME" == "win-x64" || "$PACKAGERUNTIME" == "win-x86" ]]; then
|
||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/$PACKAGERUNTIME/node.exe" node12/bin
|
||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/$PACKAGERUNTIME/node.lib" node12/bin
|
||||
if [[ "$PRECACHE" != "" ]]; then
|
||||
acquireExternalTool "https://github.com/microsoft/vswhere/releases/download/2.6.7/vswhere.exe" vswhere
|
||||
fi
|
||||
@@ -136,13 +136,23 @@ if [[ "$PACKAGERUNTIME" == "osx-x64" ]]; then
|
||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-darwin-x64.tar.gz" node12 fix_nested_dir
|
||||
fi
|
||||
|
||||
# Download the external tools common across Linux PACKAGERUNTIMEs (excluding OSX).
|
||||
if [[ "$PACKAGERUNTIME" == "linux-x64" || "$PACKAGERUNTIME" == "rhel.6-x64" ]]; then
|
||||
# Download the external tools for Linux PACKAGERUNTIMEs.
|
||||
if [[ "$PACKAGERUNTIME" == "linux-x64" ]]; then
|
||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-x64.tar.gz" node12 fix_nested_dir
|
||||
# TODO: Repath this blob to use a consistent version format (_ vs .)
|
||||
acquireExternalTool "https://vstsagenttools.blob.core.windows.net/tools/nodejs/12_4_0/alpine/node-v${NODE12_VERSION}-alpine.tar.gz" node12_alpine
|
||||
# acquireExternalTool "https://vstsagenttools.blob.core.windows.net/tools/nodejs/12.13.0/alpine/x64/node-v${NODE12_VERSION}-alpine-x64.tar.gz" node12_alpine
|
||||
fi
|
||||
|
||||
if [[ "$PACKAGERUNTIME" == "linux-arm64" ]]; then
|
||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-arm64.tar.gz" node12 fix_nested_dir
|
||||
# TODO: alpine node runtime for arm64(8)
|
||||
# acquireExternalTool "https://vstsagenttools.blob.core.windows.net/tools/nodejs/12.13.0/alpine/arm64/node-v${NODE12_VERSION}-alpine-arm64.tar.gz" node12_alpine
|
||||
fi
|
||||
|
||||
if [[ "$PACKAGERUNTIME" == "linux-arm" ]]; then
|
||||
acquireExternalTool "$NODE_URL/v${NODE12_VERSION}/node-v${NODE12_VERSION}-linux-armv7l.tar.gz" node12 fix_nested_dir
|
||||
# TODO: alpine node runtime for arm32(7)
|
||||
# Need to set up custom gcc toolchain to cross compile on x64 ubuntu for armv7 (per https://github.com/nodejs/node/blob/master/BUILDING.md)
|
||||
# acquireExternalTool "https://vstsagenttools.blob.core.windows.net/tools/nodejs/12.13.0/alpine/arm/node-v${NODE12_VERSION}-alpine-arm.tar.gz" node12_alpine
|
||||
fi
|
||||
|
||||
@@ -60,10 +60,9 @@ then
|
||||
print_errormessage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ubuntu 18 uses libcurl4
|
||||
# ubuntu 14, 16 and other linux use libcurl3
|
||||
apt install -y libcurl3 || apt install -y libcurl4
|
||||
|
||||
# libissl version prefer: libssl1.1 -> libssl1.0.2 -> libssl1.0.0
|
||||
apt install -y libssl1.1$ || apt install -y libssl1.0.2$ || apt install -y libssl1.0.0$
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'apt' failed with exit code '$?'"
|
||||
@@ -71,18 +70,8 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# debian 9 use libssl1.0.2
|
||||
# other debian linux use libssl1.0.0
|
||||
apt install -y libssl1.0.0 || apt install -y libssl1.0.2
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'apt' failed with exit code '$?'"
|
||||
print_errormessage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# libicu version prefer: libicu52 -> libicu55 -> libicu57 -> libicu60
|
||||
apt install -y libicu52 || apt install -y libicu55 || apt install -y libicu57 || apt install -y libicu60
|
||||
# libicu version prefer: libicu63 -> libicu60 -> libicu57 -> libicu55 -> libicu52
|
||||
apt install -y libicu63 || apt install -y libicu60 || apt install -y libicu57 || apt install -y libicu55 || apt install -y libicu52
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'apt' failed with exit code '$?'"
|
||||
@@ -101,9 +90,8 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ubuntu 18 uses libcurl4
|
||||
# ubuntu 14, 16 and other linux use libcurl3
|
||||
apt-get install -y libcurl3 || apt-get install -y libcurl4
|
||||
# libissl version prefer: libssl1.1 -> libssl1.0.2 -> libssl1.0.0
|
||||
apt-get install -y libssl1.1$ || apt-get install -y libssl1.0.2$ || apt install -y libssl1.0.0$
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'apt-get' failed with exit code '$?'"
|
||||
@@ -111,18 +99,8 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# debian 9 use libssl1.0.2
|
||||
# other debian linux use libssl1.0.0
|
||||
apt-get install -y libssl1.0.0 || apt install -y libssl1.0.2
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'apt-get' failed with exit code '$?'"
|
||||
print_errormessage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# libicu version prefer: libicu52 -> libicu55 -> libicu57 -> libicu60
|
||||
apt-get install -y libicu52 || apt install -y libicu55 || apt install -y libicu57 || apt install -y libicu60
|
||||
# libicu version prefer: libicu63 -> libicu60 -> libicu57 -> libicu55 -> libicu52
|
||||
apt-get install -y libicu63 || apt-get install -y libicu60 || apt install -y libicu57 || apt install -y libicu55 || apt install -y libicu52
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'apt-get' failed with exit code '$?'"
|
||||
@@ -149,46 +127,7 @@ then
|
||||
command -v dnf
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
useCompatSsl=0
|
||||
grep -i 'fedora release 28' /etc/fedora-release
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
useCompatSsl=1
|
||||
else
|
||||
grep -i 'fedora release 27' /etc/fedora-release
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
useCompatSsl=1
|
||||
else
|
||||
grep -i 'fedora release 26' /etc/fedora-release
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
useCompatSsl=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $useCompatSsl -eq 1 ]
|
||||
then
|
||||
echo "Use compat-openssl10-devel instead of openssl-devel for Fedora 27/28 (dotnet core requires openssl 1.0.x)"
|
||||
dnf install -y compat-openssl10
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'dnf' failed with exit code '$?'"
|
||||
print_errormessage
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
dnf install -y openssl-libs
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'dnf' failed with exit code '$?'"
|
||||
print_errormessage
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
dnf install -y lttng-ust libcurl krb5-libs zlib libicu
|
||||
dnf install -y lttng-ust openssl-libs krb5-libs zlib libicu
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'dnf' failed with exit code '$?'"
|
||||
@@ -204,22 +143,13 @@ then
|
||||
command -v yum
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
yum install -y openssl-libs libcurl krb5-libs zlib libicu
|
||||
yum install -y lttng-ust openssl-libs krb5-libs zlib libicu
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'yum' failed with exit code '$?'"
|
||||
print_errormessage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# install lttng-ust separately since it's not part of offical package repository
|
||||
yum install -y wget && wget -P /etc/yum.repos.d/ https://packages.efficios.com/repo.files/EfficiOS-RHEL7-x86-64.repo && rpmkeys --import https://packages.efficios.com/rhel/repo.key && yum updateinfo && yum install -y lttng-ust
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'lttng-ust' installation failed with exit code '$?'"
|
||||
print_errormessage
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Can not find 'yum'"
|
||||
print_errormessage
|
||||
@@ -230,13 +160,14 @@ then
|
||||
# we might on OpenSUSE
|
||||
OSTYPE=$(grep ID_LIKE /etc/os-release | cut -f2 -d=)
|
||||
echo $OSTYPE
|
||||
if [ $OSTYPE == '"suse"' ]
|
||||
echo $OSTYPE | grep "suse"
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "The current OS is SUSE based"
|
||||
command -v zypper
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
zypper -n install lttng-ust libopenssl1_0_0 libcurl4 krb5 zlib libicu52_1
|
||||
zypper -n install lttng-ust libopenssl1_1 krb5 zlib libicu60_2
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "'zypper' failed with exit code '$?'"
|
||||
|
||||
@@ -8,7 +8,7 @@ if [ $user_id -eq 0 -a -z "$AGENT_ALLOW_RUNASROOT" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check dotnet core 2.1 dependencies for Linux
|
||||
# Check dotnet core 3.0 dependencies for Linux
|
||||
if [[ (`uname` == "Linux") ]]
|
||||
then
|
||||
command -v ldd > /dev/null
|
||||
@@ -20,29 +20,22 @@ then
|
||||
|
||||
ldd ./bin/libcoreclr.so | grep 'not found'
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Dependencies is missing for Dotnet Core 2.1"
|
||||
echo "Execute ./bin/installdependencies.sh to install any missing Dotnet Core 2.1 dependencies."
|
||||
echo "Dependencies is missing for Dotnet Core 3.0"
|
||||
echo "Execute ./bin/installdependencies.sh to install any missing Dotnet Core 3.0 dependencies."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ldd ./bin/System.Security.Cryptography.Native.OpenSsl.so | grep 'not found'
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Dependencies is missing for Dotnet Core 2.1"
|
||||
echo "Execute ./bin/installdependencies.sh to install any missing Dotnet Core 2.1 dependencies."
|
||||
echo "Dependencies is missing for Dotnet Core 3.0"
|
||||
echo "Execute ./bin/installdependencies.sh to install any missing Dotnet Core 3.0 dependencies."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ldd ./bin/System.IO.Compression.Native.so | grep 'not found'
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Dependencies is missing for Dotnet Core 2.1"
|
||||
echo "Execute ./bin/installdependencies.sh to install any missing Dotnet Core 2.1 dependencies."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ldd ./bin/System.Net.Http.Native.so | grep 'not found'
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Dependencies is missing for Dotnet Core 2.1"
|
||||
echo "Execute ./bin/installdependencies.sh to install any missing Dotnet Core 2.1 dependencies."
|
||||
echo "Dependencies is missing for Dotnet Core 3.0"
|
||||
echo "Execute ./bin/installdependencies.sh to install any missing Dotnet Core 3.0 dependencies."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -59,8 +52,8 @@ then
|
||||
libpath=${LD_LIBRARY_PATH:-}
|
||||
$LDCONFIG_COMMAND -NXv ${libpath//:/} 2>&1 | grep libicu >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Libicu's dependencies is missing for Dotnet Core 2.1"
|
||||
echo "Execute ./bin/installdependencies.sh to install any missing Dotnet Core 2.1 dependencies."
|
||||
echo "Libicu's dependencies is missing for Dotnet Core 3.0"
|
||||
echo "Execute ./bin/installdependencies.sh to install any missing Dotnet Core 3.0 dependencies."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Runner.Sdk;
|
||||
|
||||
namespace GitHub.Runner.Common.Capabilities
|
||||
{
|
||||
[ServiceLocator(Default = typeof(CapabilitiesManager))]
|
||||
public interface ICapabilitiesManager : IRunnerService
|
||||
{
|
||||
Task<Dictionary<string, string>> GetCapabilitiesAsync(RunnerSettings settings, CancellationToken token);
|
||||
}
|
||||
|
||||
public sealed class CapabilitiesManager : RunnerService, ICapabilitiesManager
|
||||
{
|
||||
public async Task<Dictionary<string, string>> GetCapabilitiesAsync(RunnerSettings settings, CancellationToken cancellationToken)
|
||||
{
|
||||
Trace.Entering();
|
||||
ArgUtil.NotNull(settings, nameof(settings));
|
||||
|
||||
// Initialize a dictionary of capabilities.
|
||||
var capabilities = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (settings.SkipCapabilitiesScan)
|
||||
{
|
||||
Trace.Info("Skip capabilities scan.");
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
// Get the providers.
|
||||
var extensionManager = HostContext.GetService<IExtensionManager>();
|
||||
IEnumerable<ICapabilitiesProvider> providers =
|
||||
extensionManager
|
||||
.GetExtensions<ICapabilitiesProvider>()
|
||||
?.OrderBy(x => x.Order);
|
||||
|
||||
// Add each capability returned from each provider.
|
||||
foreach (ICapabilitiesProvider provider in providers ?? new ICapabilitiesProvider[0])
|
||||
{
|
||||
foreach (Capability capability in await provider.GetCapabilitiesAsync(settings, cancellationToken) ?? new List<Capability>())
|
||||
{
|
||||
// Make sure we mask secrets in capabilities values.
|
||||
capabilities[capability.Name] = HostContext.SecretMasker.MaskSecrets(capability.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ICapabilitiesProvider : IExtension
|
||||
{
|
||||
int Order { get; }
|
||||
|
||||
Task<List<Capability>> GetCapabilitiesAsync(RunnerSettings settings, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
public sealed class Capability
|
||||
{
|
||||
public string Name { get; }
|
||||
public string Value { get; }
|
||||
|
||||
public Capability(string name, string value)
|
||||
{
|
||||
ArgUtil.NotNullOrEmpty(name, nameof(name));
|
||||
Name = name;
|
||||
Value = value ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Runner.Sdk;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GitHub.Runner.Common.Capabilities
|
||||
{
|
||||
public sealed class RunnerCapabilitiesProvider : RunnerService, ICapabilitiesProvider
|
||||
{
|
||||
public Type ExtensionType => typeof(ICapabilitiesProvider);
|
||||
|
||||
public int Order => 99; // Process last to override prior.
|
||||
|
||||
public Task<List<Capability>> GetCapabilitiesAsync(RunnerSettings settings, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgUtil.NotNull(settings, nameof(settings));
|
||||
var capabilities = new List<Capability>();
|
||||
Add(capabilities, "Runner.Name", settings.AgentName ?? string.Empty);
|
||||
Add(capabilities, "Runner.OS", VarUtil.OS);
|
||||
Add(capabilities, "Runner.OSArchitecture", VarUtil.OSArchitecture);
|
||||
#if OS_WINDOWS
|
||||
Add(capabilities, "Runner.OSVersion", GetOSVersionString());
|
||||
#endif
|
||||
Add(capabilities, "InteractiveSession", (HostContext.StartupType != StartupType.Service).ToString());
|
||||
Add(capabilities, "Runner.Version", BuildConstants.RunnerPackage.Version);
|
||||
Add(capabilities, "Runner.ComputerName", Environment.MachineName ?? string.Empty);
|
||||
Add(capabilities, "Runner.HomeDirectory", HostContext.GetDirectory(WellKnownDirectory.Root));
|
||||
return Task.FromResult(capabilities);
|
||||
}
|
||||
|
||||
private void Add(List<Capability> capabilities, string name, string value)
|
||||
{
|
||||
Trace.Info($"Adding '{name}': '{value}'");
|
||||
capabilities.Add(new Capability(name, value));
|
||||
}
|
||||
|
||||
private object GetHklmValue(string keyName, string valueName)
|
||||
{
|
||||
keyName = $@"HKEY_LOCAL_MACHINE\{keyName}";
|
||||
object value = Registry.GetValue(keyName, valueName, defaultValue: null);
|
||||
if (object.ReferenceEquals(value, null))
|
||||
{
|
||||
Trace.Info($"Key name '{keyName}', value name '{valueName}' is null.");
|
||||
return null;
|
||||
}
|
||||
|
||||
Trace.Info($"Key name '{keyName}', value name '{valueName}': '{value}'");
|
||||
return value;
|
||||
}
|
||||
|
||||
private string GetOSVersionString()
|
||||
{
|
||||
// Do not use System.Environment.OSVersion.Version to resolve the OS version number.
|
||||
// It leverages the GetVersionEx function which may report an incorrect version
|
||||
// depending on the app's manifest. For details, see:
|
||||
// https://msdn.microsoft.com/library/windows/desktop/ms724451(v=vs.85).aspx
|
||||
|
||||
// Attempt to retrieve the major/minor version from the new registry values added in
|
||||
// in Windows 10.
|
||||
//
|
||||
// The registry value "CurrentVersion" is unreliable in Windows 10. It contains the
|
||||
// value "6.3" instead of "10.0".
|
||||
object major = GetHklmValue(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMajorVersionNumber");
|
||||
object minor = GetHklmValue(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMinorVersionNumber");
|
||||
string majorMinorString;
|
||||
if (major != null && minor != null)
|
||||
{
|
||||
majorMinorString = StringUtil.Format("{0}.{1}", major, minor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback to the registry value "CurrentVersion".
|
||||
majorMinorString = GetHklmValue(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion") as string;
|
||||
}
|
||||
|
||||
// Opted to use the registry value "CurrentBuildNumber" over "CurrentBuild". Based on brief
|
||||
// internet investigation, the only difference appears to be that on Windows XP "CurrentBuild"
|
||||
// was unreliable and "CurrentBuildNumber" was the correct choice.
|
||||
string build = GetHklmValue(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentBuildNumber") as string;
|
||||
return StringUtil.Format("{0}.{1}", majorMinorString, build);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,10 +39,6 @@ namespace GitHub.Runner.Common
|
||||
var extensions = new List<IExtension>();
|
||||
switch (typeof(T).FullName)
|
||||
{
|
||||
// Listener capabilities providers.
|
||||
case "GitHub.Runner.Common.Capabilities.ICapabilitiesProvider":
|
||||
Add<T>(extensions, "GitHub.Runner.Common.Capabilities.RunnerCapabilitiesProvider, Runner.Common");
|
||||
break;
|
||||
// Action command extensions.
|
||||
case "GitHub.Runner.Worker.IActionCommandExtension":
|
||||
Add<T>(extensions, "GitHub.Runner.Worker.InternalPluginSetRepoPathCommandExtension, Runner.Worker");
|
||||
@@ -58,6 +54,7 @@ namespace GitHub.Runner.Common
|
||||
Add<T>(extensions, "GitHub.Runner.Worker.DebugCommandExtension, Runner.Worker");
|
||||
Add<T>(extensions, "GitHub.Runner.Worker.GroupCommandExtension, Runner.Worker");
|
||||
Add<T>(extensions, "GitHub.Runner.Worker.EndGroupCommandExtension, Runner.Worker");
|
||||
Add<T>(extensions, "GitHub.Runner.Worker.EchoCommandExtension, Runner.Worker");
|
||||
break;
|
||||
default:
|
||||
// This should never happen.
|
||||
|
||||
@@ -84,9 +84,6 @@ namespace GitHub.Runner.Common
|
||||
this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscape);
|
||||
this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscapeShift1);
|
||||
this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscapeShift2);
|
||||
this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscapeShift3);
|
||||
this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscapeShift4);
|
||||
this.SecretMasker.AddValueEncoder(ValueEncoders.Base64StringEscapeShift5);
|
||||
this.SecretMasker.AddValueEncoder(ValueEncoders.ExpressionStringEscape);
|
||||
this.SecretMasker.AddValueEncoder(ValueEncoders.JsonStringEscape);
|
||||
this.SecretMasker.AddValueEncoder(ValueEncoders.UriDataEscape);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm;rhel.6-x64;osx-x64</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<AssetTargetFallback>portable-net45+win8</AssetTargetFallback>
|
||||
<NoWarn>NU1701;NU1603</NoWarn>
|
||||
<Version>$(Version)</Version>
|
||||
<TieredCompilationQuickJit>true</TieredCompilationQuickJit>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -26,43 +27,5 @@
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<DebugType>portable</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">
|
||||
<DefineConstants>OS_OSX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true' AND '$(Configuration)' == 'Debug'">
|
||||
<DefineConstants>OS_OSX;DEBUG;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace GitHub.Runner.Common
|
||||
Task DeleteAgentAsync(int agentPoolId, int agentId);
|
||||
Task<List<TaskAgentPool>> GetAgentPoolsAsync(string agentPoolName = null, TaskAgentPoolType poolType = TaskAgentPoolType.Automation);
|
||||
Task<List<TaskAgent>> GetAgentsAsync(int agentPoolId, string agentName = null);
|
||||
Task<TaskAgent> UpdateAgentAsync(int agentPoolId, TaskAgent agent);
|
||||
Task<TaskAgent> ReplaceAgentAsync(int agentPoolId, TaskAgent agent);
|
||||
|
||||
// messagequeue
|
||||
Task<TaskAgentSession> CreateAgentSessionAsync(Int32 poolId, TaskAgentSession session, CancellationToken cancellationToken);
|
||||
@@ -257,7 +257,7 @@ namespace GitHub.Runner.Common
|
||||
return _genericTaskAgentClient.GetAgentsAsync(agentPoolId, agentName, false);
|
||||
}
|
||||
|
||||
public Task<TaskAgent> UpdateAgentAsync(int agentPoolId, TaskAgent agent)
|
||||
public Task<TaskAgent> ReplaceAgentAsync(int agentPoolId, TaskAgent agent)
|
||||
{
|
||||
CheckConnection(RunnerConnectionType.Generic);
|
||||
return _genericTaskAgentClient.ReplaceAgentAsync(agentPoolId, agent);
|
||||
|
||||
@@ -54,6 +54,8 @@ namespace GitHub.Runner.Common.Util
|
||||
return "X64";
|
||||
case Constants.Architecture.Arm:
|
||||
return "ARM";
|
||||
case Constants.Architecture.Arm64:
|
||||
return "ARM64";
|
||||
default:
|
||||
throw new NotSupportedException(); // Should never reach here.
|
||||
}
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Common.Capabilities;
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Services.Common;
|
||||
using GitHub.Services.OAuth;
|
||||
using GitHub.Services.WebApi;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using GitHub.Runner.Common;
|
||||
using GitHub.Runner.Sdk;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
|
||||
namespace GitHub.Runner.Listener.Configuration
|
||||
{
|
||||
@@ -168,7 +163,8 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
{
|
||||
// Get the URL
|
||||
var inputUrl = command.GetUrl();
|
||||
if (!inputUrl.Contains("github.com", StringComparison.OrdinalIgnoreCase))
|
||||
if (!inputUrl.Contains("github.com", StringComparison.OrdinalIgnoreCase) &&
|
||||
!inputUrl.Contains("github.localhost", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
runnerSettings.ServerUrl = inputUrl;
|
||||
// Get the credentials
|
||||
@@ -238,11 +234,8 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
{
|
||||
runnerSettings.AgentName = command.GetAgentName();
|
||||
|
||||
// Get the system capabilities.
|
||||
Dictionary<string, string> systemCapabilities = await HostContext.GetService<ICapabilitiesManager>().GetCapabilitiesAsync(runnerSettings, CancellationToken.None);
|
||||
|
||||
_term.WriteLine();
|
||||
|
||||
|
||||
var agents = await _runnerServer.GetAgentsAsync(runnerSettings.PoolId, runnerSettings.AgentName);
|
||||
Trace.Verbose("Returns {0} agents", agents.Count);
|
||||
agent = agents.FirstOrDefault();
|
||||
@@ -251,12 +244,12 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
_term.WriteLine("A runner exists with the same name", ConsoleColor.Yellow);
|
||||
if (command.GetReplace())
|
||||
{
|
||||
// Update existing agent with new PublicKey, agent version and SystemCapabilities.
|
||||
agent = UpdateExistingAgent(agent, publicKey, systemCapabilities);
|
||||
// Update existing agent with new PublicKey, agent version.
|
||||
agent = UpdateExistingAgent(agent, publicKey);
|
||||
|
||||
try
|
||||
{
|
||||
agent = await _runnerServer.UpdateAgentAsync(runnerSettings.PoolId, agent);
|
||||
agent = await _runnerServer.ReplaceAgentAsync(runnerSettings.PoolId, agent);
|
||||
_term.WriteSuccessMessage("Successfully replaced the runner");
|
||||
break;
|
||||
}
|
||||
@@ -275,7 +268,7 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
else
|
||||
{
|
||||
// Create a new agent.
|
||||
agent = CreateNewAgent(runnerSettings.AgentName, publicKey, systemCapabilities);
|
||||
agent = CreateNewAgent(runnerSettings.AgentName, publicKey);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -435,7 +428,7 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
{
|
||||
ArgUtil.Equal(RunMode.Normal, HostContext.RunMode, nameof(HostContext.RunMode));
|
||||
string currentAction = string.Empty;
|
||||
|
||||
|
||||
_term.WriteSection("Runner removal");
|
||||
|
||||
try
|
||||
@@ -499,7 +492,7 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
else
|
||||
{
|
||||
await _runnerServer.DeleteAgentAsync(settings.PoolId, settings.AgentId);
|
||||
|
||||
|
||||
_term.WriteLine();
|
||||
_term.WriteSuccessMessage("Runner removed successfully");
|
||||
}
|
||||
@@ -573,7 +566,7 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
}
|
||||
|
||||
|
||||
private TaskAgent UpdateExistingAgent(TaskAgent agent, RSAParameters publicKey, Dictionary<string, string> systemCapabilities)
|
||||
private TaskAgent UpdateExistingAgent(TaskAgent agent, RSAParameters publicKey)
|
||||
{
|
||||
ArgUtil.NotNull(agent, nameof(agent));
|
||||
agent.Authorization = new TaskAgentAuthorization
|
||||
@@ -585,15 +578,14 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
agent.Version = BuildConstants.RunnerPackage.Version;
|
||||
agent.OSDescription = RuntimeInformation.OSDescription;
|
||||
|
||||
foreach (KeyValuePair<string, string> capability in systemCapabilities)
|
||||
{
|
||||
agent.SystemCapabilities[capability.Key] = capability.Value ?? string.Empty;
|
||||
}
|
||||
agent.Labels.Add("self-hosted");
|
||||
agent.Labels.Add(VarUtil.OS);
|
||||
agent.Labels.Add(VarUtil.OSArchitecture);
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
||||
private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey, Dictionary<string, string> systemCapabilities)
|
||||
private TaskAgent CreateNewAgent(string agentName, RSAParameters publicKey)
|
||||
{
|
||||
TaskAgent agent = new TaskAgent(agentName)
|
||||
{
|
||||
@@ -606,10 +598,9 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
OSDescription = RuntimeInformation.OSDescription,
|
||||
};
|
||||
|
||||
foreach (KeyValuePair<string, string> capability in systemCapabilities)
|
||||
{
|
||||
agent.SystemCapabilities[capability.Key] = capability.Value ?? string.Empty;
|
||||
}
|
||||
agent.Labels.Add("self-hosted");
|
||||
agent.Labels.Add(VarUtil.OS);
|
||||
agent.Labels.Add(VarUtil.OSArchitecture);
|
||||
|
||||
return agent;
|
||||
}
|
||||
@@ -638,7 +629,7 @@ namespace GitHub.Runner.Listener.Configuration
|
||||
private async Task<GitHubAuthResult> GetTenantCredential(string githubUrl, string githubToken)
|
||||
{
|
||||
var gitHubUrl = new UriBuilder(githubUrl);
|
||||
var githubApiUrl = $"https://api.github.com/repos/{gitHubUrl.Path.Trim('/')}/actions-runners/registration";
|
||||
var githubApiUrl = $"https://api.{gitHubUrl.Host}/repos/{gitHubUrl.Path.Trim('/')}/actions-runners/registration";
|
||||
using (var httpClientHandler = HostContext.CreateHttpClientHandler())
|
||||
using (var httpClient = new HttpClient(httpClientHandler))
|
||||
{
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Common.Capabilities;
|
||||
using GitHub.Runner.Listener.Configuration;
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Services.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -10,7 +8,6 @@ using System.Threading.Tasks;
|
||||
using System.Security.Cryptography;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using GitHub.Services.WebApi;
|
||||
using GitHub.Services.OAuth;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -59,9 +56,6 @@ namespace GitHub.Runner.Listener
|
||||
var serverUrl = _settings.ServerUrl;
|
||||
Trace.Info(_settings);
|
||||
|
||||
// Capabilities.
|
||||
Dictionary<string, string> systemCapabilities = await HostContext.GetService<ICapabilitiesManager>().GetCapabilitiesAsync(_settings, token);
|
||||
|
||||
// Create connection.
|
||||
Trace.Info("Loading Credentials");
|
||||
var credMgr = HostContext.GetService<ICredentialManager>();
|
||||
@@ -75,7 +69,7 @@ namespace GitHub.Runner.Listener
|
||||
OSDescription = RuntimeInformation.OSDescription,
|
||||
};
|
||||
string sessionName = $"{Environment.MachineName ?? "RUNNER"}";
|
||||
var taskAgentSession = new TaskAgentSession(sessionName, agent, systemCapabilities);
|
||||
var taskAgentSession = new TaskAgentSession(sessionName, agent);
|
||||
|
||||
string errorMessage = string.Empty;
|
||||
bool encounteringError = false;
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm;rhel.6-x64;osx-x64</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<AssetTargetFallback>portable-net45+win8</AssetTargetFallback>
|
||||
<NoWarn>NU1701;NU1603</NoWarn>
|
||||
<Version>$(Version)</Version>
|
||||
<TieredCompilationQuickJit>true</TieredCompilationQuickJit>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -28,43 +30,5 @@
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<DebugType>portable</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">
|
||||
<DefineConstants>OS_OSX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true' AND '$(Configuration)' == 'Debug'">
|
||||
<DefineConstants>OS_OSX;DEBUG;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm;rhel.6-x64;osx-x64</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<AssetTargetFallback>portable-net45+win8</AssetTargetFallback>
|
||||
<NoWarn>NU1701;NU1603</NoWarn>
|
||||
<Version>$(Version)</Version>
|
||||
<TieredCompilationQuickJit>true</TieredCompilationQuickJit>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -22,42 +24,4 @@
|
||||
<DebugType>portable</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">
|
||||
<DefineConstants>OS_OSX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true' AND '$(Configuration)' == 'Debug'">
|
||||
<DefineConstants>OS_OSX;DEBUG;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -236,15 +236,15 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
// try upload all files for the first time.
|
||||
UploadResult uploadResult = await ParallelUploadAsync(context, files, maxConcurrentUploads, _uploadCancellationTokenSource.Token);
|
||||
|
||||
if (uploadResult.FailedFiles.Count == 0)
|
||||
if (uploadResult.RetryFiles.Count == 0)
|
||||
{
|
||||
// all files have been upload succeed.
|
||||
context.Output("File upload succeed.");
|
||||
context.Output("File upload complete.");
|
||||
return uploadResult.TotalFileSizeUploaded;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Output($"{uploadResult.FailedFiles.Count} files failed to upload, retry these files after a minute.");
|
||||
context.Output($"{uploadResult.RetryFiles.Count} files failed to upload, retry these files after a minute.");
|
||||
}
|
||||
|
||||
// Delay 1 min then retry failed files.
|
||||
@@ -255,13 +255,13 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
}
|
||||
|
||||
// Retry upload all failed files.
|
||||
context.Output($"Start retry {uploadResult.FailedFiles.Count} failed files upload.");
|
||||
UploadResult retryUploadResult = await ParallelUploadAsync(context, uploadResult.FailedFiles, maxConcurrentUploads, _uploadCancellationTokenSource.Token);
|
||||
context.Output($"Start retry {uploadResult.RetryFiles.Count} failed files upload.");
|
||||
UploadResult retryUploadResult = await ParallelUploadAsync(context, uploadResult.RetryFiles, maxConcurrentUploads, _uploadCancellationTokenSource.Token);
|
||||
|
||||
if (retryUploadResult.FailedFiles.Count == 0)
|
||||
if (retryUploadResult.RetryFiles.Count == 0)
|
||||
{
|
||||
// all files have been upload succeed after retry.
|
||||
context.Output("File upload succeed after retry.");
|
||||
context.Output("File upload complete after retry.");
|
||||
return uploadResult.TotalFileSizeUploaded + retryUploadResult.TotalFileSizeUploaded;
|
||||
}
|
||||
else
|
||||
@@ -465,75 +465,61 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
using (FileStream fs = File.Open(fileToUpload, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
string itemPath = (_containerPath.TrimEnd('/') + "/" + fileToUpload.Remove(0, _sourceParentDirectory.Length + 1)).Replace('\\', '/');
|
||||
uploadTimer.Restart();
|
||||
bool catchExceptionDuringUpload = false;
|
||||
HttpResponseMessage response = null;
|
||||
bool failAndExit = false;
|
||||
try
|
||||
{
|
||||
response = await _fileContainerHttpClient.UploadFileAsync(_containerId, itemPath, fs, _projectId, cancellationToken: token, chunkSize: 4 * 1024 * 1024);
|
||||
uploadTimer.Restart();
|
||||
using (HttpResponseMessage response = await _fileContainerHttpClient.UploadFileAsync(_containerId, itemPath, fs, _projectId, cancellationToken: token, chunkSize: 4 * 1024 * 1024))
|
||||
{
|
||||
if (response == null || response.StatusCode != HttpStatusCode.Created)
|
||||
{
|
||||
context.Output($"Unable to copy file to server StatusCode={response?.StatusCode}: {response?.ReasonPhrase}. Source file path: {fileToUpload}. Target server path: {itemPath}");
|
||||
|
||||
if (response?.StatusCode == HttpStatusCode.Conflict)
|
||||
{
|
||||
// fail upload task but continue with any other files
|
||||
context.Error($"Error '{fileToUpload}' has already been uploaded.");
|
||||
}
|
||||
else if (_fileContainerHttpClient.IsFastFailResponse(response))
|
||||
{
|
||||
// Fast fail: we received an http status code where we should abandon our efforts
|
||||
context.Output($"Cannot continue uploading files, so draining upload queue of {_fileUploadQueue.Count} items.");
|
||||
DrainUploadQueue(context);
|
||||
failedFiles.Clear();
|
||||
failAndExit = true;
|
||||
throw new UploadFailedException($"Critical failure uploading '{fileToUpload}'");
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Debug($"Adding '{fileToUpload}' to retry list.");
|
||||
failedFiles.Add(fileToUpload);
|
||||
}
|
||||
throw new UploadFailedException($"Http failure response '{response?.StatusCode}': '{response?.ReasonPhrase}' while uploading '{fileToUpload}'");
|
||||
}
|
||||
|
||||
uploadTimer.Stop();
|
||||
context.Debug($"File: '{fileToUpload}' took {uploadTimer.ElapsedMilliseconds} milliseconds to finish upload");
|
||||
uploadedSize += fs.Length;
|
||||
OutputLogForFile(context, fileToUpload, $"Detail upload trace for file: {itemPath}", context.Debug);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) when (token.IsCancellationRequested)
|
||||
{
|
||||
context.Output($"File upload has been cancelled during upload file: '{fileToUpload}'.");
|
||||
if (response != null)
|
||||
{
|
||||
response.Dispose();
|
||||
response = null;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
catchExceptionDuringUpload = true;
|
||||
context.Output($"Fail to upload '{fileToUpload}' due to '{ex.Message}'.");
|
||||
context.Output(ex.ToString());
|
||||
}
|
||||
|
||||
uploadTimer.Stop();
|
||||
if (catchExceptionDuringUpload || (response != null && response.StatusCode != HttpStatusCode.Created))
|
||||
{
|
||||
if (response != null)
|
||||
OutputLogForFile(context, fileToUpload, $"Detail upload trace for file that fail to upload: {itemPath}", context.Output);
|
||||
|
||||
if (failAndExit)
|
||||
{
|
||||
context.Output($"Unable to copy file to server StatusCode={response.StatusCode}: {response.ReasonPhrase}. Source file path: {fileToUpload}. Target server path: {itemPath}");
|
||||
context.Debug("Exiting upload.");
|
||||
throw;
|
||||
}
|
||||
|
||||
// output detail upload trace for the file.
|
||||
ConcurrentQueue<string> logQueue;
|
||||
if (_fileUploadTraceLog.TryGetValue(itemPath, out logQueue))
|
||||
{
|
||||
context.Output($"Detail upload trace for file that fail to upload: {itemPath}");
|
||||
string message;
|
||||
while (logQueue.TryDequeue(out message))
|
||||
{
|
||||
context.Output(message);
|
||||
}
|
||||
}
|
||||
|
||||
// tracking file that failed to upload.
|
||||
failedFiles.Add(fileToUpload);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Debug($"File: '{fileToUpload}' took {uploadTimer.ElapsedMilliseconds} milliseconds to finish upload");
|
||||
uploadedSize += fs.Length;
|
||||
// debug detail upload trace for the file.
|
||||
ConcurrentQueue<string> logQueue;
|
||||
if (_fileUploadTraceLog.TryGetValue(itemPath, out logQueue))
|
||||
{
|
||||
context.Debug($"Detail upload trace for file: {itemPath}");
|
||||
string message;
|
||||
while (logQueue.TryDequeue(out message))
|
||||
{
|
||||
context.Debug(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (response != null)
|
||||
{
|
||||
response.Dispose();
|
||||
response = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,6 +576,30 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
}
|
||||
}
|
||||
|
||||
private void DrainUploadQueue(RunnerActionPluginExecutionContext context)
|
||||
{
|
||||
while (_fileUploadQueue.TryDequeue(out string fileToUpload))
|
||||
{
|
||||
context.Debug($"Clearing upload queue: '{fileToUpload}'");
|
||||
Interlocked.Increment(ref _uploadFilesProcessed);
|
||||
}
|
||||
}
|
||||
|
||||
private void OutputLogForFile(RunnerActionPluginExecutionContext context, string itemPath, string logDescription, Action<string> log)
|
||||
{
|
||||
// output detail upload trace for the file.
|
||||
ConcurrentQueue<string> logQueue;
|
||||
if (_fileUploadTraceLog.TryGetValue(itemPath, out logQueue))
|
||||
{
|
||||
log(logDescription);
|
||||
string message;
|
||||
while (logQueue.TryDequeue(out message))
|
||||
{
|
||||
log(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UploadFileTraceReportReceived(object sender, ReportTraceEventArgs e)
|
||||
{
|
||||
ConcurrentQueue<string> logQueue = _fileUploadTraceLog.GetOrAdd(e.File, new ConcurrentQueue<string>());
|
||||
@@ -607,22 +617,22 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
{
|
||||
public UploadResult()
|
||||
{
|
||||
FailedFiles = new List<string>();
|
||||
RetryFiles = new List<string>();
|
||||
TotalFileSizeUploaded = 0;
|
||||
}
|
||||
|
||||
public UploadResult(List<string> failedFiles, long totalFileSizeUploaded)
|
||||
public UploadResult(List<string> retryFiles, long totalFileSizeUploaded)
|
||||
{
|
||||
FailedFiles = failedFiles;
|
||||
RetryFiles = retryFiles ?? new List<string>();
|
||||
TotalFileSizeUploaded = totalFileSizeUploaded;
|
||||
}
|
||||
public List<string> FailedFiles { get; set; }
|
||||
public List<string> RetryFiles { get; set; }
|
||||
|
||||
public long TotalFileSizeUploaded { get; set; }
|
||||
|
||||
public void AddUploadResult(UploadResult resultToAdd)
|
||||
{
|
||||
this.FailedFiles.AddRange(resultToAdd.FailedFiles);
|
||||
this.RetryFiles.AddRange(resultToAdd.RetryFiles);
|
||||
this.TotalFileSizeUploaded += resultToAdd.TotalFileSizeUploaded;
|
||||
}
|
||||
}
|
||||
@@ -657,4 +667,19 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
this.FailedFiles.AddRange(resultToAdd.FailedFiles);
|
||||
}
|
||||
}
|
||||
|
||||
public class UploadFailedException : Exception
|
||||
{
|
||||
public UploadFailedException()
|
||||
: base()
|
||||
{ }
|
||||
|
||||
public UploadFailedException(string message)
|
||||
: base(message)
|
||||
{ }
|
||||
|
||||
public UploadFailedException(string message, Exception inner)
|
||||
: base(message, inner)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -74,17 +74,22 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
context.Output($"Uploading artifact '{artifactName}' from '{fullPath}' for run #{buildId}");
|
||||
|
||||
FileContainerServer fileContainerHelper = new FileContainerServer(context.VssConnection, projectId, containerId, artifactName);
|
||||
long size = await fileContainerHelper.CopyToContainerAsync(context, fullPath, token);
|
||||
var propertiesDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
propertiesDictionary.Add("artifactsize", size.ToString());
|
||||
|
||||
string fileContainerFullPath = StringUtil.Format($"#/{containerId}/{artifactName}");
|
||||
context.Output($"Uploaded '{fullPath}' to server");
|
||||
|
||||
BuildServer buildHelper = new BuildServer(context.VssConnection);
|
||||
string jobId = context.Variables.GetValueOrDefault(WellKnownDistributedTaskVariables.JobId).Value ?? string.Empty;
|
||||
var artifact = await buildHelper.AssociateArtifact(projectId, buildId, jobId, artifactName, ArtifactResourceTypes.Container, fileContainerFullPath, propertiesDictionary, token);
|
||||
context.Output($"Associated artifact {artifactName} ({artifact.Id}) with run #{buildId}");
|
||||
try
|
||||
{
|
||||
long size = await fileContainerHelper.CopyToContainerAsync(context, fullPath, token);
|
||||
propertiesDictionary.Add("artifactsize", size.ToString());
|
||||
context.Output($"Uploaded '{size}' bytes from '{fullPath}' to server");
|
||||
}
|
||||
// if any of the results were successful, make sure to attach them to the build
|
||||
finally
|
||||
{
|
||||
string fileContainerFullPath = StringUtil.Format($"#/{containerId}/{artifactName}");
|
||||
BuildServer buildHelper = new BuildServer(context.VssConnection);
|
||||
string jobId = context.Variables.GetValueOrDefault(WellKnownDistributedTaskVariables.JobId).Value ?? string.Empty;
|
||||
var artifact = await buildHelper.AssociateArtifact(projectId, buildId, jobId, artifactName, ArtifactResourceTypes.Container, fileContainerFullPath, propertiesDictionary, token);
|
||||
context.Output($"Associated artifact {artifactName} ({artifact.Id}) with run #{buildId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm;rhel.6-x64;osx-x64</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<AssetTargetFallback>portable-net45+win8</AssetTargetFallback>
|
||||
<NoWarn>NU1701;NU1603</NoWarn>
|
||||
<Version>$(Version)</Version>
|
||||
<TieredCompilationQuickJit>true</TieredCompilationQuickJit>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -18,43 +19,5 @@
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<DebugType>portable</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">
|
||||
<DefineConstants>OS_OSX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true' AND '$(Configuration)' == 'Debug'">
|
||||
<DefineConstants>OS_OSX;DEBUG;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -70,13 +70,6 @@ namespace GitHub.Runner.Sdk
|
||||
|
||||
VssClientHttpRequestSettings.Default.UserAgent = headerValues;
|
||||
|
||||
#if OS_LINUX || OS_OSX
|
||||
// The .NET Core 2.1 runtime switched its HTTP default from HTTP 1.1 to HTTP 2.
|
||||
// This causes problems with some versions of the Curl handler.
|
||||
// See GitHub issue https://github.com/dotnet/corefx/issues/32376
|
||||
VssClientHttpRequestSettings.Default.UseHttp11 = true;
|
||||
#endif
|
||||
|
||||
var certSetting = GetCertConfiguration();
|
||||
if (certSetting != null)
|
||||
{
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm;rhel.6-x64;osx-x64</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<AssetTargetFallback>portable-net45+win8</AssetTargetFallback>
|
||||
<NoWarn>NU1701;NU1603</NoWarn>
|
||||
<Version>$(Version)</Version>
|
||||
<TieredCompilationQuickJit>true</TieredCompilationQuickJit>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -23,43 +24,5 @@
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<DebugType>portable</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">
|
||||
<DefineConstants>OS_OSX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true' AND '$(Configuration)' == 'Debug'">
|
||||
<DefineConstants>OS_OSX;DEBUG;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -27,13 +27,6 @@ namespace GitHub.Runner.Sdk
|
||||
|
||||
VssClientHttpRequestSettings.Default.UserAgent = headerValues;
|
||||
VssClientHttpRequestSettings.Default.ClientCertificateManager = clientCert;
|
||||
#if OS_LINUX || OS_OSX
|
||||
// The .NET Core 2.1 runtime switched its HTTP default from HTTP 1.1 to HTTP 2.
|
||||
// This causes problems with some versions of the Curl handler.
|
||||
// See GitHub issue https://github.com/dotnet/corefx/issues/32376
|
||||
VssClientHttpRequestSettings.Default.UseHttp11 = true;
|
||||
#endif
|
||||
|
||||
VssHttpMessageHandler.DefaultWebProxy = proxy;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -9,9 +9,8 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>RunnerService</RootNamespace>
|
||||
<AssemblyName>RunnerService</AssemblyName>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>FinalPublicKey.snk</AssemblyOriginatorKeyFile>
|
||||
<DelaySign>true</DelaySign>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
<DelaySign>false</DelaySign>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
@@ -64,7 +63,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="FinalPublicKey.snk" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resource.resx">
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace GitHub.Runner.Worker
|
||||
return false;
|
||||
}
|
||||
|
||||
// process action command in serialize oreder.
|
||||
// process action command in serialize order.
|
||||
lock (_commandSerializeLock)
|
||||
{
|
||||
if (_stopProcessCommand)
|
||||
@@ -107,26 +107,22 @@ namespace GitHub.Runner.Worker
|
||||
}
|
||||
else if (_commandExtensions.TryGetValue(actionCommand.Command, out IActionCommandExtension extension))
|
||||
{
|
||||
bool omitEcho;
|
||||
if (context.EchoOnActionCommand && !extension.OmitEcho)
|
||||
{
|
||||
context.Output(input);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
extension.ProcessCommand(context, input, actionCommand, out omitEcho);
|
||||
extension.ProcessCommand(context, input, actionCommand);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
omitEcho = true;
|
||||
context.Output(input);
|
||||
context.Error($"Unable to process command '{input}' successfully.");
|
||||
var commandInformation = extension.OmitEcho ? extension.Command : input;
|
||||
context.Error($"Unable to process command '{commandInformation}' successfully.");
|
||||
context.Error(ex);
|
||||
context.CommandResult = TaskResult.Failed;
|
||||
}
|
||||
|
||||
if (!omitEcho)
|
||||
{
|
||||
context.Output(input);
|
||||
context.Debug($"Processed command");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -142,17 +138,19 @@ namespace GitHub.Runner.Worker
|
||||
public interface IActionCommandExtension : IExtension
|
||||
{
|
||||
string Command { get; }
|
||||
bool OmitEcho { get; }
|
||||
|
||||
void ProcessCommand(IExecutionContext context, string line, ActionCommand command, out bool omitEcho);
|
||||
void ProcessCommand(IExecutionContext context, string line, ActionCommand command);
|
||||
}
|
||||
|
||||
public sealed class InternalPluginSetRepoPathCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public string Command => "internal-set-repo-path";
|
||||
public bool OmitEcho => false;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||
{
|
||||
if (!command.Properties.TryGetValue(SetRepoPathCommandProperties.repoFullName, out string repoFullName) || string.IsNullOrEmpty(repoFullName))
|
||||
{
|
||||
@@ -166,8 +164,6 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
var directoryManager = HostContext.GetService<IPipelineDirectoryManager>();
|
||||
var trackingConfig = directoryManager.UpdateRepositoryDirectory(context, repoFullName, command.Data, StringUtil.ConvertToBoolean(workspaceRepo));
|
||||
|
||||
omitEcho = true;
|
||||
}
|
||||
|
||||
private static class SetRepoPathCommandProperties
|
||||
@@ -180,10 +176,11 @@ namespace GitHub.Runner.Worker
|
||||
public sealed class SetEnvCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public string Command => "set-env";
|
||||
public bool OmitEcho => false;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||
{
|
||||
if (!command.Properties.TryGetValue(SetEnvCommandProperties.Name, out string envName) || string.IsNullOrEmpty(envName))
|
||||
{
|
||||
@@ -192,9 +189,7 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
context.EnvironmentVariables[envName] = command.Data;
|
||||
context.SetEnvContext(envName, command.Data);
|
||||
context.Output(line);
|
||||
context.Debug($"{envName}='{command.Data}'");
|
||||
omitEcho = true;
|
||||
}
|
||||
|
||||
private static class SetEnvCommandProperties
|
||||
@@ -206,10 +201,11 @@ namespace GitHub.Runner.Worker
|
||||
public sealed class SetOutputCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public string Command => "set-output";
|
||||
public bool OmitEcho => false;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||
{
|
||||
if (!command.Properties.TryGetValue(SetOutputCommandProperties.Name, out string outputName) || string.IsNullOrEmpty(outputName))
|
||||
{
|
||||
@@ -217,9 +213,7 @@ namespace GitHub.Runner.Worker
|
||||
}
|
||||
|
||||
context.SetOutput(outputName, command.Data, out var reference);
|
||||
context.Output(line);
|
||||
context.Debug($"{reference}='{command.Data}'");
|
||||
omitEcho = true;
|
||||
}
|
||||
|
||||
private static class SetOutputCommandProperties
|
||||
@@ -231,10 +225,11 @@ namespace GitHub.Runner.Worker
|
||||
public sealed class SaveStateCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public string Command => "save-state";
|
||||
public bool OmitEcho => false;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||
{
|
||||
if (!command.Properties.TryGetValue(SaveStateCommandProperties.Name, out string stateName) || string.IsNullOrEmpty(stateName))
|
||||
{
|
||||
@@ -243,7 +238,6 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
context.IntraActionState[stateName] = command.Data;
|
||||
context.Debug($"Save intra-action state {stateName} = {command.Data}");
|
||||
omitEcho = true;
|
||||
}
|
||||
|
||||
private static class SaveStateCommandProperties
|
||||
@@ -255,49 +249,53 @@ namespace GitHub.Runner.Worker
|
||||
public sealed class AddMaskCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public string Command => "add-mask";
|
||||
public bool OmitEcho => true;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(command.Data))
|
||||
{
|
||||
context.Warning("Can't add secret mask for empty string.");
|
||||
context.Warning("Can't add secret mask for empty string in ##[add-mask] command.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (context.EchoOnActionCommand)
|
||||
{
|
||||
context.Output($"::{Command}::***");
|
||||
}
|
||||
|
||||
HostContext.SecretMasker.AddValue(command.Data);
|
||||
Trace.Info($"Add new secret mask with length of {command.Data.Length}");
|
||||
}
|
||||
|
||||
omitEcho = true;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class AddPathCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public string Command => "add-path";
|
||||
public bool OmitEcho => false;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||
{
|
||||
ArgUtil.NotNullOrEmpty(command.Data, "path");
|
||||
context.PrependPath.RemoveAll(x => string.Equals(x, command.Data, StringComparison.CurrentCulture));
|
||||
context.PrependPath.Add(command.Data);
|
||||
omitEcho = false;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class AddMatcherCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public string Command => "add-matcher";
|
||||
public bool OmitEcho => false;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||
{
|
||||
omitEcho = false;
|
||||
var file = command.Data;
|
||||
|
||||
// File is required
|
||||
@@ -339,26 +337,26 @@ namespace GitHub.Runner.Worker
|
||||
public sealed class RemoveMatcherCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public string Command => "remove-matcher";
|
||||
public bool OmitEcho => false;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||
{
|
||||
omitEcho = false;
|
||||
command.Properties.TryGetValue(RemoveMatcherCommandProperties.Owner, out string owner);
|
||||
var file = command.Data;
|
||||
|
||||
// Owner and file are mutually exclusive
|
||||
if (!string.IsNullOrEmpty(owner) && !string.IsNullOrEmpty(file))
|
||||
{
|
||||
context.Warning("Either specify a matcher owner name or a file path. Both values cannot be set.");
|
||||
context.Warning("Either specify an owner name or a file path in ##[remove-matcher] command. Both values cannot be set.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Owner or file is required
|
||||
if (string.IsNullOrEmpty(owner) && string.IsNullOrEmpty(file))
|
||||
{
|
||||
context.Warning("Either a matcher owner name or a file path must be specified.");
|
||||
context.Warning("Either an owner name or a file path must be specified in ##[remove-matcher] command.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -407,12 +405,12 @@ namespace GitHub.Runner.Worker
|
||||
public sealed class DebugCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public string Command => "debug";
|
||||
public bool OmitEcho => true;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command)
|
||||
{
|
||||
omitEcho = true;
|
||||
context.Debug(command.Data);
|
||||
}
|
||||
}
|
||||
@@ -435,12 +433,12 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
public abstract IssueType Type { get; }
|
||||
public abstract string Command { get; }
|
||||
public bool OmitEcho => true;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command)
|
||||
{
|
||||
omitEcho = true;
|
||||
command.Properties.TryGetValue(IssueCommandProperties.File, out string file);
|
||||
command.Properties.TryGetValue(IssueCommandProperties.Line, out string line);
|
||||
command.Properties.TryGetValue(IssueCommandProperties.Column, out string column);
|
||||
@@ -515,13 +513,41 @@ namespace GitHub.Runner.Worker
|
||||
public abstract class GroupingCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public abstract string Command { get; }
|
||||
public bool OmitEcho => false;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, out bool omitEcho)
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||
{
|
||||
var data = this is GroupCommandExtension ? command.Data : string.Empty;
|
||||
context.Output($"##[{Command}]{data}");
|
||||
omitEcho = true;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class EchoCommandExtension : RunnerService, IActionCommandExtension
|
||||
{
|
||||
public string Command => "echo";
|
||||
public bool OmitEcho => false;
|
||||
|
||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||
|
||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
||||
{
|
||||
ArgUtil.NotNullOrEmpty(command.Data, "value");
|
||||
|
||||
switch (command.Data.Trim().ToUpperInvariant())
|
||||
{
|
||||
case "ON":
|
||||
context.EchoOnActionCommand = true;
|
||||
context.Debug("Setting echo command value to 'on'");
|
||||
break;
|
||||
case "OFF":
|
||||
context.EchoOnActionCommand = false;
|
||||
context.Debug("Setting echo command value to 'off'");
|
||||
break;
|
||||
default:
|
||||
throw new Exception($"Invalid echo command value. Possible values can be: 'on', 'off'. Current value is: '{command.Data}'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,9 @@ namespace GitHub.Runner.Worker
|
||||
executionContext.Warning("The 'PREVIEW_ACTION_TOKEN' secret is depreciated. Please remove it from the repository's secrets");
|
||||
}
|
||||
|
||||
// Clear the cache (local runner)
|
||||
IOUtil.DeleteDirectory(HostContext.GetDirectory(WellKnownDirectory.Actions), executionContext.CancellationToken);
|
||||
|
||||
foreach (var action in actions)
|
||||
{
|
||||
if (action.Reference.Type == Pipelines.ActionSourceType.ContainerRegistry)
|
||||
@@ -445,7 +448,7 @@ namespace GitHub.Runner.Worker
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure we get an clean folder ready to use.
|
||||
// make sure we get a clean folder ready to use.
|
||||
IOUtil.DeleteDirectory(destDirectory, executionContext.CancellationToken);
|
||||
Directory.CreateDirectory(destDirectory);
|
||||
executionContext.Output($"Download action repository '{repositoryReference.Name}@{repositoryReference.Ref}'");
|
||||
|
||||
@@ -94,7 +94,21 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
postDisplayName = $"Post {this.DisplayName}";
|
||||
}
|
||||
ExecutionContext.RegisterPostJobAction(postDisplayName, handlerData.CleanupCondition, Action);
|
||||
|
||||
var repositoryReference = Action.Reference as RepositoryPathReference;
|
||||
var pathString = string.IsNullOrEmpty(repositoryReference.Path) ? string.Empty : $"/{repositoryReference.Path}";
|
||||
var repoString = string.IsNullOrEmpty(repositoryReference.Ref) ? $"{repositoryReference.Name}{pathString}" :
|
||||
$"{repositoryReference.Name}{pathString}@{repositoryReference.Ref}";
|
||||
|
||||
ExecutionContext.Debug($"Register post job cleanup for action: {repoString}");
|
||||
|
||||
var actionRunner = HostContext.CreateService<IActionRunner>();
|
||||
actionRunner.Action = Action;
|
||||
actionRunner.Stage = ActionRunStage.Post;
|
||||
actionRunner.Condition = handlerData.CleanupCondition;
|
||||
actionRunner.DisplayName = postDisplayName;
|
||||
|
||||
ExecutionContext.RegisterPostJobStep($"{actionRunner.Action.Name}_post", actionRunner);
|
||||
}
|
||||
|
||||
IStepHost stepHost = HostContext.CreateService<IDefaultStepHost>();
|
||||
|
||||
@@ -276,7 +276,9 @@ namespace GitHub.Runner.Worker.Container
|
||||
return await ExecuteDockerCommandAsync(context, "exec", $"{options} {containerId} {command}", context.CancellationToken);
|
||||
}
|
||||
|
||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously (method has async logic on only certain platforms)
|
||||
public async Task<int> DockerExec(IExecutionContext context, string containerId, string options, string command, List<string> output)
|
||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||
{
|
||||
ArgUtil.NotNull(output, nameof(output));
|
||||
|
||||
@@ -337,7 +339,9 @@ namespace GitHub.Runner.Worker.Container
|
||||
return ExecuteDockerCommandAsync(context, command, options, null, cancellationToken);
|
||||
}
|
||||
|
||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously (method has async logic on only certain platforms)
|
||||
private async Task<int> ExecuteDockerCommandAsync(IExecutionContext context, string command, string options, IDictionary<string, string> environment, EventHandler<ProcessDataReceivedEventArgs> stdoutDataReceived, EventHandler<ProcessDataReceivedEventArgs> stderrDataReceived, CancellationToken cancellationToken = default(CancellationToken))
|
||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||
{
|
||||
string arg = $"{command} {options}".Trim();
|
||||
context.Command($"{DockerPath} {arg}");
|
||||
@@ -362,7 +366,9 @@ namespace GitHub.Runner.Worker.Container
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously (method has async logic on only certain platforms)
|
||||
private async Task<int> ExecuteDockerCommandAsync(IExecutionContext context, string command, string options, string workingDirectory, CancellationToken cancellationToken = default(CancellationToken))
|
||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||
{
|
||||
string arg = $"{command} {options}".Trim();
|
||||
context.Command($"{DockerPath} {arg}");
|
||||
|
||||
@@ -11,6 +11,7 @@ using GitHub.Runner.Common;
|
||||
using GitHub.Runner.Sdk;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
using Microsoft.Win32;
|
||||
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
|
||||
|
||||
namespace GitHub.Runner.Worker
|
||||
{
|
||||
@@ -38,6 +39,14 @@ namespace GitHub.Runner.Worker
|
||||
List<ContainerInfo> containers = data as List<ContainerInfo>;
|
||||
ArgUtil.NotNull(containers, nameof(containers));
|
||||
|
||||
var postJobStep = new JobExtensionRunner(runAsync: this.StopContainersAsync,
|
||||
condition: $"{PipelineTemplateConstants.Always}()",
|
||||
displayName: "Stop containers",
|
||||
data: data);
|
||||
|
||||
executionContext.Debug($"Register post job cleanup for stoping/deleting containers.");
|
||||
executionContext.RegisterPostJobStep(nameof(StopContainersAsync), postJobStep);
|
||||
|
||||
// Check whether we are inside a container.
|
||||
// Our container feature requires to map working directory from host to the container.
|
||||
// If we are already inside a container, we will not able to find out the real working direcotry path on the host.
|
||||
@@ -48,9 +57,6 @@ namespace GitHub.Runner.Worker
|
||||
{
|
||||
throw new NotSupportedException("Container feature is not supported when runner is already running inside container.");
|
||||
}
|
||||
#elif OS_RHEL6
|
||||
// Red Hat and CentOS 6 do not support the container feature
|
||||
throw new NotSupportedException("Runner does not support the container feature on Red Hat Enterprise Linux 6 or CentOS 6.");
|
||||
#else
|
||||
var initProcessCgroup = File.ReadLines("/proc/1/cgroup");
|
||||
if (initProcessCgroup.Any(x => x.IndexOf(":/docker/", StringComparison.OrdinalIgnoreCase) >= 0))
|
||||
|
||||
@@ -2,19 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Runner.Worker;
|
||||
using GitHub.Runner.Common.Capabilities;
|
||||
using GitHub.Services.WebApi;
|
||||
using Microsoft.Win32;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||
using GitHub.Runner.Common;
|
||||
@@ -41,7 +31,9 @@ namespace GitHub.Runner.Worker
|
||||
public sealed class DiagnosticLogManager : RunnerService, IDiagnosticLogManager
|
||||
{
|
||||
private static string DateTimeFormat = "yyyyMMdd-HHmmss";
|
||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously (method has async logic on only certain platforms)
|
||||
public async Task UploadDiagnosticLogsAsync(IExecutionContext executionContext,
|
||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||
IExecutionContext parentContext,
|
||||
Pipelines.AgentJobRequestMessage message,
|
||||
DateTime jobStartTimeUtc)
|
||||
|
||||
@@ -12,14 +12,14 @@ using GitHub.Services.WebApi;
|
||||
using GitHub.DistributedTask.Pipelines;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||
using ObjectTemplating = GitHub.DistributedTask.ObjectTemplating;
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Runner.Common;
|
||||
using GitHub.Runner.Sdk;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using ObjectTemplating = GitHub.DistributedTask.ObjectTemplating;
|
||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||
|
||||
namespace GitHub.Runner.Worker
|
||||
{
|
||||
@@ -62,6 +62,8 @@ namespace GitHub.Runner.Worker
|
||||
// Only job level ExecutionContext has PostJobSteps
|
||||
Stack<IStep> PostJobSteps { get; }
|
||||
|
||||
bool EchoOnActionCommand { get; set; }
|
||||
|
||||
// Initialize
|
||||
void InitializeJob(Pipelines.AgentJobRequestMessage message, CancellationToken token);
|
||||
void CancelToken();
|
||||
@@ -96,7 +98,7 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
// others
|
||||
void ForceTaskComplete();
|
||||
void RegisterPostJobAction(string displayName, string condition, Pipelines.ActionStep action);
|
||||
void RegisterPostJobStep(string refName, IStep step);
|
||||
}
|
||||
|
||||
public sealed class ExecutionContext : RunnerService, IExecutionContext
|
||||
@@ -153,6 +155,8 @@ namespace GitHub.Runner.Worker
|
||||
// Only job level ExecutionContext has PostJobSteps
|
||||
public Stack<IStep> PostJobSteps { get; private set; }
|
||||
|
||||
public bool EchoOnActionCommand { get; set; }
|
||||
|
||||
|
||||
public TaskResult? Result
|
||||
{
|
||||
@@ -236,27 +240,10 @@ namespace GitHub.Runner.Worker
|
||||
});
|
||||
}
|
||||
|
||||
public void RegisterPostJobAction(string displayName, string condition, Pipelines.ActionStep action)
|
||||
public void RegisterPostJobStep(string refName, IStep step)
|
||||
{
|
||||
if (action.Reference.Type != ActionSourceType.Repository)
|
||||
{
|
||||
throw new NotSupportedException("Only action that has `action.yml` can define post job execution.");
|
||||
}
|
||||
|
||||
var repositoryReference = action.Reference as RepositoryPathReference;
|
||||
var pathString = string.IsNullOrEmpty(repositoryReference.Path) ? string.Empty : $"/{repositoryReference.Path}";
|
||||
var repoString = string.IsNullOrEmpty(repositoryReference.Ref) ? $"{repositoryReference.Name}{pathString}" :
|
||||
$"{repositoryReference.Name}{pathString}@{repositoryReference.Ref}";
|
||||
|
||||
this.Debug($"Register post job cleanup for action: {repoString}");
|
||||
|
||||
var actionRunner = HostContext.CreateService<IActionRunner>();
|
||||
actionRunner.Action = action;
|
||||
actionRunner.Stage = ActionRunStage.Post;
|
||||
actionRunner.Condition = condition;
|
||||
actionRunner.DisplayName = displayName;
|
||||
actionRunner.ExecutionContext = Root.CreatePostChild(displayName, $"{actionRunner.Action.Name}_post", IntraActionState);
|
||||
Root.PostJobSteps.Push(actionRunner);
|
||||
step.ExecutionContext = Root.CreatePostChild(step.DisplayName, refName, IntraActionState);
|
||||
Root.PostJobSteps.Push(step);
|
||||
}
|
||||
|
||||
public IExecutionContext CreateChild(Guid recordId, string displayName, string refName, string scopeName, string contextName, Dictionary<string, string> intraActionState = null, int? recordOrder = null)
|
||||
@@ -292,6 +279,7 @@ namespace GitHub.Runner.Worker
|
||||
child.PrependPath = PrependPath;
|
||||
child.Container = Container;
|
||||
child.ServiceContainers = ServiceContainers;
|
||||
child.EchoOnActionCommand = EchoOnActionCommand;
|
||||
|
||||
if (recordOrder != null)
|
||||
{
|
||||
@@ -704,6 +692,9 @@ namespace GitHub.Runner.Worker
|
||||
_logger = HostContext.CreateService<IPagingLogger>();
|
||||
_logger.Setup(_mainTimelineId, _record.Id);
|
||||
|
||||
// Initialize 'echo on action command success' property, default to false, unless Step_Debug is set
|
||||
EchoOnActionCommand = Variables.Step_Debug ?? false;
|
||||
|
||||
// Verbosity (from GitHub.Step_Debug).
|
||||
WriteDebug = Variables.Step_Debug ?? false;
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
{
|
||||
public ContainerActionExecutionData Data { get; set; }
|
||||
|
||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously (method has async logic on only certain platforms)
|
||||
public async Task RunAsync(ActionRunStage stage)
|
||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||
{
|
||||
// Validate args.
|
||||
Trace.Entering();
|
||||
|
||||
@@ -263,15 +263,17 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
// Root using fromPath
|
||||
if (!string.IsNullOrWhiteSpace(match.FromPath) && !Path.IsPathRooted(file))
|
||||
{
|
||||
file = Path.Combine(match.FromPath, file);
|
||||
var fromDirectory = Path.GetDirectoryName(match.FromPath);
|
||||
if (!string.IsNullOrWhiteSpace(fromDirectory))
|
||||
{
|
||||
file = Path.Combine(fromDirectory, file);
|
||||
}
|
||||
}
|
||||
|
||||
// Root using system.defaultWorkingDirectory
|
||||
// Root using workspace
|
||||
if (!Path.IsPathRooted(file))
|
||||
{
|
||||
var githubContext = _executionContext.ExpressionValues["github"] as GitHubContext;
|
||||
ArgUtil.NotNull(githubContext, nameof(githubContext));
|
||||
var workspace = githubContext["workspace"].ToString();
|
||||
var workspace = _executionContext.GetGitHubContext("workspace");
|
||||
ArgUtil.NotNullOrEmpty(workspace, "workspace");
|
||||
|
||||
file = Path.Combine(workspace, file);
|
||||
@@ -297,7 +299,7 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
}
|
||||
else
|
||||
{
|
||||
// prefer `/` on all platforms
|
||||
// Prefer `/` on all platforms
|
||||
issue.Data["file"] = file.Substring(repositoryPath.Length).TrimStart(Path.DirectorySeparatorChar).Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,10 +60,16 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
if (string.IsNullOrEmpty(shell))
|
||||
{
|
||||
#if OS_WINDOWS
|
||||
shellCommand = "cmd";
|
||||
shellCommand = "pwsh";
|
||||
if(validateShellOnHost)
|
||||
{
|
||||
shellCommandPath = System.Environment.GetEnvironmentVariable("ComSpec");
|
||||
shellCommandPath = WhichUtil.Which(shellCommand, require: false, Trace);
|
||||
if (string.IsNullOrEmpty(shellCommandPath))
|
||||
{
|
||||
shellCommand = "powershell";
|
||||
Trace.Info($"Defaulting to {shellCommand}");
|
||||
shellCommandPath = WhichUtil.Which(shellCommand, require: true, Trace);
|
||||
}
|
||||
}
|
||||
#else
|
||||
shellCommand = "sh";
|
||||
@@ -143,9 +149,15 @@ namespace GitHub.Runner.Worker.Handlers
|
||||
if (string.IsNullOrEmpty(shell))
|
||||
{
|
||||
#if OS_WINDOWS
|
||||
shellCommand = "cmd";
|
||||
commandPath = System.Environment.GetEnvironmentVariable("ComSpec");
|
||||
ArgUtil.NotNullOrEmpty(commandPath, "%ComSpec%");
|
||||
shellCommand = "pwsh";
|
||||
commandPath = WhichUtil.Which(shellCommand, require: false, Trace);
|
||||
if (string.IsNullOrEmpty(commandPath))
|
||||
{
|
||||
shellCommand = "powershell";
|
||||
Trace.Info($"Defaulting to {shellCommand}");
|
||||
commandPath = WhichUtil.Which(shellCommand, require: true, Trace);
|
||||
}
|
||||
ArgUtil.NotNullOrEmpty(commandPath, "Default Shell");
|
||||
#else
|
||||
shellCommand = "sh";
|
||||
commandPath = WhichUtil.Which("bash", false, Trace) ?? WhichUtil.Which("sh", true, Trace);
|
||||
|
||||
@@ -110,9 +110,7 @@ namespace GitHub.Runner.Worker
|
||||
}
|
||||
}
|
||||
|
||||
// Build up 3 lists of steps, pre-job, job, post-job
|
||||
var postJobStepsBuilder = new Stack<IStep>();
|
||||
|
||||
// Build up 2 lists of steps, pre-job, job
|
||||
// Download actions not already in the cache
|
||||
Trace.Info("Downloading actions");
|
||||
var actionManager = HostContext.GetService<IActionManager>();
|
||||
@@ -134,10 +132,6 @@ namespace GitHub.Runner.Worker
|
||||
condition: $"{PipelineTemplateConstants.Success}()",
|
||||
displayName: "Initialize containers",
|
||||
data: (object)containers));
|
||||
postJobStepsBuilder.Push(new JobExtensionRunner(runAsync: containerProvider.StopContainersAsync,
|
||||
condition: $"{PipelineTemplateConstants.Always}()",
|
||||
displayName: "Stop containers",
|
||||
data: (object)containers));
|
||||
}
|
||||
|
||||
// Add action steps
|
||||
@@ -187,33 +181,9 @@ namespace GitHub.Runner.Worker
|
||||
}
|
||||
}
|
||||
|
||||
// Add post-job steps
|
||||
Trace.Info("Adding post-job steps");
|
||||
while (postJobStepsBuilder.Count > 0)
|
||||
{
|
||||
postJobSteps.Add(postJobStepsBuilder.Pop());
|
||||
}
|
||||
|
||||
// Create execution context for post-job steps
|
||||
foreach (var step in postJobSteps)
|
||||
{
|
||||
if (step is JobExtensionRunner)
|
||||
{
|
||||
JobExtensionRunner extensionStep = step as JobExtensionRunner;
|
||||
ArgUtil.NotNull(extensionStep, extensionStep.DisplayName);
|
||||
Guid stepId = Guid.NewGuid();
|
||||
extensionStep.ExecutionContext = jobContext.CreateChild(stepId, extensionStep.DisplayName, stepId.ToString("N"), null, null);
|
||||
}
|
||||
}
|
||||
|
||||
List<IStep> steps = new List<IStep>();
|
||||
steps.AddRange(preJobSteps);
|
||||
steps.AddRange(jobSteps);
|
||||
steps.AddRange(postJobSteps);
|
||||
|
||||
// Start agent log plugin host process
|
||||
// var logPlugin = HostContext.GetService<IAgentLogPlugin>();
|
||||
// await logPlugin.StartAsync(context, steps, jobContext.CancellationToken);
|
||||
|
||||
// Prepare for orphan process cleanup
|
||||
_processCleanup = jobContext.Variables.GetBoolean("process.clean") ?? true;
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm;rhel.6-x64;osx-x64</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<AssetTargetFallback>portable-net45+win8</AssetTargetFallback>
|
||||
<NoWarn>NU1701;NU1603</NoWarn>
|
||||
<Version>$(Version)</Version>
|
||||
<TieredCompilationQuickJit>true</TieredCompilationQuickJit>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -33,42 +35,4 @@
|
||||
<DebugType>portable</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">
|
||||
<DefineConstants>OS_OSX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true' AND '$(Configuration)' == 'Debug'">
|
||||
<DefineConstants>OS_OSX;DEBUG;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace GitHub.DistributedTask.Expressions2
|
||||
|
||||
// Attempt to match a named-value or index operator.
|
||||
// Note, do not push children of the index operator.
|
||||
if (node is NamedValue || node is Index)
|
||||
if (node is NamedValue || node is Sdk.Operators.Index)
|
||||
{
|
||||
// Lazy initialize the pattern segments
|
||||
if (segmentedPatterns is null)
|
||||
@@ -201,7 +201,7 @@ namespace GitHub.DistributedTask.Expressions2
|
||||
result.Push(node);
|
||||
}
|
||||
// Node is an index
|
||||
else if (node is Index index)
|
||||
else if (node is Sdk.Operators.Index index)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
@@ -218,7 +218,7 @@ namespace GitHub.DistributedTask.Expressions2
|
||||
break;
|
||||
}
|
||||
// Parameter 0 is an index
|
||||
else if (parameter0 is Index index2)
|
||||
else if (parameter0 is Sdk.Operators.Index index2)
|
||||
{
|
||||
index = index2;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Text;
|
||||
using Minimatch;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using GitHub.DistributedTask.Expressions2.Sdk;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
using GitHub.DistributedTask.Pipelines.ObjectTemplating;
|
||||
namespace GitHub.DistributedTask.Expressions2.Sdk.Functions
|
||||
@@ -28,29 +29,50 @@ namespace GitHub.DistributedTask.Expressions2.Sdk.Functions
|
||||
string searchRoot = workspaceData.Value;
|
||||
string pattern = Parameters[0].Evaluate(context).ConvertToString();
|
||||
|
||||
// Convert slashes on Windows
|
||||
if (s_isWindows)
|
||||
{
|
||||
pattern = pattern.Replace('\\', '/');
|
||||
}
|
||||
|
||||
// Root the pattern
|
||||
if (!Path.IsPathRooted(pattern))
|
||||
{
|
||||
var patternRoot = s_isWindows ? searchRoot.Replace('\\', '/').TrimEnd('/') : searchRoot.TrimEnd('/');
|
||||
pattern = string.Concat(patternRoot, "/", pattern);
|
||||
}
|
||||
|
||||
// Get all files
|
||||
context.Trace.Info($"Search root directory: '{searchRoot}'");
|
||||
context.Trace.Info($"Search pattern: '{pattern}'");
|
||||
var files = Directory.GetFiles(searchRoot, "*", SearchOption.AllDirectories).OrderBy(x => x).ToList();
|
||||
var files = Directory.GetFiles(searchRoot, "*", SearchOption.AllDirectories)
|
||||
.Select(x => s_isWindows ? x.Replace('\\', '/') : x)
|
||||
.OrderBy(x => x, StringComparer.Ordinal)
|
||||
.ToList();
|
||||
if (files.Count == 0)
|
||||
{
|
||||
throw new ArgumentException($"'hashFiles({pattern})' failed. Directory '{searchRoot}' is empty");
|
||||
throw new ArgumentException($"hashFiles('{ExpressionUtility.StringEscape(pattern)}') failed. Directory '{searchRoot}' is empty");
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Trace.Info($"Found {files.Count} files");
|
||||
}
|
||||
|
||||
// Match
|
||||
var matcher = new Minimatcher(pattern, s_minimatchOptions);
|
||||
files = matcher.Filter(files).ToList();
|
||||
files = matcher.Filter(files)
|
||||
.Select(x => s_isWindows ? x.Replace('/', '\\') : x)
|
||||
.ToList();
|
||||
if (files.Count == 0)
|
||||
{
|
||||
throw new ArgumentException($"'hashFiles({pattern})' failed. Search pattern '{pattern}' doesn't match any file under '{searchRoot}'");
|
||||
throw new ArgumentException($"hashFiles('{ExpressionUtility.StringEscape(pattern)}') failed. Search pattern '{pattern}' doesn't match any file under '{searchRoot}'");
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Trace.Info($"{files.Count} matches to hash");
|
||||
}
|
||||
|
||||
// Hash each file
|
||||
List<byte> filesSha256 = new List<byte>();
|
||||
foreach (var file in files)
|
||||
{
|
||||
@@ -64,6 +86,7 @@ namespace GitHub.DistributedTask.Expressions2.Sdk.Functions
|
||||
}
|
||||
}
|
||||
|
||||
// Hash the hashes
|
||||
using (SHA256 sha256hash = SHA256.Create())
|
||||
{
|
||||
var hashBytes = sha256hash.ComputeHash(filesSha256.ToArray());
|
||||
@@ -83,11 +106,17 @@ namespace GitHub.DistributedTask.Expressions2.Sdk.Functions
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly bool s_isWindows = Environment.OSVersion.Platform != PlatformID.Unix && Environment.OSVersion.Platform != PlatformID.MacOSX;
|
||||
|
||||
// Only support basic globbing (* ? and []) and globstar (**)
|
||||
private static readonly Options s_minimatchOptions = new Options
|
||||
{
|
||||
Dot = true,
|
||||
NoBrace = true,
|
||||
NoCase = Environment.OSVersion.Platform != PlatformID.Unix && Environment.OSVersion.Platform != PlatformID.MacOSX
|
||||
NoCase = s_isWindows,
|
||||
NoComment = true,
|
||||
NoExt = true,
|
||||
NoNegate = true,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ namespace GitHub.DistributedTask.Expressions2.Tokens
|
||||
{
|
||||
case TokenKind.StartIndex: // "["
|
||||
case TokenKind.Dereference: // "."
|
||||
return new Index();
|
||||
return new Sdk.Operators.Index();
|
||||
|
||||
case TokenKind.LogicalOperator:
|
||||
switch (RawValue)
|
||||
|
||||
@@ -17,10 +17,16 @@ namespace GitHub.DistributedTask.Logging
|
||||
return Convert.ToBase64String(Encoding.UTF8.GetBytes(value));
|
||||
}
|
||||
|
||||
// Base64 is 6 bytes -> char
|
||||
// Base64 is 6 bits -> char
|
||||
// A byte is 8 bits
|
||||
// When end user doing somthing like base64(user:password)
|
||||
// The length of the leading content will cause different base64 encoding result on the password
|
||||
// So we add base64(value - 1/2/3/4/5 bytes) as secret as well.
|
||||
// So we add base64(value shifted 1 and two bytes) as secret as well.
|
||||
// B1 B2 B3 B4 B5 B6 B7
|
||||
// 000000|00 0000|0000 00|000000| 000000|00 0000|0000 00|000000|
|
||||
// Char1 Char2 Char3 Char4
|
||||
// See the above, the first byte has a character beginning at index 0, the second byte has a character beginning at index 4, the third byte has a character beginning at index 2 and then the pattern repeats
|
||||
// We register byte offsets for all these possible values
|
||||
public static String Base64StringEscapeShift1(String value)
|
||||
{
|
||||
return Base64StringEscapeShift(value, 1);
|
||||
@@ -31,21 +37,6 @@ namespace GitHub.DistributedTask.Logging
|
||||
return Base64StringEscapeShift(value, 2);
|
||||
}
|
||||
|
||||
public static String Base64StringEscapeShift3(String value)
|
||||
{
|
||||
return Base64StringEscapeShift(value, 3);
|
||||
}
|
||||
|
||||
public static String Base64StringEscapeShift4(String value)
|
||||
{
|
||||
return Base64StringEscapeShift(value, 4);
|
||||
}
|
||||
|
||||
public static String Base64StringEscapeShift5(String value)
|
||||
{
|
||||
return Base64StringEscapeShift(value, 5);
|
||||
}
|
||||
|
||||
public static String ExpressionStringEscape(String value)
|
||||
{
|
||||
return Expressions.ExpressionUtil.StringEscape(value);
|
||||
|
||||
@@ -55,14 +55,9 @@ namespace GitHub.DistributedTask.WebApi
|
||||
m_properties = new PropertiesCollection(agentToBeCloned.m_properties);
|
||||
}
|
||||
|
||||
if (agentToBeCloned.m_systemCapabilities != null && agentToBeCloned.m_systemCapabilities.Count > 0)
|
||||
if (agentToBeCloned.m_labels != null && agentToBeCloned.m_labels.Count > 0)
|
||||
{
|
||||
m_systemCapabilities = new Dictionary<String, String>(agentToBeCloned.m_systemCapabilities, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
if (agentToBeCloned.m_userCapabilities != null && agentToBeCloned.m_userCapabilities.Count > 0)
|
||||
{
|
||||
m_userCapabilities = new Dictionary<String, String>(agentToBeCloned.m_userCapabilities, StringComparer.OrdinalIgnoreCase);
|
||||
m_labels = new HashSet<string>(agentToBeCloned.m_labels, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
if (agentToBeCloned.PendingUpdate != null)
|
||||
@@ -152,32 +147,17 @@ namespace GitHub.DistributedTask.WebApi
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// System-defined capabilities supported by this agent's host.
|
||||
/// The labels of the runner
|
||||
/// </summary>
|
||||
public IDictionary<String, String> SystemCapabilities
|
||||
public ISet<string> Labels
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_systemCapabilities == null)
|
||||
if (m_labels == null)
|
||||
{
|
||||
m_systemCapabilities = new Dictionary<String, String>(StringComparer.OrdinalIgnoreCase);
|
||||
m_labels = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
return m_systemCapabilities;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User-defined capabilities supported by this agent's host.
|
||||
/// </summary>
|
||||
public IDictionary<String, String> UserCapabilities
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_userCapabilities == null)
|
||||
{
|
||||
m_userCapabilities = new Dictionary<String, String>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
return m_userCapabilities;
|
||||
return m_labels;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,10 +194,7 @@ namespace GitHub.DistributedTask.WebApi
|
||||
[DataMember(IsRequired = false, EmitDefaultValue = false, Name = "Properties")]
|
||||
private PropertiesCollection m_properties;
|
||||
|
||||
[DataMember(IsRequired = false, EmitDefaultValue = false, Name = "SystemCapabilities")]
|
||||
private Dictionary<String, String> m_systemCapabilities;
|
||||
|
||||
[DataMember(IsRequired = false, EmitDefaultValue = false, Name = "UserCapabilities")]
|
||||
private Dictionary<String, String> m_userCapabilities;
|
||||
[DataMember(IsRequired = false, EmitDefaultValue = false, Name = "Labels")]
|
||||
private HashSet<string> m_labels;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,8 +246,7 @@ namespace GitHub.DistributedTask.WebApi
|
||||
PlanType = hubName,
|
||||
ScopeId = scopeIdentifier,
|
||||
PlanId = planId,
|
||||
JobId = jobId,
|
||||
Demands = demands,
|
||||
JobId = jobId
|
||||
};
|
||||
|
||||
return QueueAgentRequestByPoolAsync(poolId, request, userState, cancellationToken);
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace GitHub.DistributedTask.WebApi
|
||||
this.PoolId = requestToBeCloned.PoolId;
|
||||
this.JobId = requestToBeCloned.JobId;
|
||||
this.JobName = requestToBeCloned.JobName;
|
||||
this.Demands = new List<Demand>(requestToBeCloned.Demands ?? new Demand[0]);
|
||||
this.LockToken = requestToBeCloned.LockToken;
|
||||
this.ExpectedDuration = requestToBeCloned.ExpectedDuration;
|
||||
this.OrchestrationId = requestToBeCloned.OrchestrationId;
|
||||
@@ -68,6 +67,11 @@ namespace GitHub.DistributedTask.WebApi
|
||||
{
|
||||
this.AgentSpecification = new JObject(requestToBeCloned.AgentSpecification);
|
||||
}
|
||||
|
||||
if (requestToBeCloned.Labels != null)
|
||||
{
|
||||
this.Labels = new HashSet<string>(requestToBeCloned.Labels, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -229,6 +233,7 @@ namespace GitHub.DistributedTask.WebApi
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
[DataMember(Order = 16, EmitDefaultValue = false)]
|
||||
[Obsolete("No more demands, use labels", true)]
|
||||
public IList<Demand> Demands
|
||||
{
|
||||
get;
|
||||
@@ -386,6 +391,13 @@ namespace GitHub.DistributedTask.WebApi
|
||||
set;
|
||||
}
|
||||
|
||||
[DataMember(Order = 33, EmitDefaultValue = false)]
|
||||
public ISet<string> Labels
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[IgnoreDataMember]
|
||||
internal Guid? LockToken
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace GitHub.DistributedTask.WebApi
|
||||
@@ -27,29 +26,6 @@ namespace GitHub.DistributedTask.WebApi
|
||||
this.OwnerName = ownerName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <c>TaskAgentSession</c> isntance with the specified owner name, agent, and capabilities.
|
||||
/// </summary>
|
||||
/// <param name="ownerName">The name of the owner for this session. This should typically be the agent machine</param>
|
||||
/// <param name="agent">The target agent for the session</param>
|
||||
/// <param name="systemCapabilities">A collection of capabilities to publish on session creation</param>
|
||||
public TaskAgentSession(
|
||||
String ownerName,
|
||||
TaskAgentReference agent,
|
||||
IDictionary<String, String> systemCapabilities)
|
||||
{
|
||||
this.Agent = agent;
|
||||
this.OwnerName = ownerName;
|
||||
|
||||
foreach (var capability in systemCapabilities)
|
||||
{
|
||||
if (capability.Value != null)
|
||||
{
|
||||
this.SystemCapabilities.Add(capability.Key, capability.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this session.
|
||||
/// </summary>
|
||||
@@ -89,33 +65,5 @@ namespace GitHub.DistributedTask.WebApi
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of system capabilities used for this session.
|
||||
/// </summary>
|
||||
public IDictionary<String, String> SystemCapabilities
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_systemCapabilities == null)
|
||||
{
|
||||
m_systemCapabilities = new Dictionary<String, String>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
return m_systemCapabilities;
|
||||
}
|
||||
}
|
||||
|
||||
[OnSerializing]
|
||||
private void OnSerializing(StreamingContext context)
|
||||
{
|
||||
if (m_systemCapabilities?.Count == 0)
|
||||
{
|
||||
m_systemCapabilities = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[DataMember(IsRequired = false, EmitDefaultValue = false, Name = "SystemCapabilities")]
|
||||
private IDictionary<String, String> m_systemCapabilities;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm;rhel.6-x64;osx-x64</RuntimeIdentifiers>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<AssetTargetFallback>portable-net45+win8</AssetTargetFallback>
|
||||
<NoWarn>NU1701;NU1603</NoWarn>
|
||||
@@ -11,6 +11,7 @@
|
||||
<DefineConstants>NETSTANDARD;NET_STANDARD;TRACE</DefineConstants>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<TieredCompilationQuickJit>true</TieredCompilationQuickJit>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -21,11 +22,7 @@
|
||||
<PackageReference Include="System.Security.Cryptography.Cng" Version="4.4.0" />
|
||||
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="4.4.0" />
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.4.0" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.4.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.0" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="3.19.4" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.9.1" />
|
||||
<PackageReference Include="WindowsAzure.Storage" Version="8.7.0" />
|
||||
<PackageReference Include="Minimatch" Version="2.0.0" />
|
||||
<PackageReference Include="YamlDotNet.Signed" Version="5.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -397,6 +397,11 @@ namespace GitHub.Services.FileContainer.Client
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (IsFastFailResponse(response))
|
||||
{
|
||||
FileUploadTrace(itemPath, $"Chunk '{currentChunk}' attempt '{attempt}' of file '{itemPath}' received non-success status code {response.StatusCode} for sending request and cannot continue.");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
FileUploadTrace(itemPath, $"Chunk '{currentChunk}' attempt '{attempt}' of file '{itemPath}' received non-success status code {response.StatusCode} for sending request.");
|
||||
@@ -538,6 +543,17 @@ namespace GitHub.Services.FileContainer.Client
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
public bool IsFastFailResponse(HttpResponseMessage response)
|
||||
{
|
||||
int statusCode = (int)response?.StatusCode;
|
||||
return statusCode >= 400 && statusCode <= 499;
|
||||
}
|
||||
|
||||
protected override bool ShouldThrowError(HttpResponseMessage response)
|
||||
{
|
||||
return !response.IsSuccessStatusCode && !IsFastFailResponse(response);
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> ContainerGetRequestAsync(
|
||||
Int64 containerId,
|
||||
String itemPath,
|
||||
|
||||
@@ -47,8 +47,8 @@ namespace GitHub.Runner.Common.Tests
|
||||
});
|
||||
|
||||
// Assert.
|
||||
Assert.Equal(hc.SecretMasker.MaskSecrets("secret value 1"), "***");
|
||||
Assert.Equal(hc.SecretMasker.MaskSecrets("secret value 2"), "***");
|
||||
Assert.Equal("***", hc.SecretMasker.MaskSecrets("secret value 1"));
|
||||
Assert.Equal("***", hc.SecretMasker.MaskSecrets("secret value 2"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,9 +90,9 @@ namespace GitHub.Runner.Common.Tests
|
||||
trace.Info("Args: {0}", clp.Args.Count);
|
||||
Assert.True(clp.Args.Count == 2);
|
||||
Assert.True(clp.Args.ContainsKey("arg1"));
|
||||
Assert.Equal(clp.Args["arg1"], "arg1val");
|
||||
Assert.Equal("arg1val", clp.Args["arg1"]);
|
||||
Assert.True(clp.Args.ContainsKey("arg2"));
|
||||
Assert.Equal(clp.Args["arg2"], "arg2val");
|
||||
Assert.Equal("arg2val", clp.Args["arg2"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,8 +113,8 @@ namespace GitHub.Runner.Common.Tests
|
||||
|
||||
trace.Info("Args: {0}", clp.Flags.Count);
|
||||
Assert.True(clp.Flags.Count == 2);
|
||||
Assert.True(clp.Flags.Contains("flag1"));
|
||||
Assert.True(clp.Flags.Contains("flag2"));
|
||||
Assert.Contains("flag1", clp.Flags);
|
||||
Assert.Contains("flag2", clp.Flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace GitHub.Runner.Common.Tests
|
||||
"win-x86",
|
||||
"linux-x64",
|
||||
"linux-arm",
|
||||
"rhel.6-x64",
|
||||
"linux-arm64",
|
||||
"osx-x64"
|
||||
};
|
||||
|
||||
|
||||
@@ -36,10 +36,10 @@ namespace GitHub.Runner.Common.Tests.Worker.Container
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(result0);
|
||||
Assert.Equal(result0.Count, 0);
|
||||
Assert.Equal(0, result0.Count);
|
||||
|
||||
Assert.NotNull(result1);
|
||||
Assert.Equal(result1.Count, 1);
|
||||
Assert.Equal(1, result1.Count);
|
||||
var result1Port80Mapping = result1.Find(pm =>
|
||||
string.Equals(pm.ContainerPort, "80") &&
|
||||
string.Equals(pm.HostPort, "32881") &&
|
||||
@@ -48,10 +48,10 @@ namespace GitHub.Runner.Common.Tests.Worker.Container
|
||||
Assert.NotNull(result1Port80Mapping);
|
||||
|
||||
Assert.NotNull(result1Empty);
|
||||
Assert.Equal(result1Empty.Count, 0);
|
||||
Assert.Equal(0, result1Empty.Count);
|
||||
|
||||
Assert.NotNull(result2);
|
||||
Assert.Equal(result2.Count, 2);
|
||||
Assert.Equal(2, result2.Count);
|
||||
var result2Port80Mapping = result2.Find(pm =>
|
||||
string.Equals(pm.ContainerPort, "80") &&
|
||||
string.Equals(pm.HostPort, "32881") &&
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using GitHub.Runner.Common.Capabilities;
|
||||
using GitHub.Runner.Worker;
|
||||
using GitHub.Runner.Worker;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -21,12 +20,12 @@ namespace GitHub.Runner.Common.Tests
|
||||
manager.Initialize(tc);
|
||||
|
||||
// Act.
|
||||
List<ICapabilitiesProvider> extensions = manager.GetExtensions<ICapabilitiesProvider>();
|
||||
List<IActionCommandExtension> extensions = manager.GetExtensions<IActionCommandExtension>();
|
||||
|
||||
// Assert.
|
||||
Assert.True(
|
||||
extensions.Any(x => x is RunnerCapabilitiesProvider),
|
||||
$"Expected {nameof(RunnerCapabilitiesProvider)} extension to be returned as a job extension.");
|
||||
extensions.Any(x => x is SetEnvCommandExtension),
|
||||
$"Expected {nameof(SetEnvCommandExtension)} extension to be returned as a job extension.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,9 +41,9 @@ namespace GitHub.Runner.Common.Tests
|
||||
manager.Initialize(tc);
|
||||
|
||||
// Act/Assert.
|
||||
AssertContains<GitHub.Runner.Common.Capabilities.ICapabilitiesProvider>(
|
||||
AssertContains<GitHub.Runner.Worker.IActionCommandExtension>(
|
||||
manager,
|
||||
concreteType: typeof(GitHub.Runner.Common.Capabilities.RunnerCapabilitiesProvider));
|
||||
concreteType: typeof(GitHub.Runner.Worker.SetEnvCommandExtension));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using GitHub.Runner.Common.Util;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Xunit;
|
||||
|
||||
@@ -67,7 +69,45 @@ namespace GitHub.Runner.Common.Tests
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup([CallerMemberName] string testName = "")
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Common")]
|
||||
public void DefaultSecretMaskers()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Arrange.
|
||||
Setup();
|
||||
|
||||
// Act.
|
||||
_hc.SecretMasker.AddValue("Password123!");
|
||||
_hc.SecretMasker.AddValue("Pass\"word\"123!");
|
||||
_hc.SecretMasker.AddValue("Pass word 123!");
|
||||
_hc.SecretMasker.AddValue("Pass<word>123!");
|
||||
_hc.SecretMasker.AddValue("Pass'word'123!");
|
||||
|
||||
// Assert.
|
||||
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Password123!123"));
|
||||
Assert.Equal("password123", _hc.SecretMasker.MaskSecrets("password123"));
|
||||
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Pass\\\"word\\\"123!123"));
|
||||
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Pass%20word%20123%21123"));
|
||||
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Pass<word>123!123"));
|
||||
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Pass''word''123!123"));
|
||||
Assert.Equal("OlBh***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($":Password123!"))));
|
||||
Assert.Equal("YTpQ***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"a:Password123!"))));
|
||||
Assert.Equal("YWI6***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"ab:Password123!"))));
|
||||
Assert.Equal("YWJjOlBh***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abc:Password123!"))));
|
||||
Assert.Equal("YWJjZDpQ***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abcd:Password123!"))));
|
||||
Assert.Equal("YWJjZGU6***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abcde:Password123!"))));
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Cleanup.
|
||||
Teardown();
|
||||
}
|
||||
}
|
||||
|
||||
private void Setup([CallerMemberName] string testName = "")
|
||||
{
|
||||
_tokenSource = new CancellationTokenSource();
|
||||
_hc = new HostContext(
|
||||
@@ -75,7 +115,7 @@ namespace GitHub.Runner.Common.Tests
|
||||
logFile: Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), $"trace_{nameof(HostContextL0)}_{testName}.log"));
|
||||
}
|
||||
|
||||
public void Teardown()
|
||||
private void Teardown()
|
||||
{
|
||||
_hc?.Dispose();
|
||||
_tokenSource?.Dispose();
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace GitHub.Runner.Common.Tests
|
||||
// Assert.
|
||||
Assert.Equal("some agent", actual);
|
||||
Assert.Equal(string.Empty, Environment.GetEnvironmentVariable("ACTIONS_RUNNER_INPUT_AGENT") ?? string.Empty); // Should remove.
|
||||
Assert.Equal(hc.SecretMasker.MaskSecrets("some agent"), "some agent");
|
||||
Assert.Equal("some agent", hc.SecretMasker.MaskSecrets("some agent"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -80,7 +80,7 @@ namespace GitHub.Runner.Common.Tests
|
||||
// Assert.
|
||||
Assert.Equal("some secret token value", actual);
|
||||
Assert.Equal(string.Empty, Environment.GetEnvironmentVariable("ACTIONS_RUNNER_INPUT_TOKEN") ?? string.Empty); // Should remove.
|
||||
Assert.Equal(hc.SecretMasker.MaskSecrets("some secret token value"), "***");
|
||||
Assert.Equal("***", hc.SecretMasker.MaskSecrets("some secret token value"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -250,7 +250,7 @@ namespace GitHub.Runner.Common.Tests
|
||||
bool actual = command.Unattended;
|
||||
|
||||
// Assert.
|
||||
Assert.Equal(true, actual);
|
||||
Assert.True(actual);
|
||||
Assert.Equal(string.Empty, Environment.GetEnvironmentVariable("ACTIONS_RUNNER_INPUT_UNATTENDED") ?? string.Empty); // Should remove.
|
||||
}
|
||||
finally
|
||||
@@ -720,7 +720,7 @@ namespace GitHub.Runner.Common.Tests
|
||||
var command = new CommandSettings(hc, args: new string[] { "badcommand" });
|
||||
|
||||
// Assert.
|
||||
Assert.True(command.Validate().Contains("badcommand"));
|
||||
Assert.Contains("badcommand", command.Validate());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,7 +735,7 @@ namespace GitHub.Runner.Common.Tests
|
||||
var command = new CommandSettings(hc, args: new string[] { "--badflag" });
|
||||
|
||||
// Assert.
|
||||
Assert.True(command.Validate().Contains("badflag"));
|
||||
Assert.Contains("badflag", command.Validate());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ namespace GitHub.Runner.Common.Tests
|
||||
var command = new CommandSettings(hc, args: new string[] { "--badargname", "bad arg value" });
|
||||
|
||||
// Assert.
|
||||
Assert.True(command.Validate().Contains("badargname"));
|
||||
Assert.Contains("badargname", command.Validate());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
using GitHub.Runner.Common.Capabilities;
|
||||
using GitHub.Runner.Listener.Configuration;
|
||||
using Moq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace GitHub.Runner.Common.Tests.Listener
|
||||
{
|
||||
public sealed class AgentCapabilitiesProviderTestL0
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Agent")]
|
||||
public async void TestGetCapabilities()
|
||||
{
|
||||
using (var hc = new TestHostContext(this))
|
||||
using (var tokenSource = new CancellationTokenSource())
|
||||
{
|
||||
Mock<IConfigurationManager> configurationManager = new Mock<IConfigurationManager>();
|
||||
hc.SetSingleton<IConfigurationManager>(configurationManager.Object);
|
||||
|
||||
// Arrange
|
||||
var provider = new RunnerCapabilitiesProvider();
|
||||
provider.Initialize(hc);
|
||||
var settings = new RunnerSettings() { AgentName = "IAmAgent007" };
|
||||
|
||||
// Act
|
||||
List<Capability> capabilities = await provider.GetCapabilitiesAsync(settings, tokenSource.Token);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(capabilities);
|
||||
Capability runnerNameCapability = capabilities.SingleOrDefault(x => string.Equals(x.Name, "Runner.Name", StringComparison.Ordinal));
|
||||
Assert.NotNull(runnerNameCapability);
|
||||
Assert.Equal("IAmAgent007", runnerNameCapability.Value);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Agent")]
|
||||
public async void TestInteractiveSessionCapability()
|
||||
{
|
||||
using (var hc = new TestHostContext(this))
|
||||
using (var tokenSource = new CancellationTokenSource())
|
||||
{
|
||||
hc.StartupType = StartupType.AutoStartup;
|
||||
await VerifyInteractiveSessionCapability(hc, tokenSource.Token, true);
|
||||
|
||||
hc.StartupType = StartupType.Service;
|
||||
await VerifyInteractiveSessionCapability(hc, tokenSource.Token, false);
|
||||
|
||||
hc.StartupType = StartupType.Manual;
|
||||
await VerifyInteractiveSessionCapability(hc, tokenSource.Token, true);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task VerifyInteractiveSessionCapability(IHostContext hc, CancellationToken token, bool expectedValue)
|
||||
{
|
||||
// Arrange
|
||||
var provider = new RunnerCapabilitiesProvider();
|
||||
provider.Initialize(hc);
|
||||
var settings = new RunnerSettings() { AgentName = "IAmAgent007" };
|
||||
|
||||
// Act
|
||||
List<Capability> capabilities = await provider.GetCapabilitiesAsync(settings, token);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(capabilities);
|
||||
Capability iSessionCapability = capabilities.SingleOrDefault(x => string.Equals(x.Name, "InteractiveSession", StringComparison.Ordinal));
|
||||
Assert.NotNull(iSessionCapability);
|
||||
bool.TryParse(iSessionCapability.Value, out bool isInteractive);
|
||||
Assert.Equal(expectedValue, isInteractive);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Listener;
|
||||
using GitHub.Runner.Common.Capabilities;
|
||||
using GitHub.Runner.Listener.Configuration;
|
||||
using GitHub.Runner.Common.Util;
|
||||
using GitHub.Services.WebApi;
|
||||
@@ -40,16 +39,10 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
||||
#endif
|
||||
|
||||
private Mock<IRSAKeyManager> _rsaKeyManager;
|
||||
private ICapabilitiesManager _capabilitiesManager;
|
||||
// private DeploymentGroupAgentConfigProvider _deploymentGroupAgentConfigProvider;
|
||||
private string _expectedToken = "expectedToken";
|
||||
private string _expectedServerUrl = "https://localhost";
|
||||
private string _expectedAgentName = "expectedAgentName";
|
||||
private string _expectedPoolName = "poolName";
|
||||
private string _expectedCollectionName = "testCollectionName";
|
||||
private string _expectedProjectName = "testProjectName";
|
||||
private string _expectedProjectId = "edf3f94e-d251-49df-bfce-602d6c967409";
|
||||
private string _expectedMachineGroupName = "testMachineGroupName";
|
||||
private string _expectedAuthType = "pat";
|
||||
private string _expectedWorkFolder = "_work";
|
||||
private int _expectedPoolId = 1;
|
||||
@@ -78,8 +71,6 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
||||
_serviceControlManager = new Mock<ILinuxServiceControlManager>();
|
||||
#endif
|
||||
|
||||
_capabilitiesManager = new CapabilitiesManager();
|
||||
|
||||
var expectedAgent = new TaskAgent(_expectedAgentName) { Id = 1 };
|
||||
var expectedDeploymentMachine = new DeploymentMachine() { Agent = expectedAgent, Id = _expectedDeploymentMachineId };
|
||||
expectedAgent.Authorization = new TaskAgentAuthorization
|
||||
@@ -127,7 +118,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
||||
_agentServer.Setup(x => x.GetAgentsAsync(It.IsAny<int>(), It.IsAny<string>())).Returns(Task.FromResult(expectedAgents));
|
||||
|
||||
_agentServer.Setup(x => x.AddAgentAsync(It.IsAny<int>(), It.IsAny<TaskAgent>())).Returns(Task.FromResult(expectedAgent));
|
||||
_agentServer.Setup(x => x.UpdateAgentAsync(It.IsAny<int>(), It.IsAny<TaskAgent>())).Returns(Task.FromResult(expectedAgent));
|
||||
_agentServer.Setup(x => x.ReplaceAgentAsync(It.IsAny<int>(), It.IsAny<TaskAgent>())).Returns(Task.FromResult(expectedAgent));
|
||||
|
||||
rsa = new RSACryptoServiceProvider(2048);
|
||||
|
||||
@@ -143,8 +134,6 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
||||
tc.SetSingleton<IExtensionManager>(_extnMgr.Object);
|
||||
tc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
||||
tc.SetSingleton<ILocationServer>(_locationServer.Object);
|
||||
// tc.SetSingleton<IDeploymentGroupServer>(_machineGroupServer.Object);
|
||||
tc.SetSingleton<ICapabilitiesManager>(_capabilitiesManager);
|
||||
tc.SetSingleton<IRunnerWebProxy>(_runnerWebProxy.Object);
|
||||
tc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
||||
|
||||
@@ -208,12 +197,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
||||
// validate GetAgentPoolsAsync gets called once with automation pool type
|
||||
_agentServer.Verify(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.Is<TaskAgentPoolType>(p => p == TaskAgentPoolType.Automation)), Times.Once);
|
||||
|
||||
// validate GetAgentPoolsAsync not called with deployment pool type
|
||||
_agentServer.Verify(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.Is<TaskAgentPoolType>(p => p == TaskAgentPoolType.Deployment)), Times.Never);
|
||||
|
||||
// For build and release agent / deployment pool, tags logic should not get trigger;
|
||||
// _machineGroupServer.Verify(x =>
|
||||
// x.UpdateDeploymentTargetsAsync(It.IsAny<Guid>(), It.IsAny<int>(), It.IsAny<List<DeploymentMachine>>()), Times.Never);
|
||||
_agentServer.Verify(x => x.AddAgentAsync(It.IsAny<int>(), It.Is<TaskAgent>(a => a.Labels.Contains("self-hosted") && a.Labels.Contains(VarUtil.OS) && a.Labels.Contains(VarUtil.OSArchitecture))), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using GitHub.Services.Common;
|
||||
using GitHub.Services.WebApi;
|
||||
using GitHub.Runner.Listener;
|
||||
using GitHub.Runner.Common.Capabilities;
|
||||
using GitHub.Runner.Listener.Configuration;
|
||||
using Moq;
|
||||
using System;
|
||||
@@ -21,7 +20,6 @@ namespace GitHub.Runner.Common.Tests.Listener
|
||||
private Mock<IConfigurationManager> _config;
|
||||
private Mock<IRunnerServer> _agentServer;
|
||||
private Mock<ICredentialManager> _credMgr;
|
||||
private Mock<ICapabilitiesManager> _capabilitiesManager;
|
||||
|
||||
public MessageListenerL0()
|
||||
{
|
||||
@@ -30,7 +28,6 @@ namespace GitHub.Runner.Common.Tests.Listener
|
||||
_config.Setup(x => x.LoadSettings()).Returns(_settings);
|
||||
_agentServer = new Mock<IRunnerServer>();
|
||||
_credMgr = new Mock<ICredentialManager>();
|
||||
_capabilitiesManager = new Mock<ICapabilitiesManager>();
|
||||
}
|
||||
|
||||
private TestHostContext CreateTestContext([CallerMemberName] String testName = "")
|
||||
@@ -39,7 +36,6 @@ namespace GitHub.Runner.Common.Tests.Listener
|
||||
tc.SetSingleton<IConfigurationManager>(_config.Object);
|
||||
tc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
||||
tc.SetSingleton<ICredentialManager>(_credMgr.Object);
|
||||
tc.SetSingleton<ICapabilitiesManager>(_capabilitiesManager.Object);
|
||||
return tc;
|
||||
}
|
||||
|
||||
@@ -62,8 +58,6 @@ namespace GitHub.Runner.Common.Tests.Listener
|
||||
tokenSource.Token))
|
||||
.Returns(Task.FromResult(expectedSession));
|
||||
|
||||
_capabilitiesManager.Setup(x => x.GetCapabilitiesAsync(_settings, It.IsAny<CancellationToken>())).Returns(Task.FromResult(new Dictionary<string, string>()));
|
||||
|
||||
_credMgr.Setup(x => x.LoadCredentials()).Returns(new VssCredentials());
|
||||
|
||||
// Act.
|
||||
@@ -106,8 +100,6 @@ namespace GitHub.Runner.Common.Tests.Listener
|
||||
tokenSource.Token))
|
||||
.Returns(Task.FromResult(expectedSession));
|
||||
|
||||
_capabilitiesManager.Setup(x => x.GetCapabilitiesAsync(_settings, It.IsAny<CancellationToken>())).Returns(Task.FromResult(new Dictionary<string, string>()));
|
||||
|
||||
_credMgr.Setup(x => x.LoadCredentials()).Returns(new VssCredentials());
|
||||
|
||||
// Act.
|
||||
@@ -153,8 +145,6 @@ namespace GitHub.Runner.Common.Tests.Listener
|
||||
tokenSource.Token))
|
||||
.Returns(Task.FromResult(expectedSession));
|
||||
|
||||
_capabilitiesManager.Setup(x => x.GetCapabilitiesAsync(_settings, It.IsAny<CancellationToken>())).Returns(Task.FromResult(new Dictionary<string, string>()));
|
||||
|
||||
_credMgr.Setup(x => x.LoadCredentials()).Returns(new VssCredentials());
|
||||
|
||||
// Act.
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
||||
string line;
|
||||
while ((line = freader.ReadLine()) != null)
|
||||
{
|
||||
Assert.True(line.EndsWith(LogData));
|
||||
Assert.EndsWith(LogData, line);
|
||||
bytesWritten += logDataSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using GitHub.Runner.Listener;
|
||||
using GitHub.Runner.Common.Capabilities;
|
||||
using GitHub.Runner.Listener.Configuration;
|
||||
using GitHub.Runner.Worker;
|
||||
using GitHub.Runner.Worker.Handlers;
|
||||
@@ -44,7 +43,6 @@ namespace GitHub.Runner.Common.Tests
|
||||
typeof(IHostContext),
|
||||
typeof(ITraceManager),
|
||||
typeof(IThrottlingReporter),
|
||||
typeof(ICapabilitiesProvider)
|
||||
};
|
||||
Validate(
|
||||
assembly: typeof(IHostContext).GetTypeInfo().Assembly,
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace GitHub.Runner.Common.Tests.Util
|
||||
var connect = VssUtil.CreateConnection(new Uri("https://github.com/actions/runner"), new VssCredentials());
|
||||
|
||||
// Assert.
|
||||
Assert.Equal(connect.Settings.MaxRetryRequest.ToString(), "10");
|
||||
Assert.Equal(connect.Settings.SendTimeout.TotalSeconds.ToString(), "360");
|
||||
Assert.Equal("10", connect.Settings.MaxRetryRequest.ToString());
|
||||
Assert.Equal("360", connect.Settings.SendTimeout.TotalSeconds.ToString());
|
||||
|
||||
trace.Info("Set httpretry to 100.");
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_HTTP_RETRY", "100");
|
||||
@@ -42,8 +42,8 @@ namespace GitHub.Runner.Common.Tests.Util
|
||||
connect = VssUtil.CreateConnection(new Uri("https://github.com/actions/runner"), new VssCredentials());
|
||||
|
||||
// Assert.
|
||||
Assert.Equal(connect.Settings.MaxRetryRequest.ToString(), "10");
|
||||
Assert.Equal(connect.Settings.SendTimeout.TotalSeconds.ToString(), "1200");
|
||||
Assert.Equal("10", connect.Settings.MaxRetryRequest.ToString());
|
||||
Assert.Equal("1200", connect.Settings.SendTimeout.TotalSeconds.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Worker;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||
|
||||
namespace GitHub.Runner.Common.Tests.Worker
|
||||
{
|
||||
@@ -146,5 +147,159 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar"));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void EchoProcessCommand()
|
||||
{
|
||||
using (TestHostContext _hc = new TestHostContext(this))
|
||||
{
|
||||
var extensionManager = new Mock<IExtensionManager>();
|
||||
var echoCommand = new EchoCommandExtension();
|
||||
echoCommand.Initialize(_hc);
|
||||
|
||||
extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
||||
.Returns(new List<IActionCommandExtension>() { echoCommand });
|
||||
_hc.SetSingleton<IExtensionManager>(extensionManager.Object);
|
||||
|
||||
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns((string tag, string line) =>
|
||||
{
|
||||
_hc.GetTrace().Info($"{tag} {line}");
|
||||
return 1;
|
||||
});
|
||||
|
||||
_ec.SetupAllProperties();
|
||||
|
||||
ActionCommandManager commandManager = new ActionCommandManager();
|
||||
commandManager.Initialize(_hc);
|
||||
|
||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||
|
||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::on"));
|
||||
Assert.True(_ec.Object.EchoOnActionCommand);
|
||||
|
||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::off"));
|
||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||
|
||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::ON"));
|
||||
Assert.True(_ec.Object.EchoOnActionCommand);
|
||||
|
||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::Off "));
|
||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void EchoProcessCommandDebugOn()
|
||||
{
|
||||
using (TestHostContext _hc = new TestHostContext(this))
|
||||
{
|
||||
// Set up a few things
|
||||
// 1. Job request message (with ACTIONS_STEP_DEBUG = true)
|
||||
TaskOrchestrationPlanReference plan = new TaskOrchestrationPlanReference();
|
||||
TimelineReference timeline = new TimelineReference();
|
||||
JobEnvironment environment = new JobEnvironment();
|
||||
environment.SystemConnection = new ServiceEndpoint();
|
||||
List<TaskInstance> tasks = new List<TaskInstance>();
|
||||
Guid JobId = Guid.NewGuid();
|
||||
string jobName = "some job name";
|
||||
var jobRequest = Pipelines.AgentJobRequestMessageUtil.Convert(new AgentJobRequestMessage(plan, timeline, JobId, jobName, jobName, environment, tasks));
|
||||
jobRequest.Resources.Repositories.Add(new Pipelines.RepositoryResource()
|
||||
{
|
||||
Alias = Pipelines.PipelineConstants.SelfAlias,
|
||||
Id = "github",
|
||||
Version = "sha1"
|
||||
});
|
||||
jobRequest.ContextData["github"] = new Pipelines.ContextData.DictionaryContextData();
|
||||
jobRequest.Variables["ACTIONS_STEP_DEBUG"] = "true";
|
||||
|
||||
// Some service dependencies
|
||||
var jobServerQueue = new Mock<IJobServerQueue>();
|
||||
jobServerQueue.Setup(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.IsAny<TimelineRecord>()));
|
||||
|
||||
_hc.SetSingleton(jobServerQueue.Object);
|
||||
|
||||
var extensionManager = new Mock<IExtensionManager>();
|
||||
var echoCommand = new EchoCommandExtension();
|
||||
echoCommand.Initialize(_hc);
|
||||
|
||||
extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
||||
.Returns(new List<IActionCommandExtension>() { echoCommand });
|
||||
_hc.SetSingleton<IExtensionManager>(extensionManager.Object);
|
||||
|
||||
var configurationStore = new Mock<IConfigurationStore>();
|
||||
configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings());
|
||||
_hc.SetSingleton(configurationStore.Object);
|
||||
|
||||
var pagingLogger = new Mock<IPagingLogger>();
|
||||
_hc.EnqueueInstance(pagingLogger.Object);
|
||||
|
||||
ActionCommandManager commandManager = new ActionCommandManager();
|
||||
commandManager.Initialize(_hc);
|
||||
|
||||
var _ec = new Runner.Worker.ExecutionContext();
|
||||
_ec.Initialize(_hc);
|
||||
|
||||
// Initialize the job (to exercise logic that sets EchoOnActionCommand)
|
||||
_ec.InitializeJob(jobRequest, System.Threading.CancellationToken.None);
|
||||
|
||||
_ec.Complete();
|
||||
|
||||
Assert.True(_ec.EchoOnActionCommand);
|
||||
|
||||
Assert.True(commandManager.TryProcessCommand(_ec, "::echo::off"));
|
||||
Assert.False(_ec.EchoOnActionCommand);
|
||||
|
||||
Assert.True(commandManager.TryProcessCommand(_ec, "::echo::on"));
|
||||
Assert.True(_ec.EchoOnActionCommand);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void EchoProcessCommandInvalid()
|
||||
{
|
||||
using (TestHostContext _hc = new TestHostContext(this))
|
||||
{
|
||||
var extensionManager = new Mock<IExtensionManager>();
|
||||
var echoCommand = new EchoCommandExtension();
|
||||
echoCommand.Initialize(_hc);
|
||||
|
||||
extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
||||
.Returns(new List<IActionCommandExtension>() { echoCommand });
|
||||
_hc.SetSingleton<IExtensionManager>(extensionManager.Object);
|
||||
|
||||
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns((string tag, string line) =>
|
||||
{
|
||||
_hc.GetTrace().Info($"{tag} {line}");
|
||||
return 1;
|
||||
});
|
||||
|
||||
_ec.SetupAllProperties();
|
||||
|
||||
ActionCommandManager commandManager = new ActionCommandManager();
|
||||
commandManager.Initialize(_hc);
|
||||
|
||||
// Echo commands below are considered "processed", but are invalid
|
||||
// 1. Invalid echo value
|
||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::invalid"));
|
||||
Assert.Equal(TaskResult.Failed, _ec.Object.CommandResult);
|
||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||
|
||||
// 2. No value
|
||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::"));
|
||||
Assert.Equal(TaskResult.Failed, _ec.Object.CommandResult);
|
||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,6 +233,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
@@ -272,6 +273,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Teardown();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
@@ -306,6 +308,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#if OS_LINUX
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
@@ -772,6 +775,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Teardown();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
|
||||
@@ -37,25 +37,25 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
|
||||
//Assert
|
||||
|
||||
Assert.Equal(result.Name, "Hello World");
|
||||
Assert.Equal(result.Description, "Greet the world and record the time");
|
||||
Assert.Equal(result.Inputs.Count, 2);
|
||||
Assert.Equal(result.Inputs[0].Key.AssertString("key").Value, "greeting");
|
||||
Assert.Equal(result.Inputs[0].Value.AssertString("value").Value, "Hello");
|
||||
Assert.Equal(result.Inputs[1].Key.AssertString("key").Value, "entryPoint");
|
||||
Assert.Equal(result.Inputs[1].Value.AssertString("value").Value, "");
|
||||
Assert.Equal("Hello World", result.Name);
|
||||
Assert.Equal("Greet the world and record the time", result.Description);
|
||||
Assert.Equal(2, result.Inputs.Count);
|
||||
Assert.Equal("greeting", result.Inputs[0].Key.AssertString("key").Value);
|
||||
Assert.Equal("Hello", result.Inputs[0].Value.AssertString("value").Value);
|
||||
Assert.Equal("entryPoint", result.Inputs[1].Key.AssertString("key").Value);
|
||||
Assert.Equal("", result.Inputs[1].Value.AssertString("value").Value);
|
||||
|
||||
Assert.Equal(result.Execution.ExecutionType, ActionExecutionType.Container);
|
||||
Assert.Equal(ActionExecutionType.Container, result.Execution.ExecutionType);
|
||||
|
||||
var containerAction = result.Execution as ContainerActionExecutionData;
|
||||
|
||||
Assert.Equal(containerAction.Image, "Dockerfile");
|
||||
Assert.Equal(containerAction.EntryPoint, "main.sh");
|
||||
Assert.Equal(containerAction.Arguments[0].ToString(), "bzz");
|
||||
Assert.Equal(containerAction.Environment[0].Key.ToString(), "Token");
|
||||
Assert.Equal(containerAction.Environment[0].Value.ToString(), "foo");
|
||||
Assert.Equal(containerAction.Environment[1].Key.ToString(), "Url");
|
||||
Assert.Equal(containerAction.Environment[1].Value.ToString(), "bar");
|
||||
Assert.Equal("Dockerfile", containerAction.Image);
|
||||
Assert.Equal("main.sh", containerAction.EntryPoint);
|
||||
Assert.Equal("bzz", containerAction.Arguments[0].ToString());
|
||||
Assert.Equal("Token", containerAction.Environment[0].Key.ToString());
|
||||
Assert.Equal("foo", containerAction.Environment[0].Value.ToString());
|
||||
Assert.Equal("Url", containerAction.Environment[1].Key.ToString());
|
||||
Assert.Equal("bar", containerAction.Environment[1].Value.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -81,27 +81,27 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
|
||||
//Assert
|
||||
|
||||
Assert.Equal(result.Name, "Hello World");
|
||||
Assert.Equal(result.Description, "Greet the world and record the time");
|
||||
Assert.Equal(result.Inputs.Count, 2);
|
||||
Assert.Equal(result.Inputs[0].Key.AssertString("key").Value, "greeting");
|
||||
Assert.Equal(result.Inputs[0].Value.AssertString("value").Value, "Hello");
|
||||
Assert.Equal(result.Inputs[1].Key.AssertString("key").Value, "entryPoint");
|
||||
Assert.Equal(result.Inputs[1].Value.AssertString("value").Value, "");
|
||||
Assert.Equal("Hello World", result.Name);
|
||||
Assert.Equal("Greet the world and record the time", result.Description);
|
||||
Assert.Equal(2, result.Inputs.Count);
|
||||
Assert.Equal("greeting", result.Inputs[0].Key.AssertString("key").Value);
|
||||
Assert.Equal("Hello", result.Inputs[0].Value.AssertString("value").Value);
|
||||
Assert.Equal("entryPoint", result.Inputs[1].Key.AssertString("key").Value);
|
||||
Assert.Equal("", result.Inputs[1].Value.AssertString("value").Value);
|
||||
|
||||
Assert.Equal(result.Execution.ExecutionType, ActionExecutionType.Container);
|
||||
Assert.Equal(ActionExecutionType.Container, result.Execution.ExecutionType);
|
||||
|
||||
var containerAction = result.Execution as ContainerActionExecutionData;
|
||||
|
||||
Assert.Equal(containerAction.Image, "Dockerfile");
|
||||
Assert.Equal(containerAction.EntryPoint, "main.sh");
|
||||
Assert.Equal(containerAction.Cleanup, "cleanup.sh");
|
||||
Assert.Equal(containerAction.CleanupCondition, "failure()");
|
||||
Assert.Equal(containerAction.Arguments[0].ToString(), "bzz");
|
||||
Assert.Equal(containerAction.Environment[0].Key.ToString(), "Token");
|
||||
Assert.Equal(containerAction.Environment[0].Value.ToString(), "foo");
|
||||
Assert.Equal(containerAction.Environment[1].Key.ToString(), "Url");
|
||||
Assert.Equal(containerAction.Environment[1].Value.ToString(), "bar");
|
||||
Assert.Equal("Dockerfile", containerAction.Image);
|
||||
Assert.Equal("main.sh", containerAction.EntryPoint);
|
||||
Assert.Equal("cleanup.sh", containerAction.Cleanup);
|
||||
Assert.Equal("failure()", containerAction.CleanupCondition);
|
||||
Assert.Equal("bzz", containerAction.Arguments[0].ToString());
|
||||
Assert.Equal("Token", containerAction.Environment[0].Key.ToString());
|
||||
Assert.Equal("foo", containerAction.Environment[0].Value.ToString());
|
||||
Assert.Equal("Url", containerAction.Environment[1].Key.ToString());
|
||||
Assert.Equal("bar", containerAction.Environment[1].Value.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -126,19 +126,19 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
var result = actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "dockerfileaction_noargs_noenv_noentrypoint.yml"));
|
||||
|
||||
//Assert
|
||||
Assert.Equal(result.Name, "Hello World");
|
||||
Assert.Equal(result.Description, "Greet the world and record the time");
|
||||
Assert.Equal(result.Inputs.Count, 2);
|
||||
Assert.Equal(result.Inputs[0].Key.AssertString("key").Value, "greeting");
|
||||
Assert.Equal(result.Inputs[0].Value.AssertString("value").Value, "Hello");
|
||||
Assert.Equal(result.Inputs[1].Key.AssertString("key").Value, "entryPoint");
|
||||
Assert.Equal(result.Inputs[1].Value.AssertString("value").Value, "");
|
||||
Assert.Equal("Hello World", result.Name);
|
||||
Assert.Equal("Greet the world and record the time", result.Description);
|
||||
Assert.Equal(2, result.Inputs.Count);
|
||||
Assert.Equal("greeting", result.Inputs[0].Key.AssertString("key").Value);
|
||||
Assert.Equal("Hello", result.Inputs[0].Value.AssertString("value").Value);
|
||||
Assert.Equal("entryPoint", result.Inputs[1].Key.AssertString("key").Value);
|
||||
Assert.Equal("", result.Inputs[1].Value.AssertString("value").Value);
|
||||
|
||||
Assert.Equal(result.Execution.ExecutionType, ActionExecutionType.Container);
|
||||
Assert.Equal(ActionExecutionType.Container, result.Execution.ExecutionType);
|
||||
|
||||
var containerAction = result.Execution as ContainerActionExecutionData;
|
||||
|
||||
Assert.Equal(containerAction.Image, "Dockerfile");
|
||||
Assert.Equal("Dockerfile", containerAction.Image);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -164,25 +164,25 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
|
||||
//Assert
|
||||
|
||||
Assert.Equal(result.Name, "Hello World");
|
||||
Assert.Equal(result.Description, "Greet the world and record the time");
|
||||
Assert.Equal(result.Inputs.Count, 2);
|
||||
Assert.Equal(result.Inputs[0].Key.AssertString("key").Value, "greeting");
|
||||
Assert.Equal(result.Inputs[0].Value.AssertString("value").Value, "Hello");
|
||||
Assert.Equal(result.Inputs[1].Key.AssertString("key").Value, "entryPoint");
|
||||
Assert.Equal(result.Inputs[1].Value.AssertString("value").Value, "");
|
||||
Assert.Equal("Hello World", result.Name);
|
||||
Assert.Equal("Greet the world and record the time", result.Description);
|
||||
Assert.Equal(2, result.Inputs.Count);
|
||||
Assert.Equal("greeting", result.Inputs[0].Key.AssertString("key").Value);
|
||||
Assert.Equal("Hello", result.Inputs[0].Value.AssertString("value").Value);
|
||||
Assert.Equal("entryPoint", result.Inputs[1].Key.AssertString("key").Value);
|
||||
Assert.Equal("", result.Inputs[1].Value.AssertString("value").Value);
|
||||
|
||||
Assert.Equal(result.Execution.ExecutionType, ActionExecutionType.Container);
|
||||
Assert.Equal(ActionExecutionType.Container, result.Execution.ExecutionType);
|
||||
|
||||
var containerAction = result.Execution as ContainerActionExecutionData;
|
||||
|
||||
Assert.Equal(containerAction.Image, "Dockerfile");
|
||||
Assert.Equal(containerAction.EntryPoint, "main.sh");
|
||||
Assert.Equal(containerAction.Arguments[0].ToString(), "${{ inputs.greeting }}");
|
||||
Assert.Equal(containerAction.Environment[0].Key.ToString(), "Token");
|
||||
Assert.Equal(containerAction.Environment[0].Value.ToString(), "foo");
|
||||
Assert.Equal(containerAction.Environment[1].Key.ToString(), "Url");
|
||||
Assert.Equal(containerAction.Environment[1].Value.ToString(), "${{ inputs.entryPoint }}");
|
||||
Assert.Equal("Dockerfile", containerAction.Image);
|
||||
Assert.Equal("main.sh", containerAction.EntryPoint);
|
||||
Assert.Equal("${{ inputs.greeting }}", containerAction.Arguments[0].ToString());
|
||||
Assert.Equal("Token", containerAction.Environment[0].Key.ToString());
|
||||
Assert.Equal("foo", containerAction.Environment[0].Value.ToString());
|
||||
Assert.Equal("Url", containerAction.Environment[1].Key.ToString());
|
||||
Assert.Equal("${{ inputs.entryPoint }}", containerAction.Environment[1].Value.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -207,25 +207,25 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
var result = actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "dockerhubaction.yml"));
|
||||
|
||||
//Assert
|
||||
Assert.Equal(result.Name, "Hello World");
|
||||
Assert.Equal(result.Description, "Greet the world and record the time");
|
||||
Assert.Equal(result.Inputs.Count, 2);
|
||||
Assert.Equal(result.Inputs[0].Key.AssertString("key").Value, "greeting");
|
||||
Assert.Equal(result.Inputs[0].Value.AssertString("value").Value, "Hello");
|
||||
Assert.Equal(result.Inputs[1].Key.AssertString("key").Value, "entryPoint");
|
||||
Assert.Equal(result.Inputs[1].Value.AssertString("value").Value, "");
|
||||
Assert.Equal("Hello World", result.Name);
|
||||
Assert.Equal("Greet the world and record the time", result.Description);
|
||||
Assert.Equal(2, result.Inputs.Count);
|
||||
Assert.Equal("greeting", result.Inputs[0].Key.AssertString("key").Value);
|
||||
Assert.Equal("Hello", result.Inputs[0].Value.AssertString("value").Value);
|
||||
Assert.Equal("entryPoint", result.Inputs[1].Key.AssertString("key").Value);
|
||||
Assert.Equal("", result.Inputs[1].Value.AssertString("value").Value);
|
||||
|
||||
Assert.Equal(result.Execution.ExecutionType, ActionExecutionType.Container);
|
||||
Assert.Equal(ActionExecutionType.Container, result.Execution.ExecutionType);
|
||||
|
||||
var containerAction = result.Execution as ContainerActionExecutionData;
|
||||
|
||||
Assert.Equal(containerAction.Image, "docker://ubuntu:18.04");
|
||||
Assert.Equal(containerAction.EntryPoint, "main.sh");
|
||||
Assert.Equal(containerAction.Arguments[0].ToString(), "bzz");
|
||||
Assert.Equal(containerAction.Environment[0].Key.ToString(), "Token");
|
||||
Assert.Equal(containerAction.Environment[0].Value.ToString(), "foo");
|
||||
Assert.Equal(containerAction.Environment[1].Key.ToString(), "Url");
|
||||
Assert.Equal(containerAction.Environment[1].Value.ToString(), "bar");
|
||||
Assert.Equal("docker://ubuntu:18.04", containerAction.Image);
|
||||
Assert.Equal("main.sh", containerAction.EntryPoint);
|
||||
Assert.Equal("bzz", containerAction.Arguments[0].ToString());
|
||||
Assert.Equal("Token", containerAction.Environment[0].Key.ToString());
|
||||
Assert.Equal("foo", containerAction.Environment[0].Value.ToString());
|
||||
Assert.Equal("Url", containerAction.Environment[1].Key.ToString());
|
||||
Assert.Equal("bar", containerAction.Environment[1].Value.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -250,24 +250,24 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
var result = actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "nodeaction.yml"));
|
||||
|
||||
//Assert
|
||||
Assert.Equal(result.Name, "Hello World");
|
||||
Assert.Equal(result.Description, "Greet the world and record the time");
|
||||
Assert.Equal(result.Inputs.Count, 2);
|
||||
Assert.Equal(result.Inputs[0].Key.AssertString("key").Value, "greeting");
|
||||
Assert.Equal(result.Inputs[0].Value.AssertString("value").Value, "Hello");
|
||||
Assert.Equal(result.Inputs[1].Key.AssertString("key").Value, "entryPoint");
|
||||
Assert.Equal(result.Inputs[1].Value.AssertString("value").Value, "");
|
||||
Assert.Equal(result.Deprecated.Count, 1);
|
||||
Assert.Equal("Hello World", result.Name);
|
||||
Assert.Equal("Greet the world and record the time", result.Description);
|
||||
Assert.Equal(2, result.Inputs.Count);
|
||||
Assert.Equal("greeting", result.Inputs[0].Key.AssertString("key").Value);
|
||||
Assert.Equal("Hello", result.Inputs[0].Value.AssertString("value").Value);
|
||||
Assert.Equal("entryPoint", result.Inputs[1].Key.AssertString("key").Value);
|
||||
Assert.Equal("", result.Inputs[1].Value.AssertString("value").Value);
|
||||
Assert.Equal(1, result.Deprecated.Count);
|
||||
|
||||
Assert.True(result.Deprecated.ContainsKey("greeting"));
|
||||
result.Deprecated.TryGetValue("greeting", out string value);
|
||||
Assert.Equal(value, "This property has been deprecated");
|
||||
Assert.Equal("This property has been deprecated", value);
|
||||
|
||||
Assert.Equal(result.Execution.ExecutionType, ActionExecutionType.NodeJS);
|
||||
Assert.Equal(ActionExecutionType.NodeJS, result.Execution.ExecutionType);
|
||||
|
||||
var nodeAction = result.Execution as NodeJSActionExecutionData;
|
||||
|
||||
Assert.Equal(nodeAction.Script, "main.js");
|
||||
Assert.Equal("main.js", nodeAction.Script);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -292,26 +292,26 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
var result = actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "nodeaction_cleanup.yml"));
|
||||
|
||||
//Assert
|
||||
Assert.Equal(result.Name, "Hello World");
|
||||
Assert.Equal(result.Description, "Greet the world and record the time");
|
||||
Assert.Equal(result.Inputs.Count, 2);
|
||||
Assert.Equal(result.Inputs[0].Key.AssertString("key").Value, "greeting");
|
||||
Assert.Equal(result.Inputs[0].Value.AssertString("value").Value, "Hello");
|
||||
Assert.Equal(result.Inputs[1].Key.AssertString("key").Value, "entryPoint");
|
||||
Assert.Equal(result.Inputs[1].Value.AssertString("value").Value, "");
|
||||
Assert.Equal(result.Deprecated.Count, 1);
|
||||
Assert.Equal("Hello World", result.Name);
|
||||
Assert.Equal("Greet the world and record the time", result.Description);
|
||||
Assert.Equal(2, result.Inputs.Count);
|
||||
Assert.Equal("greeting", result.Inputs[0].Key.AssertString("key").Value);
|
||||
Assert.Equal("Hello", result.Inputs[0].Value.AssertString("value").Value);
|
||||
Assert.Equal("entryPoint", result.Inputs[1].Key.AssertString("key").Value);
|
||||
Assert.Equal("", result.Inputs[1].Value.AssertString("value").Value);
|
||||
Assert.Equal(1, result.Deprecated.Count);
|
||||
|
||||
Assert.True(result.Deprecated.ContainsKey("greeting"));
|
||||
result.Deprecated.TryGetValue("greeting", out string value);
|
||||
Assert.Equal(value, "This property has been deprecated");
|
||||
Assert.Equal("This property has been deprecated", value);
|
||||
|
||||
Assert.Equal(result.Execution.ExecutionType, ActionExecutionType.NodeJS);
|
||||
Assert.Equal(ActionExecutionType.NodeJS, result.Execution.ExecutionType);
|
||||
|
||||
var nodeAction = result.Execution as NodeJSActionExecutionData;
|
||||
|
||||
Assert.Equal(nodeAction.Script, "main.js");
|
||||
Assert.Equal(nodeAction.Cleanup, "cleanup.js");
|
||||
Assert.Equal(nodeAction.CleanupCondition, "cancelled()");
|
||||
Assert.Equal("main.js", nodeAction.Script);
|
||||
Assert.Equal("cleanup.js", nodeAction.Cleanup);
|
||||
Assert.Equal("cancelled()", nodeAction.CleanupCondition);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -336,19 +336,19 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
var result = actionManifest.Load(_ec.Object, Path.Combine(TestUtil.GetTestDataPath(), "pluginaction.yml"));
|
||||
|
||||
//Assert
|
||||
Assert.Equal(result.Name, "Hello World");
|
||||
Assert.Equal(result.Description, "Greet the world and record the time");
|
||||
Assert.Equal(result.Inputs.Count, 2);
|
||||
Assert.Equal(result.Inputs[0].Key.AssertString("key").Value, "greeting");
|
||||
Assert.Equal(result.Inputs[0].Value.AssertString("value").Value, "Hello");
|
||||
Assert.Equal(result.Inputs[1].Key.AssertString("key").Value, "entryPoint");
|
||||
Assert.Equal(result.Inputs[1].Value.AssertString("value").Value, "");
|
||||
Assert.Equal("Hello World", result.Name);
|
||||
Assert.Equal("Greet the world and record the time", result.Description);
|
||||
Assert.Equal(2, result.Inputs.Count);
|
||||
Assert.Equal("greeting", result.Inputs[0].Key.AssertString("key").Value);
|
||||
Assert.Equal("Hello", result.Inputs[0].Value.AssertString("value").Value);
|
||||
Assert.Equal("entryPoint", result.Inputs[1].Key.AssertString("key").Value);
|
||||
Assert.Equal("", result.Inputs[1].Value.AssertString("value").Value);
|
||||
|
||||
Assert.Equal(result.Execution.ExecutionType, ActionExecutionType.Plugin);
|
||||
Assert.Equal(ActionExecutionType.Plugin, result.Execution.ExecutionType);
|
||||
|
||||
var pluginAction = result.Execution as PluginActionExecutionData;
|
||||
|
||||
Assert.Equal(pluginAction.Plugin, "someplugin");
|
||||
Assert.Equal("someplugin", pluginAction.Plugin);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -383,9 +383,9 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
var result = actionManifest.EvaluateContainerArguments(_ec.Object, arguments, evaluateContext);
|
||||
|
||||
//Assert
|
||||
Assert.Equal(result[0], "hello");
|
||||
Assert.Equal(result[1], "test");
|
||||
Assert.Equal(result.Count, 2);
|
||||
Assert.Equal("hello", result[0]);
|
||||
Assert.Equal("test", result[1]);
|
||||
Assert.Equal(2, result.Count);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -420,9 +420,9 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
var result = actionManifest.EvaluateContainerEnvironment(_ec.Object, environment, evaluateContext);
|
||||
|
||||
//Assert
|
||||
Assert.Equal(result["hello"], "hello");
|
||||
Assert.Equal(result["test"], "test");
|
||||
Assert.Equal(result.Count, 2);
|
||||
Assert.Equal("hello", result["hello"]);
|
||||
Assert.Equal("test", result["test"]);
|
||||
Assert.Equal(2, result.Count);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -459,13 +459,13 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
var result = actionManifest.EvaluateDefaultInput(_ec.Object, "testInput", new StringToken(null, null, null, "defaultValue"), evaluateContext);
|
||||
|
||||
//Assert
|
||||
Assert.Equal(result, "defaultValue");
|
||||
Assert.Equal("defaultValue", result);
|
||||
|
||||
//Act
|
||||
result = actionManifest.EvaluateDefaultInput(_ec.Object, "testInput", new BasicExpressionToken(null, null, null, "github.ref"), evaluateContext);
|
||||
|
||||
//Assert
|
||||
Assert.Equal(result, "refs/heads/master");
|
||||
Assert.Equal("refs/heads/master", result);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -31,7 +31,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
private TestHostContext _hc;
|
||||
private ActionRunner _actionRunner;
|
||||
private IActionManifestManager _actionManifestManager;
|
||||
private string _workFolder;
|
||||
private DictionaryContextData _context = new DictionaryContextData();
|
||||
|
||||
[Fact]
|
||||
@@ -75,9 +74,9 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
}
|
||||
|
||||
//Assert
|
||||
Assert.Equal(finialInputs["input1"], "test1");
|
||||
Assert.Equal(finialInputs["input2"], "test2");
|
||||
Assert.Equal(finialInputs["input3"], "github");
|
||||
Assert.Equal("test1", finialInputs["input1"]);
|
||||
Assert.Equal("test2", finialInputs["input2"]);
|
||||
Assert.Equal("github", finialInputs["input3"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -278,24 +277,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
Assert.Equal("${{ matrix.node }}", _actionRunner.DisplayName);
|
||||
}
|
||||
|
||||
private void CreateAction(string yamlContent, out Pipelines.ActionStep instance, out string directory)
|
||||
{
|
||||
directory = Path.Combine(_workFolder, Constants.Path.ActionsDirectory, "GitHub/actions".Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar), "master");
|
||||
string file = Path.Combine(directory, Constants.Path.ActionManifestFile);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(file));
|
||||
File.WriteAllText(file, yamlContent);
|
||||
instance = new Pipelines.ActionStep()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Reference = new Pipelines.RepositoryPathReference()
|
||||
{
|
||||
Name = "GitHub/actions",
|
||||
Ref = "master",
|
||||
RepositoryType = Pipelines.RepositoryTypes.GitHub
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void Setup([CallerMemberName] string name = "")
|
||||
{
|
||||
_ecTokenSource?.Dispose();
|
||||
|
||||
@@ -206,8 +206,22 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
var action2 = jobContext.CreateChild(Guid.NewGuid(), "action_2", "action_2", null, null);
|
||||
action2.IntraActionState["state"] = "2";
|
||||
|
||||
action1.RegisterPostJobAction("post1", "always()", new Pipelines.ActionStep() { Name = "post1", DisplayName = "Test 1", Reference = new Pipelines.RepositoryPathReference() { Name = "actions/action" } });
|
||||
action2.RegisterPostJobAction("post2", "always()", new Pipelines.ActionStep() { Name = "post2", DisplayName = "Test 2", Reference = new Pipelines.RepositoryPathReference() { Name = "actions/action" } });
|
||||
|
||||
var postRunner1 = hc.CreateService<IActionRunner>();
|
||||
postRunner1.Action = new Pipelines.ActionStep() { Name = "post1", DisplayName = "Test 1", Reference = new Pipelines.RepositoryPathReference() { Name = "actions/action" } };
|
||||
postRunner1.Stage = ActionRunStage.Post;
|
||||
postRunner1.Condition = "always()";
|
||||
postRunner1.DisplayName = "post1";
|
||||
|
||||
|
||||
var postRunner2 = hc.CreateService<IActionRunner>();
|
||||
postRunner2.Action = new Pipelines.ActionStep() { Name = "post2", DisplayName = "Test 2", Reference = new Pipelines.RepositoryPathReference() { Name = "actions/action" } };
|
||||
postRunner2.Stage = ActionRunStage.Post;
|
||||
postRunner2.Condition = "always()";
|
||||
postRunner2.DisplayName = "post2";
|
||||
|
||||
action1.RegisterPostJobStep("post1", postRunner1);
|
||||
action2.RegisterPostJobStep("post2", postRunner2);
|
||||
|
||||
Assert.NotNull(jobContext.JobSteps);
|
||||
Assert.NotNull(jobContext.PostJobSteps);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using GitHub.Runner.Sdk;
|
||||
@@ -158,7 +159,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void Code()
|
||||
public void MatcherCode()
|
||||
{
|
||||
var matchers = new IssueMatchersConfig
|
||||
{
|
||||
@@ -300,7 +301,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void LineColumn()
|
||||
public void MatcherLineColumn()
|
||||
{
|
||||
var matchers = new IssueMatchersConfig
|
||||
{
|
||||
@@ -348,7 +349,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void ProcessCommand()
|
||||
public void MatcherDoesNotReceiveCommand()
|
||||
{
|
||||
using (Setup())
|
||||
using (_outputManager)
|
||||
@@ -382,7 +383,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void RemoveColorCodes()
|
||||
public void MatcherRemoveColorCodes()
|
||||
{
|
||||
using (Setup())
|
||||
using (_outputManager)
|
||||
@@ -528,7 +529,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void Severity()
|
||||
public void MatcherSeverity()
|
||||
{
|
||||
var matchers = new IssueMatchersConfig
|
||||
{
|
||||
@@ -589,7 +590,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void Timeout()
|
||||
public void MatcherTimeout()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("GITHUB_ACTIONS_RUNNER_ISSUE_MATCHER_TIMEOUT", "0:0:0.01");
|
||||
var matchers = new IssueMatchersConfig
|
||||
@@ -640,10 +641,216 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
}
|
||||
}
|
||||
|
||||
// todo: roots file against fromPath
|
||||
// todo: roots file against system.defaultWorkingDirectory
|
||||
// todo: matches repository
|
||||
// todo: checks file exists
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void MatcherFile()
|
||||
{
|
||||
var matchers = new IssueMatchersConfig
|
||||
{
|
||||
Matchers =
|
||||
{
|
||||
new IssueMatcherConfig
|
||||
{
|
||||
Owner = "my-matcher-1",
|
||||
Patterns = new[]
|
||||
{
|
||||
new IssuePatternConfig
|
||||
{
|
||||
Pattern = @"(.+): (.+)",
|
||||
File = 1,
|
||||
Message = 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
using (var hostContext = Setup(matchers: matchers))
|
||||
using (_outputManager)
|
||||
{
|
||||
// Setup github.workspace
|
||||
var workDirectory = hostContext.GetDirectory(WellKnownDirectory.Work);
|
||||
ArgUtil.NotNullOrEmpty(workDirectory, nameof(workDirectory));
|
||||
Directory.CreateDirectory(workDirectory);
|
||||
var workspaceDirectory = Path.Combine(workDirectory, "workspace");
|
||||
Directory.CreateDirectory(workspaceDirectory);
|
||||
_executionContext.Setup(x => x.GetGitHubContext("workspace")).Returns(workspaceDirectory);
|
||||
|
||||
// Create a test file
|
||||
Directory.CreateDirectory(Path.Combine(workspaceDirectory, "some-directory"));
|
||||
var filePath = Path.Combine(workspaceDirectory, "some-directory", "some-file.txt");
|
||||
File.WriteAllText(filePath, "");
|
||||
|
||||
// Process
|
||||
Process("some-directory/some-file.txt: some error");
|
||||
Assert.Equal(1, _issues.Count);
|
||||
Assert.Equal("some error", _issues[0].Item1.Message);
|
||||
Assert.Equal("some-directory/some-file.txt", _issues[0].Item1.Data["file"]);
|
||||
Assert.Equal(0, _commands.Count);
|
||||
Assert.Equal(0, _messages.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void MatcherFileExists()
|
||||
{
|
||||
var matchers = new IssueMatchersConfig
|
||||
{
|
||||
Matchers =
|
||||
{
|
||||
new IssueMatcherConfig
|
||||
{
|
||||
Owner = "my-matcher-1",
|
||||
Patterns = new[]
|
||||
{
|
||||
new IssuePatternConfig
|
||||
{
|
||||
Pattern = @"(.+): (.+)",
|
||||
File = 1,
|
||||
Message = 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
using (var hostContext = Setup(matchers: matchers))
|
||||
using (_outputManager)
|
||||
{
|
||||
// Setup github.workspace
|
||||
var workDirectory = hostContext.GetDirectory(WellKnownDirectory.Work);
|
||||
ArgUtil.NotNullOrEmpty(workDirectory, nameof(workDirectory));
|
||||
Directory.CreateDirectory(workDirectory);
|
||||
var workspaceDirectory = Path.Combine(workDirectory, "workspace");
|
||||
Directory.CreateDirectory(workspaceDirectory);
|
||||
_executionContext.Setup(x => x.GetGitHubContext("workspace")).Returns(workspaceDirectory);
|
||||
|
||||
// Create a test file
|
||||
File.WriteAllText(Path.Combine(workspaceDirectory, "some-file-1.txt"), "");
|
||||
|
||||
// Process
|
||||
Process("some-file-1.txt: some error 1"); // file exists
|
||||
Process("some-file-2.txt: some error 2"); // file does not exist
|
||||
|
||||
Assert.Equal(2, _issues.Count);
|
||||
Assert.Equal("some error 1", _issues[0].Item1.Message);
|
||||
Assert.Equal("some-file-1.txt", _issues[0].Item1.Data["file"]);
|
||||
Assert.Equal("some error 2", _issues[1].Item1.Message);
|
||||
Assert.False(_issues[1].Item1.Data.ContainsKey("file")); // does not contain file key
|
||||
Assert.Equal(0, _commands.Count);
|
||||
Assert.Equal(0, _messages.Where(x => !x.StartsWith("##[debug]")).Count());
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void MatcherFileOutsideRepository()
|
||||
{
|
||||
var matchers = new IssueMatchersConfig
|
||||
{
|
||||
Matchers =
|
||||
{
|
||||
new IssueMatcherConfig
|
||||
{
|
||||
Owner = "my-matcher-1",
|
||||
Patterns = new[]
|
||||
{
|
||||
new IssuePatternConfig
|
||||
{
|
||||
Pattern = @"(.+): (.+)",
|
||||
File = 1,
|
||||
Message = 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
using (var hostContext = Setup(matchers: matchers))
|
||||
using (_outputManager)
|
||||
{
|
||||
// Setup github.workspace
|
||||
var workDirectory = hostContext.GetDirectory(WellKnownDirectory.Work);
|
||||
ArgUtil.NotNullOrEmpty(workDirectory, nameof(workDirectory));
|
||||
Directory.CreateDirectory(workDirectory);
|
||||
var workspaceDirectory = Path.Combine(workDirectory, "workspace");
|
||||
Directory.CreateDirectory(workspaceDirectory);
|
||||
_executionContext.Setup(x => x.GetGitHubContext("workspace")).Returns(workspaceDirectory);
|
||||
|
||||
// Create test files
|
||||
var filePath1 = Path.Combine(workspaceDirectory, "some-file-1.txt");
|
||||
File.WriteAllText(filePath1, "");
|
||||
var workspaceSiblingDirectory = Path.Combine(Path.GetDirectoryName(workspaceDirectory), "workspace-sibling");
|
||||
Directory.CreateDirectory(workspaceSiblingDirectory);
|
||||
var filePath2 = Path.Combine(workspaceSiblingDirectory, "some-file-2.txt");
|
||||
File.WriteAllText(filePath2, "");
|
||||
|
||||
// Process
|
||||
Process($"{filePath1}: some error 1"); // file exists inside workspace
|
||||
Process($"{filePath2}: some error 2"); // file exists outside workspace
|
||||
|
||||
Assert.Equal(2, _issues.Count);
|
||||
Assert.Equal("some error 1", _issues[0].Item1.Message);
|
||||
Assert.Equal("some-file-1.txt", _issues[0].Item1.Data["file"]);
|
||||
Assert.Equal("some error 2", _issues[1].Item1.Message);
|
||||
Assert.False(_issues[1].Item1.Data.ContainsKey("file")); // does not contain file key
|
||||
Assert.Equal(0, _commands.Count);
|
||||
Assert.Equal(0, _messages.Where(x => !x.StartsWith("##[debug]")).Count());
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void MatcherFromPath()
|
||||
{
|
||||
var matchers = new IssueMatchersConfig
|
||||
{
|
||||
Matchers =
|
||||
{
|
||||
new IssueMatcherConfig
|
||||
{
|
||||
Owner = "my-matcher-1",
|
||||
Patterns = new[]
|
||||
{
|
||||
new IssuePatternConfig
|
||||
{
|
||||
Pattern = @"(.+): (.+) \[(.+)\]",
|
||||
File = 1,
|
||||
Message = 2,
|
||||
FromPath = 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
using (var hostContext = Setup(matchers: matchers))
|
||||
using (_outputManager)
|
||||
{
|
||||
// Setup github.workspace
|
||||
var workDirectory = hostContext.GetDirectory(WellKnownDirectory.Work);
|
||||
ArgUtil.NotNullOrEmpty(workDirectory, nameof(workDirectory));
|
||||
Directory.CreateDirectory(workDirectory);
|
||||
var workspaceDirectory = Path.Combine(workDirectory, "workspace");
|
||||
Directory.CreateDirectory(workspaceDirectory);
|
||||
_executionContext.Setup(x => x.GetGitHubContext("workspace")).Returns(workspaceDirectory);
|
||||
|
||||
// Create a test file
|
||||
Directory.CreateDirectory(Path.Combine(workspaceDirectory, "some-directory"));
|
||||
Directory.CreateDirectory(Path.Combine(workspaceDirectory, "some-project", "some-directory"));
|
||||
var filePath = Path.Combine(workspaceDirectory, "some-project", "some-directory", "some-file.txt");
|
||||
File.WriteAllText(filePath, "");
|
||||
|
||||
// Process
|
||||
Process("some-directory/some-file.txt: some error [some-project/some-project.proj]");
|
||||
Assert.Equal(1, _issues.Count);
|
||||
Assert.Equal("some error", _issues[0].Item1.Message);
|
||||
Assert.Equal("some-project/some-directory/some-file.txt", _issues[0].Item1.Data["file"]);
|
||||
Assert.Equal(0, _commands.Count);
|
||||
Assert.Equal(0, _messages.Count);
|
||||
}
|
||||
}
|
||||
|
||||
private TestHostContext Setup(
|
||||
[CallerMemberName] string name = "",
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
string actual = variables.Get("no such");
|
||||
|
||||
// Assert.
|
||||
Assert.Equal(null, actual);
|
||||
Assert.Null(actual);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm;rhel.6-x64;osx-x64</RuntimeIdentifiers>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<RuntimeIdentifiers>win-x64;win-x86;linux-x64;linux-arm64;linux-arm;osx-x64</RuntimeIdentifiers>
|
||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
<AssetTargetFallback>portable-net45+win8</AssetTargetFallback>
|
||||
<NoWarn>NU1701;NU1603;NU1603;xUnit2013;</NoWarn>
|
||||
@@ -29,42 +29,4 @@
|
||||
<DebugType>portable</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x64'">
|
||||
<DefineConstants>OS_WINDOWS;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'win-x86'">
|
||||
<DefineConstants>OS_WINDOWS;X86;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">
|
||||
<DefineConstants>OS_OSX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true' AND '$(Configuration)' == 'Debug'">
|
||||
<DefineConstants>OS_OSX;DEBUG;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-x64'">
|
||||
<DefineConstants>OS_LINUX;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'rhel.6-x64'">
|
||||
<DefineConstants>OS_LINUX;OS_RHEL6;X64;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true' AND '$(Configuration)' == 'Debug' AND '$(PackageRuntime)' == 'linux-arm'">
|
||||
<DefineConstants>OS_LINUX;ARM;DEBUG;TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
102
src/dev.sh
102
src/dev.sh
@@ -10,13 +10,14 @@ set -e
|
||||
|
||||
DEV_CMD=$1
|
||||
DEV_CONFIG=$2
|
||||
DEV_TARGET_RUNTIME=$3
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
LAYOUT_DIR="$SCRIPT_DIR/../_layout"
|
||||
DOWNLOAD_DIR="$SCRIPT_DIR/../_downloads/netcore2x"
|
||||
PACKAGE_DIR="$SCRIPT_DIR/../_package"
|
||||
DOTNETSDK_ROOT="$SCRIPT_DIR/../_dotnetsdk"
|
||||
DOTNETSDK_VERSION="2.2.300"
|
||||
DOTNETSDK_VERSION="3.0.100"
|
||||
DOTNETSDK_INSTALLDIR="$DOTNETSDK_ROOT/$DOTNETSDK_VERSION"
|
||||
RUNNER_VERSION=$(cat runnerversion)
|
||||
|
||||
@@ -33,64 +34,60 @@ if [[ ($(uname) == "Linux") || ($(uname) == "Darwin") ]]; then
|
||||
fi
|
||||
|
||||
if [[ "$CURRENT_PLATFORM" == 'windows' ]]; then
|
||||
RUNTIME_ID='win-x64'
|
||||
if [[ "$PROCESSOR_ARCHITECTURE" == 'x86' ]]; then
|
||||
RUNTIME_ID='win-x86'
|
||||
fi
|
||||
RUNTIME_ID='win-x64'
|
||||
if [[ "$PROCESSOR_ARCHITECTURE" == 'x86' ]]; then
|
||||
RUNTIME_ID='win-x86'
|
||||
fi
|
||||
elif [[ "$CURRENT_PLATFORM" == 'linux' ]]; then
|
||||
RUNTIME_ID="linux-x64"
|
||||
if command -v uname > /dev/null; then
|
||||
CPU_NAME=$(uname -m)
|
||||
case $CPU_NAME in
|
||||
armv7l) RUNTIME_ID="linux-arm";;
|
||||
aarch64) RUNTIME_ID="linux-arm";;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ -e /etc/redhat-release ]; then
|
||||
redhatRelease=$(</etc/redhat-release)
|
||||
if [[ $redhatRelease == "CentOS release 6."* || $redhatRelease == "Red Hat Enterprise Linux Server release 6."* ]]; then
|
||||
RUNTIME_ID='rhel.6-x64'
|
||||
fi
|
||||
fi
|
||||
|
||||
RUNTIME_ID="linux-x64"
|
||||
if command -v uname > /dev/null; then
|
||||
CPU_NAME=$(uname -m)
|
||||
case $CPU_NAME in
|
||||
armv7l) RUNTIME_ID="linux-arm";;
|
||||
aarch64) RUNTIME_ID="linux-arm64";;
|
||||
esac
|
||||
fi
|
||||
elif [[ "$CURRENT_PLATFORM" == 'darwin' ]]; then
|
||||
RUNTIME_ID='osx-x64'
|
||||
RUNTIME_ID='osx-x64'
|
||||
fi
|
||||
|
||||
if [[ -n "$DEV_TARGET_RUNTIME" ]]; then
|
||||
RUNTIME_ID="$DEV_TARGET_RUNTIME"
|
||||
fi
|
||||
|
||||
# Make sure current platform support publish the dotnet runtime
|
||||
# Windows can publish win-x86/x64
|
||||
# Linux can publish linux-x64/arm/rhel.6-x64
|
||||
# Linux can publish linux-x64/arm/arm64
|
||||
# OSX can publish osx-x64
|
||||
if [[ "$CURRENT_PLATFORM" == 'windows' ]]; then
|
||||
if [[ ("$RUNTIME_ID" != 'win-x86') && ("$RUNTIME_ID" != 'win-x64') ]]; then
|
||||
echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ("$RUNTIME_ID" != 'win-x86') && ("$RUNTIME_ID" != 'win-x64') ]]; then
|
||||
echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$CURRENT_PLATFORM" == 'linux' ]]; then
|
||||
if [[ ("$RUNTIME_ID" != 'linux-x64') && ("$RUNTIME_ID" != 'linux-arm') && ("$RUNTIME_ID" != 'rhel.6-x64') ]]; then
|
||||
echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ("$RUNTIME_ID" != 'linux-x64') && ("$RUNTIME_ID" != 'linux-x86') && ("$RUNTIME_ID" != 'linux-arm64') && ("$RUNTIME_ID" != 'linux-arm') ]]; then
|
||||
echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$CURRENT_PLATFORM" == 'darwin' ]]; then
|
||||
if [[ ("$RUNTIME_ID" != 'osx-x64') ]]; then
|
||||
echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ("$RUNTIME_ID" != 'osx-x64') ]]; then
|
||||
echo "Failed: Can't build $RUNTIME_ID package $CURRENT_PLATFORM" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
function failed()
|
||||
{
|
||||
local error=${1:-Undefined error}
|
||||
echo "Failed: $error" >&2
|
||||
popd
|
||||
exit 1
|
||||
local error=${1:-Undefined error}
|
||||
echo "Failed: $error" >&2
|
||||
popd
|
||||
exit 1
|
||||
}
|
||||
|
||||
function warn()
|
||||
{
|
||||
local error=${1:-Undefined error}
|
||||
echo "WARNING - FAILED: $error" >&2
|
||||
local error=${1:-Undefined error}
|
||||
echo "WARNING - FAILED: $error" >&2
|
||||
}
|
||||
|
||||
function checkRC() {
|
||||
@@ -151,7 +148,8 @@ function package ()
|
||||
echo "You must build first. Expecting to find ${LAYOUT_DIR}/bin"
|
||||
fi
|
||||
|
||||
runner_ver=$("${LAYOUT_DIR}/bin/Runner.Listener" --version) || failed "version"
|
||||
# TODO: We are cross-compiling arm on x64 so we cant exec Runner.Listener. Remove after building on native arm host
|
||||
runner_ver=$("${LAYOUT_DIR}/bin/Runner.Listener" --version) || runner_ver=$(cat runnerversion) || failed "version"
|
||||
runner_pkg_name="actions-runner-${RUNTIME_ID}-${runner_ver}"
|
||||
|
||||
heading "Packaging ${runner_pkg_name}"
|
||||
@@ -208,8 +206,6 @@ fi
|
||||
echo "Prepend ${DOTNETSDK_INSTALLDIR} to %PATH%"
|
||||
export PATH=${DOTNETSDK_INSTALLDIR}:$PATH
|
||||
|
||||
heading "Github Dreamlifter Runner"
|
||||
|
||||
heading "Dotnet SDK Version"
|
||||
dotnet --version
|
||||
|
||||
@@ -233,15 +229,15 @@ if [[ "$CURRENT_PLATFORM" == 'windows' ]]; then
|
||||
fi
|
||||
|
||||
case $DEV_CMD in
|
||||
"build") build;;
|
||||
"b") build;;
|
||||
"test") runtest;;
|
||||
"t") runtest;;
|
||||
"layout") layout;;
|
||||
"l") layout;;
|
||||
"package") package;;
|
||||
"p") package;;
|
||||
*) echo "Invalid cmd. Use build(b), test(t), layout(l) or package(p)";;
|
||||
"build") build;;
|
||||
"b") build;;
|
||||
"test") runtest;;
|
||||
"t") runtest;;
|
||||
"layout") layout;;
|
||||
"l") layout;;
|
||||
"package") package;;
|
||||
"p") package;;
|
||||
*) echo "Invalid cmd. Use build(b), test(t), layout(l) or package(p)";;
|
||||
esac
|
||||
|
||||
popd
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "2.2.300"
|
||||
"version": "3.0.100"
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
2.159.0
|
||||
2.161.0
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
parameters:
|
||||
targetRuntime: ''
|
||||
|
||||
steps:
|
||||
|
||||
# Build agent layout
|
||||
- script: dev.cmd layout Release
|
||||
- script: dev.cmd layout Release ${{ parameters.targetRuntime }}
|
||||
workingDirectory: src
|
||||
displayName: Build & Layout Release
|
||||
displayName: Build & Layout Release ${{ parameters.targetRuntime }}
|
||||
|
||||
# Run test
|
||||
- script: dev.cmd test
|
||||
|
||||
Reference in New Issue
Block a user