From ea30c24f7f8755c99d3dd7fdb3f7a449c9a8f004 Mon Sep 17 00:00:00 2001 From: Sergio Date: Sun, 23 Nov 2025 20:36:45 +0100 Subject: [PATCH] afegit CI/CD --- .claude/settings.local.json | 15 -- .gitea/workflows/release.yml | 254 ++++++++++++++++++++++++ .gitignore | 7 + Makefile | 53 ++++- docker/Dockerfile.build | 46 +++++ docker/docker-compose.runner.yml | 28 +++ source/core/resources/resource_pack.cpp | 2 - 7 files changed, 387 insertions(+), 18 deletions(-) delete mode 100644 .claude/settings.local.json create mode 100644 .gitea/workflows/release.yml create mode 100644 docker/Dockerfile.build create mode 100644 docker/docker-compose.runner.yml diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index 25f2e95..0000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(cat:*)", - "Bash(cmake --build:*)", - "Bash(chmod:*)", - "Bash(.git/hooks/pre-commit)", - "Bash(brew --prefix:*)", - "Bash(make setup_hooks:*)", - "Bash(tools/hooks/pre-commit)" - ], - "deny": [], - "ask": [] - } -} diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..572dc7d --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,254 @@ +# Workflow para crear releases automáticos cuando se crea un tag +# +# Uso: +# git tag v0.2 +# git push --tags +# +# Esto disparará el workflow y creará un release con binarios para: +# - Linux x64 +# - Windows x64 +# - Raspberry Pi ARM64 + +name: Release + +on: + push: + tags: + - 'v*' + +env: + SDL3_VERSION: "3.2.26" + +jobs: + # ============================================================================ + # BUILD LINUX x64 + # ============================================================================ + build-linux: + runs-on: ubuntu-latest + container: + image: ubuntu:24.04 + steps: + - name: Instalar dependencias + run: | + apt-get update + apt-get install -y \ + nodejs npm \ + build-essential cmake git pkg-config \ + libgl1-mesa-dev libglu1-mesa-dev \ + libx11-dev libxext-dev libxrandr-dev libxcursor-dev \ + libxi-dev libxinerama-dev libxxf86vm-dev libxss-dev \ + libasound2-dev libpulse-dev libudev-dev libdbus-1-dev \ + libwayland-dev libxkbcommon-dev + + - name: Compilar SDL3 + run: | + cd /tmp + git clone --depth 1 --branch release-${{ env.SDL3_VERSION }} https://github.com/libsdl-org/SDL.git + cd SDL + cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr + cmake --build build -j$(nproc) + cmake --install build + + - name: Checkout + uses: actions/checkout@v4 + + - name: Generar project.h + run: | + GIT_HASH=$(git rev-parse --short=7 HEAD) + RAW_VERSION=$(echo "${{ github.ref_name }}" | sed 's/^v//') + TARGET_NAME=$(awk '/^project/ {gsub(/[)(]/, " "); print $2}' CMakeLists.txt) + LONG_NAME=$(grep 'PROJECT_LONG_NAME' CMakeLists.txt | sed 's/.*"\(.*\)".*/\1/') + COPYRIGHT=$(sed -n 's/.*set(PROJECT_COPYRIGHT "\([^"]*\)".*/\1/p' CMakeLists.txt) + sed -e "s/@PROJECT_NAME@/$TARGET_NAME/g" \ + -e "s/@PROJECT_LONG_NAME@/$LONG_NAME/g" \ + -e "s/@PROJECT_VERSION@/$RAW_VERSION/g" \ + -e "s/@PROJECT_COPYRIGHT@/$COPYRIGHT/g" \ + -e "s/@GIT_HASH@/$GIT_HASH/g" \ + source/project.h.in > source/project.h + + - name: Compilar pack_tool + run: | + g++ -std=c++20 -Wall -Os -Isource \ + tools/pack_resources/pack_resources.cpp \ + source/core/resources/resource_pack.cpp \ + -o tools/pack_resources/pack_resources + + - name: Generar resources.pack + run: ./tools/pack_resources/pack_resources data resources.pack + + - name: Compilar para Linux + run: | + TARGET_NAME=$(awk '/^project/ {gsub(/[)(]/, " "); print $2}' CMakeLists.txt) + CPP_FILES=$(find source -name "*.cpp") + g++ $CPP_FILES \ + -Isource -DRELEASE_BUILD -DLINUX_BUILD \ + -std=c++20 -Wall -Os -ffunction-sections -fdata-sections \ + -lSDL3 -lGL \ + -o $TARGET_NAME + strip -s -R .comment -R .gnu.version $TARGET_NAME --strip-unneeded + + - name: Empaquetar release + run: | + TARGET_NAME=$(awk '/^project/ {gsub(/[)(]/, " "); print $2}' CMakeLists.txt) + VERSION="${{ github.ref_name }}" + RELEASE_NAME="${TARGET_NAME}-${VERSION}-linux-x64.tar.gz" + mkdir -p release_tmp + cp $TARGET_NAME resources.pack LICENSE README.md gamecontrollerdb.txt release_tmp/ + tar -czvf $RELEASE_NAME -C release_tmp . + echo "RELEASE_FILE=$RELEASE_NAME" >> $GITHUB_ENV + + - name: Subir artefacto + uses: actions/upload-artifact@v3 + with: + name: linux-build + path: ${{ env.RELEASE_FILE }} + + # ============================================================================ + # BUILD WINDOWS x64 (cross-compile con MinGW) + # ============================================================================ + build-windows: + runs-on: ubuntu-latest + container: + image: ubuntu:24.04 + steps: + - name: Instalar dependencias + run: | + apt-get update + apt-get install -y nodejs npm build-essential cmake git pkg-config wget mingw-w64 zip + + - name: Descargar SDL3 para Windows + run: | + cd /tmp + wget -q https://github.com/libsdl-org/SDL/releases/download/release-${{ env.SDL3_VERSION }}/SDL3-devel-${{ env.SDL3_VERSION }}-mingw.tar.gz + tar -xzf SDL3-devel-${{ env.SDL3_VERSION }}-mingw.tar.gz + # Copiar a ubicación estándar para MinGW + cp -r SDL3-${{ env.SDL3_VERSION }}/x86_64-w64-mingw32/* /usr/x86_64-w64-mingw32/ + + - name: Checkout + uses: actions/checkout@v4 + + - name: Generar project.h + run: | + GIT_HASH=$(git rev-parse --short=7 HEAD) + RAW_VERSION=$(echo "${{ github.ref_name }}" | sed 's/^v//') + TARGET_NAME=$(awk '/^project/ {gsub(/[)(]/, " "); print $2}' CMakeLists.txt) + LONG_NAME=$(grep 'PROJECT_LONG_NAME' CMakeLists.txt | sed 's/.*"\(.*\)".*/\1/') + COPYRIGHT=$(sed -n 's/.*set(PROJECT_COPYRIGHT "\([^"]*\)".*/\1/p' CMakeLists.txt) + sed -e "s/@PROJECT_NAME@/$TARGET_NAME/g" \ + -e "s/@PROJECT_LONG_NAME@/$LONG_NAME/g" \ + -e "s/@PROJECT_VERSION@/$RAW_VERSION/g" \ + -e "s/@PROJECT_COPYRIGHT@/$COPYRIGHT/g" \ + -e "s/@GIT_HASH@/$GIT_HASH/g" \ + source/project.h.in > source/project.h + + - name: Compilar pack_tool + run: | + g++ -std=c++20 -Wall -Os -Isource \ + tools/pack_resources/pack_resources.cpp \ + source/core/resources/resource_pack.cpp \ + -o tools/pack_resources/pack_resources + + - name: Generar resources.pack + run: ./tools/pack_resources/pack_resources data resources.pack + + - name: Compilar para Windows (cross-compile) + run: | + TARGET_NAME=$(awk '/^project/ {gsub(/[)(]/, " "); print $2}' CMakeLists.txt) + LONG_NAME=$(grep 'PROJECT_LONG_NAME' CMakeLists.txt | sed 's/.*"\(.*\)".*/\1/') + CPP_FILES=$(find source -name "*.cpp") + x86_64-w64-mingw32-g++ $CPP_FILES \ + -Isource -DRELEASE_BUILD -DWINDOWS_BUILD \ + -std=c++20 -Wall -Os -ffunction-sections -fdata-sections \ + -Wl,--gc-sections -static-libstdc++ -static-libgcc \ + -Wl,-subsystem,windows \ + -lmingw32 -lws2_32 -lSDL3 -lopengl32 \ + -o "${LONG_NAME}.exe" + x86_64-w64-mingw32-strip -s -R .comment -R .gnu.version "${LONG_NAME}.exe" --strip-unneeded + + - name: Empaquetar release + run: | + TARGET_NAME=$(awk '/^project/ {gsub(/[)(]/, " "); print $2}' CMakeLists.txt) + LONG_NAME=$(grep 'PROJECT_LONG_NAME' CMakeLists.txt | sed 's/.*"\(.*\)".*/\1/') + VERSION="${{ github.ref_name }}" + RELEASE_NAME="${TARGET_NAME}-${VERSION}-win32-x64.zip" + mkdir -p release_tmp + cp "${LONG_NAME}.exe" resources.pack LICENSE README.md gamecontrollerdb.txt release_tmp/ + # Copiar SDL3.dll + cp /usr/x86_64-w64-mingw32/bin/SDL3.dll release_tmp/ + cd release_tmp && zip -r ../$RELEASE_NAME . && cd .. + echo "RELEASE_FILE=$RELEASE_NAME" >> $GITHUB_ENV + + - name: Subir artefacto + uses: actions/upload-artifact@v3 + with: + name: windows-build + path: ${{ env.RELEASE_FILE }} + + # ============================================================================ + # BUILD RASPBERRY PI ARM64 - DESACTIVADO TEMPORALMENTE + # Cross-compilation con OpenGL requiere libGL para ARM64 que no está disponible + # Se puede habilitar usando emulación ARM64 con QEMU en el futuro + # ============================================================================ + # build-rpi: + # runs-on: ubuntu-latest + # ... (código comentado) + + # ============================================================================ + # CREAR RELEASE EN GITEA + # ============================================================================ + create-release: + needs: [build-linux, build-windows] + runs-on: ubuntu-latest + container: + image: ubuntu:24.04 + steps: + - name: Instalar dependencias + run: | + apt-get update -qq + apt-get install -y -qq nodejs npm git jq curl + + - name: Checkout + uses: actions/checkout@v4 + + - name: Descargar todos los artefactos + uses: actions/download-artifact@v3 + with: + path: artifacts + + - name: Listar artefactos + run: find artifacts -type f + + - name: Crear Release en Gitea + env: + GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Crear release via API de Gitea + RELEASE_RESPONSE=$(curl -s -X POST \ + -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\": \"${{ github.ref_name }}\", \"name\": \"${{ github.ref_name }}\", \"body\": \"Release ${{ github.ref_name }}\", \"draft\": false, \"prerelease\": false}" \ + "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases") + + echo "Release response: $RELEASE_RESPONSE" + RELEASE_ID=$(echo "$RELEASE_RESPONSE" | jq -r '.id') + echo "Release ID: $RELEASE_ID" + + if [ "$RELEASE_ID" = "null" ] || [ -z "$RELEASE_ID" ]; then + echo "Error: No se pudo crear el release" + exit 1 + fi + + # Subir cada artefacto + for file in artifacts/**/*; do + if [ -f "$file" ]; then + filename=$(basename "$file") + echo "Subiendo: $filename" + curl -s -X POST \ + -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/octet-stream" \ + --data-binary "@$file" \ + "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=$filename" + fi + done + + echo "Release creado: ${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}" diff --git a/.gitignore b/.gitignore index da1c6e3..aac4913 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,10 @@ resources.pack pollo_release/ tools/pack_resources/pack_resources tools/pack_resources/pack_resources.exe + +# CI/CD runner data (local) +docker/runner-data/ +docker/config.yaml + +# Claude Code local settings (mantener carpeta .claude/ para comandos) +.claude/settings.local.json diff --git a/Makefile b/Makefile index 1b4ab67..7128eb7 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,7 @@ WINDOWS_RELEASE := $(TARGET_NAME)-$(VERSION)-win32-x64.zip MACOS_INTEL_RELEASE := $(TARGET_NAME)-$(VERSION)-macos-intel.dmg MACOS_APPLE_SILICON_RELEASE := $(TARGET_NAME)-$(VERSION)-macos-apple-silicon.dmg LINUX_RELEASE := $(TARGET_NAME)-$(VERSION)-linux.tar.gz +RPI_RELEASE := $(TARGET_NAME)-$(VERSION)-rpi-arm64.tar.gz # ============================================================================== # SOURCE FILES @@ -385,6 +386,55 @@ linux_release: # Elimina la carpeta temporal $(RMDIR) "$(RELEASE_FOLDER)" +# ============================================================================== +# COMPILACIÓN PARA RASPBERRY PI (ARM64) +# ============================================================================== +RPI_CXX := aarch64-linux-gnu-g++ +RPI_STRIP := aarch64-linux-gnu-strip +RPI_CXXFLAGS := -std=$(CPP_STANDARD) -Wall -Os -ffunction-sections -fdata-sections -DLINUX_BUILD -DRPI_BUILD +RPI_LDFLAGS := -lSDL3 -lGL + +rpi_release: + @$(MAKE) pack_tool + @$(MAKE) resources.pack + @echo "Creando release para Raspberry Pi (ARM64) - Version: $(VERSION)" + +# Generate project.h from project.h.in + @echo "Generando project.h..." + @GIT_HASH=$$(git rev-parse --short=7 HEAD 2>/dev/null || echo "unknown"); \ + RAW_VERSION=$$(echo "$(VERSION)" | sed 's/^v//'); \ + COPYRIGHT=$$(sed -n 's/.*set(PROJECT_COPYRIGHT "\([^"]*\)".*/\1/p' CMakeLists.txt); \ + sed -e "s/@PROJECT_NAME@/$(TARGET_NAME)/g" \ + -e "s/@PROJECT_LONG_NAME@/$(LONG_NAME)/g" \ + -e "s/@PROJECT_VERSION@/$$RAW_VERSION/g" \ + -e "s/@PROJECT_COPYRIGHT@/$$COPYRIGHT/g" \ + -e "s/@GIT_HASH@/$$GIT_HASH/g" \ + source/project.h.in > source/project.h + +# Elimina carpetas previas + $(RMDIR) "$(RELEASE_FOLDER)" + +# Crea la carpeta temporal para realizar el lanzamiento + $(MKDIR) "$(RELEASE_FOLDER)" + +# Copia ficheros + cp resources.pack "$(RELEASE_FOLDER)" + cp LICENSE "$(RELEASE_FOLDER)" + cp README.md "$(RELEASE_FOLDER)" + cp gamecontrollerdb.txt "$(RELEASE_FOLDER)" + +# Compila con cross-compiler ARM64 + $(RPI_CXX) $(ALL_SOURCES) $(INCLUDES) -DRELEASE_BUILD $(RPI_CXXFLAGS) $(RPI_LDFLAGS) -o "$(RELEASE_FILE)" + $(RPI_STRIP) -s -R .comment -R .gnu.version "$(RELEASE_FILE)" --strip-unneeded + +# Empaqueta ficheros + $(RMFILE) "$(RPI_RELEASE)" + tar -czvf "$(RPI_RELEASE)" -C "$(RELEASE_FOLDER)" . + @echo "Release creado: $(RPI_RELEASE)" + +# Elimina la carpeta temporal + $(RMDIR) "$(RELEASE_FOLDER)" + # ============================================================================== # SETUP # ============================================================================== @@ -410,6 +460,7 @@ help: @echo " linux - Compilar para Linux" @echo " linux_debug - Compilar debug para Linux" @echo " linux_release - Crear release completo para Linux" + @echo " rpi_release - Crear release para Raspberry Pi (ARM64)" @echo " macos - Compilar para macOS" @echo " macos_debug - Compilar debug para macOS" @echo " macos_release - Crear release completo para macOS" @@ -421,4 +472,4 @@ help: FORCE: -.PHONY: windows windows_debug windows_release macos macos_debug macos_release linux linux_debug linux_release pack_tool resources.pack setup_hooks show_version help +.PHONY: windows windows_debug windows_release macos macos_debug macos_release linux linux_debug linux_release rpi_release pack_tool resources.pack setup_hooks show_version help diff --git a/docker/Dockerfile.build b/docker/Dockerfile.build new file mode 100644 index 0000000..10d0857 --- /dev/null +++ b/docker/Dockerfile.build @@ -0,0 +1,46 @@ +# Imagen para compilar pollo en múltiples plataformas +# Incluye herramientas para: Linux x64, Windows x64 (cross), Raspberry Pi ARM64 (cross) +# SDL3 se compila en cada job del workflow + +FROM ubuntu:24.04 + +ENV DEBIAN_FRONTEND=noninteractive + +# Herramientas básicas de build +RUN apt-get update && apt-get install -y \ + build-essential \ + cmake \ + git \ + pkg-config \ + wget \ + tar \ + gzip \ + zip \ + # Node.js (requerido para GitHub/Gitea Actions) + nodejs \ + npm \ + # Cross-compilación Windows + mingw-w64 \ + # Cross-compilación Raspberry Pi ARM64 + gcc-aarch64-linux-gnu \ + g++-aarch64-linux-gnu \ + # Dependencias para compilar SDL3 (Linux nativo) + libgl1-mesa-dev \ + libglu1-mesa-dev \ + libx11-dev \ + libxext-dev \ + libxrandr-dev \ + libxcursor-dev \ + libxi-dev \ + libxinerama-dev \ + libxxf86vm-dev \ + libxss-dev \ + libasound2-dev \ + libpulse-dev \ + libudev-dev \ + libdbus-1-dev \ + libwayland-dev \ + libxkbcommon-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /workspace diff --git a/docker/docker-compose.runner.yml b/docker/docker-compose.runner.yml new file mode 100644 index 0000000..44ea2b2 --- /dev/null +++ b/docker/docker-compose.runner.yml @@ -0,0 +1,28 @@ +# Docker Compose para act_runner de Gitea Actions +# +# USO: +# 1. Obtener token de registro en Gitea > Settings > Actions > Runners +# 2. Actualizar GITEA_RUNNER_REGISTRATION_TOKEN abajo +# 3. Iniciar: docker compose -f docker-compose.runner.yml up -d runner +# 4. Ver logs: docker compose -f docker-compose.runner.yml logs -f runner + +services: + runner: + image: gitea/act_runner:latest + container_name: gitea-runner-pollo + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./runner-data:/data + environment: + - GITEA_INSTANCE_URL=http://gitea:3000 + - GITEA_RUNNER_REGISTRATION_TOKEN=${RUNNER_TOKEN} + - GITEA_RUNNER_NAME=pollo-runner + - GITEA_RUNNER_LABELS=ubuntu-latest:docker://ubuntu:24.04,linux:docker://ubuntu:24.04 + - CONFIG_FILE=/data/config.yaml + networks: + - web + +networks: + web: + external: true diff --git a/source/core/resources/resource_pack.cpp b/source/core/resources/resource_pack.cpp index 838e7e6..f618fde 100644 --- a/source/core/resources/resource_pack.cpp +++ b/source/core/resources/resource_pack.cpp @@ -3,8 +3,6 @@ #include "resource_pack.hpp" -#include - #include #include #include