Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ jobs:
| `location` | | Name of Location to create Server in. | `nbg1` (Nürnberg 1) |
| `mode` | ✓ (always) | Choose either `create` to create a new GitHub Actions Runner or `delete` to delete a previously created one. | |
| `name` | ✓ (mode `delete`, optional for mode `create`) | The name for the server and label for the GitHub Actions Runner (must be unique within the project and conform to hostname rules: `^[a-zA-Z0-9_-]{1,64}`). | `gh-runner-[RANDOM-INT]` |
| `network` | | Network ID (integer) which should be attached to the Server private network interface at the creation time. | `null` |
| `network` | | Comma separated Network IDs (integer) which should be attached to the Server private network interface at the creation time. | `null` |
| `pre_runner_script` | | Specifies bash commands to run before the GitHub Actions Runner starts. It's useful for installing dependencies with apt-get, dnf, zypper etc. | |
| `primary_ipv4` | | ID (integer) of the IPv4 Primary IP to use. If omitted and `enable_ipv4` is true, a new IPv4 Primary IP will automatically be created. | `null` |
| `primary_ipv6` | | ID (integer) of the IPv6 Primary IP to use. If omitted and `enable_ipv6` is true, a new IPv6 Primary IP will automatically be created. | `null` |
Expand All @@ -169,8 +169,8 @@ jobs:
| `server_id` | ✓ (mode `stop`) | ID (integer) of Hetzner Cloud Server to delete. | |
| `server_type` | | Name of the Server type this Server should be created with. | `cx23` (Intel x86, 2 vCPU, 4GB RAM, 40GB SSD) |
| `server_wait` | | Wait up to `server_wait` retries (10 sec each) for the Hetzner Cloud Server to start. | `30` (5 min) |
| `ssh_key` | | SSH key ID (integer) which should be injected into the Server at creation time. | `null` |
| `volume` | | Specify a Volume ID (integer) to attach and mount to the Server during creation. The volume will be automatically mounted at `/mnt/HC_Volume_[VOLUME-ID]`. The volume must be in the same location as the Server. More details in [Volumes section](#Volumes). | `null` |
| `ssh_key` | | Comma separated SSH key IDs (integer) which should be injected into the Server at creation time. | `null` |
| `volume` | | Comma separated Volume IDs (integer) to attach and mount to the Server during creation. Volumes will be automatically mounted at `/mnt/HC_Volume_[VOLUME-ID]`. Volumes must be in the same location as the Server. More details in [Volumes section](#Volumes). | `null` |

## Outputs

Expand Down
75 changes: 45 additions & 30 deletions action.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ function exit_with_failure() {
exit 1
}

# Function to check all values of a comma separated list are integers
function check_all_integers() {
IFS=',' read -ra _values <<< "$1"
for value in "${_values[@]}"; do
if [[ ! "$value" =~ ^[0-9]+$ ]]; then
echo "$value"
return 1
fi
done
return 0
}

# Define required commands
MY_COMMANDS=(
base64
Expand Down Expand Up @@ -150,11 +162,12 @@ if [[ "$MY_NAME" == "hetzner" ]]; then
fi

# Set the network for the instance (default: null)
# If INPUT_NETWORK is set, use its value; otherwise, use "null".
MY_NETWORK=${INPUT_NETWORK:-"null"}
# Check if MY_NETWORK is an integer
if [[ "$MY_NETWORK" != "null" && ! "$MY_NETWORK" =~ ^[0-9]+$ ]]; then
exit_with_failure "The network ID must be 'null' or an integer!"
# If INPUT_NETWORKS is set, use its value; otherwise, use "null".
MY_NETWORKS=${INPUT_NETWORKS:-"null"}
if [[ "$MY_NETWORKS" != "null" ]]; then
invalid_value=$(check_all_integers "$MY_NETWORKS") || {
exit_with_failure "Invalid network ID: $invalid_value (must be 'null' or an integer)"
}
fi

# Set bash commands to run before the runner starts.
Expand Down Expand Up @@ -219,19 +232,21 @@ if [[ ! "$MY_SERVER_WAIT" =~ ^[0-9]+$ ]]; then
fi

# Set the SSH key to use for the instance (default: null)
# If INPUT_SSH_KEY is set, use its value; otherwise, use "null".
MY_SSH_KEY=${INPUT_SSH_KEY:-"null"}
# Check if MY_SSH_KEY is an integer
if [[ "$MY_SSH_KEY" != "null" && ! "$MY_SSH_KEY" =~ ^[0-9]+$ ]]; then
exit_with_failure "The SSH key ID must be 'null' or an integer!"
# If INPUT_SSH_KEYS is set, use its value; otherwise, use "null".
MY_SSH_KEYS=${INPUT_SSH_KEYS:-"null"}
if [[ "$MY_SSH_KEYS" != "null" ]]; then
invalid_value=$(check_all_integers "$MY_SSH_KEYS") || {
exit_with_failure "Invalid SSH key ID: $invalid_value (must be 'null' or an integer)"
}
fi

# Set the volume ID which should be attached to the instance at the creation time (default: null)
# If INPUT_VOLUME is set, use its value; otherwise, use "null".
MY_VOLUME=${INPUT_VOLUME:-"null"}
# Check if MY_VOLUME is an integer
if [[ "$MY_VOLUME" != "null" && ! "$MY_VOLUME" =~ ^[0-9]+$ ]]; then
exit_with_failure "The volume ID must be 'null' or an integer!"
# If INPUT_VOLUMES is set, use its value; otherwise, use "null".
MY_VOLUMES=${INPUT_VOLUMES:-"null"}
if [[ "$MY_VOLUMES" != "null" ]]; then
invalid_value=$(check_all_integers "$MY_VOLUMES") || {
exit_with_failure "Invalid volume ID: $invalid_value (must be 'null' or an integer)"
}
fi

#
Expand Down Expand Up @@ -292,7 +307,7 @@ if [[ "$MY_MODE" == "delete" ]]; then
echo "GitHub Actions Runner deleted successfully."
echo
echo "The Hetzner Cloud Server and its associated GitHub Actions Runner have been deleted successfully."
# Add GitHub Action job summary
# Add GitHub Action job summary
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#adding-a-job-summary
echo "The Hetzner Cloud Server and its associated GitHub Actions Runner have been deleted successfully 🗑️" >> "$GITHUB_STEP_SUMMARY"
exit 0
Expand Down Expand Up @@ -377,23 +392,23 @@ if [[ "$MY_PRIMARY_IPV6" != "null" ]]; then
jq ".public_net.ipv6 = $MY_PRIMARY_IPV6" < create-server-ipv6.json > create-server.json && \
echo "Primary IPv6 ID added to create-server.json."
fi
# Add network configuration to the create-server.json file if MY_NETWORK is not "null".
if [[ "$MY_NETWORK" != "null" ]]; then
# Add network configuration to the create-server.json file if MY_NETWORKS is not "null".
if [[ "$MY_NETWORKS" != "null" ]]; then
cp create-server.json create-server-network.json && \
jq ".networks += [$MY_NETWORK]" < create-server-network.json > create-server.json && \
echo "Network added to create-server.json."
jq ".networks += [$MY_NETWORKS]" < create-server-network.json > create-server.json && \
echo "Networks added to create-server.json."
fi
# Add SSH key configuration to the create-server.json file if MY_SSH_KEY is not "null".
if [[ "$MY_SSH_KEY" != "null" ]]; then
# Add SSH key configuration to the create-server.json file if MY_SSH_KEYS is not "null".
if [[ "$MY_SSH_KEYS" != "null" ]]; then
cp create-server.json create-server-ssh.json && \
jq ".ssh_keys += [$MY_SSH_KEY]" < create-server-ssh.json > create-server.json && \
echo "SSH key added to create-server.json."
jq ".ssh_keys += [$MY_SSH_KEYS]" < create-server-ssh.json > create-server.json && \
echo "SSH keys added to create-server.json."
fi
# Add volume configuration to the create-server.json file if MY_VOLUME is not "null".
if [[ "$MY_VOLUME" != "null" ]]; then
# Add volume configuration to the create-server.json file if MY_VOLUMES is not "null".
if [[ "$MY_VOLUMES" != "null" ]]; then
cp create-server.json create-server-volume.json && \
jq ".volumes += [$MY_VOLUME]" < create-server-volume.json > create-server.json && \
echo "Volume added to create-server.json."
jq ".volumes += [$MY_VOLUMES]" < create-server-volume.json > create-server.json && \
echo "Volumes added to create-server.json."
fi

# Send a POST request to the Hetzner Cloud API to create a server.
Expand Down Expand Up @@ -508,9 +523,9 @@ if [[ ! "$MY_GITHUB_RUNNER_ID" =~ ^[0-9]+$ ]]; then
fi

echo
echo "The Hetzner Cloud Server and its associated GitHub Actions Runner are ready for use."
echo "The Hetzner Cloud Server and its associated GitHub Actions Runner are ready for use."
echo "Runner: https://github.com/${MY_GITHUB_REPOSITORY}/settings/actions/runners/${MY_GITHUB_RUNNER_ID}"
# Add GitHub Action job summary
# Add GitHub Action job summary
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#adding-a-job-summary
echo "The Hetzner Cloud Server and its associated [GitHub Actions Runner](https://github.com/${MY_GITHUB_REPOSITORY}/settings/actions/runners/${MY_GITHUB_RUNNER_ID}) are ready for use 🚀" >> "$GITHUB_STEP_SUMMARY"
exit 0
12 changes: 6 additions & 6 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ inputs:
required: false
network:
description: >-
Network ID (integer) which should be attached to the Server private network interface at the creation time.
Comma separated Network IDs (integer) which should be attached to the Server private network interface at the creation time.
required: false
default: 'null'
pre_runner_script:
Expand Down Expand Up @@ -109,12 +109,12 @@ inputs:
default: '30'
ssh_key:
description: >-
SSH key ID (integer) or name which should be injected into the Server at creation time.
Comma separated SSH key IDs (integer) which should be injected into the Server at creation time.
required: false
default: 'null'
volume:
description: >-
Volume ID (integer) which should be attached to the Server at the creation time.
Comma separated Volume IDs (integer) which should be attached to the Server at the creation time.
required: false
default: 'null'

Expand Down Expand Up @@ -148,7 +148,7 @@ runs:
INPUT_LOCATION: ${{ inputs.location }}
INPUT_MODE: ${{ inputs.mode }}
INPUT_NAME: ${{ inputs.name }}
INPUT_NETWORK: ${{ inputs.network }}
INPUT_NETWORKS: ${{ inputs.network }}
INPUT_PRE_RUNNER_SCRIPT: ${{ inputs.pre_runner_script }}
INPUT_PRIMARY_IPV4: ${{ inputs.primary_ipv4 }}
INPUT_PRIMARY_IPV6: ${{ inputs.primary_ipv6 }}
Expand All @@ -158,5 +158,5 @@ runs:
INPUT_SERVER_ID: ${{ inputs.server_id }}
INPUT_SERVER_TYPE: ${{ inputs.server_type }}
INPUT_SERVER_WAIT: ${{ inputs.server_wait }}
INPUT_SSH_KEY: ${{ inputs.ssh_key }}
INPUT_VOLUME: ${{ inputs.volume }}
INPUT_SSH_KEYS: ${{ inputs.ssh_key }}
INPUT_VOLUMES: ${{ inputs.volume }}