Files
skelly/.gitea/workflows/build.yml

650 lines
24 KiB
YAML

name: Build Game
# Build pipeline for creating game executables across multiple platforms
#
# Features:
# - Manual trigger with individual platform checkboxes
# - Configurable version override (defaults to auto-generated)
# - Configurable tool versions (Godot, Java, Android API, etc.)
# - Flexible runner OS selection
# - Tag-based automatic builds for releases
# - Multi-platform builds (Windows, Linux, macOS, Android)
# - Artifact storage for one week
# - Comprehensive build configuration options
on:
# Manual trigger with platform selection
workflow_dispatch:
inputs:
build_windows:
description: 'Build for Windows'
required: false
default: true
type: boolean
build_linux:
description: 'Build for Linux'
required: false
default: false
type: boolean
build_macos:
description: 'Build for macOS'
required: false
default: false
type: boolean
build_android:
description: 'Build for Android'
required: false
default: false
type: boolean
version:
description: 'Version (leave empty for auto-generated)'
required: false
default: ''
type: string
build_type:
description: 'Build type'
required: true
default: 'release'
type: debug
options:
- release
- debug
godot_version:
description: 'Godot version (leave empty for default)'
required: false
default: ''
type: string
runner_os:
description: 'Runner OS (leave empty for default ubuntu-latest)'
required: false
default: ''
type: string
java_version:
description: 'Java version (leave empty for default)'
required: false
default: ''
type: string
android_api_level:
description: 'Android API level (leave empty for default)'
required: false
default: ''
type: string
# Automatic trigger on git tags (for releases)
push:
tags:
- 'v*' # Version tags (v1.0.0, v2.1.0, etc.)
- 'release-*' # Release tags
env:
# Core Configuration
GODOT_VERSION: "4.4.1"
PROJECT_NAME: "Skelly"
BUILD_DIR: "builds"
DEFAULT_VERSION: "1.0.0-dev"
# GitHub Actions Versions
ACTIONS_CHECKOUT_VERSION: "v4"
ACTIONS_CACHE_VERSION: "v4"
ACTIONS_UPLOAD_ARTIFACT_VERSION: "v3"
ACTIONS_SETUP_JAVA_VERSION: "v4"
# Third-party Actions Versions
CHICKENSOFT_SETUP_GODOT_VERSION: "v1"
ANDROID_ACTIONS_SETUP_ANDROID_VERSION: "v3"
# Runner Configuration
RUNNER_OS: "ubuntu-latest"
# Java Configuration
JAVA_DISTRIBUTION: "temurin"
JAVA_VERSION: "17"
# Android Configuration
ANDROID_API_LEVEL: "33"
ANDROID_BUILD_TOOLS_VERSION: "33.0.0"
ANDROID_CMDLINE_TOOLS_VERSION: "latest"
jobs:
# Preparation job - determines build configuration
prepare:
name: Prepare Build
runs-on: ${{ env.RUNNER_OS }}
outputs:
platforms: ${{ steps.config.outputs.platforms }}
build_type: ${{ steps.config.outputs.build_type }}
version: ${{ steps.config.outputs.version }}
artifact_name: ${{ steps.config.outputs.artifact_name }}
steps:
- name: Checkout repository
uses: actions/checkout@${{ env.ACTIONS_CHECKOUT_VERSION }}
with:
fetch-depth: 0
- name: Configure build parameters
id: config
run: |
# Override environment variables with user inputs if provided
if [[ -n "${{ github.event.inputs.godot_version }}" ]]; then
echo "GODOT_VERSION=${{ github.event.inputs.godot_version }}" >> $GITHUB_ENV
echo "🔧 Using custom Godot version: ${{ github.event.inputs.godot_version }}"
fi
if [[ -n "${{ github.event.inputs.runner_os }}" ]]; then
echo "RUNNER_OS=${{ github.event.inputs.runner_os }}" >> $GITHUB_ENV
echo "🔧 Using custom runner OS: ${{ github.event.inputs.runner_os }}"
fi
if [[ -n "${{ github.event.inputs.java_version }}" ]]; then
echo "JAVA_VERSION=${{ github.event.inputs.java_version }}" >> $GITHUB_ENV
echo "🔧 Using custom Java version: ${{ github.event.inputs.java_version }}"
fi
if [[ -n "${{ github.event.inputs.android_api_level }}" ]]; then
echo "ANDROID_API_LEVEL=${{ github.event.inputs.android_api_level }}" >> $GITHUB_ENV
echo "ANDROID_BUILD_TOOLS_VERSION=${{ github.event.inputs.android_api_level }}.0.0" >> $GITHUB_ENV
echo "🔧 Using custom Android API level: ${{ github.event.inputs.android_api_level }}"
fi
# Determine platforms to build
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
# Build platforms array from individual checkboxes
platforms=""
if [[ "${{ github.event.inputs.build_windows }}" == "true" ]]; then
platforms="${platforms}windows,"
fi
if [[ "${{ github.event.inputs.build_linux }}" == "true" ]]; then
platforms="${platforms}linux,"
fi
if [[ "${{ github.event.inputs.build_macos }}" == "true" ]]; then
platforms="${platforms}macos,"
fi
if [[ "${{ github.event.inputs.build_android }}" == "true" ]]; then
platforms="${platforms}android,"
fi
# Remove trailing comma
platforms="${platforms%,}"
build_type="${{ github.event.inputs.build_type }}"
user_version="${{ github.event.inputs.version }}"
else
# Tag-triggered build - build all platforms
platforms="windows,linux,macos,android"
build_type="release"
user_version=""
fi
# Determine version with improved logic
if [[ -n "$user_version" ]]; then
# User provided explicit version
version="$user_version"
echo "🏷️ Using user-specified version: $version"
elif [[ "${{ github.ref_type }}" == "tag" ]]; then
# Tag-triggered build - use tag name
version="${{ github.ref_name }}"
echo "🏷️ Using git tag version: $version"
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
# Manual dispatch without version - use default + git info
commit_short=$(git rev-parse --short HEAD)
branch_name="${{ github.ref_name }}"
timestamp=$(date +%Y%m%d-%H%M)
version="${{ env.DEFAULT_VERSION }}-${branch_name}-${commit_short}-${timestamp}"
echo "🏷️ Using auto-generated version: $version"
else
# Fallback for other triggers
commit_short=$(git rev-parse --short HEAD)
branch_name="${{ github.ref_name }}"
timestamp=$(date +%Y%m%d-%H%M)
version="${{ env.DEFAULT_VERSION }}-${branch_name}-${commit_short}-${timestamp}"
echo "🏷️ Using fallback version: $version"
fi
# Create artifact name
artifact_name="${{ env.PROJECT_NAME }}-${version}-${build_type}"
echo "platforms=${platforms}" >> $GITHUB_OUTPUT
echo "build_type=${build_type}" >> $GITHUB_OUTPUT
echo "version=${version}" >> $GITHUB_OUTPUT
echo "artifact_name=${artifact_name}" >> $GITHUB_OUTPUT
echo "🔧 Build Configuration:"
echo " Platforms: ${platforms}"
echo " Build Type: ${build_type}"
echo " Version: ${version}"
echo " Artifact: ${artifact_name}"
echo ""
echo "🔧 Tool Versions:"
echo " Godot: ${GODOT_VERSION}"
echo " Runner OS: ${RUNNER_OS}"
echo " Java: ${JAVA_VERSION}"
echo " Android API: ${ANDROID_API_LEVEL}"
echo " Android Build Tools: ${ANDROID_BUILD_TOOLS_VERSION}"
# Setup export templates (shared across all platform builds)
setup-templates:
name: Setup Export Templates
runs-on: ${{ env.RUNNER_OS }}
needs: prepare
steps:
- name: Cache export templates
id: cache-templates
uses: actions/cache@${{ env.ACTIONS_CACHE_VERSION }}
with:
path: ~/.local/share/godot/export_templates
key: godot-templates-${{ env.GODOT_VERSION }}
restore-keys: |
godot-templates-
- name: Setup Godot
if: steps.cache-templates.outputs.cache-hit != 'true'
uses: chickensoft-games/setup-godot@${{ env.CHICKENSOFT_SETUP_GODOT_VERSION }}
with:
version: ${{ env.GODOT_VERSION }}
use-dotnet: false
- name: Install export templates
if: steps.cache-templates.outputs.cache-hit != 'true'
run: |
echo "📦 Installing Godot export templates..."
mkdir -p ~/.local/share/godot/export_templates/${{ env.GODOT_VERSION }}.stable
wget -q https://github.com/godotengine/godot/releases/download/${{ env.GODOT_VERSION }}-stable/Godot_v${{ env.GODOT_VERSION }}-stable_export_templates.tpz
unzip -q Godot_v${{ env.GODOT_VERSION }}-stable_export_templates.tpz
mv templates/* ~/.local/share/godot/export_templates/${{ env.GODOT_VERSION }}.stable/
echo "✅ Export templates installed successfully"
ls -la ~/.local/share/godot/export_templates/${{ env.GODOT_VERSION }}.stable/
- name: Verify templates cache
run: |
echo "🔍 Verifying export templates are available:"
ls -la ~/.local/share/godot/export_templates/${{ env.GODOT_VERSION }}.stable/
# Windows build job
build-windows:
name: Build Windows
runs-on: ${{ env.RUNNER_OS }}
needs: [prepare, setup-templates]
if: contains(needs.prepare.outputs.platforms, 'windows')
steps:
- name: Checkout repository
uses: actions/checkout@${{ env.ACTIONS_CHECKOUT_VERSION }}
- name: Setup Godot
uses: chickensoft-games/setup-godot@${{ env.CHICKENSOFT_SETUP_GODOT_VERSION }}
with:
version: ${{ env.GODOT_VERSION }}
use-dotnet: false
- name: Restore export templates cache
uses: actions/cache@${{ env.ACTIONS_CACHE_VERSION }}
with:
path: ~/.local/share/godot/export_templates
key: godot-templates-${{ env.GODOT_VERSION }}
restore-keys: |
godot-templates-
- name: Create build directory
run: mkdir -p ${{ env.BUILD_DIR }}
- name: Import project assets
run: |
echo "📦 Importing project assets..."
godot --headless --verbose --editor --quit || true
sleep 2
- name: Build Windows executable
run: |
echo "🏗️ Building Windows executable..."
godot --headless --verbose --export-${{ needs.prepare.outputs.build_type }} "Windows Desktop" \
${{ env.BUILD_DIR }}/skelly-windows-${{ needs.prepare.outputs.version }}.exe
# Verify build output
if [[ -f "${{ env.BUILD_DIR }}/skelly-windows-${{ needs.prepare.outputs.version }}.exe" ]]; then
echo "✅ Windows build successful"
ls -la ${{ env.BUILD_DIR }}/
else
echo "❌ Windows build failed"
exit 1
fi
- name: Upload Windows build
uses: actions/upload-artifact@${{ env.ACTIONS_UPLOAD_ARTIFACT_VERSION }}
with:
name: ${{ needs.prepare.outputs.artifact_name }}-windows
path: ${{ env.BUILD_DIR }}/skelly-windows-${{ needs.prepare.outputs.version }}.exe
retention-days: 7
compression-level: 0
# Linux build job
build-linux:
name: Build Linux
runs-on: ${{ env.RUNNER_OS }}
needs: [prepare, setup-templates]
if: contains(needs.prepare.outputs.platforms, 'linux')
steps:
- name: Checkout repository
uses: actions/checkout@${{ env.ACTIONS_CHECKOUT_VERSION }}
- name: Setup Godot
uses: chickensoft-games/setup-godot@${{ env.CHICKENSOFT_SETUP_GODOT_VERSION }}
with:
version: ${{ env.GODOT_VERSION }}
use-dotnet: false
- name: Restore export templates cache
uses: actions/cache@${{ env.ACTIONS_CACHE_VERSION }}
with:
path: ~/.local/share/godot/export_templates
key: godot-templates-${{ env.GODOT_VERSION }}
restore-keys: |
godot-templates-
- name: Create build directory
run: mkdir -p ${{ env.BUILD_DIR }}
- name: Import project assets
run: |
echo "📦 Importing project assets..."
godot --headless --verbose --editor --quit || true
sleep 2
- name: Build Linux executable
run: |
echo "🏗️ Building Linux executable..."
godot --headless --verbose --export-${{ needs.prepare.outputs.build_type }} "Linux" \
${{ env.BUILD_DIR }}/skelly-linux-${{ needs.prepare.outputs.version }}.x86_64
# Make executable
chmod +x ${{ env.BUILD_DIR }}/skelly-linux-${{ needs.prepare.outputs.version }}.x86_64
# Verify build output
if [[ -f "${{ env.BUILD_DIR }}/skelly-linux-${{ needs.prepare.outputs.version }}.x86_64" ]]; then
echo "✅ Linux build successful"
ls -la ${{ env.BUILD_DIR }}/
else
echo "❌ Linux build failed"
exit 1
fi
- name: Upload Linux build
uses: actions/upload-artifact@${{ env.ACTIONS_UPLOAD_ARTIFACT_VERSION }}
with:
name: ${{ needs.prepare.outputs.artifact_name }}-linux
path: ${{ env.BUILD_DIR }}/skelly-linux-${{ needs.prepare.outputs.version }}.x86_64
retention-days: 7
compression-level: 0
# macOS build job
build-macos:
name: Build macOS
runs-on: ${{ env.RUNNER_OS }}
needs: [prepare, setup-templates]
if: contains(needs.prepare.outputs.platforms, 'macos')
steps:
- name: Checkout repository
uses: actions/checkout@${{ env.ACTIONS_CHECKOUT_VERSION }}
- name: Setup Godot
uses: chickensoft-games/setup-godot@${{ env.CHICKENSOFT_SETUP_GODOT_VERSION }}
with:
version: ${{ env.GODOT_VERSION }}
use-dotnet: false
- name: Restore export templates cache
uses: actions/cache@${{ env.ACTIONS_CACHE_VERSION }}
with:
path: ~/.local/share/godot/export_templates
key: godot-templates-${{ env.GODOT_VERSION }}
restore-keys: |
godot-templates-
- name: Create build directory
run: mkdir -p ${{ env.BUILD_DIR }}
- name: Import project assets
run: |
echo "📦 Importing project assets..."
godot --headless --verbose --editor --quit || true
sleep 2
- name: Build macOS application
run: |
echo "🏗️ Building macOS application..."
godot --headless --verbose --export-${{ needs.prepare.outputs.build_type }} "macOS" \
${{ env.BUILD_DIR }}/skelly-macos-${{ needs.prepare.outputs.version }}.zip
# Verify build output
if [[ -f "${{ env.BUILD_DIR }}/skelly-macos-${{ needs.prepare.outputs.version }}.zip" ]]; then
echo "✅ macOS build successful"
ls -la ${{ env.BUILD_DIR }}/
else
echo "❌ macOS build failed"
exit 1
fi
- name: Upload macOS build
uses: actions/upload-artifact@${{ env.ACTIONS_UPLOAD_ARTIFACT_VERSION }}
with:
name: ${{ needs.prepare.outputs.artifact_name }}-macos
path: ${{ env.BUILD_DIR }}/skelly-macos-${{ needs.prepare.outputs.version }}.zip
retention-days: 7
compression-level: 0
# Android build job
build-android:
name: Build Android
runs-on: ${{ env.RUNNER_OS }}
needs: [prepare, setup-templates]
if: contains(needs.prepare.outputs.platforms, 'android')
steps:
- name: Checkout repository
uses: actions/checkout@${{ env.ACTIONS_CHECKOUT_VERSION }}
- name: Setup Java
uses: actions/setup-java@${{ env.ACTIONS_SETUP_JAVA_VERSION }}
with:
distribution: ${{ env.JAVA_DISTRIBUTION }}
java-version: ${{ env.JAVA_VERSION }}
- name: Setup Android SDK
uses: android-actions/setup-android@${{ env.ANDROID_ACTIONS_SETUP_ANDROID_VERSION }}
with:
api-level: ${{ env.ANDROID_API_LEVEL }}
build-tools: ${{ env.ANDROID_BUILD_TOOLS_VERSION }}
- name: Install Android Build Tools
run: |
echo "🔧 Installing Android Build Tools..."
# Set Android environment variables
export ANDROID_HOME=${ANDROID_SDK_ROOT}
echo "ANDROID_HOME=${ANDROID_SDK_ROOT}" >> $GITHUB_ENV
echo "ANDROID_SDK_ROOT=${ANDROID_SDK_ROOT}" >> $GITHUB_ENV
# Install build-tools using sdkmanager
yes | ${ANDROID_SDK_ROOT}/cmdline-tools/${{ env.ANDROID_CMDLINE_TOOLS_VERSION }}/bin/sdkmanager --licenses || true
${ANDROID_SDK_ROOT}/cmdline-tools/${{ env.ANDROID_CMDLINE_TOOLS_VERSION }}/bin/sdkmanager "build-tools;${{ env.ANDROID_BUILD_TOOLS_VERSION }}"
${ANDROID_SDK_ROOT}/cmdline-tools/${{ env.ANDROID_CMDLINE_TOOLS_VERSION }}/bin/sdkmanager "platforms;android-${{ env.ANDROID_API_LEVEL }}"
- name: Verify Android SDK Configuration
run: |
echo "📱 Verifying Android SDK setup..."
echo "📱 Using API Level: ${{ env.ANDROID_API_LEVEL }}"
echo "📱 Using Build Tools: ${{ env.ANDROID_BUILD_TOOLS_VERSION }}"
# Verify SDK installation
echo "📱 Android SDK Location: ${ANDROID_SDK_ROOT}"
ls -la ${ANDROID_SDK_ROOT}/
echo "📱 Build Tools:"
ls -la ${ANDROID_SDK_ROOT}/build-tools/
echo "📱 Platforms:"
ls -la ${ANDROID_SDK_ROOT}/platforms/ || echo "No platforms directory"
# Verify apksigner exists
if [ -f "${ANDROID_SDK_ROOT}/build-tools/${{ env.ANDROID_BUILD_TOOLS_VERSION }}/apksigner" ]; then
echo "✅ apksigner found at ${ANDROID_SDK_ROOT}/build-tools/${{ env.ANDROID_BUILD_TOOLS_VERSION }}/apksigner"
else
echo "❌ apksigner not found!"
exit 1
fi
- name: Setup Godot
uses: chickensoft-games/setup-godot@${{ env.CHICKENSOFT_SETUP_GODOT_VERSION }}
with:
version: ${{ env.GODOT_VERSION }}
use-dotnet: false
- name: Configure Godot for Android
run: |
echo "🎮 Configuring Godot for Android builds..."
# Create Godot config directory
mkdir -p ~/.config/godot
# Configure Android SDK path in Godot settings
cat > ~/.config/godot/editor_settings-4.4.tres << EOF
[gd_resource type="EditorSettings" format=3]
[resource]
export/android/android_sdk_path = "${ANDROID_SDK_ROOT}"
export/android/debug_keystore = ""
export/android/debug_keystore_user = "androiddebugkey"
export/android/debug_keystore_pass = "android"
export/android/force_system_user = false
export/android/timestamping_authority_url = ""
export/android/shutdown_adb_on_exit = true
EOF
echo "✅ Godot Android configuration complete"
- name: Restore export templates cache
uses: actions/cache@${{ env.ACTIONS_CACHE_VERSION }}
with:
path: ~/.local/share/godot/export_templates
key: godot-templates-${{ env.GODOT_VERSION }}
restore-keys: |
godot-templates-
- name: Create build directory
run: mkdir -p ${{ env.BUILD_DIR }}
- name: Import project assets
run: |
echo "📦 Importing project assets..."
godot --headless --verbose --editor --quit || true
sleep 2
- name: Build Android APK
run: |
echo "🏗️ Building Android APK..."
# Verify Android environment
echo "📱 Android SDK: ${ANDROID_SDK_ROOT}"
echo "📱 API Level: ${{ env.ANDROID_API_LEVEL }}"
echo "📱 Build Tools Version: ${{ env.ANDROID_BUILD_TOOLS_VERSION }}"
echo "📱 Available Build Tools: $(ls ${ANDROID_SDK_ROOT}/build-tools/)"
godot --headless --verbose --export-${{ needs.prepare.outputs.build_type }} "Android" \
${{ env.BUILD_DIR }}/skelly-android-${{ needs.prepare.outputs.version }}.apk
# Verify build output
if [[ -f "${{ env.BUILD_DIR }}/skelly-android-${{ needs.prepare.outputs.version }}.apk" ]]; then
echo "✅ Android build successful"
ls -la ${{ env.BUILD_DIR }}/
# Show APK info
echo "📱 APK Information:"
file ${{ env.BUILD_DIR }}/skelly-android-${{ needs.prepare.outputs.version }}.apk
else
echo "❌ Android build failed"
exit 1
fi
- name: Upload Android build
uses: actions/upload-artifact@${{ env.ACTIONS_UPLOAD_ARTIFACT_VERSION }}
with:
name: ${{ needs.prepare.outputs.artifact_name }}-android
path: ${{ env.BUILD_DIR }}/skelly-android-${{ needs.prepare.outputs.version }}.apk
retention-days: 7
compression-level: 0
# Summary job - creates release summary
summary:
name: Build Summary
runs-on: ${{ env.RUNNER_OS }}
needs: [prepare, setup-templates, build-windows, build-linux, build-macos, build-android]
if: always()
steps:
- name: Generate build summary
run: |
echo "🎮 Build Summary for ${{ needs.prepare.outputs.artifact_name }}"
echo "=================================="
echo ""
echo "📋 Configuration:"
echo " Version: ${{ needs.prepare.outputs.version }}"
echo " Build Type: ${{ needs.prepare.outputs.build_type }}"
echo " Platforms: ${{ needs.prepare.outputs.platforms }}"
echo ""
echo "📊 Build Results:"
platforms="${{ needs.prepare.outputs.platforms }}"
if [[ "$platforms" == *"windows"* ]]; then
windows_status="${{ needs.build-windows.result }}"
echo " 🪟 Windows: $windows_status"
fi
if [[ "$platforms" == *"linux"* ]]; then
linux_status="${{ needs.build-linux.result }}"
echo " 🐧 Linux: $linux_status"
fi
if [[ "$platforms" == *"macos"* ]]; then
macos_status="${{ needs.build-macos.result }}"
echo " 🍎 macOS: $macos_status"
fi
if [[ "$platforms" == *"android"* ]]; then
android_status="${{ needs.build-android.result }}"
echo " 🤖 Android: $android_status"
fi
echo ""
echo "📦 Artifacts are available for 7 days"
echo "🔗 Download from: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
- name: Check overall build status
run: |
# Check if any required builds failed
platforms="${{ needs.prepare.outputs.platforms }}"
failed_builds=()
if [[ "$platforms" == *"windows"* ]] && [[ "${{ needs.build-windows.result }}" != "success" ]]; then
failed_builds+=("Windows")
fi
if [[ "$platforms" == *"linux"* ]] && [[ "${{ needs.build-linux.result }}" != "success" ]]; then
failed_builds+=("Linux")
fi
if [[ "$platforms" == *"macos"* ]] && [[ "${{ needs.build-macos.result }}" != "success" ]]; then
failed_builds+=("macOS")
fi
if [[ "$platforms" == *"android"* ]] && [[ "${{ needs.build-android.result }}" != "success" ]]; then
failed_builds+=("Android")
fi
if [[ ${#failed_builds[@]} -gt 0 ]]; then
echo "❌ Build failed for: ${failed_builds[*]}"
exit 1
else
echo "✅ All builds completed successfully!"
fi