name: Release on: push: tags: ['v*'] permissions: contents: write jobs: build-linux: name: Build (linux-${{ matrix.arch }}) runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: include: - arch: x86-64 runner: ubuntu-24.04 - arch: arm64 runner: ubuntu-24.04-arm steps: - name: Checkout uses: actions/checkout@v4 with: submodules: true - name: Cache apt packages uses: actions/cache@v4 with: path: /var/cache/apt/archives/*.deb key: apt-${{ matrix.arch }}-${{ hashFiles('.github/workflows/release.yml') }} restore-keys: apt-${{ matrix.arch }}- - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y \ cmake \ build-essential \ pkg-config \ libsdl2-dev \ libglew-dev \ libglm-dev \ libssl-dev \ zlib1g-dev \ libvulkan-dev \ vulkan-tools \ glslc \ libavformat-dev \ libavcodec-dev \ libswscale-dev \ libavutil-dev \ libunicorn-dev \ libx11-dev sudo apt-get install -y libstormlib-dev || true - name: Configure run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release - name: Build run: cmake --build build --parallel $(nproc) - name: Package run: | TAG="${GITHUB_REF_NAME}" STAGING="wowee-${TAG}-linux-${{ matrix.arch }}" mkdir -p "${STAGING}" # Binary cp build/bin/wowee "${STAGING}/" # Asset extraction tool (if built — requires StormLib) if [ -f build/bin/asset_extract ]; then cp build/bin/asset_extract "${STAGING}/" fi # Extraction scripts and GUI cp extract_assets.sh "${STAGING}/" cp tools/asset_pipeline_gui.py "${STAGING}/" # Assets (exclude proprietary music) rsync -a --exclude='Original Music' build/bin/assets/ "${STAGING}/assets/" # Data directory (git-tracked files only) git ls-files Data/ | while read -r f; do mkdir -p "${STAGING}/$(dirname "$f")" cp "$f" "${STAGING}/$f" done tar czf "${STAGING}.tar.gz" "${STAGING}" - name: Upload artifact uses: actions/upload-artifact@v4 with: name: wowee-linux-${{ matrix.arch }} path: wowee-*.tar.gz if-no-files-found: error build-macos: name: Build (macOS arm64) runs-on: macos-15 steps: - name: Checkout uses: actions/checkout@v4 with: submodules: true - name: Install dependencies run: | brew install cmake pkg-config sdl2 glew glm openssl@3 zlib ffmpeg unicorn \ stormlib vulkan-loader vulkan-headers shaderc dylibbundler || true brew install dylibbundler 2>/dev/null || true - name: Configure run: | BREW=$(brew --prefix) export PKG_CONFIG_PATH="$BREW/lib/pkgconfig:$(brew --prefix ffmpeg)/lib/pkgconfig:$(brew --prefix openssl@3)/lib/pkgconfig:$(brew --prefix vulkan-loader)/lib/pkgconfig:$(brew --prefix shaderc)/lib/pkgconfig" cmake -S . -B build \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_PREFIX_PATH="$BREW" \ -DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)" - name: Build run: cmake --build build --parallel $(sysctl -n hw.logicalcpu) - name: Create .app bundle run: | TAG="${GITHUB_REF_NAME}" mkdir -p Wowee.app/Contents/{MacOS,Frameworks,Resources} # Wrapper launch script printf '#!/bin/bash\ncd "$(dirname "$0")"\nexec ./wowee_bin "$@"\n' \ > Wowee.app/Contents/MacOS/wowee chmod +x Wowee.app/Contents/MacOS/wowee # Actual binary cp build/bin/wowee Wowee.app/Contents/MacOS/wowee_bin # Asset extraction tool (if built — requires StormLib) if [ -f build/bin/asset_extract ]; then cp build/bin/asset_extract Wowee.app/Contents/MacOS/ fi # Extraction scripts and GUI cp extract_assets.sh Wowee.app/Contents/MacOS/ cp tools/asset_pipeline_gui.py Wowee.app/Contents/MacOS/ # Assets (exclude proprietary music) rsync -a --exclude='Original Music' build/bin/assets/ \ Wowee.app/Contents/MacOS/assets/ # Data directory (git-tracked files only) git ls-files Data/ | while read -r f; do mkdir -p "Wowee.app/Contents/MacOS/$(dirname "$f")" cp "$f" "Wowee.app/Contents/MacOS/$f" done # Bundle dylibs if command -v dylibbundler &>/dev/null; then dylibbundler -od -b \ -x Wowee.app/Contents/MacOS/wowee_bin \ -d Wowee.app/Contents/Frameworks/ \ -p @executable_path/../Frameworks/ if [ -f Wowee.app/Contents/MacOS/asset_extract ]; then dylibbundler -od -b \ -x Wowee.app/Contents/MacOS/asset_extract \ -d Wowee.app/Contents/Frameworks/ \ -p @executable_path/../Frameworks/ fi fi # Info.plist cat > Wowee.app/Contents/Info.plist << EOF CFBundleExecutablewowee CFBundleIdentifiercom.wowee.app CFBundleNameWowee CFBundleVersion${TAG} CFBundleShortVersionString${TAG} CFBundlePackageTypeAPPL EOF # Ad-hoc codesign codesign --force --deep --sign - Wowee.app - name: Create DMG run: | TAG="${GITHUB_REF_NAME}" hdiutil create -volname Wowee -srcfolder Wowee.app -ov -format UDZO \ "wowee-${TAG}-macos-arm64.dmg" - name: Upload artifact uses: actions/upload-artifact@v4 with: name: wowee-macos-arm64 path: wowee-*.dmg if-no-files-found: error build-windows: name: Build (windows-${{ matrix.arch }}) runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: include: - arch: x86-64 runner: windows-latest msystem: MINGW64 prefix: mingw-w64-x86_64 - arch: arm64 runner: windows-11-arm msystem: CLANGARM64 prefix: mingw-w64-clang-aarch64 steps: - name: Checkout uses: actions/checkout@v4 with: submodules: true - name: Set up MSYS2 uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} update: ${{ matrix.arch == 'arm64' }} install: >- ${{ matrix.prefix }}-cmake ${{ matrix.arch == 'x86-64' && format('{0}-gcc', matrix.prefix) || format('{0}-clang', matrix.prefix) }} ${{ matrix.prefix }}-ninja ${{ matrix.prefix }}-pkgconf ${{ matrix.prefix }}-SDL2 ${{ matrix.prefix }}-glew ${{ matrix.prefix }}-glm ${{ matrix.prefix }}-openssl ${{ matrix.prefix }}-zlib ${{ matrix.prefix }}-ffmpeg ${{ matrix.prefix }}-unicorn ${{ matrix.prefix }}-vulkan-loader ${{ matrix.prefix }}-vulkan-headers ${{ matrix.prefix }}-shaderc git - name: Install optional packages shell: msys2 {0} run: | pacman -S --noconfirm --needed ${{ matrix.prefix }}-stormlib || true pacman -S --noconfirm --needed zip - name: Configure shell: msys2 {0} run: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release - name: Build shell: msys2 {0} run: cmake --build build --parallel $(nproc) - name: Bundle DLLs shell: msys2 {0} run: | for exe in build/bin/wowee.exe build/bin/asset_extract.exe; do [ -f "$exe" ] || continue ldd "$exe" \ | awk '/=> \// { print $3 }' \ | grep -iv '^/c/Windows' \ | xargs -I{} sh -c 'cp -n "{}" build/bin/ 2>/dev/null || true' done - name: Package shell: msys2 {0} run: | TAG="${GITHUB_REF_NAME}" STAGING="wowee-${TAG}-windows-${{ matrix.arch }}" mkdir -p "${STAGING}" # Binary and DLLs cp build/bin/wowee.exe "${STAGING}/" cp build/bin/*.dll "${STAGING}/" 2>/dev/null || true # Asset extraction tool (if built — requires StormLib) if [ -f build/bin/asset_extract.exe ]; then cp build/bin/asset_extract.exe "${STAGING}/" fi # Extraction scripts and GUI cp extract_assets.ps1 "${STAGING}/" cp extract_assets.bat "${STAGING}/" cp tools/asset_pipeline_gui.py "${STAGING}/" # Assets (exclude proprietary music) mkdir -p "${STAGING}/assets" for d in build/bin/assets/*/; do dirname="$(basename "$d")" [ "$dirname" = "Original Music" ] && continue cp -r "$d" "${STAGING}/assets/" done # Copy top-level asset files cp build/bin/assets/* "${STAGING}/assets/" 2>/dev/null || true # Data directory (git-tracked files only) git ls-files Data/ | while read -r f; do mkdir -p "${STAGING}/$(dirname "$f")" cp "$f" "${STAGING}/$f" done # Create ZIP zip -r "${STAGING}.zip" "${STAGING}" - name: Upload artifact uses: actions/upload-artifact@v4 with: name: wowee-windows-${{ matrix.arch }} path: wowee-*.zip if-no-files-found: error release: name: Create Release needs: [build-linux, build-macos, build-windows] runs-on: ubuntu-latest steps: - name: Download all artifacts uses: actions/download-artifact@v4 with: path: artifacts/ - name: Create GitHub Release env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} run: | TAG="${GITHUB_REF_NAME}" # Collect all release files FILES=() for f in artifacts/*/*; do FILES+=("$f") done gh release create "${TAG}" \ --title "Wowee ${TAG}" \ --generate-notes \ "${FILES[@]}"