Gitea Self-Hosted Workflow Action For CI

mortylenmortylen
9 min read

In this short tutorial I would like to describe the installation and setup of CI/CD Actions for a self-hosted Gitea server running on an Ubuntu. I will describe a script for testing and compiling code written in C# in a Visual Studio environment. I decided to separate the Actions server to a separate Ubuntu server instance for easier administration and to keep running processes from overwhelming the standalone git server. Anyway, it is possible to run Actions on the same server as Gitea, or to run Runners in Dockers. I described the installation and setup of a self-hosted git server in the previous article Gitea Self-Hosted Action Ubuntu Server. All the steps described below assume that you already have Gitea (Git-Server) installed.

Gitea Actions consists of several components. For our purpose, it is enough to know that we need ActRunner to run Actions. Like other CI Runners, ActRunner is designed to run independently on another server. It can be run using Docker or directly on the host. In this guide I will focus on running with the Docker engine. More information can be found on the official Gitea website.

Docker

The first component we will need is Docker. Using Docker we will later start ActRunner. For more information about installing Docker, see the official guide.

Let's do this.

  1. Update local packaged:

    $ sudo apt update

  2. Allow APT to access repositories via the HTTPS orotocol:

    $ sudo apt install apt-transport-https ca-certificates curl software-properties-common

  3. Add the Docket GNU Privacy Guard key to the APT keyring:

    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

  4. Add the Docker repository to the APT package manager:

    $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"

  5. Prepare an installation from a Docker repository:

    $ apt-cache policy docker-ce

  6. Install Docker:

    $ sudo apt install docker-ce

  7. Check the status of the Docket service:

    $ sudo systemctl status docker

Docker status

  1. Enable Docker to start automatically on system boot:

    $ sudo systemctl enable docker

  2. Adding an account to a Docker group:

    $ sudo usermod -aG docker ${USER}

  3. Set permissions to run the service.

    $ sudo chmod +x /var/run/docker.sock

Act Runner

Once we have Docker up and running, we can start installing ActRunner. In order for ActRunner to run on a separate server, or in a separate container, and connect to a correct Gitea instance, we need to register it with a token.

  1. Download the current version of ActRunner using wget. Replace the URL with the desired version. We recommend opting for the latest version. Here's an example for 64-bit Linux, version 0.2.10. For the full list, visit https://dl.gitea.com/act_runner/:
$ sudo wget -O act_runner https://dl.gitea.com/act_runner/0.2.10/act_runner-0.2.10-linux-amd64
$ sudo chmod +x act_runner
  1. Check the version of ActRunner:

    $ ./act_runner --version

ActRunner version

  1. ActRunner registration is important for the Runner to know for which Gitea instance to run the jobs. For this you need to generate a token. Gitea provides three levels of tokens:
  • Instance level: The admin settings page, like <your_gitea.com>/admin/actions/runners.

  • Organization level: The organization settings page, like <your_gitea.com>/org/settings/actions/runners.

  • Repository level: The repository settings page, like <your_gitea.com>/settings/actions/runners.

You can find your token on Gitea <your_gitea.com>/admin/actions/runners under Create new runner. Or separately for each repository <your_gitea.com>/settings/actions/runners under Create new runner.

Gitea Create new Ranner

Instead of <INSTANCE> enter your own URL and instead of <TOKEN> enter your own token:

$ ./act_runner register --no-interactive --instance <INSTANCE> --token <TOKEN>

For Example:

$ ./act_runner register --no-interactive --instance http://192.168.52.130:3000 --token MyAyfw5v4i8hwVGZR9NXjW0ikIHOXXXXXXXXXXXX

Gitea Runner Register

  1. After registration, all you have to do is launch ActRunner using Daemon:

    $ sudo ./act_runner daemon

Start Runner

You should now see the service tunning in the Gitea web environment.

Gitea web ranner list

If you want the service to start automatically after rebootong the server, write a simple bash script and add it to Crontab:

  1. Create a file and insert the following script into it. Change the <USER> to your administrator account or choose any other location to store the file:

    $ nano /home/<USER>/start_act_runner.sh

  2. Insert the script into the created file and edit the path to act_runner if it is different:

#!/bin/sh
sleep 60        # waiting for all services to be started
cd /home/<USER>
./act_runner daemon
  1. Enable the execution rule of our new script:

    $ sudo chmod +x /home/<USER>/start_act_runner.sh

  2. Open and edit Crontab:

    $ crontab -e

  3. Adding an instruction to the Crontab. Ensures that the script is run after the server restarts. Change <USER> to the administrator account or location where you saved the script:

    @reboot /home/<USER>/start_act_runner.sh

Crontab Add Rule

Write Workflow Action

Now that everything is set up and the Runner is running, we can create a script to automate the building and testing of source code written in the Visual Studio environment.

We'll start by creating a simple console application for testing. In this application, we'll write a basic class, such as MyMath, which will contain a function to add two numbers.

public class MyMath
{
    public double Add(double num1, double num2)
    {
        return num1 + num2;
    }
}

Next, we will add a new NUnit Test Project to our solution. Left-click on your Solution and select Add -> New Project. Visual Studio will automatically install all the necessary NUnit packages. In the newly created NUnit test project, we will add a dependency on our console application to access the MyMath class. Now, we can write a simple test for our mathematical function.

VS Add NUnit project

namespace TestProject1
{
    public class Tests
    {
        private MyMath _myMath;

        [SetUp]
        public void Setup()
        {
            _myMath = new MyMath();
        }

        [TestCase(100000.0, 10.1, 100010.1)]
        [TestCase(-100000.0, -10.1, -100010.1)]
        [TestCase(0.0, 0.0, 0.0)]
        [Description("Verifies that the MyMath.Add() function works correctly with real numbers.")]
        public void MyMath_Add_RealNumber(double number1, double number2, double expected)
        {
            // Act
            double result = _myMath.Add(number1, number2);
            // Assert
            Assert.That(expected, Is.EqualTo(result), $"Not Correct: ({number1}) + ({number2})");
        }
    }
}

Don't forget to add dependency to your test project. As shown, three test cases are performed. The first test case checks positive numbers, the second tests negative numbers, and the last one tests zero. If the function calculates correctly, the test should pass.

You can try to run your test in Visual Studio.

VS Run tests

Now for the interesting part. We will create a new repository on Gitea and link it to the project in Visual Studio. After that, we simply push the project to Gitea. With the foundation in place, we can start writing the action to run the automated testing.

All actions must be stored in the .gitea/workflows folder in our repository. Actions are written in YAML format, and any file with the yaml suffix placed in .gitea/workflows/ will be automatically executed.

Let's create the following action, name it for example nunit_test.yaml, and save it in the .gitea/workflows/ directory of the repository:

Gitea new workflow action

name: Testing Example
on:
  push:
    branches:
      - master

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository code
        uses: actions/checkout@v4

      - name: Setup dotnet
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: '8.0.x'

      - name: Restore dependencies
        run: dotnet restore

      - name: Build app
        run: dotnet build -c Release --no-restore

      - name: Run automated tests
        run: dotnet test -c Release --no-build

The first line name: Testing Example is the name of the workflow. We can name the workflow action as it suits us.

on:             # The trigger for this workflow.
  push:         # Push event, it is run whenever someone makes a push.
    branches:   # Filter for a specific branche. You can skip it if you want to run action for each branche.
      - master

The jobs: section represents a group of tasks that will run sequentially. In this case, the job is named build-and-test. The runs-on: attribute specifies the operating system for the job.

Steps Breakdown

  1. Check out the repository code: It's always a good idea to check out the source code of your repository within your workflow at the beginning.
- name: Check out repository code
  uses: actions/checkout@v4
  1. Set up the .NET SDK environment: Ensure the correct version of the .NET SDK is installed for the next steps. Specify your required version(s).
- name: Setup dotnet
  uses: actions/setup-dotnet@v3
  with:
    dotnet-version: '8.0.x'
  1. Restore dependencies: Execute shell commands directly from the script using the run command. The dotnet restore command will ensure that all required dependencies and NuGet packages are downloaded and restored.
- name: Restore dependencies
  run: dotnet restore
  1. Build the application: Build the source code to check if the compiler finds any errors in the code.
- name: Run automated tests
  run: dotnet build -c Release --no-restore
  1. Run the automated tests: Execute the tests you wrote.
- name: Run automated tests
  run: dotnet test -c Release --no-build

Enhancing the Workflow

To improve the workflow, we can log the test results and upload them as an artifact. Rewrite the test execution and add another step to the job, specifying your own path to the generated file.

- name: Generate test report
  run: dotnet test -c Release --no-build --logger "html;logfilename=test_results.html"

- name: Upload report as artifact
  uses: actions/upload-artifact@v3
  with:
    name: test-reports
    path: ${{ gitea.workspace }}/TestProject1/TestResults/test_results.html

Test Workflow Action

If we have both the console project and the test project stored in the Gitea repository and our workflow action is ready, the next step is to test it. Let's make a change to our code, commit the changes, and push them to the master branch of the repository. Then, in the Gitea web interface, we will see the action running.

Gitea run workflow action

Conclusion

With Gitea up and running, we added Docker to our setup to facilitate containerized environments, which streamline development and deployment processes. We then configured a Gitea Actions runner using Docker, allowing us to automate our build and test workflows. To demonstrate of this setup, we created a simple console application in Visual Studio, wrote a basic MyMath class, and then added an NUnit Test Project to test our code. We crafted a Gitea workflow action to automatically build and test our application whenever changes are pushed to the repository. By following these steps, we have created self-hosted Git server environment that supports automated testing and continuous integration.

With your Gitea server fully operational, you can now enjoy the benefits of a self-hosted Git solution, customize it to fit your team's needs, and continue to expand its capabilities with additional workflows and integrations. May your code bring you joy!

For more details on configuring Gitea and other settings, be sure to check out my article Gitea Self-Hosted Action Ubuntu Server.

๐Ÿ“ท Cover photo by Yancy Min


๐Ÿ‘‰ My github profileGitHub

๐Ÿ‘‰ My blog pageHashnode

10
Subscribe to my newsletter

Read articles from mortylen directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

mortylen
mortylen

I have many years of experience in the field of IT. Currently, I am employed as a software developer, where I specialize in developing applications for industries, and internal company applications and systems. My alternative contact: mortyleninfo@gmx.com Bitecoin donation address: bc1qnnq2l9ug6wkymy8c5nwer9dm95n50nx32u6f77