For a long time, I wanted to have a well-integrated Open-Source CI/CI Pipeline solution for my personal Gitea code hosting. There are many options out there (Drone, Woodpecker, Jenkins, Concourse, Screwdriver, and a lot more), but none of them made my day.
Ever since Gitea Actions were announced, I was eager to get to know them and use them. Now was the time for it.
For Gitea Actions to work, they have to be enabled globally in a feature flag, as well per project. See the official documentation to learn more.
Of course, you also need a runner to execute the jobs, and this is where it gets interesting: I wanted to have this runner on my Kubernetes cluster. There is an example in the act_runner
repository (official Gitea Actions runner) how to deploy it in Kubernetes. It basically spins up a Pod with two containers: In one container the runner itself is running and in the other one there is Docker-in-Docker running, which gets used by the runner to execute the commands.
The integration in Kubernetes is therefore very bare-bones, in a real integration it would run the jobs as Kubernetes Pod without the need of Docker-in-Docker.
Now it gets interesting for the second time: To successfully build a container image in a Gitea Action, I use Docker Buildx which natively supports running builds in Kubernetes, even with QEMU for multi-platform builds. That means: The Gitea Action gets executed in the Docker-in-Docker container, and then the Docker Buildx process connects directly to the Kubernetes API and executes its build job this way. A bit strange, but it works. This is an example of a Gitea Action which builds a multi-platform container image:
name: Build and Push Image
on: [ push ]
jobs:
build:
name: Build and push image
runs-on: ubuntu-latest
container: catthehacker/ubuntu:act-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Create Kubeconfig
run: |
mkdir $HOME/.kube
echo "${{ secrets.KUBECONFIG_BUILDX }}" > $HOME/.kube/config
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: kubernetes
driver-opts: |
namespace=act-runner
qemu.install=true
- name: Login to Docker Registry
uses: docker/login-action@v3
with:
registry: git.tbrnt.ch
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: |
git.tbrnt.ch/tobru/ioteer:latest
In the repository secret, add the Kubeconfig content into KUBECONFIG_BUILDX
. I created a service account and a service account token with an appropriate RoleBinding
(to the edit
ClusterRole
).
Oh, and by the way: Gitea also offers an integrated OCI compliant container registry. How cool is that? Now Gitea has everything needed for a modern code flow: Code hosting and collaboration, CI/CD Pipelines and a package / container repository. I don't need more.
The following shell snippet can be used to create a proper Kubeconfig:
server=https://zurrli.tbrnt.ch:6443
name=buildx-sa-token
ca=$(kubectl -n act-runner get secret/$name -o jsonpath='{.data.ca\.crt}')
token=$(kubectl -n act-runner get secret/$name -o jsonpath='{.data.token}' | base64 --decode)
namespace=$(kubectl -n act-runner get secret/$name -o jsonpath='{.data.namespace}' | base64 --decode)
echo "
apiVersion: v1
kind: Config
clusters:
- name: default-cluster
cluster:
certificate-authority-data: ${ca}
server: ${server}
contexts:
- name: default-context
context:
cluster: default-cluster
namespace: default
user: default-user
current-context: default-context
users:
- name: default-user
user:
token: ${token}
" > sa.kubeconfig
A few interesting facts about Gitea Actions:
- They are almost fully compatible with GitHub Actions. Usually, they are stored under the
.gitea
folder, but can also be in the.github
folder. - By default, Actions are pulled from GitHub, but Gitea maintains a mirror of a few of them under https://gitea.com/actions
- The underlying nektos/act tool can also be used to run Actions locally on your computer.
As always, my code is open, have a peak here at my real live configuration:
- Gitea Action runner deployment: https://git.tbrnt.ch/tobru/gitops-zurrli/src/branch/main/apps/act-runner
- Gitea Action to build and push a container image: https://git.tbrnt.ch/tobru/ioteer/src/branch/master/.gitea/workflows/build-push.yaml
Enjoy The Action!