616 lines
9.7 KiB
Markdown
616 lines
9.7 KiB
Markdown
# 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
|
|
```
|