mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-19 18:36:53 +02:00
4e8d8c849d
* launcher: keep primary update feed answer when the fallback request fails When the primary feed is reachable but its tag differs from the build tag, the result was discarded and the GitHub API fallback was consulted. If the fallback request failed (api.github.com rate-limits unauthenticated requests), the launcher reported an error even though the primary feed had already returned a usable update answer with a working release URL. Keep the primary feed answer and show it if the fallback fails. * emulator: validate numeric CLI arguments --screen-width, --screen-height, --gpu, and --vblank-frequency were parsed with Common::ToInt32/ToInt64, which ignores std::from_chars errors and returns 0, so values like "--screen-width abc" or "--gpu xyz" were silently accepted: zero screen size, or GPU 0 selected instead of auto (-1). Reject invalid values with an error message like the other options, using from_chars-based helpers (ParseUint32/ParseInt32); reject zero screen dimensions. * tests: add LeastRecentlyUsedCache regression tests Cover the LRU cache walk order, tick filtering in ForEachItemBelow, early-exit boolean callbacks, Touch reordering and same-tick skips, Free, and freed-id reuse by later inserts. Modeled on BitArrayTests. * tests: use a tick cutoff that detects a stale newest-item tick Collect(cache, 35) also visits c when Touch(c, 35) failed to update its tick (30 <= 35). Use a cutoff of 30 and expect only b. * Run LRU cache tests in CI --------- Co-authored-by: nmzik <Nmzik@mail.ru>
519 lines
17 KiB
YAML
519 lines
17 KiB
YAML
name: Build and Release KytyPS5
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
push:
|
|
branches: [ main, master ]
|
|
pull_request:
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
|
|
env:
|
|
SCCACHE_GHA_ENABLED: "true"
|
|
KYTY_BUILD_ORIGIN: ${{ github.repository != 'KytyPS5/KytyPS5' && 'Fork' || github.event_name == 'push' && 'Official' || 'Source' }}
|
|
KYTY_BUILD_REPOSITORY: ${{ github.repository }}
|
|
|
|
jobs:
|
|
metadata:
|
|
name: Prepare build metadata
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
release_tag: ${{ steps.release_tag.outputs.value }}
|
|
|
|
steps:
|
|
- name: Generate release tag
|
|
id: release_tag
|
|
shell: bash
|
|
run: |
|
|
echo "value=KytyPS5-$(date -u +'%Y-%m-%d')-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
|
|
|
|
windows:
|
|
name: Build KytyPS5 (Windows)
|
|
needs: metadata
|
|
runs-on: windows-2022
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Setup Visual Studio environment
|
|
uses: ilammy/msvc-dev-cmd@v1
|
|
|
|
- name: Locate vcpkg
|
|
id: vcpkg
|
|
shell: pwsh
|
|
run: |
|
|
$vcpkgRoot = Split-Path (Get-Command vcpkg).Source
|
|
$portHash = (Get-FileHash "$vcpkgRoot\ports\glslang\vcpkg.json" -Algorithm SHA256).Hash
|
|
"root=$vcpkgRoot" |
|
|
Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
|
|
"port_hash=$($portHash.ToLowerInvariant())" |
|
|
Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
|
|
|
|
- name: Cache glslang
|
|
id: glslang_cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ${{ steps.vcpkg.outputs.root }}\installed\x64-windows
|
|
key: glslang-${{ runner.os }}-${{ runner.arch }}-${{ steps.vcpkg.outputs.port_hash }}-tools-opt
|
|
|
|
- name: Install glslang
|
|
shell: pwsh
|
|
run: |
|
|
$vcpkgRoot = "${{ steps.vcpkg.outputs.root }}"
|
|
if ("${{ steps.glslang_cache.outputs.cache-hit }}" -ne "true") {
|
|
vcpkg install glslang[tools,opt]:x64-windows
|
|
}
|
|
"$vcpkgRoot\installed\x64-windows\tools\glslang" |
|
|
Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
|
|
|
- name: Install Qt 6.10.3
|
|
uses: jurplel/install-qt-action@v4
|
|
with:
|
|
version: "6.10.3"
|
|
host: windows
|
|
target: desktop
|
|
arch: win64_msvc2022_64
|
|
cache: true
|
|
|
|
- name: Setup sccache
|
|
uses: mozilla-actions/sccache-action@v0.0.11
|
|
|
|
- name: Verify toolchain
|
|
shell: cmd
|
|
run: |
|
|
git --version
|
|
cmake --version
|
|
ninja --version
|
|
clang-cl --version
|
|
glslangValidator --version
|
|
echo Qt6_DIR=%Qt6_DIR%
|
|
|
|
- name: Configure
|
|
shell: cmd
|
|
run: |
|
|
cmake -S . -B _Build/windows ^
|
|
-G Ninja ^
|
|
-DCMAKE_BUILD_TYPE=Release ^
|
|
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON ^
|
|
-DKYTY_BUILD_ORIGIN=%KYTY_BUILD_ORIGIN% ^
|
|
-DKYTY_BUILD_REPOSITORY=%KYTY_BUILD_REPOSITORY% ^
|
|
-DKYTY_RELEASE_TAG=${{ needs.metadata.outputs.release_tag }} ^
|
|
-DCMAKE_C_COMPILER=clang-cl ^
|
|
-DCMAKE_CXX_COMPILER=clang-cl ^
|
|
-DCMAKE_C_COMPILER_LAUNCHER=sccache ^
|
|
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache ^
|
|
-DCMAKE_PREFIX_PATH="%Qt6_DIR%"
|
|
|
|
- name: Build
|
|
shell: cmd
|
|
run: |
|
|
cmake --build _Build/windows --target launcher audio_out2_port_tests ime_dialog_tests lru_cache_tests virtual_memory_allocation_tests --parallel
|
|
|
|
- name: Test
|
|
shell: cmd
|
|
run: |
|
|
ctest --test-dir _Build/windows --output-on-failure -R "^(audio_out2_port|ime_dialog|lru_cache|virtual_memory_allocation)$"
|
|
|
|
- name: Install
|
|
shell: cmd
|
|
run: |
|
|
cmake --install _Build/windows --prefix _Build/windows/install
|
|
|
|
- name: Upload Windows artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: KytyPS5-Windows-x64
|
|
path: _Build/windows/install/**
|
|
if-no-files-found: error
|
|
|
|
macos:
|
|
name: Build KytyPS5 (macOS)
|
|
needs: metadata
|
|
runs-on: macos-15
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Select Xcode 26
|
|
shell: bash
|
|
run: |
|
|
xcode_path="$(ls -d /Applications/Xcode_26*.app | tail -n 1)"
|
|
test -n "$xcode_path"
|
|
sudo xcode-select --switch "$xcode_path/Contents/Developer"
|
|
xcodebuild -version
|
|
|
|
- name: Install build dependencies
|
|
shell: bash
|
|
run: brew install glslang
|
|
|
|
- name: Install Qt 6.10.3
|
|
uses: jurplel/install-qt-action@v4
|
|
with:
|
|
version: "6.10.3"
|
|
host: mac
|
|
target: desktop
|
|
arch: clang_64
|
|
cache: true
|
|
|
|
- name: Setup sccache
|
|
uses: mozilla-actions/sccache-action@v0.0.11
|
|
|
|
- name: Verify toolchain
|
|
shell: bash
|
|
run: |
|
|
git --version
|
|
cmake --version
|
|
ninja --version
|
|
clang++ --version
|
|
glslangValidator --version
|
|
echo "Host architecture: $(uname -m)"
|
|
echo "QT_ROOT_DIR=$QT_ROOT_DIR"
|
|
|
|
- name: Configure
|
|
shell: bash
|
|
run: |
|
|
cmake -S . -B _Build/macos \
|
|
-G Ninja \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
|
|
-DKYTY_BUILD_ORIGIN="$KYTY_BUILD_ORIGIN" \
|
|
-DKYTY_BUILD_REPOSITORY="$KYTY_BUILD_REPOSITORY" \
|
|
-DKYTY_RELEASE_TAG="${{ needs.metadata.outputs.release_tag }}" \
|
|
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
|
|
-DCMAKE_C_COMPILER=clang \
|
|
-DCMAKE_CXX_COMPILER=clang++ \
|
|
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
|
|
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache \
|
|
-DCMAKE_PREFIX_PATH="$QT_ROOT_DIR"
|
|
|
|
- name: Build
|
|
shell: bash
|
|
run: |
|
|
cmake --build _Build/macos \
|
|
--target launcher audio_out2_port_tests ime_dialog_tests lru_cache_tests virtual_memory_allocation_tests \
|
|
--parallel
|
|
|
|
- name: Test
|
|
shell: bash
|
|
run: |
|
|
ctest --test-dir _Build/macos --output-on-failure \
|
|
-R '^(audio_out2_port|ime_dialog|lru_cache|virtual_memory_allocation)$'
|
|
|
|
- name: Install
|
|
shell: bash
|
|
run: |
|
|
cmake --install _Build/macos --prefix _Build/macos/install
|
|
|
|
- name: Bundle MoltenVK
|
|
shell: bash
|
|
env:
|
|
MOLTENVK_VERSION: v1.4.2
|
|
MOLTENVK_SHA256: f95765a6229cb7b915990a2890ce12ebe36a730b021545d3d52ae69ce4c4024e
|
|
run: |
|
|
archive="$RUNNER_TEMP/MoltenVK-macos.tar"
|
|
package="$RUNNER_TEMP/MoltenVK"
|
|
install_dir="_Build/macos/install"
|
|
app_dir="$install_dir/KytyPS5.app"
|
|
moltenvk="$install_dir/libMoltenVK.dylib"
|
|
curl --fail --location --retry 3 \
|
|
--output "$archive" \
|
|
"https://github.com/KhronosGroup/MoltenVK/releases/download/$MOLTENVK_VERSION/MoltenVK-macos.tar"
|
|
echo "$MOLTENVK_SHA256 $archive" | shasum -a 256 --check
|
|
tar -xf "$archive" -C "$RUNNER_TEMP"
|
|
test -d "$app_dir"
|
|
install -m 755 \
|
|
"$package/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib" \
|
|
"$moltenvk"
|
|
install -m 644 "$package/LICENSE" "$install_dir/LICENSE.MoltenVK"
|
|
codesign --force --sign - --timestamp=none "$moltenvk"
|
|
install -d -m 755 "$app_dir/Contents/Frameworks" "$app_dir/Contents/Resources"
|
|
install -m 755 "$moltenvk" "$app_dir/Contents/Frameworks/libMoltenVK.dylib"
|
|
install -m 644 "$package/LICENSE" "$app_dir/Contents/Resources/LICENSE.MoltenVK"
|
|
codesign --force --sign - --timestamp=none "$app_dir"
|
|
|
|
- name: Verify artifacts
|
|
shell: bash
|
|
run: |
|
|
install_dir="_Build/macos/install"
|
|
app_dir="$install_dir/KytyPS5.app"
|
|
test -d "$app_dir"
|
|
for binary in \
|
|
"$install_dir/kyty_emulator" \
|
|
"$install_dir/libMoltenVK.dylib" \
|
|
"$app_dir/Contents/MacOS/KytyPS5" \
|
|
"$app_dir/Contents/MacOS/kyty_emulator" \
|
|
"$app_dir/Contents/Frameworks/libMoltenVK.dylib"; do
|
|
file "$binary"
|
|
lipo "$binary" -verify_arch x86_64
|
|
done
|
|
for binary in \
|
|
"$install_dir/kyty_emulator" \
|
|
"$install_dir/libMoltenVK.dylib" \
|
|
"$app_dir/Contents/MacOS/KytyPS5" \
|
|
"$app_dir/Contents/MacOS/kyty_emulator" \
|
|
"$app_dir/Contents/Frameworks/libMoltenVK.dylib"; do
|
|
codesign --verify --strict "$binary"
|
|
done
|
|
codesign --verify --deep --strict --verbose=2 "$app_dir"
|
|
|
|
- name: Package macOS artifacts
|
|
shell: bash
|
|
run: |
|
|
install_dir="_Build/macos/install"
|
|
archive="$RUNNER_TEMP/KytyPS5-macOS-x86_64.zip"
|
|
(
|
|
cd "$install_dir"
|
|
zip -qry "$archive" .
|
|
)
|
|
unzip -t "$archive"
|
|
|
|
- name: Upload macOS artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: KytyPS5-macOS-x86_64
|
|
path: ${{ runner.temp }}/KytyPS5-macOS-x86_64.zip
|
|
if-no-files-found: error
|
|
|
|
linux:
|
|
name: Build KytyPS5 (Linux)
|
|
needs: metadata
|
|
runs-on: ubuntu-24.04
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Install build dependencies
|
|
shell: bash
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install --no-install-recommends --yes \
|
|
clang \
|
|
glslang-tools \
|
|
libasound2-dev \
|
|
libdbus-1-dev \
|
|
libgl1-mesa-dev \
|
|
libpulse-dev \
|
|
libudev-dev \
|
|
libwayland-dev \
|
|
libx11-dev \
|
|
libxcursor-dev \
|
|
libxext-dev \
|
|
libxfixes-dev \
|
|
libxi-dev \
|
|
libxkbcommon-dev \
|
|
libxrandr-dev \
|
|
libxss-dev \
|
|
libxtst-dev \
|
|
lld \
|
|
pkg-config \
|
|
wayland-protocols
|
|
|
|
- name: Install Qt 6.10.3
|
|
uses: jurplel/install-qt-action@v4
|
|
with:
|
|
version: "6.10.3"
|
|
host: linux
|
|
target: desktop
|
|
arch: linux_gcc_64
|
|
cache: true
|
|
|
|
- name: Setup sccache
|
|
uses: mozilla-actions/sccache-action@v0.0.11
|
|
|
|
- name: Verify toolchain
|
|
shell: bash
|
|
run: |
|
|
git --version
|
|
cmake --version
|
|
ninja --version
|
|
clang++ --version
|
|
ld.lld --version
|
|
glslangValidator --version
|
|
echo "Qt6_DIR=$Qt6_DIR"
|
|
|
|
- name: Configure
|
|
shell: bash
|
|
run: |
|
|
mkdir -p _Build
|
|
cmake -S . -B _Build/linux \
|
|
-G Ninja \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
|
|
-DKYTY_BUILD_ORIGIN="$KYTY_BUILD_ORIGIN" \
|
|
-DKYTY_BUILD_REPOSITORY="$KYTY_BUILD_REPOSITORY" \
|
|
-DKYTY_RELEASE_TAG="${{ needs.metadata.outputs.release_tag }}" \
|
|
-DCMAKE_C_COMPILER=clang \
|
|
-DCMAKE_CXX_COMPILER=clang++ \
|
|
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
|
|
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache \
|
|
-DCMAKE_PREFIX_PATH="$Qt6_DIR" 2>&1 | tee _Build/configure.log
|
|
exit "${PIPESTATUS[0]}"
|
|
|
|
- name: Verify SDL3 backends
|
|
shell: bash
|
|
run: |
|
|
status=0
|
|
for feature in SDL_ALSA SDL_PULSEAUDIO SDL_WAYLAND SDL_X11 SDL_LIBUDEV SDL_DBUS; do
|
|
if grep -qE "^-- ${feature} +\\(Wanted: ON\\): ON" _Build/configure.log; then
|
|
echo "ok ${feature}"
|
|
else
|
|
echo "FAIL ${feature} is not enabled"
|
|
status=1
|
|
fi
|
|
done
|
|
exit "$status"
|
|
|
|
- name: Build
|
|
shell: bash
|
|
run: |
|
|
cmake --build _Build/linux \
|
|
--target launcher page_manager_tests memory_tracker_tests \
|
|
audio_out2_port_tests ime_dialog_tests lru_cache_tests virtual_memory_allocation_tests \
|
|
--parallel
|
|
|
|
- name: Test
|
|
shell: bash
|
|
run: |
|
|
ctest --test-dir _Build/linux --output-on-failure \
|
|
-R '^(audio_out2_port|ime_dialog|lru_cache|page_manager|memory_tracker|virtual_memory_allocation)$'
|
|
|
|
- name: Install
|
|
shell: bash
|
|
run: |
|
|
cmake --install _Build/linux --prefix _Build/linux/install
|
|
|
|
- name: Verify artifacts
|
|
shell: bash
|
|
run: |
|
|
file _Build/linux/install/launcher
|
|
file _Build/linux/install/kyty_emulator
|
|
file _Build/linux/install/kyty_emulator | grep -q "ELF 64-bit LSB .*x86-64"
|
|
ldd _Build/linux/install/kyty_emulator > /dev/null
|
|
readelf -d _Build/linux/install/launcher | grep -q 'RPATH.*\$ORIGIN/lib'
|
|
while IFS= read -r -d '' binary; do
|
|
while read -r dependency; do
|
|
test -e "_Build/linux/install/lib/$dependency"
|
|
done < <(
|
|
readelf -d "$binary" |
|
|
sed -n 's/.*Shared library: \[\(libQt6[^]]*\|libicu[^]]*\)\].*/\1/p'
|
|
)
|
|
done < <(
|
|
find _Build/linux/install/launcher _Build/linux/install/plugins \
|
|
-type f \( -name launcher -o -name '*.so' \) -print0
|
|
)
|
|
_Build/linux/install/kyty_emulator --help > /dev/null
|
|
|
|
- name: Upload Linux artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: KytyPS5-Linux-x86_64
|
|
path: _Build/linux/install/**
|
|
if-no-files-found: error
|
|
|
|
release:
|
|
name: Release KytyPS5
|
|
if: >-
|
|
always() &&
|
|
github.event_name == 'push' &&
|
|
github.repository == 'KytyPS5/KytyPS5' &&
|
|
(needs.windows.result == 'success' ||
|
|
needs.macos.result == 'success' ||
|
|
needs.linux.result == 'success')
|
|
needs: [metadata, windows, macos, linux]
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
env:
|
|
RELEASE_NAME: ${{ needs.metadata.outputs.release_tag }}
|
|
|
|
steps:
|
|
- name: Download Windows build
|
|
if: needs.windows.result == 'success'
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: KytyPS5-Windows-x64
|
|
path: artifacts/KytyPS5-Windows-x64
|
|
|
|
- name: Download macOS build
|
|
if: needs.macos.result == 'success'
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: KytyPS5-macOS-x86_64
|
|
path: artifacts/KytyPS5-macOS-x86_64
|
|
|
|
- name: Download Linux build
|
|
if: needs.linux.result == 'success'
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: KytyPS5-Linux-x86_64
|
|
path: artifacts/KytyPS5-Linux-x86_64
|
|
|
|
- name: Package Windows build
|
|
if: needs.windows.result == 'success'
|
|
shell: bash
|
|
run: |
|
|
windows_dir="artifacts/KytyPS5-Windows-x64"
|
|
test -d "$windows_dir"
|
|
(
|
|
cd "$windows_dir"
|
|
zip -r "$GITHUB_WORKSPACE/$RELEASE_NAME-Windows-x64.zip" .
|
|
)
|
|
|
|
- name: Package macOS build
|
|
if: needs.macos.result == 'success'
|
|
shell: bash
|
|
run: |
|
|
macos_archive="artifacts/KytyPS5-macOS-x86_64/KytyPS5-macOS-x86_64.zip"
|
|
test -f "$macos_archive"
|
|
cp "$macos_archive" "$RELEASE_NAME-macOS-x86_64.zip"
|
|
|
|
- name: Package Linux build
|
|
if: needs.linux.result == 'success'
|
|
shell: bash
|
|
run: |
|
|
linux_dir="artifacts/KytyPS5-Linux-x86_64"
|
|
test -d "$linux_dir"
|
|
chmod a+x \
|
|
"$linux_dir/launcher" \
|
|
"$linux_dir/kyty_emulator"
|
|
tar -C "$linux_dir" -czf \
|
|
"$GITHUB_WORKSPACE/$RELEASE_NAME-Linux-x86_64.tar.gz" .
|
|
|
|
- name: Create release
|
|
shell: bash
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
assets=()
|
|
for artifact in \
|
|
"$RELEASE_NAME-Windows-x64.zip" \
|
|
"$RELEASE_NAME-macOS-x86_64.zip" \
|
|
"$RELEASE_NAME-Linux-x86_64.tar.gz"; do
|
|
if [[ -f "$artifact" ]]; then
|
|
assets+=("$artifact")
|
|
fi
|
|
done
|
|
test "${#assets[@]}" -gt 0
|
|
if gh release view "$RELEASE_NAME" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then
|
|
gh release upload "$RELEASE_NAME" "${assets[@]}" \
|
|
--clobber \
|
|
--repo "$GITHUB_REPOSITORY"
|
|
else
|
|
gh release create "$RELEASE_NAME" "${assets[@]}" \
|
|
--generate-notes \
|
|
--repo "$GITHUB_REPOSITORY" \
|
|
--target "$GITHUB_SHA" \
|
|
--title "$RELEASE_NAME"
|
|
fi
|