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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ out/
**/target/
**/node_modules/
**/frontend/generated/

### environment ###
.env
112 changes: 102 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

# CI/CD course

This course will guide you through setting up and using a pipeline GitHub Actions and Google Cloud services that serves as a fundation in a CI/CD setup for a demoapplication. Below are detailed instructions for cloning the course code, setting up your local environment, configuring and integrating accounts, and deploying infrastructure and applications.
---


## Setup 1

Expand All @@ -12,13 +13,17 @@ This course will guide you through setting up and using a pipeline GitHub Action
- Install helpful extensions: Docker and Git.

2. **Git (if that is not already on your computer)**

- Download and install from: [https://git-scm.com/](https://git-scm.com/)
- Configure Git with your name and email:

```bash
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
git config --global user.name "<Your Name>"
git config --global user.email "<your.email@example.com>"
```

- Verify Git installation:

```bash
git --version
```
Expand All @@ -31,41 +36,64 @@ This course will guide you through setting up and using a pipeline GitHub Action

Start by creating a fork of this repository under your own GitHub account. From there you can
experiment freely

- Go to [the course reporitory](https://github.com/sodalabsab/cicdcourse.git)
- Select "Fork" to create your own disconnected version of the course code repository
- Marke sure to uncheck "Copy the main branch only" there is a branch in there we will use later
- Make sure to uncheck "Copy the main branch only" there is a branch in there we will use later
- Name the repository "cicdcourse" click on "Create fork"

5. **Download the repository locally**
- Go to the newly created repo in your github account and click on the green "<>Code" button. Copy the SSH URL and open a comand shell on your computer. Paste in this command to create a local repository (connected to the github repository)

```bash
git clone git@github.com:<your-username>/cicdcourse.git
```

- Replace `<your-username>` with your GitHub username.
- Change directory into the repo:

```bash
cd cicdcourse
```

- Verify the repo with the command

```bash
git remote -v
```
You sould see something like: `origin git@github.com:<your usernam>/cicdcourse.git (push)`
```

You should see something like: `origin git@github.com:<your usernam>/cicdcourse.git (push)`

6. **Docker (requires local admin)**
In orders to setup a local development environemt - we are using docker desktop as execution plattform. If you are not able to install docker because of local admin rights, you can still take part of lab 2-4.
- Donload and install from: [https://www.docker.com/products/docker-desktop](https://www.docker.com/products/docker-desktop)
- Download and install Docker Desktop:
- Docker for Windows or Mac [https://www.docker.com/get-started/](https://www.docker.com/get-started/)
- On Linux [https://docs.docker.com/desktop/setup/install/linux/](https://docs.docker.com/desktop/setup/install/linux/)
- Ensure Docker is running and verify installation:

```bash
# Verify that docker is installed
docker --version
# Verify that docker is running
docker info
```

You should see lots of information about the docker environment running on your machine.
7. **Open the code in VS Code**

VS code is a great universal IDE with many plugins that helps develop applications efficiently. For this course you will only need the bare minimum, but we encurage to explore and learn as much as possible. Most of the things in booth GitHub and Google cloud can be done directly from the IDE.

- Start VS Code and open the directory by selecting "Open folder..." from the File meny

**or**

- Navigate to the folder through terminal and enter:

```bash
# start Visual studio code in current directory
code .
```

### This is the end of the first setup session
Now the course will continue with some more slides

Expand Down Expand Up @@ -195,12 +223,76 @@ this reveals the URL for your personal dashboard - go to it and register your cl
That´s it for lab 2!

## Lab 3 - Setup a local runner
Follow the instructions on this page to download and setup a local runner on your comupter:
https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners
Instead of following the instructions on how to download and setup a local runner on your computer found [here](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners)

We will take a more platform agnostic path due ot the fact that we already have docker environment up and running. This guide will help you setup and understand the process of deploying a repository specific runner, which means your other repositories does not have access to it.

To begin with we need to create a .env file locally where we store variables, go ahead and rename the `envTemplate` file to `.env` one in the github-runner directory.

Populate the `IMAGE` variable with a name, for example *github-runner:local*, `USERNAME` with your github username and `REPOSITORY` with the current repository name.
The `TARGETPLATFORM` variable should be either **arm64** (Apple Mac) or **x64** (PC).

After this we need to visit GitHub UI and set up an Personal Access Token.

1. First navigate to Your profile -> Settings -> Developer settings -> Personal access tokens -> Fine-grained tokens
2. Select Generate Token
3. Give the token a name and description as you see fit, make sure the resource owner is set to your username, incase you are part of an organization
4. Select expiration and what access you want it to have, select *All repositories*
5. In the Repository permissions set Actions and Administration to read & write
6. Click generate token.
7. Copy and Save the token to your .env file for `ACCESS_TOKEN`.

Now view the `Dockerfile`, `docker-compose.yml` and `start.sh` and read the explanations on what is going on in these files.

When we have done this we need to prepare and *source* the .env file to the local environment.

```bash
# Navigate to the github-runner directory
# For Mac users, download dos2unix() to deal with line endings problem:
brew install dos2unix
# Or any other package manager if you are on Linux to install dos2unix
# Run it on the .env file to ensure line ending compability:
dos2unix .env

#Sourcing the .env to the local environment variables:
source .env
```
Or windows powershell:

```powershell
# Dealing with the line ending issues:
(Get-Content .env -Raw).Replace("`r`n", "`n") | Set-Content -NoNewline .env

# For windows users that are not using GitBash, use the following in Powershell:
# To source the .env file to environment
Get-Content .env | ForEach-Object { $env:$($_.Split('=')[0]) = $_.Split('=')[1] }
```

Now we are ready to build and deploy the runners in a docker setting by using the following commands:

```bash


# Build the image using multiarch to adhere to ARM64 architecture
# Tag and send it to the artifact repository
docker build --build-arg TARGETPLATFORM=${TARGETPLATFORM} -t ${IMAGE} .

# Deploy the image
docker-compose up -d

# And pull down the deployment and execute the cleanup script that unregisters the runner
docker-compose down
```

Now visit your repository on GitHub.
Enter Settings -> Actions -> Runners

And you should now see your runner with the name "docker-runner-<short-sha>"

- Open the workflow definition for the demo application ./github/workflows/demo-application.yml
You can do it locally in VS Code or directly in the GitHub UI.
- Change

Change:
```bash
jobs:
build-and-unittest:
Expand Down
59 changes: 59 additions & 0 deletions github-runner/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

FROM debian:bookworm-slim

# This first line is required to support multi-arch builds
ARG TARGETPLATFORM

# Here we define the version of the GitHub Actions Runner.
# The version is set to 2.321.0 but it will update to the latest minor.
ARG RUNNER_VERSION="2.321.0"
ARG DEBIAN_FRONTEND=noninteractive

# We add a docker user to the environment
RUN useradd -m docker

# We use debian package manager to install required packages
# We also install some nice to have packages like curl, jq, git, etc.
RUN apt-get update -y && \
apt-get install -y --no-install-recommends \
curl=7.88.1-10+deb12u12 \
ca-certificates=20230311 \
jq=1.6-2.1 \
dos2unix=7.4.3-1 \
git=1:2.39.5-0+deb12u2 \
libssl-dev=3.0.15-1~deb12u1 \
libffi-dev=3.4.4-1 \
python3=3.11.2-1+b1 \
python3-venv=3.11.2-1+b1 \
python3-pip=23.0.1+dfsg-1 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# We set the working directory to /home/docker/actions-runner
WORKDIR /home/docker/actions-runner

# We fetch the latest version of the GitHub Actions Runner and install it
# We also install the dependencies required to run the runner
# We set the ownership to the docker user and group
# Finally we remove the tarball to save space on the image.
RUN curl -O -L https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${TARGETPLATFORM}-${RUNNER_VERSION}.tar.gz && \
tar xzf ./actions-runner-linux-${TARGETPLATFORM}-${RUNNER_VERSION}.tar.gz && \
rm -f ./actions-runner-linux-${TARGETPLATFORM}-${RUNNER_VERSION}.tar.gz && \
chown -R docker ~docker /home/docker && \
/home/docker/actions-runner/bin/installdependencies.sh

# We copy the start.sh script to the image and set the ownership to the docker user and group
COPY --chown=docker:docker start.sh /home/docker/start.sh

# We set the permissions to execute the script and convert it to unix format
# We run dos2unix to convert the script to unix format to avoid issues with line endings
RUN chmod +x /home/docker/start.sh && \
dos2unix /home/docker/start.sh

# We switch to the docker user so the user does not have access to the root
# We also set the working directory to /home/docker
USER docker
WORKDIR /home/docker

# We set the entrypoint to the start.sh script
ENTRYPOINT ["./start.sh"]
66 changes: 66 additions & 0 deletions github-runner/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## Lab 3 - Setup a local runner
Instead of following the instructions on how to download and setup a local runner on your computer found [here](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners)

We will take a more platform agnostic path due ot the fact that we already have docker environment up and running. This guide will help you setup and understand the process of deploying a repository specific runner, which means your other repositories does not have access to it.

To begin with we need to create a .env file locally where we store variables, go ahead and rename the `envTemplate` file to `.env` one in the github-runner directory.

Populate the `IMAGE` variable with a name, for example *github-runner:local*, `USERNAME` with your github username and `REPOSITORY` with the current repository name.
The `TARGETPLATFORM` variable should be either **arm64** (Apple Mac) or **x64** (PC).

After this we need to visit GitHub UI and set up an Personal Access Token.

1. First navigate to Your profile -> Settings -> Developer settings -> Personal access tokens -> Fine-grained tokens
2. Select Generate Token
3. Give the token a name and description as you see fit, make sure the resource owner is set to your username, incase you are part of an organization
4. Select expiration and what access you want it to have, select *All repositories*
5. In the Repository permissions set Actions and Administration to read & write
6. Click generate token.
7. Copy and Save the token to your .env file for `ACCESS_TOKEN`.

Now view the `Dockerfile`, `docker-compose.yml` and `start.sh` and read the explanations on what is going on in these files.

When we have done this we need to prepare and *source* the .env file to the local environment.

```bash
# Navigate to the github-runner directory
# For Mac users, download dos2unix() to deal with line endings problem:
brew install dos2unix
# Or any other package manager if you are on Linux to install dos2unix
# Run it on the .env file to ensure line ending compability:
dos2unix .env

#Sourcing the .env to the local environment variables:
source .env
```
Or windows powershell:

```powershell
# Dealing with the line ending issues:
(Get-Content .env -Raw).Replace("`r`n", "`n") | Set-Content -NoNewline .env

# For windows users that are not using GitBash, use the following in Powershell:
# To source the .env file to environment
Get-Content .env | ForEach-Object { $env:$($_.Split('=')[0]) = $_.Split('=')[1] }
```

Now we are ready to build and deploy the runners in a docker container by using the following commands:

```bash


# Build the image using multiarch to adhere to ARM64 architecture
# Tag and send it to the artifact repository
docker build --build-arg TARGETPLATFORM=${TARGETPLATFORM} -t ${IMAGE} .

# Deploy the image
docker-compose up -d

# And pull down the deployment and execute the cleanup script that unregisters the runner
docker-compose down
```

Now visit your repository on GitHub.
Enter Settings -> Actions -> Runners

And you should now see your runner with the name "docker-runner-<short-sha>"
25 changes: 25 additions & 0 deletions github-runner/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This file utilizes environment variables to populate the variables needed.
services:
runner:
image: ${IMAGE}
restart: always
# The environment variables are passed to the container at runtime.
environment:
- USERNAME=${USERNAME}
- REPOSITORY=${REPOSITORY}
- ACCESS_TOKEN=${ACCESS_TOKEN}
# GitHub runners can only run one job at a time.
# If you want more jobs to run simultaniously and your hardware permits
# you can run multiple runners by changing replicas.
deploy:
mode: replicated
replicas: 1
# The following resources are to be considered as a "small" runner setup
# Feel free to adjust the resources to your needs.
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
5 changes: 5 additions & 0 deletions github-runner/envTemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
IMAGE=<image-name:tag>
USERNAME=<your-username>
REPOSITORY=<your-repository-name>
ACCESS_TOKEN=<your-github-token>
TARGETPLATFORM=<arm64_or_x64>
41 changes: 41 additions & 0 deletions github-runner/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

# Generates a unique short-sha from the date and provided info,
# needed to keep runner names unique in case of multiple runners running on the same host.
generate_hash() {
echo "${USERNAME}-${REPOSITORY}-$(date +%s.%N)-${RANDOM}" | md5sum | head -c 8
}

# Creates a URL for registering the runner with the provided org/repo.
REG_URL="https://api.github.com/repos/${USERNAME}/${REPOSITORY}/actions/runners/registration-token"

# Creates the name of the runner using the hash method.
RUNNER_NAME="docker-runner-$(generate_hash)"

# Creates a registration token for the runner using the GitHub API with the url created above and the ACCESS_TOKEN provided in the .env.
REG_TOKEN=$(curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"${REG_URL}" | jq .token --raw-output)

# Navigates to the actions runner directory where the runner is installed by the Dockerfile.
cd /home/docker/actions-runner || exit

# Configures and registres the runner with the provided URL, token,
# and name using the config.sh script file provided from GitHub.
./config.sh --url "https://github.com/${USERNAME}/${REPOSITORY}" --token "${REG_TOKEN}" --name "${RUNNER_NAME}"

# Maintenance script using the same config.sh to unregister the runner.
cleanup() {
echo "Removing runner..."
./config.sh remove --unattended --token "${REG_TOKEN}"
}

trap 'cleanup; exit 130' INT
trap 'cleanup; exit 143' TERM

# Starts the runner using the run.sh script provided from GitHub.
# The wait command is used to keep the script running until the runner is stopped.
./run.sh & wait $!
Loading