Skip to content

Commit 4cc3727

Browse files
committed
This is not the first commit message you're looking for
0 parents  commit 4cc3727

File tree

7 files changed

+330
-0
lines changed

7 files changed

+330
-0
lines changed

LICENSE

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
The MIT License (MIT)
2+
=====================
3+
4+
Copyright © 2021, Matheus Cunha
5+
6+
Permission is hereby granted, free of charge, to any person
7+
obtaining a copy of this software and associated documentation
8+
files (the “Software”), to deal in the Software without
9+
restriction, including without limitation the rights to use,
10+
copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the
12+
Software is furnished to do so, subject to the following
13+
conditions:
14+
15+
The above copyright notice and this permission notice shall be
16+
included in all copies or substantial portions of the Software.
17+
18+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
19+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25+
OTHER DEALINGS IN THE SOFTWARE.

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h1 align="center">GitHub Actions self-hosted Runner Ansible role</h1>
2+
3+
Work In Progress.
4+
5+
All-in-all the features of this Ansible role are implemented just not
6+
documented and well-presented yet. Ansible Galaxy repository import and
7+
documentation about the variables are on its way.
8+
9+
To-dos:
10+
11+
- [ ] Improve this README with variables + instructions;
12+
- [ ] Import to Ansible Galaxy;
13+
- [ ] Add CI using molecule;
14+
- [ ] Integrate GitHub actions to run the CI;
15+
- [ ] Add Code lint (YAML lint + ansible lint) on CI;
16+
- [ ] Include documentation

defaults/main.yaml

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
# Temporary path to download the GitHub Actions runner archive
3+
tmp_download_path: /tmp
4+
5+
# Whether or not to clean the downloaded package in the temporary path after
6+
# unpacking/installing it.
7+
tmp_clear_download: true
8+
9+
# Base URL to fetch the GitHub Actions Runner package with scripts that is used
10+
# to install and configure the host.
11+
gh_runner_download_base_url: https://github.com/actions/runner/releases/download
12+
13+
# GitHub Actions runner version to download and install. Multiple parallel
14+
# versions are supported since every installation+configuration (either
15+
# repository or organization) has its own path.
16+
gh_runner_version: 2.285.0
17+
18+
# GitHub Actions runner architecture, used together with the version to compose
19+
# the complete URL that is used to download the package.
20+
gh_runner_architecture: linux-x64
21+
22+
# Path to unarchive the GitHub Actions runner package, this will be the prefix
23+
# with multiple versions inside. Allowing to share the same host with many
24+
# self-hosted runners regardless of the version.
25+
gh_runner_installation_path: /usr/local/share/github-actions-runner
26+
27+
# GitHub Actions runner workspace, i.e. path used by job executions to checkout
28+
# the code, write files from the workflow, and etc.
29+
gh_runner_workspace_path: /var/cache/github-actions-runner
30+
31+
# Whether or not to remove the GitHub Actions runner, enable to clean and
32+
# deregister the host. Enable this to remove the host from GitHub Actions and
33+
# complement with the --tag uninstall
34+
gh_runner_remove_host: false
35+
36+
## Variables used to set parameters to the `config.sh` script.
37+
38+
# (REQUIRED) GitHub Actions repository URL to register this self-hosted runner.
39+
# gh_runner_config_url: ""
40+
41+
# (REQUIRED) GitHub Actions self-hosted Runner registration token, used to
42+
# authenticate the host to GitHub (either to a GitHub repository or to an GitHub
43+
# organization). Keep this value secure, e.g. using Ansible Vault.
44+
# Ref: https://docs.github.com/en/actions/hosting-your-own-runners/adding-self-hosted-runners
45+
# gh_runner_config_token: ""
46+
47+
# Define the Github Actions Runner tags, this list will be converted to a
48+
# comma-separated string
49+
gh_runner_config_labels: ["self-hosted"]

includes/download.yaml

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
- name: GitHub Actions Runner | Create workspace
3+
file:
4+
path: "{{ gh_runner_workspace_path }}"
5+
state: directory
6+
mode: 0755
7+
become: true
8+
9+
- name: GitHub Actions Runner | Check if versions is already installed
10+
stat:
11+
path: "{{ gh_runner_path }}"
12+
register: unarchived_package
13+
14+
# Download the package only if it isn't found in the installed versions
15+
- block:
16+
- name: GitHub Actions Runner | Download package
17+
get_url:
18+
url: "{{ gh_runner_download_base_url }}/v{{ gh_runner_version }}/actions-runner-{{ gh_runner_architecture }}-{{ gh_runner_version }}.tar.gz"
19+
dest: "{{ tmp_download_path }}/actions-runner-{{ gh_runner_version }}.tar.gz"
20+
mode: 0400
21+
force: yes
22+
become: true
23+
24+
- name: GitHub Actions Runner | Create installation directory
25+
file:
26+
path: "{{ gh_runner_path }}"
27+
state: directory
28+
mode: 0755
29+
become: true
30+
31+
- name: GitHub Actions Runner | Unarchive package
32+
unarchive:
33+
src: "{{ tmp_download_path }}/actions-runner-{{ gh_runner_version }}.tar.gz"
34+
dest: "{{ gh_runner_path }}"
35+
remote_src: true
36+
register: gh_runner_path_unarchived
37+
become: true
38+
39+
- name: GitHub Actions Runner | Set permissions
40+
file:
41+
path: "{{ gh_runner_path }}"
42+
owner: "{{ ansible_user_id }}"
43+
mode: 0755
44+
recurse: true
45+
become: true
46+
47+
# Remove the package after extracting the content IF tmp_clear_download is
48+
# enabled (default: true).
49+
- name: GitHub Actions Runner | Remove archived package
50+
file:
51+
path: "{{ tmp_download_path }}/actions-runner-{{ gh_runner_version }}.tar.gz"
52+
state: absent
53+
become: true
54+
when: tmp_clear_download
55+
56+
when: not unarchived_package.stat.exists

includes/install.yaml

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
- name: GitHub Actions Runner | Install dependencies
3+
shell:
4+
cmd: "{{ gh_runner_path }}/bin/installdependencies.sh"
5+
chdir: "{{ gh_runner_path }}"
6+
become: true
7+
when:
8+
# Only install dependencies if the installation directory contains changes,
9+
# which is indicated in this case by the `unarchive` task.
10+
- gh_runner_path_unarchived is defined
11+
- gh_runner_path_unarchived.changed
12+
tags:
13+
- install
14+
15+
# Check if the registration token was used before. config.sh executions aren't
16+
# idempotent, if called twice with the very same token and URL it will fail
17+
# asking to remove the host before configuring it.
18+
#
19+
# ["Cannot configure the runner because it is already configured. To
20+
# reconfigure the runner, run 'config.cmd remove' or './config.sh remove' first."]
21+
- name: GitHub Actions Runner | Check if this host+URL was already registered
22+
stat:
23+
path: "{{ gh_runner_path }}/hosts/{{ gh_runner_config_token | hash('sha256') }}"
24+
register: is_this_host_registered
25+
tags:
26+
- configure
27+
28+
- name: GitHub Actions Runner | Search for abandoned credentials
29+
stat:
30+
path: "{{ gh_runner_path }}/.credentials"
31+
register: abandoned_credentials
32+
33+
# Search only if the host is not registered, which is a clear indicator that
34+
# any credentials inside that path are from previous executions, since the
35+
# registration token is not matching any state file.
36+
when: not is_this_host_registered.stat.exists
37+
38+
- name: GitHub Actions Runner | Remove previous configuration before proceeding
39+
shell:
40+
cmd: >-
41+
{{ gh_runner_path }}/config.sh remove \
42+
--token {{ gh_runner_config_token }}
43+
chdir: "{{ gh_runner_path }}"
44+
45+
when:
46+
# So, if abandoned credentials are found AND this host is not registered, we
47+
# need to remove it before proceeding, otherwise the `config.sh` command to
48+
# register the node will fail asking to remove it (which we are proactively
49+
# doing here).
50+
- not is_this_host_registered.stat.exists
51+
- abandoned_credentials is defined
52+
- abandoned_credentials.stat.exists
53+
54+
tags:
55+
- configure
56+
57+
- name: GitHub Actions Runner | Configure Runner
58+
shell:
59+
cmd: >-
60+
{{ gh_runner_path }}/config.sh \
61+
--unattended --replace \
62+
--url {{ gh_runner_config_url }} \
63+
--token {{ gh_runner_config_token }} \
64+
--name {{ ansible_hostname }} \
65+
--work {{ gh_runner_workspace_path }} \
66+
--labels {{ gh_runner_config_labels | join(',') }}
67+
chdir: "{{ gh_runner_path }}"
68+
register: config_host_command
69+
70+
when: not is_this_host_registered.stat.exists
71+
tags:
72+
- configure
73+
74+
- name: GitHub Actions Runner | Check if path for state files exists
75+
stat:
76+
path: "{{ gh_runner_path }}/hosts"
77+
register: registered_hosts_path
78+
tags:
79+
- configure
80+
81+
- name: GitHub Actions Runner | Create hosts directory
82+
file:
83+
path: "{{ gh_runner_path }}/hosts"
84+
state: directory
85+
owner: "{{ ansible_user_id }}"
86+
mode: 0755
87+
become: true
88+
when: not registered_hosts_path.stat.exists
89+
tags:
90+
- configure
91+
92+
# Create a state file to notify next Ansible executions that a given
93+
# registration token was already used. i.e. the is_this_host_registered variable
94+
# registered and used in the credential above.
95+
- name: GitHub Actions Runner | Create state file
96+
file:
97+
path: "{{ gh_runner_path }}/hosts/{{ gh_runner_config_token | hash('sha256') }}"
98+
state: touch
99+
mode: 0400
100+
when:
101+
- config_host_command is defined
102+
- config_host_command is success
103+
become: true
104+
tags:
105+
- configure
106+
107+
- name: GitHub Actions Runner | Install service
108+
shell:
109+
cmd: "{{ gh_runner_path }}/svc.sh install"
110+
chdir: "{{ gh_runner_path }}"
111+
become: true
112+
when: not is_this_host_registered.stat.exists
113+
tags:
114+
- install
115+
116+
- name: GitHub Actions Runner | Start service
117+
shell:
118+
cmd: "{{ gh_runner_path }}/svc.sh start"
119+
chdir: "{{ gh_runner_path }}"
120+
become: true
121+
tags:
122+
- configure

includes/uninstall.yaml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
- name: GitHub Actions Runner [!!] DESTROY! | De-register Runner
3+
shell:
4+
cmd: >-
5+
{{ gh_runner_path }}/config.sh \
6+
remove --token "{{ gh_runner_config_token }}"
7+
chdir: "{{ gh_runner_path }}"
8+
become: true
9+
10+
- name: GitHub Actions Runner [!!] DESTROY! | Stop service
11+
shell:
12+
cmd: "{{ gh_runner_path }}/svc.sh uninstall"
13+
chdir: "{{ gh_runner_path }}"
14+
become: true
15+
16+
- name: GitHub Actions Runner [!!] DESTROY! | Delete workspace and installations
17+
file:
18+
state: absent
19+
path: "{{ item }}"
20+
with_items:
21+
- "{{ gh_runner_installation_path }}/"
22+
- "{{ gh_runner_workspace_path }}/"
23+
become: true

tasks/main.yaml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
- name: Variables | Check mandatory
3+
assert:
4+
that:
5+
- gh_runner_config_url is defined
6+
- gh_runner_config_token is defined
7+
8+
- name: Variables | Set installation path
9+
set_fact:
10+
# Set a exclusive path for the GitHub Actions Runner in order to support
11+
# multiple repository or organizations configured inside the same host.
12+
#
13+
# WHY? `config.sh` when registering the host will write some credentials and
14+
# files to the path in order to identify the host, although inoffensive,
15+
# this approach make it complicated to share the same host among multiple
16+
# GitHub Actions Runners (even though it is possible).
17+
#
18+
# Therefore, each GitHub repository or organization URL will be hashed to
19+
# compose the GitHub Actions Runner path.
20+
gh_runner_path: "{{ gh_runner_installation_path }}/{{ gh_runner_version }}/{{ gh_runner_config_url | hash('sha256') }}"
21+
22+
tags:
23+
- install
24+
- configure
25+
- uninstall
26+
27+
- import_tasks: "../includes/download.yaml"
28+
tags:
29+
- install
30+
31+
- import_tasks: "../includes/install.yaml"
32+
tags:
33+
- install
34+
- configure
35+
36+
- import_tasks: "../includes/uninstall.yaml"
37+
when: gh_runner_remove_host
38+
tags:
39+
- uninstall

0 commit comments

Comments
 (0)