Add Evol testbed CI image
This commit is contained in:
@@ -0,0 +1,615 @@
|
||||
# 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:
|
||||
|
||||
```text
|
||||
REGISTRY_USERNAME
|
||||
REGISTRY_PASSWORD
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
REGISTRY_USERNAME=myusername
|
||||
REGISTRY_PASSWORD=<your-gitea-access-token>
|
||||
```
|
||||
|
||||
Use your Gitea username for `REGISTRY_USERNAME`.
|
||||
|
||||
Use the token from step 3 for `REGISTRY_PASSWORD`.
|
||||
|
||||
---
|
||||
|
||||
## 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. Add Actions variables:
|
||||
- REGISTRY_HOST
|
||||
- REGISTRY_IMAGE
|
||||
- CI_IMAGE
|
||||
4. Add Actions secrets:
|
||||
- REGISTRY_USERNAME
|
||||
- REGISTRY_PASSWORD
|
||||
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
|
||||
```
|
||||
Reference in New Issue
Block a user