Skip to content

Commit d542206

Browse files
committed
Update README.md to support registration of GitHub Enterprise Cloud level runners
1 parent 20673df commit d542206

File tree

2 files changed

+124
-114
lines changed

2 files changed

+124
-114
lines changed

README.md

+19-14
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ This application is designed for controlling multi [self-hosted GitHub Action ru
1515
- Simple as more as possible, single Bash script.
1616
- Lightweight wrapper of official self-hosted runner.
1717
- Both *github.com* and *GitHub Enterprise* are support.
18-
- Both *organization* and *repository* level runners are supported.
18+
- Either *organization* or *repository* or *GitHub Cloud Enterprise* level runners are supported.
1919

2020
## Usage
2121

2222
```plain
2323
mr.bash - https://github.com/vbem/multi-runners
2424
2525
Environment variables:
26-
MR_GIHUB_BASEURL=https://github.com
27-
MR_GIHUB_API_BASEURL=https://api.github.com
26+
MR_GITHUB_BASEURL=https://github.com
27+
MR_GITHUB_API_BASEURL=https://api.github.com
2828
MR_RELEASE_URL=<latest on github.com/actions/runner/releases>
29-
MR_USER_BASE=/home
30-
MR_GITHUB_PAT=github_pat_***
29+
MR_USER_BASE=<default in /etc/default/useradd>
30+
MR_GITHUB_PAT=***
3131
3232
Sub-commands:
3333
add Add one self-hosted runner on this host
@@ -43,14 +43,15 @@ Sub-commands:
4343
e.g. ./mr.bash pat2token --org SOME_OWNER --repo SOME_REPO
4444
4545
Options:
46-
--org GitHub organization name
47-
--repo GitHub repository name, registration on organization-level if empty
48-
--user Linux local username of runner
49-
--labels Extra labels for the runner
50-
--group Runner group for the runner
51-
--token Runner registration token, takes precedence over MR_GITHUB_PAT
52-
--dotenv The lines to set in runner's '.env' files
53-
-h --help Show this help.
46+
--enterprise GitHub Cloud Enterprise name, optional
47+
--org GitHub organization name
48+
--repo GitHub repository name, registration on organization-level if empty
49+
--user Linux local username of runner
50+
--labels Extra labels for the runner
51+
--group Runner group for the runner
52+
--token Runner registration token, takes precedence over MR_GITHUB_PAT
53+
--dotenv The lines to set in runner's '.env' files
54+
-h --help Show this help.
5455
```
5556

5657
### Download this application
@@ -98,7 +99,11 @@ If limited by slow download speed, you can also manually download it to `/tmp/`,
9899

99100
### GitHub Enterprise Server editions
100101

101-
*GitHub Enterprise Server* editions usually have different server and API URL prefixes comparing with *github.com*, you can set them in environment variables `MR_GIHUB_BASEURL` and `MR_GIHUB_API_BASEURL`.
102+
*GitHub Enterprise Server* editions usually have different server and API URL prefixes comparing with *github.com*, you can set them in environment variables `MR_GITHUB_BASEURL` and `MR_GITHUB_API_BASEURL`.
103+
104+
### GitHub Enterprise Cloud level registration
105+
106+
For *GitHub Enterprise Cloud* level registration, you can specify the `--enterprise` option to set the *GitHub Enterprise Cloud* name.
102107

103108
### Setup multi-runners on single host
104109

mr.bash

+105-100
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ declare -rg MR_GITHUB_PAT
2121
# download URL of actions runner release, defaults to latest release on GitHub.com
2222
declare -rg MR_RELEASE_URL
2323
# baseurl of GitHub API, defaults to https://api.github.com
24-
declare -rg MR_GIHUB_API_BASEURL="${MR_GIHUB_API_BASEURL:-https://api.github.com}"
24+
declare -rg MR_GITHUB_API_BASEURL="${MR_GITHUB_API_BASEURL:-https://api.github.com}"
2525
# baseurl of GitHub service, defaults to https://github.com
26-
declare -rg MR_GIHUB_BASEURL="${MR_GIHUB_BASEURL:-https://github.com}"
26+
declare -rg MR_GITHUB_BASEURL="${MR_GITHUB_BASEURL:-https://github.com}"
2727
# runners' local username prefix, defaults to `runner-`
2828
declare -rg MR_USER_PREFIX="${MR_USER_PREFIX:-runner-}"
2929
# runners' local users base directory, overrides the `HOME` setting in `/etc/default/useradd`
@@ -53,12 +53,12 @@ function log::_ {
5353
&& pos="/$each$pos"
5454
done
5555
case "$1" in
56-
FATAL) color="5;1;91" ;;
57-
ERR*) color="1;91" ;;
58-
WARN*) color="95" ;;
59-
INFO* | NOTICE) color="92" ;;
60-
DEBUG) color="94" ;;
61-
*) color="96" ;;
56+
FATAL) color="5;1;91" ;;
57+
ERR*) color="1;91" ;;
58+
WARN*) color="95" ;;
59+
INFO* | NOTICE) color="92" ;;
60+
DEBUG) color="94" ;;
61+
*) color="96" ;;
6262
esac
6363
datetime="\e[3;2;90m$(date -Isecond)\e[0m"
6464
pos="\e[3;90m${pos:1}\e[0m"
@@ -110,40 +110,40 @@ function run::exists {
110110
done
111111
}
112112

113-
# Check if varible values of given varible names are not empty
114-
# $@: varible names
113+
# Check if any variable value of given variable names is not empty
114+
# $@: variable names
115115
# $?: 0 if non-empty and non-zero otherwise
116-
function str::varNotEmpty {
116+
function str::anyVarNotEmpty {
117117
local each=''
118118
for each in "$@"; do
119119
[[ -n "${!each}" ]]
120120
log::failed $? "Var '$each' is empty!" || return $?
121121
done
122122
}
123123

124-
# Check if any varible value of given varible names are not empty
125-
# $@: varible names
124+
# Check if any variable value of given variable names are not empty
125+
# $@: variable names
126126
# $?: 0 if non-empty and non-zero otherwise
127-
function str::varsNotEmpty {
127+
function str::allVarsNotEmpty {
128128
local each=''
129129
for each in "$@"; do
130130
[[ -n "${!each}" ]] && return
131131
done
132-
log::failed 1 "Vars '$@' are all empty!" || return $?
132+
log::failed 1 "Vars $* are all empty!" || return $?
133133
}
134134

135-
# Check if varible value of given varible name is IN subsequent arguments
136-
# $1: varible name
135+
# Check if variable value of given variable name is IN subsequent arguments
136+
# $1: variable name
137137
# $N: arguments as candidate set
138138
# $?: 0 if it's in and non-zero otherwise
139139
function str::varIn {
140140
local varName="$1" varVal="${!1}" each=''
141141
shift
142-
str::varNotEmpty varName || return $?
142+
str::anyVarNotEmpty varName || return $?
143143
for each in "$@"; do
144144
[[ "$each" == "$varVal" ]] && return
145145
done
146-
log::_ ERROR "Invalid value '$varVal' for varible '$varName'!"
146+
log::_ ERROR "Invalid value '$varVal' for variable '$varName'!"
147147
return 1
148148
}
149149

@@ -184,13 +184,16 @@ function mr::nproc {
184184
# https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/monitoring-and-troubleshooting-self-hosted-runners#checking-self-hosted-runner-network-connectivity
185185
# https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/autoscaling-with-self-hosted-runners#authentication-requirements
186186
# https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
187-
# $1: organization
188-
# $2: repository, registration on organization if empty
187+
# $1: enterprise
188+
# $2: organization
189+
# $3: repository, registration on organization if empty
190+
# $?: 0 if successful and non-zero otherwise
191+
# stdout: registration token
189192
function mr::pat2token {
190193
run::exists jq || return $?
191194
local enterprise="$1" org="$2" repo="$3" api='' middle='' res=''
192-
str::varNotEmpty MR_GITHUB_PAT || return $?
193-
str::varsNotEmpty org enterprise || return $?
195+
str::anyVarNotEmpty MR_GITHUB_PAT || return $?
196+
str::allVarsNotEmpty org enterprise || return $?
194197

195198
if [[ -n "$enterprise" ]]; then
196199
middle="enterprises/$enterprise"
@@ -199,7 +202,7 @@ function mr::pat2token {
199202
else
200203
middle="repos/$org/$repo"
201204
fi
202-
api="$MR_GIHUB_API_BASEURL/$middle/actions/runners/registration-token"
205+
api="$MR_GITHUB_API_BASEURL/$middle/actions/runners/registration-token"
203206

204207
log::_ DEBUG "Calling API: $api"
205208
res="$(curl -Lsm 3 --retry 1 \
@@ -246,17 +249,18 @@ function mr::downloadRunner {
246249

247250
# Add GitHub Actions Runner by local username
248251
# $1: username, optional
249-
# $2: organization
250-
# $3: repository, optional
251-
# $4: runner registration token, optional
252-
# $5: extra labels, optional
253-
# $6: group, defaults to `default`
254-
# $7: lines to set in runner's '.env' files, optional
252+
# $2: enterprise
253+
# $3: organization
254+
# $4: repository, optional
255+
# $5: runner registration token, optional
256+
# $6: extra labels, optional
257+
# $7: group, defaults to `default`
258+
# $8: lines to set in runner's '.env' files, optional
255259
# $?: 0 if successful and non-zero otherwise
256260
function mr::addRunner {
257261
local user="$1" enterprise="$2" org="$3" repo="$4" token="$5" extraLabels="$6" group="${7:-default}" dotenv="$8" tarpath=''
262+
str::allVarsNotEmpty enterprise org || return $?
258263

259-
str::varsNotEmpty enterprise org || return $?
260264
tarpath="$(mr::downloadRunner)" || return $?
261265
[[ -z "$token" ]] && { token="$(mr::pat2token "$enterprise" "$org" "$repo")" || return $?; }
262266
user="$(mr::addUser "$user")" || return $?
@@ -265,20 +269,20 @@ function mr::addRunner {
265269

266270
local labels="controller:${MR_URL#https://},username:$user,hostname:$HOSTNAME"
267271
[[ -r /etc/os-release ]] && labels="$labels,os:$(source /etc/os-release && echo "$ID-$VERSION_ID")"
268-
[[ -n "$repo" ]] && labels="$labels,$org/$repo" || labels="$labels,$org"
269272
[[ -n "$extraLabels" ]] && labels="$labels,$extraLabels"
270273

274+
local url=''
271275
if [[ -n "$enterprise" ]]; then
272-
middle="enterprises/$enterprise"
276+
url="$MR_GITHUB_BASEURL/enterprises/$enterprise"
277+
labels="$labels,$enterprise"
273278
elif [[ -z "$repo" ]]; then
274-
middle="orgs/$org"
279+
url="$MR_GITHUB_BASEURL/orgs/$org"
280+
labels="$labels,$org"
275281
else
276-
middle="repos/$org/$repo"
282+
url="$MR_GITHUB_BASEURL/repos/$org/$repo"
283+
labels="$labels,$org/$repo"
277284
fi
278285

279-
local url=''
280-
url="$MR_GIHUB_BASEURL/$middle"
281-
282286
log::_ INFO "Adding runner into local user '$user' for $url"
283287
run::logFailed sudo su --login "$user" -- -eo pipefail <<-__
284288
mkdir -p runner/mr.d && cd runner/mr.d
@@ -297,19 +301,20 @@ __
297301

298302
# Delete GitHub Actions Runner by local username
299303
# $1: username
300-
# $2: organization, optional
301-
# $3: repository, optional
302-
# $4: runner registration token, optional
304+
# $2: enterprise, optional
305+
# $3: organization, optional
306+
# $4: repository, optional
307+
# $5: runner registration token, optional
303308
# $?: 0 if successful and non-zero otherwise
304309
function mr::delRunner {
305310
local user="$1" enterprise="$2" org="$3" repo="$4" token="$5"
306-
str::varNotEmpty user || return $?
311+
str::anyVarNotEmpty user || return $?
307312

308313
if [[ -z "$token" ]]; then
309-
[[ -z "$enterprise" ]] && enterprise="$(run::logFailed sudo -Hiu "$user" -- cat runner/mr.d/org)"
314+
[[ -z "$enterprise" ]] && enterprise="$(run::logFailed sudo -Hiu "$user" -- cat runner/mr.d/enterprise)"
310315
[[ -z "$org" ]] && org="$(run::logFailed sudo -Hiu "$user" -- cat runner/mr.d/org)"
311316
[[ -z "$repo" ]] && repo="$(run::logFailed sudo -Hiu "$user" -- cat runner/mr.d/repo)"
312-
token="$(mr::pat2token "$org" "$repo")"
317+
token="$(mr::pat2token "$enterprise" "$org" "$repo")"
313318
fi
314319

315320
log::_ INFO "Deleting runner and local user '$user'"
@@ -350,8 +355,8 @@ function mr::test {
350355
HELP="$FILE_THIS - $MR_URL
351356
352357
Environment variables:
353-
MR_GIHUB_BASEURL=$MR_GIHUB_BASEURL
354-
MR_GIHUB_API_BASEURL=$MR_GIHUB_API_BASEURL
358+
MR_GITHUB_BASEURL=$MR_GITHUB_BASEURL
359+
MR_GITHUB_API_BASEURL=$MR_GITHUB_API_BASEURL
355360
MR_RELEASE_URL=${MR_RELEASE_URL:-<latest on github.com/actions/runner/releases>}
356361
MR_USER_BASE=${MR_USER_BASE:-<default in /etc/default/useradd>}
357362
MR_GITHUB_PAT=${MR_GITHUB_PAT::11}${MR_GITHUB_PAT:+***}
@@ -370,7 +375,7 @@ Sub-commands:
370375
e.g. ${BASH_SOURCE[0]} pat2token --org SOME_OWNER --repo SOME_REPO
371376
372377
Options:
373-
--enterprise GitHub Enterprise name
378+
--enterprise GitHub Cloud Enterprise name, optional
374379
--org GitHub organization name
375380
--repo GitHub repository name, registration on organization-level if empty
376381
--user Linux local username of runner
@@ -395,66 +400,66 @@ function mr::main {
395400

396401
while true; do
397402
case "$1" in
398-
-h | --help) echo -n "$HELP" && return ;;
399-
--enterprise)
400-
enterprise="$2"
401-
shift 2
402-
;;
403-
--org)
404-
org="$2"
405-
shift 2
406-
;;
407-
--repo)
408-
repo="$2"
409-
shift 2
410-
;;
411-
--user)
412-
user="$2"
413-
shift 2
414-
;;
415-
--labels)
416-
labels="$2"
417-
shift 2
418-
;;
419-
--token)
420-
token="$2"
421-
shift 2
422-
;;
423-
--group)
424-
group="$2"
425-
shift 2
426-
;;
427-
--dotenv)
428-
dotenv+="$2"$'\n'
429-
shift 2
430-
;;
431-
--)
432-
shift
433-
break
434-
;;
435-
*)
436-
log::_ ERROR "Invalid option '$1'! See '$FILE_THIS help'."
437-
return 255
438-
;;
403+
-h | --help) echo -n "$HELP" && return ;;
404+
--enterprise)
405+
enterprise="$2"
406+
shift 2
407+
;;
408+
--org)
409+
org="$2"
410+
shift 2
411+
;;
412+
--repo)
413+
repo="$2"
414+
shift 2
415+
;;
416+
--user)
417+
user="$2"
418+
shift 2
419+
;;
420+
--labels)
421+
labels="$2"
422+
shift 2
423+
;;
424+
--token)
425+
token="$2"
426+
shift 2
427+
;;
428+
--group)
429+
group="$2"
430+
shift 2
431+
;;
432+
--dotenv)
433+
dotenv+="$2"$'\n'
434+
shift 2
435+
;;
436+
--)
437+
shift
438+
break
439+
;;
440+
*)
441+
log::_ ERROR "Invalid option '$1'! See '$FILE_THIS help'."
442+
return 255
443+
;;
439444
esac
440445
done
441446

442447
# parse sub-commands into functions
443448
subCmd="$1"
444449
shift
445450
case "$subCmd" in
446-
add) mr::addRunner "$user" "$enterprise" "$org" "$repo" "$token" "$labels" "$group" "$dotenv" ;;
447-
del) mr::delRunner "$user" "$enterprise" "$org" "$repo" "$token" ;;
448-
list) mr::listRunners ;;
449-
status) mr::statusRunner "$user" ;;
450-
download) mr::downloadRunner ;;
451-
pat2token) mr::pat2token "$enterprise" "$org" "$repo" ;;
452-
help | '') echo -n "$HELP" >&2 ;;
453-
test) mr::test "$@" ;;
454-
*)
455-
log::_ ERROR "Invalid command '$1'! See '$FILE_THIS help'."
456-
return 255
457-
;;
451+
add) mr::addRunner "$user" "$enterprise" "$org" "$repo" "$token" "$labels" "$group" "$dotenv" ;;
452+
del) mr::delRunner "$user" "$enterprise" "$org" "$repo" "$token" ;;
453+
list) mr::listRunners ;;
454+
status) mr::statusRunner "$user" ;;
455+
download) mr::downloadRunner ;;
456+
pat2token) mr::pat2token "$enterprise" "$org" "$repo" ;;
457+
help | '') echo -n "$HELP" >&2 ;;
458+
test) mr::test "$@" ;;
459+
*)
460+
log::_ ERROR "Invalid command '$1'! See '$FILE_THIS help'."
461+
return 255
462+
;;
458463
esac
459464
}
460465

0 commit comments

Comments
 (0)