chore: Remove outdated GitHub workflows

- Deleted the `build-windows-fallback.yml`, `release-complex.yml`, `release-simplified.yml`, and `release.yml` workflows to streamline CI/CD processes.
- These workflows were redundant and have been replaced by more efficient configurations in the current CI setup.
This commit is contained in:
scawful
2025-10-08 17:17:41 -04:00
parent 6fa3254f32
commit 666b92bd07
5 changed files with 261 additions and 1988 deletions

View File

@@ -1,151 +0,0 @@
name: Windows Build Fallback
on:
workflow_call:
inputs:
build_type:
description: 'Build type (Debug/Release)'
required: true
type: string
default: 'Release'
platform:
description: 'Platform (x64/x86)'
required: true
type: string
default: 'x64'
env:
BUILD_TYPE: ${{ inputs.build_type }}
PLATFORM: ${{ inputs.platform }}
jobs:
build-windows-fallback:
name: Windows ${{ inputs.platform }} ${{ inputs.build_type }} (Fallback)
runs-on: windows-2022
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
# Try vcpkg first
- name: Set up vcpkg (Primary)
id: vcpkg_primary
uses: lukka/run-vcpkg@v11
continue-on-error: true
with:
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
runVcpkgInstall: true
vcpkgJsonGlob: '**/vcpkg.json'
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
env:
VCPKG_FORCE_SYSTEM_BINARIES: 1
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
VCPKG_DEFAULT_TRIPLET: '${{ inputs.platform }}-windows'
VCPKG_INSTALL_OPTIONS: '--x-install-root="${{ github.workspace }}/vcpkg_installed"'
# Fallback to newer baseline if primary fails
- name: Set up vcpkg (Fallback)
if: steps.vcpkg_primary.outcome == 'failure'
uses: lukka/run-vcpkg@v11
with:
vcpkgGitCommitId: '2024.01.12'
runVcpkgInstall: true
vcpkgJsonGlob: '**/vcpkg.json.backup'
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
env:
VCPKG_FORCE_SYSTEM_BINARIES: 1
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
VCPKG_DEFAULT_TRIPLET: '${{ inputs.platform }}-windows'
VCPKG_INSTALL_OPTIONS: '--x-install-root="${{ github.workspace }}/vcpkg_installed"'
# Fallback to manual dependency installation if both vcpkg attempts fail
- name: Install dependencies manually
if: steps.vcpkg_primary.outcome == 'failure'
shell: pwsh
run: |
Write-Host "Installing dependencies manually using Chocolatey and pre-built libraries..."
# Install Chocolatey if not present
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
}
# Install basic dependencies
choco install -y cmake ninja
# Create a minimal build configuration
Write-Host "Creating minimal build configuration for CI..."
# Set up environment variables for minimal build
echo "YAZE_MINIMAL_BUILD=ON" >> $env:GITHUB_ENV
echo "CMAKE_PREFIX_PATH=$env:GITHUB_WORKSPACE\vcpkg_installed\${{ inputs.platform }}-windows" >> $env:GITHUB_ENV
- name: Configure CMake
shell: cmd
run: |
if exist "${{ github.workspace }}\vcpkg_installed" (
echo "Using vcpkg installation..."
cmake -B build ^
-DCMAKE_BUILD_TYPE=%BUILD_TYPE% ^
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 ^
-DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake" ^
-DYAZE_BUILD_TESTS=OFF ^
-DYAZE_BUILD_EMU=OFF ^
-DYAZE_BUILD_Z3ED=OFF ^
-DYAZE_ENABLE_ROM_TESTS=OFF ^
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF ^
-DYAZE_INSTALL_LIB=OFF ^
-DYAZE_MINIMAL_BUILD=ON ^
-G "Visual Studio 17 2022" ^
-A %PLATFORM%
) else (
echo "Using minimal build configuration..."
cmake -B build ^
-DCMAKE_BUILD_TYPE=%BUILD_TYPE% ^
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 ^
-DYAZE_BUILD_TESTS=OFF ^
-DYAZE_BUILD_EMU=OFF ^
-DYAZE_BUILD_Z3ED=OFF ^
-DYAZE_ENABLE_ROM_TESTS=OFF ^
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF ^
-DYAZE_INSTALL_LIB=OFF ^
-DYAZE_MINIMAL_BUILD=ON ^
-G "Visual Studio 17 2022" ^
-A %PLATFORM%
)
- name: Build
run: cmake --build build --config %BUILD_TYPE% --parallel
- name: Test executable
shell: pwsh
run: |
$exePath = "build\bin\$env:BUILD_TYPE\yaze.exe"
if (Test-Path $exePath) {
Write-Host "✓ Executable created: $exePath" -ForegroundColor Green
# Test that it's not the test main
$testResult = & $exePath --help 2>&1
if ($testResult -match "Google Test" -or $testResult -match "gtest") {
Write-Error "Executable is running test main instead of app main!"
exit 1
}
Write-Host "✓ Executable runs correctly" -ForegroundColor Green
} else {
Write-Error "Executable not found at: $exePath"
exit 1
}
- name: Upload build artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: yaze-${{ inputs.platform }}-${{ inputs.build_type }}-fallback
path: |
build/bin/${{ inputs.build_type }}/
retention-days: 7

View File

@@ -19,57 +19,34 @@ on:
- '.github/workflows/**'
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: RelWithDebInfo
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
jobs:
# This job determines which build matrix to use based on the event type
prepare-matrix:
name: "⚙️ Prepare Build Matrix"
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- id: set-matrix
shell: bash
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "Using focused matrix for PR"
echo 'matrix={"include":[{"name":"Ubuntu 22.04 (GCC-12)","os":"ubuntu-22.04","cc":"gcc-12","cxx":"g++-12"},{"name":"macOS 14 (Clang)","os":"macos-14","cc":"clang","cxx":"clang++","vcpkg_triplet":"arm64-osx"},{"name":"Windows 2022 (MSVC x64)","os":"windows-2022","cc":"cl","cxx":"cl","vcpkg_triplet":"x64-windows","cmake_generator":"Visual Studio 17 2022","cmake_generator_platform":"x64"}]}' >> "$GITHUB_OUTPUT"
else
echo "Using comprehensive matrix for push"
echo 'matrix={"include":[{"name":"Ubuntu 22.04 (GCC-12)","os":"ubuntu-22.04","cc":"gcc-12","cxx":"g++-12"},{"name":"Ubuntu 22.04 (Clang)","os":"ubuntu-22.04","cc":"clang-15","cxx":"clang++-15"},{"name":"macOS 13 (Clang)","os":"macos-13","cc":"clang","cxx":"clang++","vcpkg_triplet":"x64-osx"},{"name":"macOS 14 (Clang)","os":"macos-14","cc":"clang","cxx":"clang++","vcpkg_triplet":"arm64-osx"},{"name":"Windows 2022 (MSVC x64)","os":"windows-2022","cc":"cl","cxx":"cl","vcpkg_triplet":"x64-windows","cmake_generator":"Visual Studio 17 2022","cmake_generator_platform":"x64"},{"name":"Windows 2022 (MSVC x86)","os":"windows-2022","cc":"cl","cxx":"cl","vcpkg_triplet":"x86-windows","cmake_generator":"Visual Studio 17 2022","cmake_generator_platform":"Win32"}]}' >> "$GITHUB_OUTPUT"
fi
build-and-test:
name: "${{ matrix.name }}"
needs: prepare-matrix
strategy:
fail-fast: false
matrix:
include:
- name: "Ubuntu 22.04 (GCC-12)"
os: ubuntu-22.04
cc: gcc-12
cxx: g++-12
vcpkg_triplet: x64-linux
- name: "Ubuntu 22.04 (Clang)"
os: ubuntu-22.04
cc: clang-15
cxx: clang++-15
vcpkg_triplet: x64-linux
- name: "macOS 13 (Clang)"
os: macos-13
cc: clang
cxx: clang++
vcpkg_triplet: x64-osx
- name: "macOS 14 (Clang)"
os: macos-14
cc: clang
cxx: clang++
vcpkg_triplet: arm64-osx
- name: "Windows 2022 (MSVC x64)"
os: windows-2022
cc: cl
cxx: cl
vcpkg_triplet: x64-windows
cmake_generator: "Visual Studio 17 2022"
cmake_generator_platform: x64
- name: "Windows 2022 (MSVC x86)"
os: windows-2022
cc: cl
cxx: cl
vcpkg_triplet: x86-windows
cmake_generator: "Visual Studio 17 2022"
cmake_generator_platform: Win32
name: ${{ matrix.name }}
matrix: ${{ fromJson(needs.prepare-matrix.outputs.matrix) }}
runs-on: ${{ matrix.os }}
steps:
@@ -77,395 +54,138 @@ jobs:
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v7
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Set up vcpkg cache
if: runner.os == 'Windows'
uses: actions/cache@v4
with:
path: |
${{ github.workspace }}/vcpkg
${{ github.workspace }}/vcpkg_installed
key: vcpkg-${{ matrix.vcpkg_triplet }}-${{ hashFiles('vcpkg.json') }}
restore-keys: |
vcpkg-${{ matrix.vcpkg_triplet }}-
# Linux-specific setup
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
ninja-build \
pkg-config \
libglew-dev \
libxext-dev \
libwavpack-dev \
libabsl-dev \
libboost-all-dev \
libboost-python-dev \
libpng-dev \
python3-dev \
libpython3-dev \
libasound2-dev \
libpulse-dev \
libaudio-dev \
libx11-dev \
libxrandr-dev \
libxcursor-dev \
libxinerama-dev \
libxi-dev \
libxss-dev \
libxxf86vm-dev \
libxkbcommon-dev \
libwayland-dev \
libdecor-0-dev \
libgtk-3-dev \
libdbus-1-dev \
gcc-12 \
g++-12 \
clang-15
- name: Set up Linux compilers
if: runner.os == 'Linux'
run: |
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/${{ matrix.cc }} 100
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/${{ matrix.cxx }} 100
# macOS-specific setup
- name: Install macOS dependencies
if: runner.os == 'macOS'
run: |
# Install Homebrew dependencies if needed
# brew install pkg-config libpng boost abseil
# Windows-specific setup (skip vcpkg for CI builds)
- name: Set up vcpkg (non-CI builds only)
if: runner.os == 'Windows' && github.event_name != 'push' && github.event_name != 'pull_request'
- name: Set up vcpkg
if: runner.os != 'Linux'
uses: lukka/run-vcpkg@v11
with:
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
runVcpkgInstall: true
vcpkgJsonGlob: '**/vcpkg.json'
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
- name: Configure CMake (Linux/macOS)
if: runner.os != 'Windows'
run: |
cmake -B ${{ github.workspace }}/build \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DCMAKE_C_COMPILER=${{ matrix.cc }} \
-DCMAKE_CXX_COMPILER=${{ matrix.cxx }} \
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 \
-DYAZE_USE_MODULAR_BUILD=ON \
-DYAZE_MINIMAL_BUILD=ON \
-DYAZE_ENABLE_ROM_TESTS=OFF \
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
-DYAZE_ENABLE_UI_TESTS=OFF \
-Wno-dev \
-GNinja
env:
VCPKG_DEFAULT_TRIPLET: ${{ matrix.vcpkg_triplet }}
- name: Configure CMake (Windows)
if: runner.os == 'Windows'
shell: cmd
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_POLICY_VERSION_MINIMUM=3.16 -DYAZE_USE_MODULAR_BUILD=ON -DYAZE_MINIMAL_BUILD=ON -DYAZE_ENABLE_ROM_TESTS=OFF -DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF -DYAZE_ENABLE_UI_TESTS=OFF -Wno-dev -G "${{ matrix.cmake_generator }}" -A ${{ matrix.cmake_generator_platform }}
sudo apt-get update
sudo apt-get install -y build-essential ninja-build pkg-config libglew-dev libxext-dev libwavpack-dev libabsl-dev libboost-all-dev libpng-dev python3-dev libpython3-dev libasound2-dev libpulse-dev libaudio-dev libx11-dev libxrandr-dev libxcursor-dev libxinerama-dev libxi-dev libxss-dev libxxf86vm-dev libxkbcommon-dev libwayland-dev libdecor-0-dev libgtk-3-dev libdbus-1-dev gcc-12 g++-12 clang-15
- name: Configure CMake
shell: bash
run: |
set -x
CMAKE_ARGS=(
"-S ."
"-B build"
"-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}"
"-DYAZE_MINIMAL_BUILD=ON"
"-DYAZE_ENABLE_ROM_TESTS=OFF"
)
if [[ "${{ runner.os }}" == "Windows" ]]; then
CMAKE_ARGS+=(
"-G" "${{ matrix.cmake_generator }}"
"-A" "${{ matrix.cmake_generator_platform }}"
"-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake"
)
elif [[ "${{ runner.os }}" == "macOS" ]]; then
CMAKE_ARGS+=(
"-G" "Ninja"
"-DCMAKE_C_COMPILER=${{ matrix.cc }}"
"-DCMAKE_CXX_COMPILER=${{ matrix.cxx }}"
"-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake"
)
else # Linux
CMAKE_ARGS+=(
"-G" "Ninja"
"-DCMAKE_C_COMPILER=${{ matrix.cc }}"
"-DCMAKE_CXX_COMPILER=${{ matrix.cxx }}"
)
fi
cmake "${{ CMAKE_ARGS[@] }}"
# Build
- name: Build
run: cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --parallel
run: cmake --build build --config ${{ env.BUILD_TYPE }} --parallel
# Test (stable core functionality only for CI)
- name: Run Core Tests
working-directory: ${{ github.workspace }}/build
working-directory: build
run: ctest --build-config ${{ env.BUILD_TYPE }} --output-on-failure -j1 -R "AsarWrapperTest|SnesTileTest|CompressionTest|SnesPaletteTest|HexTest|MessageTest"
# Run additional unit tests (allowed to fail for information only)
- name: Run Additional Unit Tests (Informational)
working-directory: ${{ github.workspace }}/build
working-directory: build
continue-on-error: true
run: ctest --build-config ${{ env.BUILD_TYPE }} --output-on-failure --parallel -R ".*Test" -E ".*RomTest.*|.*E2E.*|.*ZSCustomOverworld.*|.*IntegrationTest.*|CpuTest|Spc700Test|ApuTest"
# Package (only on successful builds)
- name: Package artifacts
if: success()
run: |
cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --target package
# Upload artifacts
- name: Upload build artifacts
if: success()
uses: actions/upload-artifact@v4
with:
name: yaze-${{ matrix.name }}-${{ github.sha }}
path: |
${{ github.workspace }}/build/bin/
${{ github.workspace }}/build/lib/
retention-days: 7
# Upload packages for release candidates
- name: Upload package artifacts
if: success() && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))
uses: actions/upload-artifact@v4
with:
name: yaze-package-${{ matrix.name }}-${{ github.sha }}
path: |
${{ github.workspace }}/build/*.tar.gz
${{ github.workspace }}/build/*.zip
${{ github.workspace }}/build/*.dmg
${{ github.workspace }}/build/*.msi
retention-days: 30
code-quality:
name: Code Quality Checks
name: "✨ Code Quality"
runs-on: ubuntu-22.04
# Relaxed requirements for releases and master branch:
# - Formatting errors become warnings
# - Fewer cppcheck categories enabled
# - Reduced clang-tidy file count
# - Job failure won't block releases
continue-on-error: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install dependencies
- name: Install linters
run: |
sudo apt-get update
sudo apt-get install -y \
clang-format-14 \
clang-tidy-14 \
cppcheck
- name: Check code formatting
sudo apt-get install -y clang-format-14 clang-tidy-14 cppcheck
- name: Check Formatting
run: |
# Relaxed formatting check for releases and master branch
if [[ "${{ github.ref }}" == "refs/heads/master" ]] || [[ "${{ github.ref }}" == refs/tags/* ]] || [[ "${{ github.event_name }}" == "pull_request" && "${{ github.base_ref }}" == "master" ]]; then
echo "🔄 Running relaxed formatting check for release/master branch..."
find src test -name "*.cc" -o -name "*.h" | \
xargs clang-format-14 --dry-run --Werror || {
echo "⚠️ Code formatting issues found, but allowing for release builds"
echo "📝 Consider running 'make format' to fix formatting before next release"
exit 0
}
else
echo "🔍 Running strict formatting check for development..."
find src test -name "*.cc" -o -name "*.h" | \
xargs clang-format-14 --dry-run --Werror
fi
find src test -name "*.cc" -o -name "*.h" | xargs clang-format-14 --dry-run --Werror
- name: Run cppcheck
run: |
if [[ "${{ github.ref }}" == "refs/heads/master" ]] || [[ "${{ github.ref }}" == refs/tags/* ]]; then
echo "🔄 Running relaxed cppcheck for release/master branch..."
cppcheck --enable=warning \
--error-exitcode=0 \
--suppress=missingIncludeSystem \
--suppress=unusedFunction \
--suppress=unmatchedSuppression \
--suppress=variableScope \
--suppress=cstyleCast \
--suppress=unreadVariable \
--suppress=unusedStructMember \
--suppress=constParameter \
--suppress=constVariable \
--suppress=useStlAlgorithm \
--suppress=noExplicitConstructor \
--suppress=passedByValue \
--suppress=functionStatic \
src/ || echo "Cppcheck completed (non-blocking for releases)"
else
echo "🔍 Running standard cppcheck for development..."
cppcheck --enable=warning,style,performance \
--error-exitcode=0 \
--suppress=missingIncludeSystem \
--suppress=unusedFunction \
--suppress=unmatchedSuppression \
--suppress=variableScope \
--suppress=cstyleCast \
--suppress=unreadVariable \
--suppress=unusedStructMember \
--suppress=constParameter \
--suppress=constVariable \
--suppress=useStlAlgorithm \
--inconclusive \
src/ || echo "Cppcheck completed with warnings (non-blocking)"
fi
- name: Run clang-tidy (lenient)
cppcheck --enable=warning,style,performance --error-exitcode=0 --suppress=missingIncludeSystem --suppress=unusedFunction --inconclusive src/
- name: Run clang-tidy
run: |
if [[ "${{ github.ref }}" == "refs/heads/master" ]] || [[ "${{ github.ref }}" == refs/tags/* ]]; then
echo "🔄 Running minimal clang-tidy for release/master branch..."
# Only check a small subset of critical files for releases
find src -name "*.cc" -not -path "*/lib/*" -not -path "*/gui/*" | head -10 | \
xargs clang-tidy-14 --config-file=.clang-tidy \
--header-filter='src/.*\.(h|hpp)$' || echo "Clang-tidy completed (non-blocking for releases)"
else
echo "🔍 Running standard clang-tidy for development..."
# Run clang-tidy on a subset of files to avoid overwhelming output
find src -name "*.cc" -not -path "*/lib/*" | head -20 | \
xargs clang-tidy-14 --config-file=.clang-tidy \
--header-filter='src/.*\.(h|hpp)$' || echo "Clang-tidy completed with warnings (non-blocking)"
fi
find src -name "*.cc" -not -path "*/lib/*" | head -20 | xargs clang-tidy-14 --header-filter='src/.*\.(h|hpp)$'
memory-sanitizer:
name: Memory Sanitizer (Linux)
name: "🔬 Memory Sanitizer (Linux)"
runs-on: ubuntu-22.04
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
ninja-build \
clang-14 \
libc++-14-dev \
libc++abi-14-dev \
libglew-dev \
libxext-dev \
libwavpack-dev \
libpng-dev \
libgtk-3-dev \
libdbus-1-dev
sudo apt-get install -y build-essential ninja-build clang-14 libc++-14-dev libc++abi-14-dev libglew-dev libxext-dev libwavpack-dev libpng-dev libgtk-3-dev libdbus-1-dev
- name: Configure with AddressSanitizer
run: |
cmake -B ${{ github.workspace }}/build \
cmake -B build -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_COMPILER=clang-14 \
-DCMAKE_CXX_COMPILER=clang++-14 \
-DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \
-DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" \
-DYAZE_USE_MODULAR_BUILD=ON \
-DYAZE_MINIMAL_BUILD=ON \
-DYAZE_ENABLE_ROM_TESTS=OFF \
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
-GNinja
-DYAZE_MINIMAL_BUILD=ON
- name: Build
run: cmake --build ${{ github.workspace }}/build --parallel
run: cmake --build build --parallel
- name: Test with AddressSanitizer
working-directory: ${{ github.workspace }}/build
working-directory: build
env:
ASAN_OPTIONS: detect_leaks=1:abort_on_error=1
run: ctest --output-on-failure
coverage:
name: Code Coverage
runs-on: ubuntu-22.04
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
ninja-build \
gcov \
lcov \
libglew-dev \
libxext-dev \
libwavpack-dev \
libpng-dev \
libgtk-3-dev \
libdbus-1-dev
- name: Configure with coverage
run: |
cmake -B ${{ github.workspace }}/build \
-DCMAKE_BUILD_TYPE=Debug \
-DYAZE_USE_MODULAR_BUILD=ON \
-DCMAKE_CXX_FLAGS="--coverage" \
-DCMAKE_C_FLAGS="--coverage" \
-DCMAKE_EXE_LINKER_FLAGS="--coverage" \
-DYAZE_MINIMAL_BUILD=ON \
-DYAZE_ENABLE_ROM_TESTS=OFF \
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
-GNinja
- name: Build
run: cmake --build ${{ github.workspace }}/build --parallel
- name: Test
working-directory: ${{ github.workspace }}/build
run: ctest --output-on-failure
- name: Generate coverage report
run: |
lcov --capture --directory ${{ github.workspace }}/build --output-file coverage.info
lcov --remove coverage.info '/usr/*' --output-file coverage.info
lcov --remove coverage.info '**/test/**' --output-file coverage.info
lcov --remove coverage.info '**/lib/**' --output-file coverage.info
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.info
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
z3ed-agent-test:
name: "z3ed Agent Test (macOS + Ollama)"
name: "🤖 z3ed Agent Test (macOS)"
runs-on: macos-14
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install macOS dependencies
- name: Install dependencies
run: brew install ollama ninja
- name: Configure and Build z3ed
run: |
brew install ollama ninja
- name: Configure CMake for z3ed
run: |
cmake -B ${{ github.workspace }}/build_test \
-DCMAKE_BUILD_TYPE=Release \
-DYAZE_USE_MODULAR_BUILD=ON \
-DZ3ED_AI=ON \
-DYAZE_BUILD_Z3ED=ON \
-DYAZE_MINIMAL_BUILD=ON \
-Wno-dev \
-GNinja
- name: Build z3ed
run: cmake --build ${{ github.workspace }}/build_test --config Release --target z3ed
continue-on-error: true
- name: Start Ollama and pull model
cmake -B build_test -G Ninja -DCMAKE_BUILD_TYPE=Release -DZ3ED_AI=ON -DYAZE_BUILD_Z3ED=ON
cmake --build build_test --config Release --target z3ed
- name: Start Ollama
run: |
ollama serve &
sleep 10
ollama pull qwen2.5-coder:7b
- name: Run z3ed Agent Test Suite
run: |
chmod +x scripts/agent_test_suite.sh
./scripts/agent_test_suite.sh ollama
./scripts/agent_test_suite.sh ollama

View File

@@ -1,712 +0,0 @@
name: Release-Complex
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-*'
workflow_dispatch:
inputs:
tag:
description: 'Release tag (must start with v and follow semantic versioning)'
required: true
default: 'v0.3.0'
type: string
env:
BUILD_TYPE: Release
jobs:
validate-and-prepare:
name: Validate Release
runs-on: ubuntu-latest
outputs:
tag_name: ${{ steps.validate.outputs.tag_name }}
release_notes: ${{ steps.notes.outputs.content }}
steps:
- name: Validate tag format
id: validate
run: |
# Debug information
echo "Event name: ${{ github.event_name }}"
echo "Ref: ${{ github.ref }}"
echo "Ref name: ${{ github.ref_name }}"
echo "Ref type: ${{ github.ref_type }}"
# Determine the tag based on trigger type
if [[ "${{ github.event_name }}" == "push" ]]; then
if [[ "${{ github.ref_type }}" != "tag" ]]; then
echo "❌ Error: Release workflow triggered by push to ${{ github.ref_type }} '${{ github.ref_name }}'"
echo "This workflow should only be triggered by pushing version tags (v1.2.3)"
echo "Use: git tag v0.3.0 && git push origin v0.3.0"
exit 1
fi
TAG="${{ github.ref_name }}"
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
TAG="${{ github.event.inputs.tag }}"
if [[ -z "$TAG" ]]; then
echo "❌ Error: No tag specified for manual workflow dispatch"
exit 1
fi
else
echo "❌ Error: Unsupported event type: ${{ github.event_name }}"
exit 1
fi
echo "Validating tag: $TAG"
# Check if tag follows semantic versioning pattern
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
echo "❌ Error: Tag '$TAG' does not follow semantic versioning format (v1.2.3 or v1.2.3-beta)"
echo "Valid examples: v0.3.0, v1.0.0, v2.1.3-beta, v1.0.0-rc1"
echo ""
echo "To create a proper release:"
echo "1. Use the helper script: ./scripts/create_release.sh 0.3.0"
echo "2. Or manually: git tag v0.3.0 && git push origin v0.3.0"
exit 1
fi
echo "✅ Tag format is valid: $TAG"
echo "VALIDATED_TAG=$TAG" >> $GITHUB_ENV
echo "tag_name=$TAG" >> $GITHUB_OUTPUT
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate release notes
id: release_notes
run: |
# Extract release version from validated tag
VERSION="${VALIDATED_TAG}"
VERSION_NUM=$(echo "$VERSION" | sed 's/^v//')
# Generate release notes using the dedicated script
echo "Extracting changelog for version: $VERSION_NUM"
if python3 scripts/extract_changelog.py "$VERSION_NUM" > release_notes.md; then
echo "Changelog extracted successfully"
echo "Release notes content:"
cat release_notes.md
else
echo "Failed to extract changelog, creating default release notes"
echo "# Yaze $VERSION Release Notes\n\nPlease see the full changelog at docs/C1-changelog.md" > release_notes.md
fi
- name: Store release notes
id: notes
run: |
# Store release notes content for later use
echo "content<<EOF" >> $GITHUB_OUTPUT
cat release_notes.md >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
build-release:
name: Build Release
needs: validate-and-prepare
strategy:
matrix:
include:
- name: "Windows x64"
os: windows-2022
vcpkg_triplet: x64-windows
cmake_generator: "Visual Studio 17 2022"
cmake_generator_platform: x64
artifact_name: "yaze-windows-x64"
artifact_path: "build/bin/Release/"
package_cmd: |
mkdir -p package
cp -r build/bin/Release/* package/ 2>/dev/null || echo "No Release binaries found, trying Debug..."
cp -r build/bin/Debug/* package/ 2>/dev/null || echo "No Debug binaries found"
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
cp README.md package/ 2>/dev/null || echo "README.md not found"
cd package && zip -r ../yaze-windows-x64.zip *
- name: "Windows ARM64"
os: windows-2022
vcpkg_triplet: arm64-windows
cmake_generator: "Visual Studio 17 2022"
cmake_generator_platform: ARM64
artifact_name: "yaze-windows-arm64"
artifact_path: "build/bin/Release/"
package_cmd: |
mkdir -p package
cp -r build/bin/Release/* package/ 2>/dev/null || echo "No Release binaries found, trying Debug..."
cp -r build/bin/Debug/* package/ 2>/dev/null || echo "No Debug binaries found"
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
cp README.md package/ 2>/dev/null || echo "README.md not found"
cd package && zip -r ../yaze-windows-arm64.zip *
- name: "macOS Universal"
os: macos-14
vcpkg_triplet: arm64-osx
artifact_name: "yaze-macos"
artifact_path: "build/bin/"
package_cmd: |
# Debug: List what was actually built
echo "Contents of build/bin/:"
ls -la build/bin/ || echo "build/bin/ does not exist"
# Check if we have a bundle or standalone executable
if [ -d "build/bin/yaze.app" ]; then
echo "Found macOS bundle, using it directly"
# Use the existing bundle and just update it
cp -r build/bin/yaze.app ./Yaze.app
# Add additional resources to the bundle
cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found"
# Update Info.plist with correct version
if [ -f "cmake/yaze.plist.in" ]; then
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
sed "s/@yaze_VERSION@/$VERSION_NUM/g" cmake/yaze.plist.in > "Yaze.app/Contents/Info.plist"
fi
else
echo "No bundle found, creating manual bundle"
# Create bundle structure manually
mkdir -p "Yaze.app/Contents/MacOS"
mkdir -p "Yaze.app/Contents/Resources"
cp build/bin/yaze "Yaze.app/Contents/MacOS/"
cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found"
# Create Info.plist with correct version
if [ -f "cmake/yaze.plist.in" ]; then
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
sed "s/@yaze_VERSION@/$VERSION_NUM/g" cmake/yaze.plist.in > "Yaze.app/Contents/Info.plist"
else
# Create a basic Info.plist
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
echo '<?xml version="1.0" encoding="UTF-8"?>' > "Yaze.app/Contents/Info.plist"
echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' >> "Yaze.app/Contents/Info.plist"
echo '<plist version="1.0">' >> "Yaze.app/Contents/Info.plist"
echo '<dict>' >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundleExecutable</key>' >> "Yaze.app/Contents/Info.plist"
echo '<string>yaze</string>' >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundleIdentifier</key>' >> "Yaze.app/Contents/Info.plist"
echo '<string>com.yaze.editor</string>' >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundleName</key>' >> "Yaze.app/Contents/Info.plist"
echo '<string>Yaze</string>' >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundleVersion</key>' >> "Yaze.app/Contents/Info.plist"
echo "<string>$VERSION_NUM</string>" >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundleShortVersionString</key>' >> "Yaze.app/Contents/Info.plist"
echo "<string>$VERSION_NUM</string>" >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundlePackageType</key>' >> "Yaze.app/Contents/Info.plist"
echo '<string>APPL</string>' >> "Yaze.app/Contents/Info.plist"
echo '</dict>' >> "Yaze.app/Contents/Info.plist"
echo '</plist>' >> "Yaze.app/Contents/Info.plist"
fi
fi
# Create DMG
mkdir dmg_staging
cp -r Yaze.app dmg_staging/
cp LICENSE dmg_staging/ 2>/dev/null || echo "LICENSE not found"
cp README.md dmg_staging/ 2>/dev/null || echo "README.md not found"
cp -r docs dmg_staging/ 2>/dev/null || echo "docs directory not found"
hdiutil create -srcfolder dmg_staging -format UDZO -volname "Yaze ${{ needs.validate-and-prepare.outputs.tag_name }}" yaze-macos.dmg
- name: "Linux x64"
os: ubuntu-22.04
artifact_name: "yaze-linux-x64"
artifact_path: "build/bin/"
package_cmd: |
mkdir package
cp build/bin/yaze package/
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
cp -r docs package/ 2>/dev/null || echo "docs directory not found"
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
cp README.md package/ 2>/dev/null || echo "README.md not found"
tar -czf yaze-linux-x64.tar.gz -C package .
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
# Clean up any potential vcpkg issues (Windows only)
- name: Clean vcpkg state (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Write-Host "Cleaning up any existing vcpkg state..."
if (Test-Path "vcpkg") {
Remove-Item -Recurse -Force "vcpkg" -ErrorAction SilentlyContinue
}
if (Test-Path "vcpkg_installed") {
Remove-Item -Recurse -Force "vcpkg_installed" -ErrorAction SilentlyContinue
}
Write-Host "Cleanup completed"
# Platform-specific dependency installation
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
ninja-build \
pkg-config \
libglew-dev \
libxext-dev \
libwavpack-dev \
libabsl-dev \
libboost-all-dev \
libpng-dev \
python3-dev \
libpython3-dev \
libasound2-dev \
libpulse-dev \
libx11-dev \
libxrandr-dev \
libxcursor-dev \
libxinerama-dev \
libxi-dev
- name: Install macOS dependencies
if: runner.os == 'macOS'
run: |
# Install Homebrew dependencies needed for UI tests and full builds
brew install pkg-config libpng boost abseil ninja gtk+3
- name: Setup build environment
run: |
echo "Using streamlined release build configuration for all platforms"
echo "Linux/macOS: UI tests enabled with full dependency support"
echo "Windows: Full build with vcpkg integration for proper releases"
echo "All platforms: Emulator and developer tools disabled for clean releases"
# Configure CMake
- name: Configure CMake (Linux/macOS)
if: runner.os != 'Windows'
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 \
-DYAZE_BUILD_TESTS=OFF \
-DYAZE_BUILD_EMU=OFF \
-DYAZE_BUILD_Z3ED=OFF \
-DYAZE_ENABLE_UI_TESTS=ON \
-DYAZE_ENABLE_ROM_TESTS=OFF \
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
-DYAZE_INSTALL_LIB=OFF \
-DYAZE_MINIMAL_BUILD=OFF \
-GNinja
# Set up vcpkg for Windows builds with fallback
- name: Set up vcpkg (Windows)
id: vcpkg_setup
if: runner.os == 'Windows'
uses: lukka/run-vcpkg@v11
continue-on-error: true
with:
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
runVcpkgInstall: true
vcpkgJsonGlob: '**/vcpkg.json'
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
env:
VCPKG_FORCE_SYSTEM_BINARIES: 1
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
VCPKG_DISABLE_METRICS: 1
VCPKG_DEFAULT_TRIPLET: ${{ matrix.vcpkg_triplet }}
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
# Debug vcpkg failure (Windows only)
- name: Debug vcpkg failure (Windows)
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'failure'
shell: pwsh
run: |
Write-Host "=== vcpkg Setup Failed - Debug Information ===" -ForegroundColor Red
Write-Host "vcpkg directory exists: $(Test-Path 'vcpkg')"
Write-Host "vcpkg_installed directory exists: $(Test-Path 'vcpkg_installed')"
if (Test-Path "vcpkg") {
Write-Host "vcpkg directory contents:"
Get-ChildItem "vcpkg" | Select-Object -First 10
}
Write-Host "Git status:"
git status --porcelain
Write-Host "=============================================" -ForegroundColor Red
# Fallback: Install dependencies manually if vcpkg fails
- name: Install dependencies manually (Windows fallback)
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'failure'
shell: pwsh
run: |
Write-Host "vcpkg setup failed, installing dependencies manually..."
# Install Chocolatey if not present
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
Write-Host "Installing Chocolatey..."
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
}
# Install basic build tools and dependencies
Write-Host "Installing build tools and dependencies..."
try {
choco install -y cmake ninja git python3
Write-Host "Successfully installed build tools via Chocolatey"
} catch {
Write-Host "Chocolatey installation failed, trying individual packages..."
choco install -y cmake || Write-Host "CMake installation failed"
choco install -y ninja || Write-Host "Ninja installation failed"
choco install -y git || Write-Host "Git installation failed"
choco install -y python3 || Write-Host "Python3 installation failed"
}
# Set up basic development environment
Write-Host "Setting up basic development environment..."
$env:Path += ";C:\Program Files\Git\bin"
# Verify installations
Write-Host "Verifying installations..."
cmake --version
ninja --version
git --version
# Set environment variable to indicate minimal build
echo "YAZE_MINIMAL_BUILD=ON" >> $env:GITHUB_ENV
echo "VCPKG_AVAILABLE=false" >> $env:GITHUB_ENV
Write-Host "Manual dependency installation completed"
Write-Host "Build will proceed with minimal configuration (no vcpkg dependencies)"
# Set vcpkg availability flag when vcpkg succeeds
- name: Set vcpkg availability flag
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'success'
shell: pwsh
run: |
echo "VCPKG_AVAILABLE=true" >> $env:GITHUB_ENV
Write-Host "vcpkg setup successful"
- name: Configure CMake (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Write-Host "Configuring CMake for Windows build..."
# Check if vcpkg is available
if ((Test-Path "${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake") -and ($env:VCPKG_AVAILABLE -ne "false")) {
Write-Host "Using vcpkg toolchain..."
cmake -B build `
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 `
-DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake" `
-DYAZE_BUILD_TESTS=OFF `
-DYAZE_BUILD_EMU=OFF `
-DYAZE_BUILD_Z3ED=OFF `
-DYAZE_ENABLE_ROM_TESTS=OFF `
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF `
-DYAZE_INSTALL_LIB=OFF `
-DYAZE_MINIMAL_BUILD=OFF `
-G "${{ matrix.cmake_generator }}" `
-A ${{ matrix.cmake_generator_platform }}
} else {
Write-Host "Using minimal build configuration (vcpkg not available)..."
cmake -B build `
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 `
-DYAZE_BUILD_TESTS=OFF `
-DYAZE_BUILD_EMU=OFF `
-DYAZE_BUILD_Z3ED=OFF `
-DYAZE_ENABLE_ROM_TESTS=OFF `
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF `
-DYAZE_INSTALL_LIB=OFF `
-DYAZE_MINIMAL_BUILD=ON `
-G "${{ matrix.cmake_generator }}" `
-A ${{ matrix.cmake_generator_platform }}
}
Write-Host "CMake configuration completed successfully"
# Verify CMake configuration (Windows only)
- name: Verify CMake configuration (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Write-Host "Verifying CMake configuration..."
if (Test-Path "build/CMakeCache.txt") {
Write-Host "✓ CMakeCache.txt found"
Write-Host "Build type: $(Select-String -Path 'build/CMakeCache.txt' -Pattern 'CMAKE_BUILD_TYPE' | ForEach-Object { $_.Line.Split('=')[1] })"
Write-Host "Minimal build: $(Select-String -Path 'build/CMakeCache.txt' -Pattern 'YAZE_MINIMAL_BUILD' | ForEach-Object { $_.Line.Split('=')[1] })"
} else {
Write-Error "CMakeCache.txt not found - CMake configuration failed!"
exit 1
}
# Build
- name: Build
run: |
echo "Building YAZE for ${{ matrix.name }}..."
cmake --build build --config ${{ env.BUILD_TYPE }} --parallel
echo "Build completed successfully!"
# Validate Visual Studio project builds (Windows only)
# Generate yaze_config.h for Visual Studio builds
- name: Generate yaze_config.h
if: runner.os == 'Windows'
shell: pwsh
run: |
$version = "${{ needs.validate-and-prepare.outputs.tag_name }}" -replace '^v', ''
$versionParts = $version -split '\.'
$major = if ($versionParts.Length -gt 0) { $versionParts[0] } else { "0" }
$minor = if ($versionParts.Length -gt 1) { $versionParts[1] } else { "0" }
$patch = if ($versionParts.Length -gt 2) { $versionParts[2] -split '-' | Select-Object -First 1 } else { "0" }
Write-Host "Generating yaze_config.h with version: $major.$minor.$patch"
Copy-Item "src\yaze_config.h.in" "yaze_config.h"
(Get-Content 'yaze_config.h') -replace '@yaze_VERSION_MAJOR@', $major -replace '@yaze_VERSION_MINOR@', $minor -replace '@yaze_VERSION_PATCH@', $patch | Set-Content 'yaze_config.h'
Write-Host "Generated yaze_config.h:"
Get-Content 'yaze_config.h'
- name: Validate Visual Studio Project Build
if: runner.os == 'Windows'
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Validating Visual Studio Project Build" -ForegroundColor Cyan
Write-Host "Platform: ${{ matrix.cmake_generator_platform }}" -ForegroundColor Yellow
Write-Host "Configuration: ${{ env.BUILD_TYPE }}" -ForegroundColor Yellow
Write-Host "========================================" -ForegroundColor Cyan
# Check if we're in the right directory
if (-not (Test-Path "yaze.sln")) {
Write-Error "yaze.sln not found. Please run this script from the project root directory."
exit 1
}
Write-Host "✓ yaze.sln found" -ForegroundColor Green
# Build using MSBuild
Write-Host "Building with MSBuild..." -ForegroundColor Yellow
$msbuildArgs = @(
"yaze.sln"
"/p:Configuration=${{ env.BUILD_TYPE }}"
"/p:Platform=${{ matrix.cmake_generator_platform }}"
"/p:VcpkgEnabled=true"
"/p:VcpkgManifestInstall=true"
"/m" # Multi-processor build
"/verbosity:minimal"
)
Write-Host "MSBuild command: msbuild $($msbuildArgs -join ' ')" -ForegroundColor Gray
& msbuild @msbuildArgs
if ($LASTEXITCODE -ne 0) {
Write-Error "MSBuild failed with exit code $LASTEXITCODE"
exit 1
}
Write-Host "✓ Visual Studio build completed successfully" -ForegroundColor Green
# Verify executable was created
$exePath = "build\bin\${{ env.BUILD_TYPE }}\yaze.exe"
if (-not (Test-Path $exePath)) {
Write-Error "Executable not found at expected path: $exePath"
exit 1
}
Write-Host "✓ Executable created: $exePath" -ForegroundColor Green
# Test that the executable runs (basic test)
Write-Host "Testing executable startup..." -ForegroundColor Yellow
$testResult = & $exePath --help 2>&1
$exitCode = $LASTEXITCODE
# Check if it's the test main or app main
if ($testResult -match "Google Test" -or $testResult -match "gtest") {
Write-Error "Executable is running test main instead of app main!"
Write-Host "Output: $testResult" -ForegroundColor Red
exit 1
}
Write-Host "✓ Executable runs correctly (exit code: $exitCode)" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "✓ Visual Studio build validation PASSED" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Cyan
# Test executable functionality (Windows)
- name: Test executable functionality (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
# Debug: List build directory contents
Write-Host "Build directory contents:" -ForegroundColor Cyan
if (Test-Path "build") {
Get-ChildItem -Recurse build -Name | Select-Object -First 20
} else {
Write-Host "build directory does not exist" -ForegroundColor Red
}
# Determine executable path for Windows
$exePath = "build\bin\${{ env.BUILD_TYPE }}\yaze.exe"
if (Test-Path $exePath) {
Write-Host "✓ Executable found: $exePath" -ForegroundColor Green
# Test that it's not the test main
$testResult = & $exePath --help 2>&1
$exitCode = $LASTEXITCODE
if ($testResult -match "Google Test" -or $testResult -match "gtest") {
Write-Error "Executable is running test main instead of app main!"
Write-Host "Output: $testResult" -ForegroundColor Red
exit 1
}
Write-Host "✓ Executable runs correctly (exit code: $exitCode)" -ForegroundColor Green
# Display file info
$exeInfo = Get-Item $exePath
Write-Host "Executable size: $([math]::Round($exeInfo.Length / 1MB, 2)) MB" -ForegroundColor Cyan
} else {
Write-Error "Executable not found at: $exePath"
exit 1
}
# Test executable functionality (macOS)
- name: Test executable functionality (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
set -e
echo "Build directory contents:"
if [ -d "build" ]; then
find build -name "*.app" -o -name "yaze" | head -10
else
echo "build directory does not exist"
exit 1
fi
# Determine executable path for macOS
exePath="build/bin/yaze.app/Contents/MacOS/yaze"
if [ -f "$exePath" ]; then
echo "✓ Executable found: $exePath"
# Test that it's not the test main
testResult=$($exePath --help 2>&1 || true)
exitCode=$?
if echo "$testResult" | grep -q "Google Test\|gtest"; then
echo "ERROR: Executable is running test main instead of app main!"
echo "Output: $testResult"
exit 1
fi
echo "✓ Executable runs correctly (exit code: $exitCode)"
# Display file info
fileSize=$(stat -f%z "$exePath")
fileSizeMB=$(echo "scale=2; $fileSize / 1024 / 1024" | bc -l)
echo "Executable size: ${fileSizeMB} MB"
else
echo "ERROR: Executable not found at: $exePath"
exit 1
fi
# Test executable functionality (Linux)
- name: Test executable functionality (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
set -e
echo "Build directory contents:"
if [ -d "build" ]; then
find build -type f -name "yaze" | head -10
else
echo "build directory does not exist"
exit 1
fi
# Determine executable path for Linux
exePath="build/bin/yaze"
if [ -f "$exePath" ]; then
echo "✓ Executable found: $exePath"
# Test that it's not the test main
testResult=$($exePath --help 2>&1 || true)
exitCode=$?
if echo "$testResult" | grep -q "Google Test\|gtest"; then
echo "ERROR: Executable is running test main instead of app main!"
echo "Output: $testResult"
exit 1
fi
echo "✓ Executable runs correctly (exit code: $exitCode)"
# Display file info
fileSize=$(stat -c%s "$exePath")
fileSizeMB=$(echo "scale=2; $fileSize / 1024 / 1024" | bc -l)
echo "Executable size: ${fileSizeMB} MB"
else
echo "ERROR: Executable not found at: $exePath"
exit 1
fi
# Verify build artifacts
- name: Verify build artifacts
shell: bash
run: |
echo "Verifying build artifacts for ${{ matrix.name }}..."
if [ -d "build/bin" ]; then
echo "Build directory contents:"
find build/bin -type f -name "yaze*" -o -name "*.exe" -o -name "*.app" | head -10
else
echo "ERROR: build/bin directory not found!"
exit 1
fi
# Package
- name: Package
shell: bash
run: |
set -e
echo "Packaging for ${{ matrix.name }}..."
${{ matrix.package_cmd }}
echo "Packaging completed successfully!"
# Create release with artifacts (will create release if it doesn't exist)
- name: Upload to Release
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ needs.validate-and-prepare.outputs.tag_name }}
name: Yaze ${{ needs.validate-and-prepare.outputs.tag_name }}
body: ${{ needs.validate-and-prepare.outputs.release_notes }}
draft: false
prerelease: ${{ contains(needs.validate-and-prepare.outputs.tag_name, 'beta') || contains(needs.validate-and-prepare.outputs.tag_name, 'alpha') || contains(needs.validate-and-prepare.outputs.tag_name, 'rc') }}
files: |
${{ matrix.artifact_name }}.*
fail_on_unmatched_files: false
publish-packages:
name: Publish Packages
needs: [validate-and-prepare, build-release]
runs-on: ubuntu-latest
if: success()
steps:
- name: Update release status
run: |
echo "Release has been published successfully"
echo "All build artifacts have been uploaded"
- name: Announce release
run: |
echo "🎉 Yaze ${{ needs.validate-and-prepare.outputs.tag_name }} has been released!"
echo "📦 Packages are now available for download"
echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ needs.validate-and-prepare.outputs.tag_name }}"

View File

@@ -1,414 +0,0 @@
name: Release-Simplified
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-*'
workflow_dispatch:
inputs:
tag:
description: 'Release tag (must start with v and follow semantic versioning)'
required: true
default: 'v0.3.0'
type: string
env:
BUILD_TYPE: Release
jobs:
validate-and-prepare:
name: Validate Release
runs-on: ubuntu-latest
outputs:
tag_name: ${{ steps.validate.outputs.tag_name }}
release_notes: ${{ steps.notes.outputs.content }}
steps:
- name: Validate tag format
id: validate
run: |
# Determine the tag based on trigger type
if [[ "${{ github.event_name }}" == "push" ]]; then
if [[ "${{ github.ref_type }}" != "tag" ]]; then
echo "❌ Error: Release workflow triggered by push to ${{ github.ref_type }} '${{ github.ref_name }}'"
echo "This workflow should only be triggered by pushing version tags (v1.2.3)"
echo "Use: git tag v0.3.0 && git push origin v0.3.0"
exit 1
fi
TAG="${{ github.ref_name }}"
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
TAG="${{ github.event.inputs.tag }}"
if [[ -z "$TAG" ]]; then
echo "❌ Error: No tag specified for manual workflow dispatch"
exit 1
fi
else
echo "❌ Error: Unsupported event type: ${{ github.event_name }}"
exit 1
fi
echo "Validating tag: $TAG"
# Check if tag follows semantic versioning pattern
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
echo "❌ Error: Tag '$TAG' does not follow semantic versioning format (v1.2.3 or v1.2.3-beta)"
echo "Valid examples: v0.3.0, v1.0.0, v2.1.3-beta, v1.0.0-rc1"
echo ""
echo "To create a proper release:"
echo "1. Use the helper script: ./scripts/create_release.sh 0.3.0"
echo "2. Or manually: git tag v0.3.0 && git push origin v0.3.0"
exit 1
fi
echo "✅ Tag format is valid: $TAG"
echo "VALIDATED_TAG=$TAG" >> $GITHUB_ENV
echo "tag_name=$TAG" >> $GITHUB_OUTPUT
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate release notes
id: release_notes
run: |
# Extract release version from validated tag
VERSION="${VALIDATED_TAG}"
VERSION_NUM=$(echo "$VERSION" | sed 's/^v//')
# Generate release notes using the dedicated script
echo "Extracting changelog for version: $VERSION_NUM"
if python3 scripts/extract_changelog.py "$VERSION_NUM" > release_notes.md; then
echo "Changelog extracted successfully"
echo "Release notes content:"
cat release_notes.md
else
echo "Failed to extract changelog, creating default release notes"
echo "# Yaze $VERSION Release Notes\n\nPlease see the full changelog at docs/C1-changelog.md" > release_notes.md
fi
- name: Store release notes
id: notes
run: |
# Store release notes content for later use
echo "content<<EOF" >> $GITHUB_OUTPUT
cat release_notes.md >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
build-release:
name: Build Release
needs: validate-and-prepare
strategy:
matrix:
include:
- name: "Windows x64"
os: windows-2022
vcpkg_triplet: x64-windows
cmake_generator: "Visual Studio 17 2022"
cmake_generator_platform: x64
artifact_name: "yaze-windows-x64"
- name: "Windows ARM64"
os: windows-2022
vcpkg_triplet: arm64-windows
cmake_generator: "Visual Studio 17 2022"
cmake_generator_platform: ARM64
artifact_name: "yaze-windows-arm64"
- name: "macOS Universal"
os: macos-14
vcpkg_triplet: arm64-osx
artifact_name: "yaze-macos"
- name: "Linux x64"
os: ubuntu-22.04
artifact_name: "yaze-linux-x64"
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
# Platform-specific dependency installation
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
ninja-build \
pkg-config \
libglew-dev \
libxext-dev \
libwavpack-dev \
libabsl-dev \
libboost-all-dev \
libpng-dev \
python3-dev \
libpython3-dev \
libasound2-dev \
libpulse-dev \
libx11-dev \
libxrandr-dev \
libxcursor-dev \
libxinerama-dev \
libxi-dev
- name: Install macOS dependencies
if: runner.os == 'macOS'
run: |
# Install Homebrew dependencies needed for UI tests and full builds
brew install pkg-config libpng boost abseil ninja gtk+3
# Set up vcpkg for Windows builds with fallback
- name: Set up vcpkg (Windows)
id: vcpkg_setup
if: runner.os == 'Windows'
uses: lukka/run-vcpkg@v11
continue-on-error: true
with:
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
runVcpkgInstall: true
vcpkgJsonGlob: '**/vcpkg.json'
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
env:
VCPKG_FORCE_SYSTEM_BINARIES: 1
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
VCPKG_DISABLE_METRICS: 1
VCPKG_DEFAULT_TRIPLET: ${{ matrix.vcpkg_triplet }}
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
# Set vcpkg availability flag when vcpkg succeeds
- name: Set vcpkg availability flag
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'success'
shell: pwsh
run: |
echo "VCPKG_AVAILABLE=true" >> $env:GITHUB_ENV
Write-Host "vcpkg setup successful"
# Fallback: Set minimal build flag when vcpkg fails
- name: Set minimal build flag (Windows fallback)
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'failure'
shell: pwsh
run: |
echo "VCPKG_AVAILABLE=false" >> $env:GITHUB_ENV
echo "YAZE_MINIMAL_BUILD=ON" >> $env:GITHUB_ENV
Write-Host "vcpkg setup failed, using minimal build configuration"
# Configure CMake
- name: Configure CMake (Linux/macOS)
if: runner.os != 'Windows'
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 \
-DYAZE_BUILD_TESTS=OFF \
-DYAZE_BUILD_EMU=OFF \
-DYAZE_BUILD_Z3ED=OFF \
-DYAZE_ENABLE_UI_TESTS=ON \
-DYAZE_ENABLE_ROM_TESTS=OFF \
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
-DYAZE_INSTALL_LIB=OFF \
-DYAZE_MINIMAL_BUILD=OFF \
-GNinja
- name: Configure CMake (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Write-Host "Configuring CMake for Windows build..."
# Check if vcpkg is available
if ((Test-Path "${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake") -and ($env:VCPKG_AVAILABLE -ne "false")) {
Write-Host "Using vcpkg toolchain..."
cmake -B build `
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 `
-DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake" `
-DYAZE_BUILD_TESTS=OFF `
-DYAZE_BUILD_EMU=OFF `
-DYAZE_BUILD_Z3ED=OFF `
-DYAZE_ENABLE_ROM_TESTS=OFF `
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF `
-DYAZE_INSTALL_LIB=OFF `
-DYAZE_MINIMAL_BUILD=OFF `
-G "${{ matrix.cmake_generator }}" `
-A ${{ matrix.cmake_generator_platform }}
} else {
Write-Host "Using minimal build configuration (vcpkg not available)..."
cmake -B build `
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 `
-DYAZE_BUILD_TESTS=OFF `
-DYAZE_BUILD_EMU=OFF `
-DYAZE_BUILD_Z3ED=OFF `
-DYAZE_ENABLE_ROM_TESTS=OFF `
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF `
-DYAZE_INSTALL_LIB=OFF `
-DYAZE_MINIMAL_BUILD=ON `
-G "${{ matrix.cmake_generator }}" `
-A ${{ matrix.cmake_generator_platform }}
}
Write-Host "CMake configuration completed successfully"
# Build
- name: Build
run: |
echo "Building YAZE for ${{ matrix.name }}..."
cmake --build build --config ${{ env.BUILD_TYPE }} --parallel
echo "Build completed successfully!"
# Test executable functionality
- name: Test executable functionality
shell: bash
run: |
set -e
echo "Testing executable for ${{ matrix.name }}..."
# Determine executable path based on platform
if [[ "${{ runner.os }}" == "Windows" ]]; then
exePath="build/bin/${{ env.BUILD_TYPE }}/yaze.exe"
elif [[ "${{ runner.os }}" == "macOS" ]]; then
exePath="build/bin/yaze.app/Contents/MacOS/yaze"
else
exePath="build/bin/yaze"
fi
if [ -f "$exePath" ]; then
echo "✓ Executable found: $exePath"
# Test that it's not the test main
testResult=$($exePath --help 2>&1 || true)
exitCode=$?
if echo "$testResult" | grep -q "Google Test\|gtest"; then
echo "ERROR: Executable is running test main instead of app main!"
echo "Output: $testResult"
exit 1
fi
echo "✓ Executable runs correctly (exit code: $exitCode)"
# Display file info
if [[ "${{ runner.os }}" == "Windows" ]]; then
fileSize=$(stat -c%s "$exePath" 2>/dev/null || echo "0")
else
fileSize=$(stat -f%z "$exePath" 2>/dev/null || stat -c%s "$exePath" 2>/dev/null || echo "0")
fi
fileSizeMB=$(echo "scale=2; $fileSize / 1024 / 1024" | bc -l 2>/dev/null || echo "0")
echo "Executable size: ${fileSizeMB} MB"
else
echo "ERROR: Executable not found at: $exePath"
exit 1
fi
# Package
- name: Package
shell: bash
run: |
set -e
echo "Packaging for ${{ matrix.name }}..."
if [[ "${{ runner.os }}" == "Windows" ]]; then
# Windows packaging
mkdir -p package
cp -r build/bin/${{ env.BUILD_TYPE }}/* package/ 2>/dev/null || echo "No Release binaries found, trying Debug..."
cp -r build/bin/Debug/* package/ 2>/dev/null || echo "No Debug binaries found"
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
cp README.md package/ 2>/dev/null || echo "README.md not found"
cd package && zip -r ../${{ matrix.artifact_name }}.zip *
elif [[ "${{ runner.os }}" == "macOS" ]]; then
# macOS packaging
if [ -d "build/bin/yaze.app" ]; then
echo "Found macOS bundle, using it directly"
cp -r build/bin/yaze.app ./Yaze.app
# Add additional resources to the bundle
cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found"
# Update Info.plist with correct version
if [ -f "cmake/yaze.plist.in" ]; then
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
sed "s/@yaze_VERSION@/$VERSION_NUM/g" cmake/yaze.plist.in > "Yaze.app/Contents/Info.plist"
fi
else
echo "No bundle found, creating manual bundle"
mkdir -p "Yaze.app/Contents/MacOS"
mkdir -p "Yaze.app/Contents/Resources"
cp build/bin/yaze "Yaze.app/Contents/MacOS/"
cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found"
# Create Info.plist with correct version
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
echo '<?xml version="1.0" encoding="UTF-8"?>' > "Yaze.app/Contents/Info.plist"
echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' >> "Yaze.app/Contents/Info.plist"
echo '<plist version="1.0">' >> "Yaze.app/Contents/Info.plist"
echo '<dict>' >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundleExecutable</key>' >> "Yaze.app/Contents/Info.plist"
echo '<string>yaze</string>' >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundleIdentifier</key>' >> "Yaze.app/Contents/Info.plist"
echo '<string>com.yaze.editor</string>' >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundleName</key>' >> "Yaze.app/Contents/Info.plist"
echo '<string>Yaze</string>' >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundleVersion</key>' >> "Yaze.app/Contents/Info.plist"
echo "<string>$VERSION_NUM</string>" >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundleShortVersionString</key>' >> "Yaze.app/Contents/Info.plist"
echo "<string>$VERSION_NUM</string>" >> "Yaze.app/Contents/Info.plist"
echo '<key>CFBundlePackageType</key>' >> "Yaze.app/Contents/Info.plist"
echo '<string>APPL</string>' >> "Yaze.app/Contents/Info.plist"
echo '</dict>' >> "Yaze.app/Contents/Info.plist"
echo '</plist>' >> "Yaze.app/Contents/Info.plist"
fi
# Create DMG
mkdir dmg_staging
cp -r Yaze.app dmg_staging/
cp LICENSE dmg_staging/ 2>/dev/null || echo "LICENSE not found"
cp README.md dmg_staging/ 2>/dev/null || echo "README.md not found"
cp -r docs dmg_staging/ 2>/dev/null || echo "docs directory not found"
hdiutil create -srcfolder dmg_staging -format UDZO -volname "Yaze ${{ needs.validate-and-prepare.outputs.tag_name }}" ${{ matrix.artifact_name }}.dmg
else
# Linux packaging
mkdir package
cp build/bin/yaze package/
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
cp -r docs package/ 2>/dev/null || echo "docs directory not found"
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
cp README.md package/ 2>/dev/null || echo "README.md not found"
tar -czf ${{ matrix.artifact_name }}.tar.gz -C package .
fi
echo "Packaging completed successfully!"
# Create release with artifacts
- name: Upload to Release
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ needs.validate-and-prepare.outputs.tag_name }}
name: Yaze ${{ needs.validate-and-prepare.outputs.tag_name }}
body: ${{ needs.validate-and-prepare.outputs.release_notes }}
draft: false
prerelease: ${{ contains(needs.validate-and-prepare.outputs.tag_name, 'beta') || contains(needs.validate-and-prepare.outputs.tag_name, 'alpha') || contains(needs.validate-and-prepare.outputs.tag_name, 'rc') }}
files: |
${{ matrix.artifact_name }}.*
publish-packages:
name: Publish Packages
needs: [validate-and-prepare, build-release]
runs-on: ubuntu-latest
if: success()
steps:
- name: Announce release
run: |
echo "🎉 Yaze ${{ needs.validate-and-prepare.outputs.tag_name }} has been released!"
echo "📦 Packages are now available for download"
echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ needs.validate-and-prepare.outputs.tag_name }}"

View File

@@ -1,98 +1,101 @@
# .github/workflows/release.yml
name: Release
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-*'
- 'v[0-9]+.[0-9]+.[0-9]+-*' # e.g., v1.2.3-beta, v1.2.3-rc1
workflow_dispatch:
inputs:
tag:
description: 'Release tag (must start with v and follow semantic versioning)'
description: 'Release tag (e.g., v0.3.0)'
required: true
default: 'v0.3.0'
type: string
concurrency:
group: release-${{ github.event_name }}-${{ github.ref_name || github.event.inputs.tag || github.run_id }}
group: release-${{ github.ref_name || github.event.inputs.tag }}
cancel-in-progress: true
permissions:
contents: write
actions: read
env:
BUILD_TYPE: Release
jobs:
validate-and-prepare:
name: Validate & Prepare
# ======================================================================================
# VALIDATE & PREPARE RELEASE
# ======================================================================================
prepare-release:
name: "✅ Validate & Prepare"
runs-on: ubuntu-latest
outputs:
tag_name: ${{ steps.validate.outputs.tag_name }}
release_notes: ${{ steps.notes.outputs.content }}
is_prerelease: ${{ steps.validate.outputs.is_prerelease }}
steps:
- name: Determine & validate tag
id: validate
shell: bash
run: |
set -euo pipefail
if [[ "${{ github.event_name }}" == "push" ]]; then
if [[ "${{ github.ref_type }}" != "tag" ]]; then
echo "Release must be triggered by a tag push (vX.Y.Z)."
exit 1
fi
TAG="${{ github.ref_name }}"
else
TAG="${{ github.event.inputs.tag }}"
[[ -n "${TAG}" ]] || { echo "No tag provided."; exit 1; }
fi
echo "Validating tag: ${TAG}"
if [[ ! "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
echo "Tag '${TAG}' must be semantic: v1.2.3 or v1.2.3-rc1"
exit 1
fi
echo "tag_name=${TAG}" >> "$GITHUB_OUTPUT"
echo "VALIDATED_TAG=${TAG}" >> "$GITHUB_ENV"
- name: Checkout
- name: "Checkout Code"
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
fetch-depth: 0 # Required for changelog extraction
- name: Set up Python
- name: "Set up Python"
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Generate release notes
id: gen_notes
- name: "Determine & Validate Tag"
id: validate
shell: bash
run: |
set -euo pipefail
if [[ "${{ github.event_name }}" == "push" ]]; then
TAG="${{ github.ref_name }}"
else
TAG="${{ github.event.inputs.tag }}"
fi
echo "Validating tag: ${TAG}"
if [[ ! "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
echo "::error::Tag '${TAG}' must follow semantic versioning (e.g., v1.2.3 or v1.2.3-beta)."
exit 1
fi
# Determine if it's a pre-release
if [[ "${TAG}" =~ - ]]; then
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
fi
echo "tag_name=${TAG}" >> "$GITHUB_OUTPUT"
echo "VALIDATED_TAG=${TAG}" >> "$GITHUB_ENV"
echo "✅ Tag is valid and processed."
- name: "Generate Release Notes"
shell: bash
run: |
set -euo pipefail
VERSION="${VALIDATED_TAG#v}"
if [[ -f scripts/extract_changelog.py ]]; then
if python3 scripts/extract_changelog.py "${VERSION}" > release_notes.md; then
echo "Changelog extracted for ${VERSION}"
else
echo "# yaze Release Notes" > release_notes.md
echo "" >> release_notes.md
echo "See docs/C1-changelog.md for full history." >> release_notes.md
fi
echo "Attempting to extract changelog for version ${VERSION}..."
python3 scripts/extract_changelog.py "${VERSION}" > release_notes.md
else
echo "# yaze Release Notes" > release_notes.md
echo "::warning::'scripts/extract_changelog.py' not found. Creating default release notes."
echo "# Yaze ${{ env.VALIDATED_TAG }} Release Notes" > release_notes.md
echo "" >> release_notes.md
echo "See docs/C1-changelog.md for full history." >> release_notes.md
echo "For a detailed list of changes, please see the project's commit history or changelog file." >> release_notes.md
fi
echo "---- RELEASE NOTES START ----"
echo "Generated release notes:"
cat release_notes.md
echo "---- RELEASE NOTES END ----"
- name: Store release notes output
- name: "Store Release Notes"
id: notes
shell: bash
run: |
@@ -102,9 +105,12 @@ jobs:
echo 'EOF'
} >> "$GITHUB_OUTPUT"
build-release:
name: Build (${{ matrix.name }})
needs: validate-and-prepare
# ======================================================================================
# BUILD & PACKAGE
# ======================================================================================
build-and-package:
name: "📦 Build (${{ matrix.name }})"
needs: prepare-release
strategy:
fail-fast: false
matrix:
@@ -115,16 +121,22 @@ jobs:
cmake_generator: "Visual Studio 17 2022"
cmake_generator_platform: x64
artifact_name: "yaze-windows-x64"
- name: "Windows arm64"
os: windows-2022
vcpkg_triplet: arm64-windows
cmake_generator: "Visual Studio 17 2022"
cmake_generator_platform: ARM64
artifact_name: "yaze-windows-arm64"
- name: "macOS arm64"
os: macos-14
vcpkg_triplet: arm64-osx
mac_arch: arm64
artifact_name: "yaze-macos-arm64"
artifact_name: "yaze-macos-arm64-slice"
- name: "macOS x86_64"
os: macos-14
vcpkg_triplet: x64-osx
mac_arch: x86_64
artifact_name: "yaze-macos-x86_64"
artifact_name: "yaze-macos-x86_64-slice"
- name: "Linux x64"
os: ubuntu-22.04
artifact_name: "yaze-linux-x64"
@@ -132,357 +144,175 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
- name: "Checkout Code"
uses: actions/checkout@v4
with:
submodules: recursive
# ---------- Speed: ccache on Unix ----------
- name: Install ccache (Linux)
- name: "Install Dependencies (Linux)"
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y ccache
sudo apt-get install -y build-essential ninja-build pkg-config libglew-dev libxext-dev libwavpack-dev libabsl-dev libboost-all-dev libpng-dev python3-dev libpython3-dev libasound2-dev libpulse-dev libx11-dev libxrandr-dev libxcursor-dev libxinerama-dev libxi-dev
- name: Install ccache (macOS)
- name: "Install Dependencies (macOS)"
if: runner.os == 'macOS'
run: brew install ccache
run: brew install ninja cmake
- name: Cache ccache
if: runner.os != 'Windows'
uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt', '**/*.cmake') }}
restore-keys: |
ccache-${{ runner.os }}-
# ---------- Dependencies ----------
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential ninja-build pkg-config \
libglew-dev libxext-dev libwavpack-dev \
libabsl-dev libboost-all-dev libpng-dev \
python3-dev libpython3-dev \
libasound2-dev libpulse-dev \
libx11-dev libxrandr-dev libxcursor-dev \
libxinerama-dev libxi-dev
- name: Install macOS build tools
if: runner.os == 'macOS'
run: |
brew update
brew install pkg-config ninja cmake
# ---------- vcpkg (Windows & macOS) ----------
- name: Prepare vcpkg download cache (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$dl = Join-Path $env:GITHUB_WORKSPACE 'vcpkg_downloads'
New-Item -ItemType Directory -Force -Path $dl | Out-Null
- name: Set up vcpkg (Windows)
id: vcpkg_win
if: runner.os == 'Windows'
- name: "Set up vcpkg"
uses: lukka/run-vcpkg@v11
with:
vcpkgGitCommitId: '4334d8b4c8916018600212ab4dd4bbdc343065d1'
runVcpkgInstall: true
vcpkgJsonGlob: '**/vcpkg.json'
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
env:
VCPKG_FORCE_SYSTEM_BINARIES: 1
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
VCPKG_DISABLE_METRICS: 1
VCPKG_DEFAULT_TRIPLET: ${{ matrix.vcpkg_triplet }}
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
VCPKG_USE_SYSTEM_BINARIES: 1
VCPKG_DOWNLOADS: ${{ github.workspace }}/vcpkg_downloads
VCPKG_DEFAULT_HOST_TRIPLET: x64-windows
VCPKG_FEATURE_FLAGS: versions
- name: Mark vcpkg availability (Windows)
if: runner.os == 'Windows' && steps.vcpkg_win.outcome == 'success'
shell: pwsh
run: echo "VCPKG_AVAILABLE=true" >> $env:GITHUB_ENV
- name: Mark minimal build (Windows fallback)
if: runner.os == 'Windows' && steps.vcpkg_win.outcome != 'success'
shell: pwsh
- name: "Configure CMake"
shell: bash
run: |
echo "VCPKG_AVAILABLE=false" >> $env:GITHUB_ENV
echo "YAZE_MINIMAL_BUILD=ON" >> $env:GITHUB_ENV
- name: Prepare vcpkg download cache (macOS)
if: runner.os == 'macOS'
run: mkdir -p "${{ github.workspace }}/vcpkg_downloads"
- name: Set up vcpkg (macOS)
if: runner.os == 'macOS'
uses: lukka/run-vcpkg@v11
with:
vcpkgGitCommitId: '4334d8b4c8916018600212ab4dd4bbdc343065d1'
runVcpkgInstall: true
vcpkgJsonGlob: '**/vcpkg.json'
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
env:
VCPKG_FORCE_SYSTEM_BINARIES: 1
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
VCPKG_DISABLE_METRICS: 1
VCPKG_DEFAULT_TRIPLET: ${{ matrix.vcpkg_triplet }}
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
VCPKG_USE_SYSTEM_BINARIES: 1
VCPKG_DOWNLOADS: ${{ github.workspace }}/vcpkg_downloads
VCPKG_FEATURE_FLAGS: versions
# ---------- Configure ----------
- name: Configure CMake (Linux)
if: runner.os == 'Linux'
run: |
rm -rf build && mkdir -p build
cmake -S . -B build \
-GNinja \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 \
-DYAZE_USE_MODULAR_BUILD=ON \
-DYAZE_BUILD_TESTS=ON \
-DYAZE_BUILD_EMU=OFF \
-DYAZE_BUILD_Z3ED=ON \
-DYAZE_ENABLE_UI_TESTS=ON \
-DYAZE_ENABLE_ROM_TESTS=OFF \
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
-DYAZE_INSTALL_LIB=OFF \
-DYAZE_MINIMAL_BUILD=OFF \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Configure CMake (macOS per-arch)
if: runner.os == 'macOS'
run: |
rm -rf build && mkdir -p build
cmake -S . -B build \
-GNinja \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 \
-DYAZE_USE_MODULAR_BUILD=ON \
-DYAZE_BUILD_TESTS=ON \
-DYAZE_BUILD_EMU=OFF \
-DYAZE_BUILD_Z3ED=ON \
-DYAZE_ENABLE_UI_TESTS=ON \
-DYAZE_ENABLE_ROM_TESTS=OFF \
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
-DYAZE_INSTALL_LIB=OFF \
-DYAZE_MINIMAL_BUILD=OFF \
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 \
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.mac_arch }} \
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Configure CMake (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
if (Test-Path build) { Remove-Item -Recurse -Force build }
New-Item -ItemType Directory -Path build | Out-Null
$toolchain = Join-Path $env:VCPKG_ROOT 'scripts\buildsystems\vcpkg.cmake'
$useVcpkg = (Test-Path $toolchain) -and ($env:VCPKG_AVAILABLE -ne 'false')
$args = @(
'-S','.',
'-B','build',
'-G','${{ matrix.cmake_generator }}',
'-A','${{ matrix.cmake_generator_platform }}',
'-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}',
'-DCMAKE_POLICY_VERSION_MINIMUM=3.16',
'-DYAZE_USE_MODULAR_BUILD=ON',
'-DYAZE_BUILD_TESTS=ON',
'-DYAZE_BUILD_EMU=OFF',
'-DYAZE_BUILD_Z3ED=ON',
'-DYAZE_ENABLE_UI_TESTS=ON',
'-DYAZE_ENABLE_ROM_TESTS=ON',
'-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF',
'-DYAZE_INSTALL_LIB=OFF'
set -x
CMAKE_ARGS=(
"-S ."
"-B build"
"-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}"
"-DYAZE_BUILD_TESTS=OFF"
"-DYAZE_BUILD_EMU=OFF"
"-DYAZE_BUILD_Z3ED=ON"
)
if ($useVcpkg) {
$args += "-DCMAKE_TOOLCHAIN_FILE=$toolchain"
}
if [[ "${{ runner.os }}" == "Windows" ]]; then
CMAKE_ARGS+=(
"-G" "${{ matrix.cmake_generator }}"
"-A" "${{ matrix.cmake_generator_platform }}"
"-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake"
)
elif [[ "${{ runner.os }}" == "macOS" ]]; then
CMAKE_ARGS+=(
"-G" "Ninja"
"-DCMAKE_OSX_ARCHITECTURES=${{ matrix.mac_arch }}"
"-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0"
"-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake"
)
else # Linux
CMAKE_ARGS+=("-G" "Ninja")
fi
cmake @args
cmake "${CMAKE_ARGS[@]}"
# ---------- Build ----------
- name: Build
shell: bash
- name: "Build Project"
run: cmake --build build --config ${{ env.BUILD_TYPE }} --parallel
# ---------- Smoke test ----------
- name: Test executable
- name: "Package Artifacts"
shell: bash
run: |
set -euo pipefail
ARTIFACT_NAME="${{ matrix.artifact_name }}"
# Create staging directory
mkdir -p stage
if [[ "${{ runner.os }}" == "Windows" ]]; then
EXE="build/bin/${{ env.BUILD_TYPE }}/yaze.exe"
cp -r build/bin/${{ env.BUILD_TYPE }}/* stage/
cp -r assets/ stage/assets/
cp LICENSE README.md stage/
(cd stage && powershell -Command "Compress-Archive -Path * -DestinationPath ../${ARTIFACT_NAME}.zip")
echo "Created ${ARTIFACT_NAME}.zip"
elif [[ "${{ runner.os }}" == "macOS" ]]; then
EXE="build/bin/yaze.app/Contents/MacOS/yaze"
else
EXE="build/bin/yaze"
# For macOS, we stage the .app bundle as a "slice" for the universal merge job
cp -R build/bin/yaze.app stage/
echo "Staged yaze.app slice for ${ARTIFACT_NAME}"
else # Linux
cp build/bin/yaze stage/
cp -r assets/ stage/assets/
cp LICENSE README.md stage/
tar -czf "${ARTIFACT_NAME}.tar.gz" -C stage .
echo "Created ${ARTIFACT_NAME}.tar.gz"
fi
[[ -f "$EXE" ]] || { echo "Executable not found: $EXE"; exit 1; }
out="$("$EXE" --help || true)"
if echo "$out" | grep -Ei 'Google Test|gtest' >/dev/null; then
echo "Executable is test main, expected app main."
exit 1
fi
ls -lh "$EXE"
# ---------- Package / Stage ----------
- name: Package / Stage
shell: bash
run: |
set -euo pipefail
ART="${{ matrix.artifact_name }}"
case "${{ runner.os }}" in
Windows)
cmake --build build --config ${{ env.BUILD_TYPE }} --target package || true
pkg="$(ls build/yaze-*.zip 2>/dev/null | head -n1 || true)"
if [[ -n "${pkg}" ]]; then
cp "${pkg}" "${ART}.zip"
else
mkdir -p package
cp -r "build/bin/${{ env.BUILD_TYPE }}"/* package/
[[ -d assets ]] && cp -r assets package/
[[ -f LICENSE ]] && cp LICENSE package/
[[ -f README.md ]] && cp README.md package/
(cd package && powershell.exe -NoLogo -NoProfile -Command "Compress-Archive -Path * -DestinationPath ../${ART}.zip -Force")
fi
;;
macOS)
# stage per-arch outputs for universal merge
mkdir -p slice
cp -R build/bin/yaze.app slice/
[[ -d assets ]] && cp -R assets slice/ || true
[[ -f LICENSE ]] && cp LICENSE slice/ || true
[[ -f README.md ]] && cp README.md slice/ || true
;;
Linux)
mkdir -p package
cp build/bin/yaze package/
[[ -d assets ]] && cp -r assets package/
[[ -d docs ]] && cp -r docs package/
[[ -f LICENSE ]] && cp LICENSE package/
[[ -f README.md ]] && cp README.md package/
tar -czf "${ART}.tar.gz" -C package .
;;
esac
echo "Staged/packaged for ${ART}"
- name: Upload artifact
- name: "Upload Artifact"
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: |
${{ matrix.artifact_name }}.zip
${{ matrix.artifact_name }}.tar.gz
slice/**
if-no-files-found: ignore
retention-days: 7
stage/
if-no-files-found: error
retention-days: 5
macos-universal-merge:
name: Merge macOS slices -> universal2
needs: build-release
# ======================================================================================
# MERGE MACOS & CREATE UNIVERSAL BINARY
# ======================================================================================
merge-macos-universal:
name: "🍎 Merge macOS Universal"
needs: build-and-package
runs-on: macos-14
steps:
- name: Download macOS arm64 slice
- name: "Download arm64 Slice"
uses: actions/download-artifact@v4
with:
name: yaze-macos-arm64
path: mac-arm64
name: yaze-macos-arm64-slice
path: arm64-slice
- name: Download macOS x86_64 slice
- name: "Download x86_64 Slice"
uses: actions/download-artifact@v4
with:
name: yaze-macos-x86_64
path: mac-x86_64
name: yaze-macos-x86_64-slice
path: x86_64-slice
- name: Merge with lipo
- name: "Create Universal Binary"
shell: bash
run: |
set -euo pipefail
ARM_BIN="mac-arm64/slice/yaze.app/Contents/MacOS/yaze"
X64_BIN="mac-x86_64/slice/yaze.app/Contents/MacOS/yaze"
[[ -f "$ARM_BIN" && -f "$X64_BIN" ]]
ARM_APP="arm64-slice/yaze.app"
X64_APP="x86_64-slice/yaze.app"
# Use the arm64 bundle as the base
cp -R "${ARM_APP}" ./yaze.app
echo "Merging executables..."
lipo -create "${ARM_APP}/Contents/MacOS/yaze" "${X64_APP}/Contents/MacOS/yaze" -output "./yaze.app/Contents/MacOS/yaze"
echo "Verifying universal binary..."
lipo -info "./yaze.app/Contents/MacOS/yaze"
echo "Creating DMG..."
hdiutil create -fs HFS+ -srcfolder ./yaze.app -volname "yaze ${{ needs.prepare-release.outputs.tag_name }}" yaze-macos-universal.dmg
# Copy arm64 bundle as base
cp -R "mac-arm64/slice/yaze.app" "yaze.app"
# Merge executable
lipo -create "$ARM_BIN" "$X64_BIN" -output "yaze.app/Contents/MacOS/yaze"
lipo -info "yaze.app/Contents/MacOS/yaze"
# Optionally merge any arch-specific helper binaries similarly if present
- name: Repackage universal app
shell: bash
run: |
set -euo pipefail
mkdir -p package
cp -R yaze.app package/
# Prefer arm64 assets/LICENSE/README if present
[[ -d mac-arm64/slice/assets ]] && cp -R mac-arm64/slice/assets package/ || true
[[ -f mac-arm64/slice/LICENSE ]] && cp mac-arm64/slice/LICENSE package/ || true
[[ -f mac-arm64/slice/README.md ]] && cp mac-arm64/slice/README.md package/ || true
ditto -c -k --sequesterRsrc --keepParent package "yaze-macos-universal.zip"
echo "Created yaze-macos-universal.zip"
- name: Upload universal macOS artifact
- name: "Upload Universal macOS Artifact"
uses: actions/upload-artifact@v4
with:
name: yaze-macos
path: yaze-macos-universal.zip
retention-days: 7
name: yaze-macos-universal
path: yaze-macos-universal.dmg
if-no-files-found: error
retention-days: 5
create-release:
name: Create GitHub Release
needs: [validate-and-prepare, build-release, macos-universal-merge]
# ======================================================================================
# CREATE GITHUB RELEASE
# ======================================================================================
create-github-release:
name: "🚀 Create GitHub Release"
needs: [prepare-release, build-and-package, merge-macos-universal]
runs-on: ubuntu-latest
steps:
- name: Download all build artifacts
- name: "Download All Artifacts"
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Summarize artifacts
shell: bash
run: |
echo "Artifacts downloaded:"
find dist -maxdepth 3 -type f -print -exec ls -lh {} \;
- name: "List Artifacts"
run: ls -lR dist
- name: Create/Update Release
- name: "Create/Update Release"
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.validate-and-prepare.outputs.tag_name }}
name: yaze ${{ needs.validate-and-prepare.outputs.tag_name }}
body: ${{ needs.validate-and-prepare.outputs.release_notes }}
tag_name: ${{ needs.prepare-release.outputs.tag_name }}
name: "yaze ${{ needs.prepare-release.outputs.tag_name }}"
body: ${{ needs.prepare-release.outputs.release_notes }}
draft: false
prerelease: ${{ contains(needs.validate-and-prepare.outputs.tag_name, 'beta') || contains(needs.validate-and-prepare.outputs.tag_name, 'alpha') || contains(needs.validate-and-prepare.outputs.tag_name, 'rc') }}
files: |
dist/**/*
prerelease: ${{ needs.prepare-release.outputs.is_prerelease }}
files: dist/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-packages:
name: Publish Packages (announce)
needs: [validate-and-prepare, create-release]
runs-on: ubuntu-latest
steps:
- name: Announce release
run: |
echo "🎉 yaze ${{ needs.validate-and-prepare.outputs.tag_name }} has been released!"
echo "📦 Packages are now available for download"
echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ needs.validate-and-prepare.outputs.tag_name }}"