Skip to content

Commit 3c08bef

Browse files
committed
Restructure scripts
Update README.md
1 parent 14c6410 commit 3c08bef

File tree

6 files changed

+191
-160
lines changed

6 files changed

+191
-160
lines changed

Dockerfile

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,9 @@ RUN mkdir actions-runner && cd actions-runner \
5050
# Install additional dependencies
5151
RUN chown -R docker ~docker && /home/docker/actions-runner/bin/installdependencies.sh
5252

53-
# Add start script and make it executable
54-
ADD scripts/start.sh start.sh
55-
ADD scripts/detector.sh detector.sh
56-
RUN chmod +x start.sh
57-
RUN chmod +x detector.sh
53+
# Copy ALL scripts make them executable
54+
COPY scripts/* .
55+
RUN chmod +x *.sh
5856

5957
# Set the user to "docker" so all subsequent commands are run as the docker user
6058
USER docker

README.md

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,31 +30,51 @@ docker compose up -d
3030
- **LABELS** - Runner labels (comma separated). Uses `"docker-node,${os_name}-${architecture}"`
3131
- **REUSE_EXISTING** - Re-use existing configuration. Defaults to `false`
3232

33-
> `REUSE_EXISTING` can come in handy when a container restarts due to a problem,
34-
> or when a container is terminated without gracefully shutting down.
33+
> [!NOTE]
34+
> `REUSE_EXISTING` flag can be useful when a container restarts due to an issue or
35+
> when a container is reused after being terminated without shutting down gracefully.
36+
> <details>
37+
> <summary><strong>More info</strong></summary>
38+
>
39+
> Following files/directories are created (commonly across `macOS`, `Linux` and `Windows` runners)
40+
> only when the runner has been configured
41+
> - `_work`
42+
> - `_diag`
43+
> - `.runner`
44+
> - `.credentials`
45+
> - `.credentials_rsaparams`
46+
>
47+
> So, a simple check on one or more of these files' presence should confirm if the runner has been configured already
48+
>
49+
> **Note:** Warnings like the ones below are common, and GitHub typically reconnects the runner automatically.
50+
> ```text
51+
> A session for this runner already exists.
52+
> ```
53+
> ```
54+
> Runner connect error: The actions runner i-058175xh7908r2u46 already has an active session.. Retrying until reconnected.
55+
> ```
56+
> </details>
3557
3658
> [!WARNING]
3759
Using this image **without** the env var `GIT_REPOSITORY` will create an organization level runner.
3860
Using self-hosted runners in public repositories pose some considerable security threats.
3961
> - [#self-hosted-runner-security]
4062
> - [#restricting-the-use-of-self-hosted-runners]
4163
> - [#configuring-required-approval-for-workflows-from-public-forks]
42-
>
43-
> **Author Note:** _Be mindful of the env vars you set when spinning up containers_
4464
4565
<details>
46-
<summary><strong>Env vars for startup notifications</strong></summary>
66+
<summary><strong>Env vars for notifications</strong></summary>
4767
48-
> This project supports [ntfy] and [telegram bot] for startup notifications.
68+
> This project supports [ntfy] and [telegram bot] for startup/shutdown notifications.
4969
5070
**NTFY**
5171
5272
Choose ntfy setup instructions with [basic][ntfy-setup-basic] **OR** [authentication][ntfy-setup-auth] abilities
5373
54-
- **NTFY_USERNAME** - Ntfy username for authentication _(if topic is protected)_
55-
- **NTFY_PASSWORD** - Ntfy password for authentication _(if topic is protected)_
5674
- **NTFY_URL** - Ntfy endpoint for notifications.
5775
- **NTFY_TOPIC** - Topic to which the notifications have to be sent.
76+
- **NTFY_USERNAME** - Ntfy username for authentication _(if topic is protected)_
77+
- **NTFY_PASSWORD** - Ntfy password for authentication _(if topic is protected)_
5878
5979
**Telegram**
6080
@@ -63,16 +83,22 @@ Steps for telegram bot configuration
6383
1. Use [BotFather] to create a telegram bot token
6484
2. Send a test message to the Telegram bot you created
6585
3. Use the URL https://api.telegram.org/bot{token}/getUpdates to get the Chat ID
66-
- You can also use Thread ID to send notifications to a particular thread within a chat window
86+
- You can also use Thread ID to send notifications to a particular thread within a group
6787
6888
```shell
6989
export TELEGRAM_BOT_TOKEN="your-bot-token"
7090
export CHAT_ID=$(curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates" | jq -r '.result[0].message.chat.id')
71-
export THREAD_ID=$(curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates" | jq -r '.result[0]|.update_id')
7291
```
7392
7493
- **TELEGRAM_BOT_TOKEN** - Telegram Bot token
7594
- **TELEGRAM_CHAT_ID** - Chat ID to which the notifications have to be sent.
95+
- **THREAD_ID** - Optional thread ID to send notifications to a specific thread.
96+
97+
> **Note:** To send notifications to threads, the bot should be added to a group with [Topics][telegram-topics] enabled.<br>
98+
> Send a message to the bot in a group thread
99+
> ```shell
100+
> export THREAD_ID=$(curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getUpdates" | jq -r '.result[0]|.update_id')
101+
> ```
76102
77103
</details>
78104
@@ -105,6 +131,8 @@ docker build --build-arg RUNNER_VERSION=$RUNNER_VERSION -t runner .
105131
[ntfy-setup-basic]: https://docs.ntfy.sh/install/
106132
[ntfy-setup-auth]: https://community.home-assistant.io/t/setting-up-private-and-secure-ntfy-messaging-for-ha-notifications/632952
107133
[BotFather]: https://t.me/botfather
134+
[telegram-topics]: https://telegram.org/blog/topics-in-groups-collectible-usernames
135+
[telegram-threads]: https://core.telegram.org/api/threads
108136

109137
[#restricting-the-use-of-self-hosted-runners]: https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#restricting-the-use-of-self-hosted-runners
110138
[#self-hosted-runner-security]: https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#self-hosted-runner-security

scripts/config.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
3+
repo_level_runner() {
4+
# https://docs.github.com/en/rest/actions/self-hosted-runners#create-a-registration-token-for-a-repository
5+
REG_TOKEN=$(curl -sX POST \
6+
-H "Accept: application/vnd.github.v3+json" \
7+
-H "Authorization: Bearer ${GIT_TOKEN}" \
8+
"https://api.github.com/repos/${GIT_OWNER}/${GIT_REPOSITORY}/actions/runners/registration-token" \
9+
| jq .token --raw-output)
10+
cd "/home/docker/actions-runner" || exit 1
11+
./config.sh --unattended \
12+
--work "${WORK_DIR}" \
13+
--labels "${LABELS}" \
14+
--token "${REG_TOKEN}" \
15+
--name "${RUNNER_NAME}" \
16+
--runnergroup "${RUNNER_GROUP}" \
17+
--url "https://github.com/${GIT_OWNER}/${GIT_REPOSITORY}"
18+
}
19+
20+
org_level_runner() {
21+
# https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#restricting-the-use-of-self-hosted-runners
22+
# https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#self-hosted-runner-security
23+
# https://docs.github.com/en/rest/actions/self-hosted-runners#create-a-registration-token-for-an-organization
24+
REG_TOKEN=$(curl -sX POST \
25+
-H "Accept: application/vnd.github.v3+json" \
26+
-H "Authorization: Bearer ${GIT_TOKEN}" \
27+
"https://api.github.com/orgs/${GIT_OWNER}/actions/runners/registration-token" \
28+
| jq .token --raw-output)
29+
cd "/home/docker/actions-runner" || exit 1
30+
./config.sh \
31+
--work "${WORK_DIR}" \
32+
--labels "${LABELS}" \
33+
--token "${REG_TOKEN}" \
34+
--name "${RUNNER_NAME}" \
35+
--runnergroup "${RUNNER_GROUP}" \
36+
--url "https://github.com/${GIT_OWNER}"
37+
}

scripts/notify.sh

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/bin/bash
2+
3+
NOTIFICATION_TITLE="GitHub Actions Runner - Docker Node"
4+
5+
ntfy_fn() {
6+
# Send NTFY notification
7+
body="$1"
8+
9+
if [[ -n "$NTFY_TOPIC" && -n "$NTFY_URL" ]]; then
10+
# Remove trailing '/' if present
11+
# https://github.com/binwiederhier/ntfy/issues/370
12+
NTFY_URL=${NTFY_URL%/}
13+
response=$(curl -s -o /tmp/ntfy -w "%{http_code}" -X POST \
14+
-u "$NTFY_USERNAME:$NTFY_PASSWORD" \
15+
-H "X-Title: ${NOTIFICATION_TITLE}" \
16+
-H "Content-Type: application/x-www-form-urlencoded" \
17+
--data "${body}" \
18+
"$NTFY_URL/$NTFY_TOPIC")
19+
status_code="${response: -3}"
20+
if [ "$status_code" -eq 200 ]; then
21+
log "Ntfy notification was successful"
22+
elif [[ -f "/tmp/ntfy" ]]; then
23+
log "Failed to send ntfy notification"
24+
response_payload="$(cat /tmp/ntfy)"
25+
reason=$(echo "$response_payload" | jq '.error')
26+
# Output the extracted description or the full response if jq fails
27+
if [ "$reason" != "null" ]; then
28+
log "[$status_code]: $reason"
29+
else
30+
log "[$status_code]: $(cat /tmp/ntfy)"
31+
fi
32+
else
33+
log "Failed to send ntfy notification - ${status_code}"
34+
fi
35+
rm -f /tmp/ntfy
36+
else
37+
log "Ntfy notifications is not setup"
38+
fi
39+
}
40+
41+
telegram_fn() {
42+
# Send Telegram notification
43+
body="$1"
44+
45+
if [[ -n "$TELEGRAM_BOT_TOKEN" && -n "$TELEGRAM_CHAT_ID" ]]; then
46+
notification_preference=${DISABLE_TELEGRAM_NOTIFICATION:-false}
47+
48+
# Base JSON payload
49+
message=$(printf "*%s*\n\n%s" "${NOTIFICATION_TITLE}" "${body}")
50+
payload=$(jq -n \
51+
--arg chat_id "$TELEGRAM_CHAT_ID" \
52+
--arg text "$message" \
53+
--arg parse_mode "markdown" \
54+
--arg disable_notification "$notification_preference" \
55+
'{
56+
chat_id: $chat_id,
57+
text: $text,
58+
parse_mode: $parse_mode,
59+
disable_notification: $disable_notification
60+
}')
61+
62+
# Add 'message_thread_id' if TELEGRAM_THREAD_ID is available and not null
63+
if [ -n "$TELEGRAM_THREAD_ID" ]; then
64+
payload=$(echo "$payload" | jq --arg thread_id "$TELEGRAM_THREAD_ID" '. + {message_thread_id: $thread_id}')
65+
fi
66+
67+
response=$(curl -s -o /tmp/telegram -w "%{http_code}" -X POST \
68+
-H 'Content-Type: application/json' \
69+
-d "$payload" \
70+
"https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage")
71+
status_code="${response: -3}"
72+
if [ "$status_code" -eq 200 ]; then
73+
log "Telegram notification was successful"
74+
elif [[ -f "/tmp/telegram" ]]; then
75+
log "Failed to send telegram notification"
76+
response_payload="$(cat /tmp/telegram)"
77+
reason=$(echo "$response_payload" | jq '.description')
78+
# Output the extracted description or the full response if jq fails
79+
if [ "$reason" != "null" ]; then
80+
log "[$status_code]: $reason"
81+
else
82+
log "[$status_code]: $(cat /tmp/telegram)"
83+
fi
84+
else
85+
log "Failed to send telegram notification - ${status_code}"
86+
fi
87+
rm -f /tmp/telegram
88+
else
89+
log "Telegram notifications is not setup"
90+
fi
91+
}

scripts/squire.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
log() {
2+
dt_stamp=$(date -u +"%Y-%m-%d %H:%M:%SZ")
3+
echo "${dt_stamp}: $1"
4+
}
5+
6+
instance_id() {
7+
# Use randomly generated instance IDs (AWS format) as default runner names
8+
letters=$(tr -dc '[:lower:]' < /dev/urandom | head -c 4)
9+
digits=$(tr -dc '0-9' < /dev/urandom | head -c 12)
10+
eid=$(echo "$letters$digits" | fold -w1 | shuf | tr -d '\n')
11+
echo "i-0$eid"
12+
}
13+
14+
cleanup() {
15+
log "Removing runner..."
16+
ntfy_fn "Removing runner: '${RUNNER_NAME}'"
17+
telegram_fn "Removing runner: '${RUNNER_NAME}'"
18+
./config.sh remove --token "${REG_TOKEN}"
19+
}

0 commit comments

Comments
 (0)