Skip to content

Commit

Permalink
das-110: Add script to setup a github runner on project (#113)
Browse files Browse the repository at this point in the history
* das-110: Add script to setup a github runner on project

* das-110: add das runner doc

* das-110: Github Runner doc
  • Loading branch information
levisingularity authored Oct 21, 2024
1 parent 36b2cb7 commit fcb5f16
Show file tree
Hide file tree
Showing 3 changed files with 263 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ build-semver:

publish-semver:
@docker image push trueagi/das:semantic-versioning

github-runner:
@bash $(CURDIR)/scripts/github-runner/main.sh
98 changes: 98 additions & 0 deletions docs/das-runner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# GitHub Self-Hosted Runner Setup Guide

This guide walks through the steps required to configure a self-hosted GitHub Actions runner for projects in the `singnet` organization using the `github-runner` script.

## Script Overview

The script automates the process of:
1. Connecting to a remote server (using either password or SSH key authentication).
2. Fetching the list of GitHub repositories.
3. Selecting a repository to configure the runner for.
4. Installing the GitHub Actions runner on the server.
5. Configuring the runner and creating a `systemd` service to manage it.

## Pre-requisites

Before running the script, ensure the following:
1. The `gh` CLI is installed and authenticated with GitHub.
- You can install the `gh` CLI by following [this link](https://cli.github.com/).
2. You have SSH access to the server where the runner will be installed.
3. `jq` is installed on the local machine to parse JSON responses.

### Installing `gh` and `jq`

```bash
# Install GitHub CLI
sudo apt install gh

# Install jq
sudo apt install jq
```

## Usage Instructions

### 1. Running the Script

Start the script with the following command:

```bash
make github-runner
```

### 2. Enter Server Details

The script will prompt you for the following details:
- **Server IP:** The IP address of the server where the GitHub runner will be installed.
- **Username:** The username for SSH access to the server.

### 3. Authentication Method

Select the method to authenticate on the server:
- **1) Password:** Use a password for SSH.
- **2) Private Key:** Use a private key for SSH.

Depending on your choice, you will either be prompted for your password or the path to your SSH private key.

### 4. Fetching Repositories

The script will use the `gh` CLI to list all repositories in the `singnet` organization. It will display the list, and you can select the repository for which the runner will be configured.

### 5. Installing Runner on the Server

After selecting the project, the script will:
- Create a folder on the server to hold the GitHub Actions runner files.
- Download and extract the GitHub Actions runner software.
- Set the correct permissions for the runner files.

### 6. Retrieving Runner Token

The script will generate a registration token required to link the runner to the selected GitHub repository. This step is handled via the GitHub CLI.

### 7. Configuring the Runner on the Server

The runner is configured on the remote server by executing the necessary setup commands, such as linking it to the chosen repository and setting up the `systemd` service for automatic management.

### 8. Creating a Systemd Service

The script creates a `systemd` service file on the server to manage the GitHub Actions runner as a service. This allows the runner to automatically start on boot and restart if it crashes.

### 9. Commands for Managing the Runner

Once the runner is set up, you can use the following commands on the server to manage it:

- **Start the runner:**
```bash
sudo systemctl start <runner-service-name>
```

- **Check the runner status:**
```bash
sudo systemctl status <runner-service-name>
```

- **Stop the runner:**
```bash
sudo systemctl stop <runner-service-name>
```

Replace `<runner-service-name>` with the actual name of the service, which is derived from the project name (e.g., `myproject-runner`).
162 changes: 162 additions & 0 deletions scripts/github-runner/main.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/bin/bash

GITHUB_USER="singnet"

function get_server_details() {
read -p "Enter the Server IP: " SERVER_IP
read -p "Enter the Username: " USERNAME
}

function select_auth_method() {
echo "Choose the authentication method:"
echo "1) Password"
echo "2) Private Key"
read -p "Enter your choice [1-2]: " AUTH_METHOD
}

function ask_credentials() {
if [ "$AUTH_METHOD" == "1" ]; then
read -s -p "Enter your password: " PASSWORD
echo
else
read -e -p "Enter the path to your private key: " PRIVATE_KEY
fi
}

function fetch_github_repositories() {
if ! command -v gh &> /dev/null; then
echo "'gh' CLI is not installed. Please install it from 'https://cli.github.com'."
return 1
fi

REPOS=$(gh repo list "$GITHUB_USER" --limit 100 --json name,sshUrl -q '.[] | "\(.name)"')

if [ -z "$REPOS" ]; then
echo "No repositories found for user/organization: $GITHUB_USER."
return 1
else
echo "$REPOS"
fi
}

function select_project() {
PROJECTS=$(fetch_github_repositories)

if [ $? -ne 0 ]; then
echo "Unable to fetch repositories. Exiting..."
exit 1
fi

IFS=$'\n' read -r -d '' -a PROJECT_ARRAY <<< "$PROJECTS"

echo "Select the project:"
select PROJECT in "${PROJECT_ARRAY[@]}"; do
if [ -n "$PROJECT" ]; then
break
else
echo "Invalid choice. Please select a project."
fi
done
}

function execute_commands_on_server() {
local commands="$1"
local ssh_command
ssh_command=$( [[ "$AUTH_METHOD" == "1" ]] && echo "sshpass -p '$PASSWORD'" || echo "ssh -i '$PRIVATE_KEY'" )
ssh_command+=" -o StrictHostKeyChecking=no $USERNAME@$SERVER_IP"

eval "$ssh_command '$commands'"
}

function install_runner_requirements_on_server() {
remote_commands="
sudo mkdir -p $RUNNER_FOLDER_PATH && cd $RUNNER_FOLDER_PATH;
sudo chmod -R 775 $RUNNER_FOLDER_PATH;
sudo chown -R root:github-runner $RUNNER_FOLDER_PATH;
curl -o actions-runner-linux-x64-2.320.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.320.0/actions-runner-linux-x64-2.320.0.tar.gz;
tar --strip-components=1 -xzf ./actions-runner-linux-x64-2.320.0.tar.gz;
"

execute_commands_on_server "$remote_commands"
}

function get_runner_token() {
if ! command -v gh &> /dev/null; then
echo "'gh' CLI is not installed. Please install it with 'https://cli.github.com'."
exit 1
fi

if ! gh auth status &> /dev/null; then
echo "Authenticating with GitHub..."
gh auth login
fi

REPO_URL="https://github.com/$GITHUB_USER/$PROJECT"
TOKEN=$(gh api -X POST "repos/$GITHUB_USER/$PROJECT/actions/runners/registration-token" | jq -r .token)

if [ -z "$TOKEN" ]; then
echo "Failed to retrieve the GitHub Actions runner token."
exit 1
fi
}

function create_github_runner_service() {
remote_commands="sudo tee /etc/systemd/system/${RUNNER_FOLDER_NAME}.service > /dev/null <<EOF
[Unit]
Description=GitHub Runner Service for ${PROJECT}
After=network.target
[Service]
User=ubuntu
WorkingDirectory=${RUNNER_FOLDER_PATH}
ExecStart=${RUNNER_FOLDER_PATH}/run.sh
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload;
sudo systemctl enable ${RUNNER_FOLDER_NAME};
sudo systemctl start ${RUNNER_FOLDER_NAME};
"

execute_commands_on_server "$remote_commands"
}

function configure_runner_on_server() {
remote_commands="
cd $RUNNER_FOLDER_PATH;
./config.sh --url $REPO_URL --token $TOKEN;
"

execute_commands_on_server "$remote_commands"
}

function main() {
get_server_details
select_auth_method
ask_credentials
select_project

RUNNER_FOLDER_NAME="${PROJECT}-runner"
RUNNER_FOLDER_PATH="/opt/$RUNNER_FOLDER_NAME"

echo "Entered data:"
echo "Server IP: $SERVER_IP"
echo "Username: $USERNAME"
echo "Authentication Method: $( [[ "$AUTH_METHOD" == "1" ]] && echo "Password" || echo "Private Key (Path: $PRIVATE_KEY)" )"
echo "Selected Project: $PROJECT"

echo "Setting up runner on the server..."
install_runner_requirements_on_server

echo "Retrieving GitHub Actions runner token..."
get_runner_token

configure_runner_on_server

create_github_runner_service
echo "Runner setup complete!"
}

main "$@"

0 comments on commit fcb5f16

Please sign in to comment.