Github/Gitea Actions -- notes

The configuration format is similar to Github actions, so that will be nice.

https://blog.gitea.io/2022/12/feature-preview-gitea-actions/

act_runner is written in go, so no need to run nodejs bloat on the runners, saves some precious memory for real tasks to run. This is one of our github actions runners running for one CI, if you have multiple CI loops then add it up.

   2314 khem       20   0  500M 20884 17412 S  0.0  0.0  0:00.48 ./externals/node16/bin/node ./bin/RunnerService.js

Github has a C# running:

Do they also have a Node.js one?

Here is source for Gitea runner:

Looks like it is based on:

A Go app to run Github actions locally – neat stuff!

This is really neat – you can write gitea actions in Go:

To enable actions, add the following to your configuration file:

[actions]
ENABLED=true

Then, when you log into Gitea, you will see a new “Runners” section in the admin page:

Another article on Gitea Actions:

Security considerations

One thing we sometimes want to do is run an action on our own runner – especially if we are doing Yocto builds or something. However, Github provides this advice:

We recommend that you only use self-hosted runners with private repositories.

This makes sense as pull requests can insert malicious commands into the workflow file that would get executed by your runner. So what are the options for doing CI on a public Github repo where you need to run it on your own hardware? Some possibilities:

  • only run CI on branches in the main repo. (It seems Github does this by default anyway as I can’t get the SIOT repo to run CI on outside PRs). This would limit exposure to only code that has been reviewed or committed by a member of the repo.
    • The Zephyr project runs CI on outside PRs
  • only run CI on a staging branch that only the owner of the CI machine has permission merge to
    • but it would be really nice to run CI on code in PRs
  • sandbox the runner:
    • run inside docker (docker in docker)?
    • run docker in Rootless mode
  • manually start the process (can review workflow file changes, etc)
  • keep the workflow files outside of the git repo, and initiate the runner using a local workflow, perhaps with act.
    • one issue with this is it won’t automatically feed results back to Github/Gitea.
  • use a machine in the cloud where it does not matter as much if it gets hacked.

Seems there is no perfect solution if you want to use your personal workstation, which has plenty of spare CPU cycles, for CI …

Specifying workflow containers

Got my first batch of Gitea workflows working:

Learned some interesting things. In the .runner file, you can specify a docker container that the runner provides:

{
  "WARNING": "This file is automatically generated by act-runner. Do not edit it manually unless you know what you are doing. Removing this file will cause act runner to re-register as a new runner.",
  "id": 1,
  "uuid": "9d92b4db-c55a-4046-85b0-438e4a90aaa",
  "name": "ceres",
  "token": "...",
  "address": "https://git.mycompany.com",
  "labels": [
    "arch:docker://node:16-bullseye"
  ]
}

The label is the critical part. The second part indicates we should run the CI task in a docker container named node:16-bullseye.

In the CI tasks, you need to have a matching label:

jobs:
  Explore-Gitea-Actions:
    runs-on: arch
    container:
      image: node:16-bullseye
    steps:
      - run:
          echo "🎉 The job was automatically triggered by a ${{ gitea.event_name
          }} event."

The runs-on, and container need to match the labels in the runner config.

This does mitigate the security problem somewhat because the runner config states the job must be run in a container, not on bare OS, so this does somewhat limit the access the CI job has to the host machine’s filesystem, etc. This security is probably good enough within a company where people who are committing code are trusted, but may not be good enough for “Internet” security where anyone can fire off a CI task with anything in it.

It appears the Gitea act_runner exec command, which is used to test workflows locally, runs workflows in a node:16-bullseye container by default. So having your Gitea server/runner workflow container match the local exec workflow container makes a ton of sense.

Secrets

You can specify secrets in Gitea in the web UI:

In this case, the secret contains a SSH key used to copy files to a remote machine.

The secret can be accessed in a workflow as show in the example below:

     - name: set up ssh key
        run: |
          mkdir -p ~/.ssh
          chmod 700 ~/.ssh
          echo "${{ secrets.SUMMA_SSH }}" > ~/.ssh/summa.key
          chmod 600 ~/.ssh/summa.key

Running workflows locally

One of the neatest things with Gitea actions is you can run the runner locally to test your workflows. However, in this scenario you cannot access secrets configured in Gitea, but you can pass them in on the command line as shown in the following example:

act_runner-0.2.6-linux-amd64 exec -W ./.gitea/workflows/deploy.yaml -s SUMMA_SSH="$(<~/.ssh/zsumma)"

Gitea actions are fairly well done. I enjoy using them: