Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f840647b3 | ||
|
|
e2fbd1dc95 | ||
|
|
8d6acf2a7f | ||
|
|
6b3b42a840 | ||
|
|
826f58682e | ||
|
|
2eefff4b69 | ||
|
|
8456f7667d | ||
|
|
7f092c96db |
@@ -1,57 +0,0 @@
|
|||||||
# Automate Configuring Self-Hosted Runners
|
|
||||||
|
|
||||||
|
|
||||||
## Export PAT
|
|
||||||
|
|
||||||
Before running any of these sample scripts, create a GitHub PAT and export it before running the script
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export RUNNER_CFG_PAT=yourPAT
|
|
||||||
```
|
|
||||||
|
|
||||||
## Create running as a service
|
|
||||||
|
|
||||||
**Scenario**: Run on a machine or VM (not container) which automates:
|
|
||||||
|
|
||||||
- Resolving latest released runner
|
|
||||||
- Download and extract latest
|
|
||||||
- Acquire a registration token
|
|
||||||
- Configure the runner
|
|
||||||
- Run as a systemd (linux) or Launchd (osx) service
|
|
||||||
|
|
||||||
:point_right: [Sample script here](../scripts/create-latest-svc.sh) :point_left:
|
|
||||||
|
|
||||||
Run as a one-liner. NOTE: replace with yourorg/yourrepo (repo level) or just yourorg (org level)
|
|
||||||
```bash
|
|
||||||
curl -s https://raw.githubusercontent.com/actions/runner/automate/scripts/create-latest-svc.sh | bash -s yourorg/yourrepo
|
|
||||||
```
|
|
||||||
|
|
||||||
## Uninstall running as service
|
|
||||||
|
|
||||||
**Scenario**: Run on a machine or VM (not container) which automates:
|
|
||||||
|
|
||||||
- Stops and uninstalls the systemd (linux) or Launchd (osx) service
|
|
||||||
- Acquires a removal token
|
|
||||||
- Removes the runner
|
|
||||||
|
|
||||||
:point_right: [Sample script here](../scripts/remove-svc.sh) :point_left:
|
|
||||||
|
|
||||||
Repo level one liner. NOTE: replace with yourorg/yourrepo (repo level) or just yourorg (org level)
|
|
||||||
```bash
|
|
||||||
curl -s https://raw.githubusercontent.com/actions/runner/automate/scripts/remove-svc.sh | bash -s yourorg/yourrepo
|
|
||||||
```
|
|
||||||
|
|
||||||
### Delete an offline runner
|
|
||||||
|
|
||||||
**Scenario**: Deletes a registered runner that is offline:
|
|
||||||
|
|
||||||
- Ensures the runner is offline
|
|
||||||
- Resolves id from name
|
|
||||||
- Deletes the runner
|
|
||||||
|
|
||||||
:point_right: [Sample script here](../scripts/delete.sh) :point_left:
|
|
||||||
|
|
||||||
Repo level one-liner. NOTE: replace with yourorg/yourrepo (repo level) or just yourorg (org level) and replace runnername
|
|
||||||
```bash
|
|
||||||
curl -s https://raw.githubusercontent.com/actions/runner/automate/scripts/delete.sh | bash -s yourorg/yourrepo runnername
|
|
||||||
```
|
|
||||||
@@ -40,7 +40,7 @@ Debian based OS (Debian, Ubuntu, Linux Mint)
|
|||||||
- libssl1.1, libssl1.0.2 or libssl1.0.0
|
- libssl1.1, libssl1.0.2 or libssl1.0.0
|
||||||
- libicu63, libicu60, libicu57 or libicu55
|
- libicu63, libicu60, libicu57 or libicu55
|
||||||
|
|
||||||
Fedora based OS (Fedora, Red Hat Enterprise Linux, CentOS, Oracle Linux 7)
|
Fedora based OS (Fedora, Redhat, Centos, Oracle Linux 7)
|
||||||
|
|
||||||
- lttng-ust
|
- lttng-ust
|
||||||
- openssl-libs
|
- openssl-libs
|
||||||
|
|||||||
+22
-23
@@ -1,22 +1,21 @@
|
|||||||
## Features
|
## Features
|
||||||
- Runner support for GHES Alpha (#381 #386 #390 #393 $401)
|
- Better telemetry tracing for self-hosted runner. (#405)
|
||||||
- Allow secrets context in Container.env (#388)
|
- Launch middle man process on macOS to workaround SIP limit (#416)
|
||||||
|
- Added support for custom labels (#414, #425)
|
||||||
|
- support 'pre' execution for actions. (#389)
|
||||||
## Bugs
|
## Bugs
|
||||||
- Raise warning when volume mount root. (#413)
|
- ArgumentNullException: Value cannot be null, for anonymous volume mounts (#426)
|
||||||
- Fix typo (#394)
|
|
||||||
## Misc
|
## Misc
|
||||||
- N/A
|
- N/A
|
||||||
|
|
||||||
## Windows x64
|
## Windows x64
|
||||||
We recommend configuring the runner in a root folder of the Windows drive (e.g. "C:\actions-runner"). This will help avoid issues related to service identity folder permissions and long file path restrictions on Windows.
|
We recommend configuring the runner in a root folder of the Windows drive (e.g. "C:\actions-runner"). This will help avoid issues related to service identity folder permissions and long file path restrictions on Windows
|
||||||
|
```
|
||||||
The following snipped needs to be run on `powershell`:
|
// Create a folder under the drive root
|
||||||
``` powershell
|
|
||||||
# Create a folder under the drive root
|
|
||||||
mkdir \actions-runner ; cd \actions-runner
|
mkdir \actions-runner ; cd \actions-runner
|
||||||
# Download the latest runner package
|
// Download the latest runner package
|
||||||
Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-win-x64-<RUNNER_VERSION>.zip -OutFile actions-runner-win-x64-<RUNNER_VERSION>.zip
|
Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-win-x64-<RUNNER_VERSION>.zip -OutFile actions-runner-win-x64-<RUNNER_VERSION>.zip
|
||||||
# Extract the installer
|
// Extract the installer
|
||||||
Add-Type -AssemblyName System.IO.Compression.FileSystem ;
|
Add-Type -AssemblyName System.IO.Compression.FileSystem ;
|
||||||
[System.IO.Compression.ZipFile]::ExtractToDirectory("$PWD\actions-runner-win-x64-<RUNNER_VERSION>.zip", "$PWD")
|
[System.IO.Compression.ZipFile]::ExtractToDirectory("$PWD\actions-runner-win-x64-<RUNNER_VERSION>.zip", "$PWD")
|
||||||
```
|
```
|
||||||
@@ -24,44 +23,44 @@ Add-Type -AssemblyName System.IO.Compression.FileSystem ;
|
|||||||
## OSX
|
## OSX
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
# Create a folder
|
// Create a folder
|
||||||
mkdir actions-runner && cd actions-runner
|
mkdir actions-runner && cd actions-runner
|
||||||
# Download the latest runner package
|
// Download the latest runner package
|
||||||
curl -O -L https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz
|
curl -O -L https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz
|
||||||
# Extract the installer
|
// Extract the installer
|
||||||
tar xzf ./actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz
|
tar xzf ./actions-runner-osx-x64-<RUNNER_VERSION>.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
## Linux x64
|
## Linux x64
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
# Create a folder
|
// Create a folder
|
||||||
mkdir actions-runner && cd actions-runner
|
mkdir actions-runner && cd actions-runner
|
||||||
# Download the latest runner package
|
// Download the latest runner package
|
||||||
curl -O -L https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-linux-x64-<RUNNER_VERSION>.tar.gz
|
curl -O -L https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-linux-x64-<RUNNER_VERSION>.tar.gz
|
||||||
# Extract the installer
|
// Extract the installer
|
||||||
tar xzf ./actions-runner-linux-x64-<RUNNER_VERSION>.tar.gz
|
tar xzf ./actions-runner-linux-x64-<RUNNER_VERSION>.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
## Linux arm64 (Pre-release)
|
## Linux arm64 (Pre-release)
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
# Create a folder
|
// Create a folder
|
||||||
mkdir actions-runner && cd actions-runner
|
mkdir actions-runner && cd actions-runner
|
||||||
# Download the latest runner package
|
// Download the latest runner package
|
||||||
curl -O -L https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz
|
curl -O -L https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz
|
||||||
# Extract the installer
|
// Extract the installer
|
||||||
tar xzf ./actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz
|
tar xzf ./actions-runner-linux-arm64-<RUNNER_VERSION>.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
## Linux arm (Pre-release)
|
## Linux arm (Pre-release)
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
# Create a folder
|
// Create a folder
|
||||||
mkdir actions-runner && cd actions-runner
|
mkdir actions-runner && cd actions-runner
|
||||||
# Download the latest runner package
|
// Download the latest runner package
|
||||||
curl -O -L https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz
|
curl -O -L https://github.com/actions/runner/releases/download/v<RUNNER_VERSION>/actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz
|
||||||
# Extract the installer
|
// Extract the installer
|
||||||
tar xzf ./actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz
|
tar xzf ./actions-runner-linux-arm-<RUNNER_VERSION>.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
2.168.0
|
2.169.1
|
||||||
|
|||||||
@@ -1,135 +0,0 @@
|
|||||||
#/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
#
|
|
||||||
# Downloads latest releases (not pre-release) runner
|
|
||||||
# Configures as a service
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# RUNNER_CFG_PAT=<yourPAT> ./create-latest-svc.sh myuser/myrepo
|
|
||||||
# RUNNER_CFG_PAT=<yourPAT> ./create-latest-svc.sh myorg
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# export RUNNER_CFG_PAT=<yourPAT>
|
|
||||||
# ./create-latest-svc scope [name] [user]
|
|
||||||
#
|
|
||||||
# scope required repo (:owner/:repo) or org (:organization)
|
|
||||||
# name optional defaults to hostname
|
|
||||||
# user optional user svc will run as. defaults to current
|
|
||||||
#
|
|
||||||
# Notes:
|
|
||||||
# PATS over envvars are more secure
|
|
||||||
# Should be used on VMs and not containers
|
|
||||||
# Works on OSX and Linux
|
|
||||||
# Assumes x64 arch
|
|
||||||
#
|
|
||||||
|
|
||||||
runner_scope=${1}
|
|
||||||
runner_name=${2:-$(hostname)}
|
|
||||||
svc_user=${3:-$USER}
|
|
||||||
|
|
||||||
echo "Configuring runner @ ${runner_scope}"
|
|
||||||
sudo echo
|
|
||||||
|
|
||||||
#---------------------------------------
|
|
||||||
# Validate Environment
|
|
||||||
#---------------------------------------
|
|
||||||
runner_plat=linux
|
|
||||||
[ ! -z "$(which sw_vers)" ] && runner_plat=osx;
|
|
||||||
|
|
||||||
function fatal()
|
|
||||||
{
|
|
||||||
echo "error: $1" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -z "${runner_scope}" ]; then fatal "supply scope as argument 1"; fi
|
|
||||||
if [ -z "${RUNNER_CFG_PAT}" ]; then fatal "RUNNER_CFG_PAT must be set before calling"; fi
|
|
||||||
|
|
||||||
which curl || fatal "curl required. Please install in PATH with apt-get, brew, etc"
|
|
||||||
which jq || fatal "jq required. Please install in PATH with apt-get, brew, etc"
|
|
||||||
|
|
||||||
# bail early if there's already a runner there. also sudo early
|
|
||||||
if [ -d ./runner ]; then
|
|
||||||
fatal "Runner already exists. Use a different directory or delete ./runner"
|
|
||||||
fi
|
|
||||||
|
|
||||||
sudo -u ${svc_user} mkdir runner
|
|
||||||
|
|
||||||
# TODO: validate not in a container
|
|
||||||
# TODO: validate systemd or osx svc installer
|
|
||||||
|
|
||||||
#--------------------------------------
|
|
||||||
# Get a config token
|
|
||||||
#--------------------------------------
|
|
||||||
echo
|
|
||||||
echo "Generating a registration token..."
|
|
||||||
|
|
||||||
# if the scope has a slash, it's an repo runner
|
|
||||||
base_api_url="https://api.github.com/orgs"
|
|
||||||
if [[ "$runner_scope" == *\/* ]]; then
|
|
||||||
base_api_url="https://api.github.com/repos"
|
|
||||||
fi
|
|
||||||
|
|
||||||
export RUNNER_TOKEN=$(curl -s -X POST ${base_api_url}/${runner_scope}/actions/runners/registration-token -H "accept: application/vnd.github.everest-preview+json" -H "authorization: token ${RUNNER_CFG_PAT}" | jq -r '.token')
|
|
||||||
|
|
||||||
if [ -z "$RUNNER_TOKEN" ]; then fatal "Failed to get a token"; fi
|
|
||||||
|
|
||||||
#---------------------------------------
|
|
||||||
# Download latest released and extract
|
|
||||||
#---------------------------------------
|
|
||||||
echo
|
|
||||||
echo "Downloading latest runner ..."
|
|
||||||
|
|
||||||
latest_version_label=$(curl -s -X GET 'https://api.github.com/repos/actions/runner/releases/latest' | jq -r '.tag_name')
|
|
||||||
latest_version=$(echo ${latest_version_label:1})
|
|
||||||
runner_file="actions-runner-${runner_plat}-x64-${latest_version}.tar.gz"
|
|
||||||
|
|
||||||
if [ -f "${runner_file}" ]; then
|
|
||||||
echo "${runner_file} exists. skipping download."
|
|
||||||
else
|
|
||||||
runner_url="https://github.com/actions/runner/releases/download/${latest_version_label}/${runner_file}"
|
|
||||||
|
|
||||||
echo "Downloading ${latest_version_label} for ${runner_plat} ..."
|
|
||||||
echo $runner_url
|
|
||||||
|
|
||||||
curl -O -L ${runner_url}
|
|
||||||
fi
|
|
||||||
|
|
||||||
ls -la *.tar.gz
|
|
||||||
|
|
||||||
#---------------------------------------------------
|
|
||||||
# extract to runner directory in this directory
|
|
||||||
#---------------------------------------------------
|
|
||||||
echo
|
|
||||||
echo "Extracting ${runner_file} to ./runner"
|
|
||||||
|
|
||||||
tar xzf "./${runner_file}" -C runner
|
|
||||||
|
|
||||||
# export of pass
|
|
||||||
sudo chown -R $svc_user ./runner
|
|
||||||
|
|
||||||
pushd ./runner
|
|
||||||
|
|
||||||
#---------------------------------------
|
|
||||||
# Unattend config
|
|
||||||
#---------------------------------------
|
|
||||||
runner_url="https://github.com/${runner_scope}"
|
|
||||||
echo
|
|
||||||
echo "Configuring ${runner_name} @ $runner_url"
|
|
||||||
echo "./config.sh --unattended --url $runner_url --token *** --name $runner_name"
|
|
||||||
sudo -E -u ${svc_user} ./config.sh --unattended --url $runner_url --token $RUNNER_TOKEN --name $runner_name
|
|
||||||
|
|
||||||
#---------------------------------------
|
|
||||||
# Configuring as a service
|
|
||||||
#---------------------------------------
|
|
||||||
echo
|
|
||||||
echo "Configuring as a service ..."
|
|
||||||
prefix=""
|
|
||||||
if [ "${runner_plat}" == "linux" ]; then
|
|
||||||
prefix="sudo "
|
|
||||||
fi
|
|
||||||
|
|
||||||
${prefix}./svc.sh install ${svc_user}
|
|
||||||
${prefix}./svc.sh start
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
#/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
#
|
|
||||||
# Force deletes a runner from the service
|
|
||||||
# The caller should have already ensured the runner is gone and/or stopped
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# RUNNER_CFG_PAT=<yourPAT> ./delete.sh myuser/myrepo myname
|
|
||||||
# RUNNER_CFG_PAT=<yourPAT> ./delete.sh myorg
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# export RUNNER_CFG_PAT=<yourPAT>
|
|
||||||
# ./delete.sh scope name
|
|
||||||
#
|
|
||||||
# scope required repo (:owner/:repo) or org (:organization)
|
|
||||||
# name optional defaults to hostname. name to delete
|
|
||||||
#
|
|
||||||
# Notes:
|
|
||||||
# PATS over envvars are more secure
|
|
||||||
# Works on OSX and Linux
|
|
||||||
# Assumes x64 arch
|
|
||||||
#
|
|
||||||
|
|
||||||
runner_scope=${1}
|
|
||||||
runner_name=${2}
|
|
||||||
|
|
||||||
echo "Deleting runner ${runner_name} @ ${runner_scope}"
|
|
||||||
|
|
||||||
function fatal()
|
|
||||||
{
|
|
||||||
echo "error: $1" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -z "${runner_scope}" ]; then fatal "supply scope as argument 1"; fi
|
|
||||||
if [ -z "${runner_name}" ]; then fatal "supply name as argument 2"; fi
|
|
||||||
if [ -z "${RUNNER_CFG_PAT}" ]; then fatal "RUNNER_CFG_PAT must be set before calling"; fi
|
|
||||||
|
|
||||||
which curl || fatal "curl required. Please install in PATH with apt-get, brew, etc"
|
|
||||||
which jq || fatal "jq required. Please install in PATH with apt-get, brew, etc"
|
|
||||||
|
|
||||||
base_api_url="https://api.github.com/orgs"
|
|
||||||
if [[ "$runner_scope" == *\/* ]]; then
|
|
||||||
base_api_url="https://api.github.com/repos"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------
|
|
||||||
# Ensure offline
|
|
||||||
#--------------------------------------
|
|
||||||
runner_status=$(curl -s -X GET ${base_api_url}/${runner_scope}/actions/runners?per_page=100 -H "accept: application/vnd.github.everest-preview+json" -H "authorization: token ${RUNNER_CFG_PAT}" \
|
|
||||||
| jq -M -j ".runners | .[] | [select(.name == \"${runner_name}\")] | .[0].status")
|
|
||||||
|
|
||||||
if [ -z "${runner_status}" ]; then
|
|
||||||
fatal "Could not find runner with name ${runner_name}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Status: ${runner_status}"
|
|
||||||
|
|
||||||
if [ "${runner_status}" != "offline" ]; then
|
|
||||||
fatal "Runner should be offline before removing"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#--------------------------------------
|
|
||||||
# Get id of runner to remove
|
|
||||||
#--------------------------------------
|
|
||||||
runner_id=$(curl -s -X GET ${base_api_url}/${runner_scope}/actions/runners?per_page=100 -H "accept: application/vnd.github.everest-preview+json" -H "authorization: token ${RUNNER_CFG_PAT}" \
|
|
||||||
| jq -M -j ".runners | .[] | [select(.name == \"${runner_name}\")] | .[0].id")
|
|
||||||
|
|
||||||
if [ -z "${runner_id}" ]; then
|
|
||||||
fatal "Could not find runner with name ${runner_name}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Removing id ${runner_id}"
|
|
||||||
|
|
||||||
#--------------------------------------
|
|
||||||
# Remove the runner
|
|
||||||
#--------------------------------------
|
|
||||||
curl -s -X DELETE ${base_api_url}/${runner_scope}/actions/runners/${runner_id} -H "authorization: token ${RUNNER_CFG_PAT}"
|
|
||||||
|
|
||||||
echo "Done."
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
#/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
#
|
|
||||||
# Removes a runner running as a service
|
|
||||||
# Must be run on the machine where the service is run
|
|
||||||
#
|
|
||||||
# Examples:
|
|
||||||
# RUNNER_CFG_PAT=<yourPAT> ./remove-svc.sh myuser/myrepo
|
|
||||||
# RUNNER_CFG_PAT=<yourPAT> ./remove-svc.sh myorg
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# export RUNNER_CFG_PAT=<yourPAT>
|
|
||||||
# ./remove-svc scope name
|
|
||||||
#
|
|
||||||
# scope required repo (:owner/:repo) or org (:organization)
|
|
||||||
# name optional defaults to hostname. name to uninstall and remove
|
|
||||||
#
|
|
||||||
# Notes:
|
|
||||||
# PATS over envvars are more secure
|
|
||||||
# Should be used on VMs and not containers
|
|
||||||
# Works on OSX and Linux
|
|
||||||
# Assumes x64 arch
|
|
||||||
#
|
|
||||||
|
|
||||||
runner_scope=${1}
|
|
||||||
runner_name=${2:-$(hostname)}
|
|
||||||
|
|
||||||
echo "Uninstalling runner ${runner_name} @ ${runner_scope}"
|
|
||||||
sudo echo
|
|
||||||
|
|
||||||
function fatal()
|
|
||||||
{
|
|
||||||
echo "error: $1" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -z "${runner_scope}" ]; then fatal "supply scope as argument 1"; fi
|
|
||||||
if [ -z "${RUNNER_CFG_PAT}" ]; then fatal "RUNNER_CFG_PAT must be set before calling"; fi
|
|
||||||
|
|
||||||
which curl || fatal "curl required. Please install in PATH with apt-get, brew, etc"
|
|
||||||
which jq || fatal "jq required. Please install in PATH with apt-get, brew, etc"
|
|
||||||
|
|
||||||
runner_plat=linux
|
|
||||||
[ ! -z "$(which sw_vers)" ] && runner_plat=osx;
|
|
||||||
|
|
||||||
#--------------------------------------
|
|
||||||
# Get a remove token
|
|
||||||
#--------------------------------------
|
|
||||||
echo
|
|
||||||
echo "Generating a removal token..."
|
|
||||||
|
|
||||||
# if the scope has a slash, it's an repo runner
|
|
||||||
base_api_url="https://api.github.com/orgs"
|
|
||||||
if [[ "$runner_scope" == *\/* ]]; then
|
|
||||||
base_api_url="https://api.github.com/repos"
|
|
||||||
fi
|
|
||||||
|
|
||||||
export REMOVE_TOKEN=$(curl -s -X POST ${base_api_url}/${runner_scope}/actions/runners/remove-token -H "accept: application/vnd.github.everest-preview+json" -H "authorization: token ${RUNNER_CFG_PAT}" | jq -r '.token')
|
|
||||||
|
|
||||||
if [ -z "$REMOVE_TOKEN" ]; then fatal "Failed to get a token"; fi
|
|
||||||
|
|
||||||
#---------------------------------------
|
|
||||||
# Stop and uninstall the service
|
|
||||||
#---------------------------------------
|
|
||||||
echo
|
|
||||||
echo "Uninstall the service ..."
|
|
||||||
pushd ./runner
|
|
||||||
prefix=""
|
|
||||||
if [ "${runner_plat}" == "linux" ]; then
|
|
||||||
prefix="sudo "
|
|
||||||
fi
|
|
||||||
${prefix}./svc.sh stop
|
|
||||||
${prefix}./svc.sh uninstall
|
|
||||||
${prefix}./config.sh remove --token $REMOVE_TOKEN
|
|
||||||
@@ -9,7 +9,7 @@ fi
|
|||||||
|
|
||||||
# Determine OS type
|
# Determine OS type
|
||||||
# Debian based OS (Debian, Ubuntu, Linux Mint) has /etc/debian_version
|
# Debian based OS (Debian, Ubuntu, Linux Mint) has /etc/debian_version
|
||||||
# Fedora based OS (Fedora, Red Hat Enterprise Linux, CentOS, Oracle Linux 7) has /etc/redhat-release
|
# Fedora based OS (Fedora, Redhat, Centos, Oracle Linux 7) has /etc/redhat-release
|
||||||
# SUSE based OS (OpenSUSE, SUSE Enterprise) has ID_LIKE=suse in /etc/os-release
|
# SUSE based OS (OpenSUSE, SUSE Enterprise) has ID_LIKE=suse in /etc/os-release
|
||||||
|
|
||||||
function print_errormessage()
|
function print_errormessage()
|
||||||
@@ -116,12 +116,12 @@ then
|
|||||||
elif [ -e /etc/redhat-release ]
|
elif [ -e /etc/redhat-release ]
|
||||||
then
|
then
|
||||||
echo "The current OS is Fedora based"
|
echo "The current OS is Fedora based"
|
||||||
echo "--Fedora/RHEL/CentOS Version--"
|
echo "--------Redhat Version--------"
|
||||||
cat /etc/redhat-release
|
cat /etc/redhat-release
|
||||||
echo "------------------------------"
|
echo "------------------------------"
|
||||||
|
|
||||||
# use dnf on fedora
|
# use dnf on fedora
|
||||||
# use yum on centos and rhel
|
# use yum on centos and redhat
|
||||||
if [ -e /etc/fedora-release ]
|
if [ -e /etc/fedora-release ]
|
||||||
then
|
then
|
||||||
command -v dnf
|
command -v dnf
|
||||||
@@ -191,7 +191,7 @@ then
|
|||||||
redhatRelease=$(</etc/redhat-release)
|
redhatRelease=$(</etc/redhat-release)
|
||||||
if [[ $redhatRelease == "CentOS release 6."* || $redhatRelease == "Red Hat Enterprise Linux Server release 6."* ]]
|
if [[ $redhatRelease == "CentOS release 6."* || $redhatRelease == "Red Hat Enterprise Linux Server release 6."* ]]
|
||||||
then
|
then
|
||||||
echo "The current OS is Red Hat Enterprise Linux 6 or CentOS 6"
|
echo "The current OS is Red Hat Enterprise Linux 6 or Centos 6"
|
||||||
|
|
||||||
# Install known dependencies, as a best effort.
|
# Install known dependencies, as a best effort.
|
||||||
# The remaining dependencies are covered by the GitHub doc that will be shown by `print_rhel6message`
|
# The remaining dependencies are covered by the GitHub doc that will be shown by `print_rhel6message`
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ namespace GitHub.Runner.Common
|
|||||||
this.SecretMasker.AddValueEncoder(ValueEncoders.JsonStringEscape);
|
this.SecretMasker.AddValueEncoder(ValueEncoders.JsonStringEscape);
|
||||||
this.SecretMasker.AddValueEncoder(ValueEncoders.UriDataEscape);
|
this.SecretMasker.AddValueEncoder(ValueEncoders.UriDataEscape);
|
||||||
this.SecretMasker.AddValueEncoder(ValueEncoders.XmlDataEscape);
|
this.SecretMasker.AddValueEncoder(ValueEncoders.XmlDataEscape);
|
||||||
this.SecretMasker.AddValueEncoder(ValueEncoders.TrimDoubleQuotes);
|
|
||||||
|
|
||||||
// Create the trace manager.
|
// Create the trace manager.
|
||||||
if (string.IsNullOrEmpty(logFile))
|
if (string.IsNullOrEmpty(logFile))
|
||||||
|
|||||||
@@ -143,10 +143,8 @@ namespace GitHub.Runner.Worker
|
|||||||
var templateEvaluator = ExecutionContext.ToPipelineTemplateEvaluator();
|
var templateEvaluator = ExecutionContext.ToPipelineTemplateEvaluator();
|
||||||
var inputs = templateEvaluator.EvaluateStepInputs(Action.Inputs, ExecutionContext.ExpressionValues, ExecutionContext.ExpressionFunctions);
|
var inputs = templateEvaluator.EvaluateStepInputs(Action.Inputs, ExecutionContext.ExpressionValues, ExecutionContext.ExpressionFunctions);
|
||||||
|
|
||||||
var userInputs = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
foreach (KeyValuePair<string, string> input in inputs)
|
foreach (KeyValuePair<string, string> input in inputs)
|
||||||
{
|
{
|
||||||
userInputs.Add(input.Key);
|
|
||||||
string message = "";
|
string message = "";
|
||||||
if (definition.Data?.Deprecated?.TryGetValue(input.Key, out message) == true)
|
if (definition.Data?.Deprecated?.TryGetValue(input.Key, out message) == true)
|
||||||
{
|
{
|
||||||
@@ -154,15 +152,13 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var validInputs = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
// Merge the default inputs from the definition
|
// Merge the default inputs from the definition
|
||||||
if (definition.Data?.Inputs != null)
|
if (definition.Data?.Inputs != null)
|
||||||
{
|
{
|
||||||
var manifestManager = HostContext.GetService<IActionManifestManager>();
|
var manifestManager = HostContext.GetService<IActionManifestManager>();
|
||||||
foreach (var input in definition.Data.Inputs)
|
foreach (var input in (definition.Data?.Inputs))
|
||||||
{
|
{
|
||||||
string key = input.Key.AssertString("action input name").Value;
|
string key = input.Key.AssertString("action input name").Value;
|
||||||
validInputs.Add(key);
|
|
||||||
if (!inputs.ContainsKey(key))
|
if (!inputs.ContainsKey(key))
|
||||||
{
|
{
|
||||||
inputs[key] = manifestManager.EvaluateDefaultInput(ExecutionContext, key, input.Value);
|
inputs[key] = manifestManager.EvaluateDefaultInput(ExecutionContext, key, input.Value);
|
||||||
@@ -170,14 +166,6 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var input in userInputs)
|
|
||||||
{
|
|
||||||
if (!validInputs.Contains(input))
|
|
||||||
{
|
|
||||||
ExecutionContext.Warning($"Unexpected input '{input}', valid inputs are ['{string.Join("', '", validInputs)}']");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the action environment.
|
// Load the action environment.
|
||||||
ExecutionContext.Debug("Loading env");
|
ExecutionContext.Debug("Loading env");
|
||||||
var environment = new Dictionary<String, String>(VarUtil.EnvironmentVariableKeyComparer);
|
var environment = new Dictionary<String, String>(VarUtil.EnvironmentVariableKeyComparer);
|
||||||
|
|||||||
@@ -149,14 +149,14 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
throw new NotSupportedException(msg);
|
throw new NotSupportedException(msg);
|
||||||
}
|
}
|
||||||
nodeExternal = "node12_alpine";
|
nodeExternal = "node12_alpine";
|
||||||
executionContext.Debug($"Container distribution is alpine. Running JavaScript Action with external tool: {nodeExternal}");
|
executionContext.Output($"Container distribution is alpine. Running JavaScript Action with external tool: {nodeExternal}");
|
||||||
return nodeExternal;
|
return nodeExternal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Optimistically use the default
|
// Optimistically use the default
|
||||||
nodeExternal = "node12";
|
nodeExternal = "node12";
|
||||||
executionContext.Debug($"Running JavaScript Action with default external tool: {nodeExternal}");
|
executionContext.Output($"Running JavaScript Action with default external tool: {nodeExternal}");
|
||||||
return nodeExternal;
|
return nodeExternal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,20 +60,6 @@ namespace GitHub.DistributedTask.Logging
|
|||||||
return SecurityElement.Escape(value);
|
return SecurityElement.Escape(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String TrimDoubleQuotes(String value)
|
|
||||||
{
|
|
||||||
var trimmed = string.Empty;
|
|
||||||
if (!string.IsNullOrEmpty(value) &&
|
|
||||||
value.Length > 8 &&
|
|
||||||
value.StartsWith('"') &&
|
|
||||||
value.EndsWith('"'))
|
|
||||||
{
|
|
||||||
trimmed = value.Substring(1, value.Length - 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return trimmed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string Base64StringEscapeShift(String value, int shift)
|
private static string Base64StringEscapeShift(String value, int shift)
|
||||||
{
|
{
|
||||||
var bytes = Encoding.UTF8.GetBytes(value);
|
var bytes = Encoding.UTF8.GetBytes(value);
|
||||||
|
|||||||
@@ -85,8 +85,6 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
_hc.SecretMasker.AddValue("Pass word 123!");
|
_hc.SecretMasker.AddValue("Pass word 123!");
|
||||||
_hc.SecretMasker.AddValue("Pass<word>123!");
|
_hc.SecretMasker.AddValue("Pass<word>123!");
|
||||||
_hc.SecretMasker.AddValue("Pass'word'123!");
|
_hc.SecretMasker.AddValue("Pass'word'123!");
|
||||||
_hc.SecretMasker.AddValue("\"Password123!!\"");
|
|
||||||
_hc.SecretMasker.AddValue("\"short\"");
|
|
||||||
|
|
||||||
// Assert.
|
// Assert.
|
||||||
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Password123!123"));
|
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Password123!123"));
|
||||||
@@ -101,9 +99,6 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
Assert.Equal("YWJjOlBh***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abc: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("YWJjZDpQ***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abcd:Password123!"))));
|
||||||
Assert.Equal("YWJjZGU6***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abcde:Password123!"))));
|
Assert.Equal("YWJjZGU6***", _hc.SecretMasker.MaskSecrets(Convert.ToBase64String(Encoding.UTF8.GetBytes($"abcde:Password123!"))));
|
||||||
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123Password123!!123"));
|
|
||||||
Assert.Equal("123short123", _hc.SecretMasker.MaskSecrets("123short123"));
|
|
||||||
Assert.Equal("123***123", _hc.SecretMasker.MaskSecrets("123\"short\"123"));
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -278,59 +278,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
Assert.Equal("${{ matrix.node }}", _actionRunner.DisplayName);
|
Assert.Equal("${{ matrix.node }}", _actionRunner.DisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
[Trait("Level", "L0")]
|
|
||||||
[Trait("Category", "Worker")]
|
|
||||||
public async void WarnInvalidInputs()
|
|
||||||
{
|
|
||||||
//Arrange
|
|
||||||
Setup();
|
|
||||||
var actionId = Guid.NewGuid();
|
|
||||||
var actionInputs = new MappingToken(null, null, null);
|
|
||||||
actionInputs.Add(new StringToken(null, null, null, "input1"), new StringToken(null, null, null, "test1"));
|
|
||||||
actionInputs.Add(new StringToken(null, null, null, "input2"), new StringToken(null, null, null, "test2"));
|
|
||||||
actionInputs.Add(new StringToken(null, null, null, "invalid1"), new StringToken(null, null, null, "invalid1"));
|
|
||||||
actionInputs.Add(new StringToken(null, null, null, "invalid2"), new StringToken(null, null, null, "invalid2"));
|
|
||||||
var action = new Pipelines.ActionStep()
|
|
||||||
{
|
|
||||||
Name = "action",
|
|
||||||
Id = actionId,
|
|
||||||
Reference = new Pipelines.ContainerRegistryReference()
|
|
||||||
{
|
|
||||||
Image = "ubuntu:16.04"
|
|
||||||
},
|
|
||||||
Inputs = actionInputs
|
|
||||||
};
|
|
||||||
|
|
||||||
_actionRunner.Action = action;
|
|
||||||
|
|
||||||
Dictionary<string, string> finialInputs = new Dictionary<string, string>();
|
|
||||||
_handlerFactory.Setup(x => x.Create(It.IsAny<IExecutionContext>(), It.IsAny<ActionStepDefinitionReference>(), It.IsAny<IStepHost>(), It.IsAny<ActionExecutionData>(), It.IsAny<Dictionary<string, string>>(), It.IsAny<Dictionary<string, string>>(), It.IsAny<Variables>(), It.IsAny<string>()))
|
|
||||||
.Callback((IExecutionContext executionContext, Pipelines.ActionStepDefinitionReference actionReference, IStepHost stepHost, ActionExecutionData data, Dictionary<string, string> inputs, Dictionary<string, string> environment, Variables runtimeVariables, string taskDirectory) =>
|
|
||||||
{
|
|
||||||
finialInputs = inputs;
|
|
||||||
})
|
|
||||||
.Returns(new Mock<IHandler>().Object);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
await _actionRunner.RunAsync();
|
|
||||||
|
|
||||||
foreach (var input in finialInputs)
|
|
||||||
{
|
|
||||||
_hc.GetTrace().Info($"Input: {input.Key}={input.Value}");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
Assert.Equal("test1", finialInputs["input1"]);
|
|
||||||
Assert.Equal("test2", finialInputs["input2"]);
|
|
||||||
Assert.Equal("github", finialInputs["input3"]);
|
|
||||||
Assert.Equal("invalid1", finialInputs["invalid1"]);
|
|
||||||
Assert.Equal("invalid2", finialInputs["invalid2"]);
|
|
||||||
|
|
||||||
_ec.Verify(x => x.AddIssue(It.Is<Issue>(s => s.Message.Contains("Unexpected input 'invalid1'")), It.IsAny<string>()), Times.Once);
|
|
||||||
_ec.Verify(x => x.AddIssue(It.Is<Issue>(s => s.Message.Contains("Unexpected input 'invalid2'")), It.IsAny<string>()), Times.Once);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Setup([CallerMemberName] string name = "")
|
private void Setup([CallerMemberName] string name = "")
|
||||||
{
|
{
|
||||||
_ecTokenSource?.Dispose();
|
_ecTokenSource?.Dispose();
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
2.169.0
|
2.169.1
|
||||||
|
|||||||
Reference in New Issue
Block a user