Compare commits

..

15 Commits

Author SHA1 Message Date
mo7sen 9101023921 pkg-config setup for vulkan
build-ci-image / image (push) Successful in 2m57s
2026-05-06 01:57:07 +03:00
mo7sen 1f029fd69b Replaced apt packages with LunarG's Vulkan SDK
build-ci-image / image (push) Failing after 2m33s
2026-05-06 01:52:35 +03:00
mo7sen 113e8c71b4 Added libshaderc-dev package installation to image
build-ci-image / image (push) Successful in 2m45s
2026-05-06 01:25:19 +03:00
mo7sen 00c63c4fcc Added cmake package installation to image
build-ci-image / image (push) Successful in 3m3s
2026-05-05 02:23:55 +03:00
mo7sen f27b2fe4d3 Added libxkbcommon-dev package installation to image
build-ci-image / image (push) Successful in 5m28s
2026-05-05 02:08:55 +03:00
mo7sen b5190cd75e Added xi-dev package installation to image
build-ci-image / image (push) Successful in 20m49s
2026-05-05 01:45:20 +03:00
mo7sen dbbd799a6c Added xcursor-dev package to image installation
build-ci-image / image (push) Successful in 13m31s
2026-05-05 01:19:56 +03:00
mo7sen 4c602043e5 Optimized image build time
build-ci-image / image (push) Successful in 27m49s
2026-05-05 00:49:44 +03:00
mo7sen 931e172071 Added libxinerama-dev to installed packages
build-ci-image / image (push) Failing after 8m20s
2026-05-05 00:40:42 +03:00
mo7sen b82c944425 Added xrandr installation to image
build-ci-image / image (push) Successful in 29m49s
2026-05-05 00:08:58 +03:00
mo7sen d792cfba20 Added valgrind installation to image
build-ci-image / image (push) Successful in 3m29s
2026-05-03 19:57:13 +03:00
mo7sen 8bdfdd5a6b Added gcovr installation to image
build-ci-image / image (push) Successful in 4m13s
2026-05-03 18:56:20 +03:00
mo7sen 5ae9d0b1e5 Flatten testbed repository layout
build-ci-image / image (push) Successful in 9s
2026-05-02 20:42:12 +03:00
mo7sen 1ce1dd61da Remove clang22 image tag
build-ci-image / image (push) Successful in 2m24s
2026-05-02 18:44:48 +03:00
mo7sen 1d3d77e8c9 Add Mesa Vulkan drivers to CI image 2026-05-02 18:41:59 +03:00
10 changed files with 209 additions and 1075 deletions
-91
View File
@@ -1,91 +0,0 @@
# setup-build-env Gitea Action
Reusable Gitea/GitHub-compatible composite action for Debian/Ubuntu runners. It installs:
- Clang/LLVM, default `22`
- Meson, installed in an isolated Python virtual environment to avoid PEP 668 `externally-managed-environment` errors
- Ninja
- Python 3, pip, venv
- Vulkan development tooling / SDK packages
## Local use inside a repository
Put this directory at:
```text
.gitea/actions/setup-build-env
```
Then use it from a workflow:
```yaml
name: build
on:
push:
pull_request:
jobs:
linux:
runs-on: ubuntu-latest
container:
image: debian:trixie
steps:
- uses: actions/checkout@v4
- uses: ./.gitea/actions/setup-build-env
with:
llvm-version: "22"
vulkan-source: apt
- run: |
meson setup build --native-file build_options/meson-clang-linux
meson compile -C build
```
## Use from a shared action repository
Create a dedicated repository, for example:
```text
gitea.example.com/actions/setup-build-env
```
Put `action.yml`, `scripts/setup.sh`, and this README at the root of that repository. Then tag it:
```bash
git tag v1
git push origin v1
```
Use it from all projects:
```yaml
- uses: actions/setup-build-env@v1
```
or with your full Gitea owner/repo path, depending on your Gitea Actions configuration:
```yaml
- uses: your-org/setup-build-env@v1
```
## Inputs
| Input | Default | Description |
| --- | --- | --- |
| `llvm-version` | `22` | LLVM/Clang major version. Installs packages like `clang-22`, `lld-22`, `llvm-22-dev`. |
| `meson-version` | `latest` | Meson version installed into `/opt/meson-venv`. Use e.g. `1.6.1` to pin. |
| `install-vulkan` | `true` | Install Vulkan packages. |
| `vulkan-source` | `apt` | `apt` for distro packages, or `lunarg` for the LunarG apt repository. |
| `lunarg-sdk-version` | `1.4.309.0` | LunarG SDK version used when `vulkan-source: lunarg`. |
| `make-default` | `true` | Makes `clang`, `clang++`, `lld`, etc point at the selected LLVM version through `update-alternatives`. |
## Notes
- This action assumes an apt-based Debian/Ubuntu runner/container.
- If your runner is not root, it needs passwordless `sudo`.
- `vulkan-source: apt` is recommended for CI because it is the most robust across Debian/Ubuntu images.
- `vulkan-source: lunarg` is best used on Ubuntu images supported by LunarG.
- Because this installs system packages, caching the entire result is normally done at the runner/container-image level. For faster builds, consider creating your own Docker image from the commands in `scripts/setup.sh`.
-43
View File
@@ -1,43 +0,0 @@
name: Setup C/C++ Vulkan build environment
description: Install Clang/LLVM, Meson, Ninja, Python, and Vulkan SDK packages on Debian/Ubuntu Gitea runners.
inputs:
llvm-version:
description: LLVM/Clang major version to install.
required: false
default: "22"
meson-version:
description: Meson version to install via isolated Python venv. Use "latest" for newest.
required: false
default: "latest"
install-vulkan:
description: Install Vulkan SDK/development packages.
required: false
default: "true"
vulkan-source:
description: "Vulkan package source: apt or lunarg. apt is more robust on self-hosted runners."
required: false
default: "apt"
lunarg-sdk-version:
description: LunarG SDK version, used only when vulkan-source=lunarg. Example: 1.4.309.0
required: false
default: "1.4.309.0"
make-default:
description: Make selected clang/clang++/llvm tools the default compiler commands.
required: false
default: "true"
runs:
using: composite
steps:
- name: Install build environment
shell: bash
run: |
"${{ github.action_path }}/scripts/setup.sh"
env:
LLVM_VERSION: ${{ inputs.llvm-version }}
MESON_VERSION: ${{ inputs.meson-version }}
INSTALL_VULKAN: ${{ inputs.install-vulkan }}
VULKAN_SOURCE: ${{ inputs.vulkan-source }}
LUNARG_SDK_VERSION: ${{ inputs.lunarg-sdk-version }}
MAKE_DEFAULT: ${{ inputs.make-default }}
@@ -1,133 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
LLVM_VERSION="${LLVM_VERSION:-22}"
MESON_VERSION="${MESON_VERSION:-latest}"
INSTALL_VULKAN="${INSTALL_VULKAN:-true}"
VULKAN_SOURCE="${VULKAN_SOURCE:-apt}"
LUNARG_SDK_VERSION="${LUNARG_SDK_VERSION:-1.4.309.0}"
MAKE_DEFAULT="${MAKE_DEFAULT:-true}"
log() { printf '\n\033[1;34m==> %s\033[0m\n' "$*"; }
warn() { printf '\n\033[1;33mwarning: %s\033[0m\n' "$*" >&2; }
if command -v sudo >/dev/null 2>&1 && [ "$(id -u)" -ne 0 ]; then
SUDO=sudo
else
SUDO=""
fi
export DEBIAN_FRONTEND=noninteractive
apt_install() {
$SUDO apt-get install -y --no-install-recommends "$@"
}
log "Installing base packages"
$SUDO apt-get update
apt_install \
ca-certificates \
curl \
gnupg \
lsb-release \
software-properties-common \
wget \
xz-utils \
build-essential \
pkg-config \
git \
python3 \
python3-venv \
python3-pip \
ninja-build
log "Installing LLVM/Clang ${LLVM_VERSION}"
if ! apt-cache show "clang-${LLVM_VERSION}" >/dev/null 2>&1; then
warn "clang-${LLVM_VERSION} is not in the current apt sources; adding apt.llvm.org"
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | $SUDO gpg --dearmor -o /usr/share/keyrings/llvm-snapshot.gpg
CODENAME="$(. /etc/os-release && printf '%s' "${VERSION_CODENAME:-}")"
if [ -z "$CODENAME" ]; then
CODENAME="$(lsb_release -sc)"
fi
echo "deb [signed-by=/usr/share/keyrings/llvm-snapshot.gpg] http://apt.llvm.org/${CODENAME}/ llvm-toolchain-${CODENAME}-${LLVM_VERSION} main" | \
$SUDO tee "/etc/apt/sources.list.d/llvm-${LLVM_VERSION}.list" >/dev/null
$SUDO apt-get update
fi
apt_install \
"clang-${LLVM_VERSION}" \
"clang-tools-${LLVM_VERSION}" \
"lld-${LLVM_VERSION}" \
"lldb-${LLVM_VERSION}" \
"llvm-${LLVM_VERSION}" \
"llvm-${LLVM_VERSION}-dev"
if [ "$MAKE_DEFAULT" = "true" ]; then
log "Making Clang ${LLVM_VERSION} the default compiler for this runner"
for tool in clang clang++ clang-cpp llvm-ar llvm-ranlib llvm-nm llvm-strip lld lldb; do
if command -v "${tool}-${LLVM_VERSION}" >/dev/null 2>&1; then
$SUDO update-alternatives --install "/usr/bin/${tool}" "${tool}" "$(command -v "${tool}-${LLVM_VERSION}")" 100
fi
done
fi
log "Installing Meson in an isolated venv"
MESON_VENV="/opt/meson-venv"
$SUDO python3 -m venv "$MESON_VENV"
$SUDO "$MESON_VENV/bin/python" -m pip install --upgrade pip setuptools wheel
if [ "$MESON_VERSION" = "latest" ]; then
$SUDO "$MESON_VENV/bin/python" -m pip install --upgrade meson
else
$SUDO "$MESON_VENV/bin/python" -m pip install --upgrade "meson==${MESON_VERSION}"
fi
$SUDO ln -sf "$MESON_VENV/bin/meson" /usr/local/bin/meson
if [ "$INSTALL_VULKAN" = "true" ]; then
case "$VULKAN_SOURCE" in
apt)
log "Installing Vulkan development packages from distro apt repositories"
apt_install \
libvulkan-dev \
vulkan-tools \
vulkan-validationlayers \
glslang-tools \
spirv-tools \
spirv-headers || {
warn "Some Vulkan packages were unavailable; retrying minimal Vulkan package set"
apt_install libvulkan-dev vulkan-tools glslang-tools spirv-tools
}
;;
lunarg)
log "Installing Vulkan SDK from LunarG (${LUNARG_SDK_VERSION})"
. /etc/os-release
if [ "${ID:-}" != "ubuntu" ]; then
warn "LunarG apt repo is Ubuntu-oriented. Falling back to distro apt Vulkan packages."
apt_install libvulkan-dev vulkan-tools glslang-tools spirv-tools
else
CODENAME="${VERSION_CODENAME:-$(lsb_release -sc)}"
curl -fsSL https://packages.lunarg.com/lunarg-signing-key-pub.asc | \
$SUDO gpg --dearmor -o /usr/share/keyrings/lunarg.gpg
echo "deb [signed-by=/usr/share/keyrings/lunarg.gpg] https://packages.lunarg.com/vulkan/${LUNARG_SDK_VERSION}/ubuntu ${CODENAME} main" | \
$SUDO tee /etc/apt/sources.list.d/lunarg-vulkan-sdk.list >/dev/null
$SUDO apt-get update
apt_install vulkan-sdk
fi
;;
*)
echo "Unsupported VULKAN_SOURCE=${VULKAN_SOURCE}; expected apt or lunarg" >&2
exit 2
;;
esac
fi
log "Versions"
python3 --version
python3 -m pip --version || true
meson --version
ninja --version
clang --version
if command -v vulkaninfo >/dev/null 2>&1; then
vulkaninfo --summary || true
fi
log "Build environment ready"
+22 -9
View File
@@ -3,7 +3,7 @@ name: build-ci-image
on:
push:
paths:
- ci/Dockerfile
- Dockerfile
- .dockerignore
- .gitea/workflows/build-ci-image.yml
workflow_dispatch:
@@ -37,17 +37,30 @@ jobs:
-u "$username" \
--password-stdin
- name: Build CI image
- name: Build and push CI image
env:
DOCKER_BUILDKIT: 1
run: |
if docker buildx version >/dev/null 2>&1; then
docker buildx create --use --name evol-testbed-builder || docker buildx use evol-testbed-builder
docker buildx build \
--build-arg BASE_IMAGE=catthehacker/ubuntu:act-latest \
--build-arg LLVM_VERSION=22 \
--build-arg MESON_VERSION=latest \
--cache-from type=registry,ref="$REGISTRY_IMAGE:buildcache" \
--cache-to type=registry,ref="$REGISTRY_IMAGE:buildcache",mode=max \
--tag "$REGISTRY_IMAGE:latest" \
--file Dockerfile \
--push \
.
else
echo "docker buildx is unavailable; falling back to uncached docker build"
docker build \
--build-arg BASE_IMAGE=catthehacker/ubuntu:act-latest \
--build-arg LLVM_VERSION=22 \
--build-arg MESON_VERSION=latest \
-t "$REGISTRY_IMAGE:latest" \
-t "$REGISTRY_IMAGE:clang22" \
-f ci/Dockerfile .
- name: Push CI image
run: |
--tag "$REGISTRY_IMAGE:latest" \
--file Dockerfile \
.
docker push "$REGISTRY_IMAGE:latest"
docker push "$REGISTRY_IMAGE:clang22"
fi
-34
View File
@@ -1,34 +0,0 @@
name: build
# This is a manual smoke-test for the already-published image.
# Do not run it on every push in this image repository, because the first push
# happens before the image exists in the registry.
on:
workflow_dispatch:
jobs:
linux:
runs-on: ubuntu-latest
container:
image: git.neosisyphus.com/evol3d/evol-testbed:clang22
steps:
- uses: actions/checkout@v4
- name: Check CI toolchain
run: |
clang --version
clang++ --version
meson --version
ninja --version
python3 --version
vulkaninfo --summary || true
- name: Configure
run: |
meson setup build
- name: Build
run: |
meson compile -C build
+52 -26
View File
@@ -1,16 +1,16 @@
# syntax=docker/dockerfile:1.7
# Gitea Actions CI image for C/C++ + Vulkan projects.
# This extends the Ubuntu image commonly used by Gitea/act_runner so JS actions
# such as actions/checkout keep working.
#
# Build:
# docker build -t evol-testbed:latest -f ci/Dockerfile .
# docker build -t evol-testbed:latest .
ARG BASE_IMAGE=catthehacker/ubuntu:act-latest
FROM ${BASE_IMAGE}
ARG LLVM_VERSION=22
ARG MESON_VERSION=latest
ARG USE_LUNARG_VULKAN=false
ARG LUNARG_SDK_VERSION=1.4.309.0
ENV DEBIAN_FRONTEND=noninteractive
@@ -20,11 +20,16 @@ ENV AR=llvm-ar
ENV RANLIB=llvm-ranlib
ENV NM=llvm-nm
ENV STRIP=llvm-strip
ENV VULKAN_SDK=/opt/vulkan-sdk/current/x86_64
ENV PATH="${VULKAN_SDK}/bin:${PATH}"
ENV LD_LIBRARY_PATH="${VULKAN_SDK}/lib:${LD_LIBRARY_PATH}"
ENV PKG_CONFIG_PATH="${VULKAN_SDK}/lib/pkgconfig:${PKG_CONFIG_PATH}"
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Base compiler/build/Python/Vulkan packages from Ubuntu.
RUN set -eux; \
# Base compiler/build/Python packages from Ubuntu.
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
ca-certificates \
@@ -33,6 +38,11 @@ RUN set -eux; \
lsb-release \
wget \
xz-utils \
libxrandr-dev \
libxinerama-dev \
libxcursor-dev \
libxi-dev \
libxkbcommon-dev \
git \
build-essential \
pkg-config \
@@ -41,16 +51,14 @@ RUN set -eux; \
python3-pip \
python3-venv \
ninja-build \
libvulkan-dev \
vulkan-tools \
vulkan-validationlayers \
glslang-tools \
spirv-tools \
spirv-headers; \
cmake \
gcovr \
valgrind; \
rm -rf /var/lib/apt/lists/*
# LLVM/Clang from apt.llvm.org.
RUN set -eux; \
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
set -eux; \
codename="$(. /etc/os-release && echo "${VERSION_CODENAME}")"; \
curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key \
| gpg --dearmor -o /usr/share/keyrings/llvm-snapshot.gpg; \
@@ -69,19 +77,34 @@ RUN set -eux; \
"llvm-${LLVM_VERSION}-tools"; \
rm -rf /var/lib/apt/lists/*
# Optional LunarG Vulkan SDK repo. Disabled by default because Ubuntu distro
# Vulkan packages are more stable for CI and usually enough for building/testing.
RUN set -eux; \
if [ "${USE_LUNARG_VULKAN}" = "true" ]; then \
codename="$(. /etc/os-release && echo "${VERSION_CODENAME}")"; \
curl -fsSL https://packages.lunarg.com/lunarg-signing-key-pub.asc \
| gpg --dearmor -o /usr/share/keyrings/lunarg.gpg; \
echo "deb [signed-by=/usr/share/keyrings/lunarg.gpg] https://packages.lunarg.com/vulkan/${LUNARG_SDK_VERSION}/ubuntu ${codename} main" \
> /etc/apt/sources.list.d/lunarg-vulkan-sdk.list; \
apt-get update; \
apt-get install -y --no-install-recommends vulkan-sdk; \
rm -rf /var/lib/apt/lists/*; \
fi
# LunarG Vulkan SDK from the official tarball.
RUN --mount=type=cache,target=/root/.cache/vulkan-sdk \
set -eux; \
sdk_archive="/root/.cache/vulkan-sdk/vulkansdk-linux-x86_64-${LUNARG_SDK_VERSION}.tar.xz"; \
if [ ! -f "${sdk_archive}" ]; then \
curl -fL "https://sdk.lunarg.com/sdk/download/${LUNARG_SDK_VERSION}/linux/vulkansdk-linux-x86_64-${LUNARG_SDK_VERSION}.tar.xz" \
-o "${sdk_archive}"; \
fi; \
mkdir -p /opt/vulkan-sdk; \
tar -xJf "${sdk_archive}" -C /opt/vulkan-sdk; \
ln -sfn "/opt/vulkan-sdk/${LUNARG_SDK_VERSION}" /opt/vulkan-sdk/current; \
mkdir -p "${VULKAN_SDK}/lib/pkgconfig"; \
if [ ! -f "${VULKAN_SDK}/lib/pkgconfig/vulkan.pc" ]; then \
{ \
echo "prefix=${VULKAN_SDK}"; \
echo 'exec_prefix=${prefix}'; \
echo 'libdir=${exec_prefix}/lib'; \
echo 'includedir=${prefix}/include'; \
echo; \
echo 'Name: Vulkan-Loader'; \
echo 'Description: Vulkan Loader'; \
echo "Version: ${LUNARG_SDK_VERSION}"; \
echo 'Libs: -L${libdir} -lvulkan'; \
echo 'Cflags: -I${includedir}'; \
} > "${VULKAN_SDK}/lib/pkgconfig/vulkan.pc"; \
fi; \
echo "${VULKAN_SDK}/lib" > /etc/ld.so.conf.d/vulkan-sdk.conf; \
ldconfig
# Make LLVM_VERSION the default clang toolchain.
RUN set -eux; \
@@ -96,7 +119,8 @@ RUN set -eux; \
update-alternatives --install /usr/bin/llvm-strip llvm-strip "/usr/bin/llvm-strip-${LLVM_VERSION}" 100
# Meson in an isolated venv avoids Debian/Ubuntu PEP 668 externally-managed pip errors.
RUN set -eux; \
RUN --mount=type=cache,target=/root/.cache/pip \
set -eux; \
python3 -m venv /opt/meson-venv; \
/opt/meson-venv/bin/python -m pip install --upgrade pip setuptools wheel; \
if [ "${MESON_VERSION}" = "latest" ]; then \
@@ -113,6 +137,8 @@ RUN set -eux; \
clang++ --version; \
meson --version; \
ninja --version; \
vulkaninfo --summary || true
glslangValidator --version; \
spirv-val --version; \
pkg-config --modversion vulkan
CMD ["bash"]
+130
View File
@@ -0,0 +1,130 @@
# evol-testbed
Reusable Gitea Actions container image for Evol C/C++/Vulkan builds.
Image:
```text
git.neosisyphus.com/evol3d/evol-testbed:latest
```
The image extends:
```text
catthehacker/ubuntu:act-latest
```
Included tools:
- Clang/LLVM 22
- `clang-format-22`
- `clang-tidy-22`
- `lld-22`
- `lldb-22`
- Meson
- Ninja
- Python 3 / pip / venv
- LunarG Vulkan SDK headers/tools
- `build-essential`
- `pkg-config`
- Git
## Build locally
```bash
docker build -t evol-testbed:latest .
# Optional: choose a different LunarG Vulkan SDK version
# docker build --build-arg LUNARG_SDK_VERSION=1.4.309.0 -t evol-testbed:latest .
```
Test locally:
```bash
docker run --rm -it evol-testbed:latest bash -lc '
clang --version &&
clang++ --version &&
meson --version &&
ninja --version &&
python3 --version &&
pkg-config --modversion vulkan &&
vulkaninfo --summary || true
'
```
## Push manually
```bash
docker login git.neosisyphus.com
docker tag evol-testbed:latest git.neosisyphus.com/evol3d/evol-testbed:latest
docker push git.neosisyphus.com/evol3d/evol-testbed:latest
```
## Automatic publishing
The workflow at:
```text
.gitea/workflows/build-ci-image.yml
```
builds and pushes the image on changes to `Dockerfile`, `.dockerignore`, or the workflow itself.
Required Gitea Actions secret:
```text
REGISTRY_PASSWORD
```
Use a Gitea token/password with package/container registry write permission.
Optional secret:
```text
REGISTRY_USERNAME
```
If `REGISTRY_USERNAME` is omitted, the workflow uses `$GITHUB_ACTOR`.
## Use from another Gitea project
```yaml
name: build
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
container:
image: git.neosisyphus.com/evol3d/evol-testbed:latest
steps:
- uses: actions/checkout@v4
- name: Check toolchain
run: |
clang --version
clang++ --version
meson --version
ninja --version
python3 --version
pkg-config --modversion vulkan
vulkaninfo --summary || true
- name: Configure
run: meson setup build
- name: Build
run: meson compile -C build
```
Use the fully-qualified image path. Do not use only `evol-testbed:latest`; Docker will look on Docker Hub or for a local image instead of your Gitea registry.
## Notes
- `latest` may be cached by the runner unless `act_runner` is configured with `container.force_pull: true`.
- `vulkaninfo` may still fail on unusual runners, but Vulkan headers and build tools are installed. Use `pkg-config --modversion vulkan` as the compile-time check.
-5
View File
@@ -1,5 +0,0 @@
.git
build
.cache
.venv
subprojects/packagecache
-113
View File
@@ -1,113 +0,0 @@
# Gitea Actions CI image
This image extends Gitea/act's Ubuntu runner image:
```text
catthehacker/ubuntu:act-latest
```
It includes:
- Clang/LLVM 22
- Meson
- Ninja
- Python 3 + pip + venv
- Vulkan development packages/tools
- Git/build-essential/pkg-config
- Node/runtime pieces inherited from the act Ubuntu image, so JavaScript actions like `actions/checkout` keep working
## Files prepared
```text
ci/Dockerfile
.dockerignore
.gitea/workflows/build-ci-image.yml
.gitea/workflows/build.yml
```
## Required Gitea variables/secrets
In your repository or organization settings, add these **Actions variables**:
```text
REGISTRY_HOST=git.neosisyphus.com
REGISTRY_IMAGE=git.neosisyphus.com/evol3d/evol-testbed
CI_IMAGE=git.neosisyphus.com/evol3d/evol-testbed
```
Add this **Actions secret**:
```text
REGISTRY_PASSWORD=your-gitea-token-or-password
```
The token/password needs permission to publish packages/container images.
Optional: add this secret if your registry username is different from the Gitea Actions actor:
```text
REGISTRY_USERNAME=your-gitea-username
```
If `REGISTRY_USERNAME` is not set, the workflow uses `$GITHUB_ACTOR`.
## Build manually
```bash
docker build -t evol-testbed:latest -f ci/Dockerfile .
```
Test:
```bash
docker run --rm -it evol-testbed:latest bash -lc '
clang --version &&
meson --version &&
ninja --version &&
python3 --version &&
vulkaninfo --summary || true
'
```
Tag and push:
```bash
docker login git.neosisyphus.com
docker tag evol-testbed:latest git.neosisyphus.com/evol3d/evol-testbed:latest
docker tag evol-testbed:latest git.neosisyphus.com/evol3d/evol-testbed:clang22
docker push git.neosisyphus.com/evol3d/evol-testbed:latest
docker push git.neosisyphus.com/evol3d/evol-testbed:clang22
```
## Build automatically in Gitea Actions
After setting the variables/secrets above, run:
```text
.gitea/workflows/build-ci-image.yml
```
It builds and pushes:
```text
${REGISTRY_IMAGE}:latest
${REGISTRY_IMAGE}:clang22
```
## Use in normal builds
`.gitea/workflows/build.yml` is already prepared to use:
```yaml
container:
image: ${{ vars.CI_IMAGE }}:clang22
```
If expressions do not work in `container.image` on your Gitea version, replace it with the literal image path:
```yaml
container:
image: git.neosisyphus.com/evol3d/evol-testbed:clang22
```
-616
View File
@@ -1,616 +0,0 @@
# Using the Clang 22 + Vulkan Gitea Actions CI Image
This guide explains how to build, publish, and use the prepared Docker image for Gitea Actions.
The prepared files are:
```text
ci/Dockerfile
ci/README.md
ci/USE_CI_IMAGE.md
.dockerignore
.gitea/workflows/build-ci-image.yml
.gitea/workflows/build.yml
```
The image extends:
```text
catthehacker/ubuntu:act-latest
```
It includes:
- Clang/LLVM 22
- `clang-format-22`
- `clang-tidy-22`
- `lld-22`
- `lldb-22`
- Meson
- Ninja
- Python 3 / pip / venv
- Vulkan development packages/tools
- `build-essential`
- `pkg-config`
- Git
- Gitea/act-compatible tooling inherited from the base image
---
## 1. Decide your image name
Pick a container image path in your Gitea registry.
Example Gitea host:
```text
git.neosisyphus.com
```
Organization:
```text
evol3d
```
Image path:
```text
git.neosisyphus.com/evol3d/evol-testbed
```
The pushed tags will be:
```text
git.neosisyphus.com/evol3d/evol-testbed:latest
git.neosisyphus.com/evol3d/evol-testbed:clang22
```
---
## 2. Commit the prepared files
From the repository root:
```bash
git add ci/Dockerfile ci/README.md ci/USE_CI_IMAGE.md .dockerignore .gitea/workflows/build-ci-image.yml .gitea/workflows/build.yml
git commit -m "Add reusable Clang 22 Vulkan CI image"
git push
```
---
## 3. Create a Gitea access token
In the Gitea web UI:
1. Open your user menu.
2. Go to **Settings**.
3. Go to **Applications**.
4. Create a new access token.
5. Give it package/container registry write permissions.
Depending on your Gitea version, the permission may be named one of:
```text
package
packages
write:package
write:packages
```
Copy the token. It will be used as the registry password.
---
## 4. Add Gitea Actions variables
In your repository:
1. Go to **Settings**.
2. Go to **Actions**.
3. Go to **Variables**.
4. Add these variables:
```text
REGISTRY_HOST=git.neosisyphus.com
REGISTRY_IMAGE=git.neosisyphus.com/evol3d/evol-testbed
CI_IMAGE=git.neosisyphus.com/evol3d/evol-testbed
```
Use your actual values.
### `REGISTRY_HOST`
Only the hostname:
```text
git.neosisyphus.com
```
Do not include `https://`.
Correct:
```text
git.neosisyphus.com
```
Wrong:
```text
https://git.neosisyphus.com
```
### `REGISTRY_IMAGE`
The full image path without a tag:
```text
git.neosisyphus.com/evol3d/evol-testbed
```
### `CI_IMAGE`
Usually the same as `REGISTRY_IMAGE`:
```text
git.neosisyphus.com/evol3d/evol-testbed
```
This is used by the normal build workflow.
---
## 5. Add Gitea Actions secrets
In your repository:
1. Go to **Settings**.
2. Go to **Actions**.
3. Go to **Secrets**.
4. Add this required secret:
```text
REGISTRY_PASSWORD
```
Example:
```text
REGISTRY_PASSWORD=<your-gitea-access-token>
```
Use the token from step 3 for `REGISTRY_PASSWORD`.
Optional: add this secret if your registry username is different from the Gitea Actions actor:
```text
REGISTRY_USERNAME=myusername
```
If `REGISTRY_USERNAME` is not set, the workflow uses `$GITHUB_ACTOR`.
---
## 6. Check the image build workflow
The image build workflow is:
```text
.gitea/workflows/build-ci-image.yml
```
It logs into your registry, builds the image, and pushes two tags:
```text
latest
clang22
```
The important commands are:
```yaml
- name: Build CI image
run: |
docker build \
--build-arg BASE_IMAGE=catthehacker/ubuntu:act-latest \
--build-arg LLVM_VERSION=22 \
--build-arg MESON_VERSION=latest \
-t "${{ vars.REGISTRY_IMAGE }}:latest" \
-t "${{ vars.REGISTRY_IMAGE }}:clang22" \
-f ci/Dockerfile .
- name: Push CI image
run: |
docker push "${{ vars.REGISTRY_IMAGE }}:latest"
docker push "${{ vars.REGISTRY_IMAGE }}:clang22"
```
---
## 7. Make sure your runner can build Docker images
The image-building workflow needs Docker.
On the runner host, check:
```bash
docker version
```
If that works, the host has Docker.
Your Gitea runner still needs permission to access Docker.
### Option A: `act_runner` runs directly on the host
If your runner runs directly on the machine, make sure the runner user can use Docker.
Check the runner user, then add it to the Docker group if needed:
```bash
sudo usermod -aG docker <runner-user>
sudo systemctl restart act_runner
```
Test as that user:
```bash
docker ps
```
### Option B: `act_runner` runs inside Docker
If `act_runner` itself runs inside a container, it needs the host Docker socket mounted:
```bash
-v /var/run/docker.sock:/var/run/docker.sock
```
Example:
```bash
docker run -d \
--name gitea-act-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /opt/act-runner/config.yaml:/config.yaml \
-v /opt/act-runner/data:/data \
gitea/act_runner:latest
```
Without the socket mount, the workflow cannot run `docker build`.
---
## 8. Run the image build workflow
There are two ways.
### Method 1: push changes
The workflow triggers when these files change:
```text
ci/Dockerfile
.dockerignore
.gitea/workflows/build-ci-image.yml
```
So this is enough:
```bash
git push
```
### Method 2: manual workflow dispatch
If your Gitea version supports `workflow_dispatch`:
1. Go to your repository.
2. Open **Actions**.
3. Select **build-ci-image**.
4. Click **Run workflow**.
---
## 9. Confirm the image was pushed
In Gitea:
1. Open the repository or organization.
2. Go to **Packages**.
3. Look for:
```text
evol-testbed
```
Confirm these tags exist:
```text
latest
clang22
```
---
## 10. Use the image in your normal build workflow
The prepared normal workflow is:
```text
.gitea/workflows/build.yml
```
It uses:
```yaml
container:
image: ${{ vars.CI_IMAGE }}:clang22
```
If you set:
```text
CI_IMAGE=git.neosisyphus.com/evol3d/evol-testbed
```
then the workflow uses:
```text
git.neosisyphus.com/evol3d/evol-testbed:clang22
```
The key workflow shape is:
```yaml
name: build
on:
push:
pull_request:
jobs:
linux:
runs-on: ubuntu-latest
container:
image: ${{ vars.CI_IMAGE }}:clang22
steps:
- uses: actions/checkout@v4
- name: Check CI toolchain
run: |
clang --version
clang++ --version
meson --version
ninja --version
python3 --version
vulkaninfo --summary || true
- name: Configure
run: |
meson setup build
- name: Build
run: |
meson compile -C build
```
Commit and push:
```bash
git add .gitea/workflows/build.yml
git commit -m "Use Clang 22 Vulkan CI image"
git push
```
---
## 11. If `vars.CI_IMAGE` does not work in `container.image`
Some Gitea/act versions may not expand variables in `container.image`.
If the build fails because the image name is invalid, replace this:
```yaml
container:
image: ${{ vars.CI_IMAGE }}:clang22
```
with the literal image name:
```yaml
container:
image: git.neosisyphus.com/evol3d/evol-testbed:clang22
```
Then commit and push:
```bash
git add .gitea/workflows/build.yml
git commit -m "Use literal CI image path"
git push
```
---
## 12. If the image is private
Your runner must be able to pull it.
Log in on the runner host:
```bash
docker login git.neosisyphus.com
```
Use your Gitea username and token.
If `act_runner` runs as a system service, log in as the same user that runs `act_runner`, or configure Docker credentials for that user.
Then restart the runner:
```bash
sudo systemctl restart act_runner
```
If your runner itself is Dockerized, make sure Docker credentials are available to the runner setup.
---
## 13. Test the image manually on the runner
On the runner host:
```bash
docker pull git.neosisyphus.com/evol3d/evol-testbed:clang22
```
Run it:
```bash
docker run --rm -it git.neosisyphus.com/evol3d/evol-testbed:clang22 bash
```
Inside the container:
```bash
clang --version
clang++ --version
meson --version
ninja --version
python3 --version
vulkaninfo --summary
```
Expected results:
- `clang` should be version 22.
- `meson` should print a version.
- `ninja` should print a version.
- `vulkaninfo --summary` may fail if the CI machine has no GPU/display/runtime Vulkan driver. That is usually okay for compile-only CI as long as Vulkan headers/tools are installed.
Exit:
```bash
exit
```
---
## 14. Use it in other projects
Once the image exists, any project can use it:
```yaml
name: build
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
container:
image: git.neosisyphus.com/evol3d/evol-testbed:clang22
steps:
- uses: actions/checkout@v4
- run: |
meson setup build
meson compile -C build
```
No more installing LLVM/Vulkan/Meson every CI run.
---
## 15. Updating the image later
Edit:
```text
ci/Dockerfile
```
Then:
```bash
git add ci/Dockerfile
git commit -m "Update CI image"
git push
```
The image workflow will rebuild and push:
```text
latest
clang22
```
Your normal builds will use the updated image next time they run.
---
## 16. Recommended: version image tags
Instead of only using:
```text
clang22
```
consider immutable tags:
```text
clang22-v1
clang22-v2
clang22-2026-05
```
Example build command tag:
```yaml
-t "${{ vars.REGISTRY_IMAGE }}:clang22-v1"
```
Then use:
```yaml
container:
image: git.neosisyphus.com/evol3d/evol-testbed:clang22-v1
```
This avoids surprise breakage when `clang22` or `latest` changes.
---
## 17. Quick checklist
```text
1. Commit ci/Dockerfile and workflows.
2. Create Gitea token with package/container write access.
3. Registry/image values are already hardcoded in the workflow.
4. Add Actions secrets:
- REGISTRY_PASSWORD
- REGISTRY_USERNAME only if needed
5. Make sure the runner can run docker build.
6. Run build-ci-image workflow.
7. Confirm image appears in Gitea Packages.
8. Use image in .gitea/workflows/build.yml.
9. Push normal project code.
10. Build should run inside the prebuilt Clang/Vulkan image.
```
The most important final workflow line is:
```yaml
container:
image: git.neosisyphus.com/evol3d/evol-testbed:clang22
```