From 62cfb45fe12098f0acb3cca55a87dcce7dce0672 Mon Sep 17 00:00:00 2001 From: Robear Selwans Date: Sat, 2 May 2026 17:52:25 +0300 Subject: [PATCH] Add setup build environment action --- .gitea/actions/setup-build-env/README.md | 91 ++++++++++++ .gitea/actions/setup-build-env/action.yml | 43 ++++++ .../actions/setup-build-env/scripts/setup.sh | 133 ++++++++++++++++++ 3 files changed, 267 insertions(+) create mode 100644 .gitea/actions/setup-build-env/README.md create mode 100644 .gitea/actions/setup-build-env/action.yml create mode 100755 .gitea/actions/setup-build-env/scripts/setup.sh diff --git a/.gitea/actions/setup-build-env/README.md b/.gitea/actions/setup-build-env/README.md new file mode 100644 index 0000000..c227047 --- /dev/null +++ b/.gitea/actions/setup-build-env/README.md @@ -0,0 +1,91 @@ +# 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`. diff --git a/.gitea/actions/setup-build-env/action.yml b/.gitea/actions/setup-build-env/action.yml new file mode 100644 index 0000000..aeb84c2 --- /dev/null +++ b/.gitea/actions/setup-build-env/action.yml @@ -0,0 +1,43 @@ +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 }} diff --git a/.gitea/actions/setup-build-env/scripts/setup.sh b/.gitea/actions/setup-build-env/scripts/setup.sh new file mode 100755 index 0000000..b952c2d --- /dev/null +++ b/.gitea/actions/setup-build-env/scripts/setup.sh @@ -0,0 +1,133 @@ +#!/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"