Repository navigation
build-soda #213
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: build-soda | |
| on: | |
| push: | |
| branches: | |
| - 'soda' | |
| workflow_dispatch: | |
| inputs: | |
| recovery_run: | |
| description: 'Run with completed Wine builds and package tests' | |
| required: false | |
| type: string | |
| architecture: | |
| description: 'Candidate architecture' | |
| required: true | |
| type: choice | |
| options: | |
| - x86_64 | |
| - aarch64 | |
| default: x86_64 | |
| pgo: | |
| description: 'Build a PGO candidate' | |
| required: true | |
| type: boolean | |
| default: false | |
| baseline_run_id: | |
| description: 'Run ID containing the baseline artifact' | |
| required: false | |
| type: string | |
| permissions: | |
| actions: read | |
| contents: read | |
| env: | |
| WINE_VERSION: '11.0' | |
| REVISION: '28-experimental' | |
| RELEASE_CODENAME: 'Windows Escape' | |
| WINE_TKG_COMMIT: '04ddf86c96817d2f8bb45aefc04c9ad3871ca740' | |
| VALVE_WINE_TAG: 'experimental-wine-bleeding-edge-11.0-428201-20260904-pdf1645-w0509a0-dd7ac25-v35bdee' | |
| VALVE_WINE_COMMIT: '0509a0b64a4852741364c95bcdc67ae8f74ef11d' | |
| PROTON_COMMIT: 'b7a763327f0cb76e9e0bd53dc4de95dee0d4c3b7' | |
| FEX_COMMIT: '1cc4b93e7a71c883ec021b71359f136394dc1f3c' | |
| OPENXR_SDK_COMMIT: '8899a91c17ce9618f565f42408b47db1d6e9ccc7' | |
| PGO_BASELINE_RUN_ID: '33972726566' | |
| BUILD_TOOLS_COMMIT: 'fcba104217c6daddddebe69d2dc2e39bc9025848' | |
| MONADO_VERSION: '21.0.0+git2905.e26a272c1~dfsg1-2build2' | |
| WINE_MONO_VERSION: '10.4.1' | |
| WINE_MONO_SHA256: '071f4b2887e1c97a11d791ff3d65be9429eed6dec4c2708888bfd546ba358e23' | |
| RELEASE_NOTES: |- | |
| <img src="https://raw.githubusercontent.com/bottlesdevs/data/main/logo/soda-logo.svg" width="64" /> | |
| This is a Wine TKG build based on Valve's Wine (experimental bleeding edge) source code. | |
| Soda 11.0-28 Experimental fixes LDAP initialization with empty or padded host lists and Direct2D command lists after their storage grows. It adds Vector3 keyframe animation interfaces and InteractionTracker close support used by Office's UI. | |
| Eagle keeps the bottle's DLL overrides, follows the loaded binaries for symbol lookup and finishes a trace when only Wine's built-in desktop services remain. Mutex tracing skips unrelated handle closes. | |
| The identity bridge now handles long socket paths. Use the latest Bottles main build for both sides of this fix. | |
| Enable Eagle Tracing in the bottle's Preferences to collect per-launch logs in logs/runs. Review them before sharing. Eagle is included in the x86_64 runner for x86 and x64 apps; it is not included in the ARM64 runner. Matching application symbols are required for source names and lines. Console input/output is disconnected during tracing. | |
| Other Office startup, sign-in and document crashes remain under investigation. | |
| jobs: | |
| patches: | |
| if: inputs.recovery_run == '' | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: check Soda patches | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| run: | | |
| git clone --filter=blob:none --no-checkout --depth=1 --branch "$VALVE_WINE_TAG" https://github.com/ValveSoftware/wine.git /tmp/valve-wine | |
| git -C /tmp/valve-wine checkout --detach "$VALVE_WINE_COMMIT" | |
| test "$(git -C /tmp/valve-wine rev-parse HEAD)" = "$VALVE_WINE_COMMIT" | |
| git clone --filter=blob:none --no-checkout https://github.com/ValveSoftware/Proton.git /tmp/proton | |
| git -C /tmp/proton sparse-checkout set --no-cone /wineopenxr | |
| git -C /tmp/proton checkout --detach "$PROTON_COMMIT" | |
| test "$(git -C /tmp/proton rev-parse HEAD)" = "$PROTON_COMMIT" | |
| .github/import-msicu.sh /tmp/valve-wine | |
| .github/import-wineopenxr.sh /tmp/valve-wine /tmp/proton/wineopenxr | |
| for patch in "$GITHUB_WORKSPACE"/wine-tkg-userpatches/*.mypatch; do | |
| git -C /tmp/valve-wine apply --check "$patch" | |
| git -C /tmp/valve-wine apply "$patch" | |
| done | |
| grep -F '@ stdcall SLLoadApplicationPolicies(ptr ptr long ptr)' /tmp/valve-wine/dlls/sppc/sppc.spec | |
| grep -F 'HRESULT WINAPI SLLoadApplicationPolicies' /tmp/valve-wine/dlls/sppc/sppc.c | |
| for symbol in SL_I_OOB_GRACE_PERIOD SL_E_APPLICATION_POLICIES_MISSING SL_E_AUTHN_CHALLENGE_NOT_SET SL_E_AUTHN_CANT_VERIFY; do | |
| grep -F "#define $symbol" /tmp/valve-wine/include/slerror.h | |
| done | |
| grep -F '@ stdcall GetDispatcherQueueForCurrentThread(ptr)' /tmp/valve-wine/dlls/coremessaging/coremessaging.spec | |
| grep -F '@ stdcall CalculatePopupWindowPosition(ptr ptr long ptr ptr)' /tmp/valve-wine/dlls/user32/user32.spec | |
| grep -F '@ stdcall -syscall NtUserCalculatePopupWindowPosition(ptr ptr long ptr ptr)' /tmp/valve-wine/dlls/win32u/win32u.spec | |
| build: | |
| needs: patches | |
| if: github.event_name == 'push' || inputs.architecture == 'x86_64' | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| archive_name: ${{ steps.identity.outputs.archive_name }} | |
| component_name: ${{ steps.identity.outputs.component_name }} | |
| pgo: ${{ steps.identity.outputs.pgo }} | |
| publish: ${{ steps.identity.outputs.publish }} | |
| prerelease: ${{ steps.identity.outputs.prerelease }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: define build identity | |
| id: identity | |
| run: | | |
| version="$WINE_VERSION-$REVISION" | |
| pgo=false | |
| publish=false | |
| prerelease=false | |
| if [[ "$GITHUB_EVENT_NAME" == "push" && "$GITHUB_REF" == "refs/heads/soda" ]]; then | |
| pgo=true | |
| publish=true | |
| if [[ "$REVISION" == *-experimental ]]; then | |
| prerelease=true | |
| fi | |
| else | |
| version="$version-${GITHUB_SHA::7}" | |
| if [[ "${{ inputs.pgo }}" == "true" ]]; then | |
| pgo=true | |
| version="$version-pgo" | |
| fi | |
| fi | |
| component_name="soda-$version-x86_64" | |
| echo "archive_name=$component_name.tar.xz" >> "$GITHUB_OUTPUT" | |
| echo "component_name=$component_name" >> "$GITHUB_OUTPUT" | |
| echo "pgo=$pgo" >> "$GITHUB_OUTPUT" | |
| echo "publish=$publish" >> "$GITHUB_OUTPUT" | |
| echo "prerelease=$prerelease" >> "$GITHUB_OUTPUT" | |
| - name: setup | |
| working-directory: /home/runner/work/ | |
| run: | | |
| mkdir -p /home/runner/.config/frogminer/ | |
| sudo apt purge -y ubuntu-advantage-tools python3-update-manager | |
| sudo dpkg --add-architecture i386 && sudo apt update | |
| sudo apt-mark hold grub-common grub-efi-amd64-bin python3 python3-apt shim-signed | |
| sudo apt install aptitude | |
| sudo aptitude remove -y '?narrow(?installed,?version(deb.sury.org))' | |
| sudo apt install -f | |
| sudo apt-get install -y -o Dpkg::Options::="--force-overwrite" libpcap-dev:amd64 libpcap-dev:i386 | |
| sudo apt-get install -y libglib2.0-dev-bin libglib2.0-dev:amd64 | |
| sudo aptitude install -y -o Dpkg::Options::="--force-overwrite" \ | |
| libglib2.0-dev-bin:amd64 \ | |
| libgudev-1.0-dev:amd64 \ | |
| libgudev-1.0-dev:i386 \ | |
| libvulkan-dev:amd64 \ | |
| libvulkan-dev:i386 | |
| sudo apt-get install -y -o Dpkg::Options::="--force-overwrite" libpcsclite-dev:amd64 libpcsclite-dev:i386 | |
| sudo apt-get install -y libsecret-1-dev:amd64 libsecret-1-0:i386 | |
| bash "$GITHUB_WORKSPACE/.github/soda-secret-headers.sh" "$GITHUB_WORKSPACE/.soda-secret-amd64" amd64 | |
| bash "$GITHUB_WORKSPACE/.github/soda-secret-headers.sh" "$GITHUB_WORKSPACE/.soda-secret-i386" i386 | |
| sudo apt-get install -y \ | |
| g++ \ | |
| cmake \ | |
| file \ | |
| g++-mingw-w64-i686 \ | |
| g++-mingw-w64-x86-64 \ | |
| libopenxr-dev:amd64 \ | |
| "libopenxr1-monado=$MONADO_VERSION" \ | |
| mesa-vulkan-drivers \ | |
| "monado-service=$MONADO_VERSION" \ | |
| ninja-build \ | |
| xvfb | |
| sudo apt-get check | |
| - name: clone wine-tkg-git repo | |
| working-directory: /home/runner/work/ | |
| run: | | |
| git clone https://github.com/Frogging-Family/wine-tkg-git.git | |
| cd wine-tkg-git/wine-tkg-git | |
| git checkout "$WINE_TKG_COMMIT" | |
| sed -i "s/_LOCAL_PRESET=\"\"/_LOCAL_PRESET=\"valve-exp-bleeding\"/g" customization.cfg | |
| sed -i "s|^_bleeding_tag=.*|_bleeding_tag=\"$VALVE_WINE_TAG\"|" wine-tkg-profiles/wine-tkg-valve-exp-bleeding.cfg | |
| sed -i '/^ubuntu_pkgs_64=/ s/libgstreamer-plugins-base1.0-dev/libgstreamer-plugins-base1.0-dev:amd64/' wine-tkg-scripts/deps | |
| cp "$GITHUB_WORKSPACE"/wine-tkg-userpatches/*.mypatch wine-tkg-userpatches/ | |
| git clone --filter=blob:none --no-checkout https://github.com/ValveSoftware/Proton.git /tmp/proton | |
| git -C /tmp/proton sparse-checkout set --no-cone /OpenXR-SDK /wineopenxr | |
| git -C /tmp/proton checkout --detach "$PROTON_COMMIT" | |
| test "$(git -C /tmp/proton rev-parse HEAD)" = "$PROTON_COMMIT" | |
| git -C /tmp/proton submodule update --init --depth=1 OpenXR-SDK | |
| test "$(git -C /tmp/proton/OpenXR-SDK rev-parse HEAD)" = "$OPENXR_SDK_COMMIT" | |
| sed -i '/ _source_cleanup/a\ "$GITHUB_WORKSPACE/.github/import-msicu.sh" "${srcdir}/${_winesrcdir}"\n "$GITHUB_WORKSPACE/.github/import-wineopenxr.sh" "${srcdir}/${_winesrcdir}" "/tmp/proton/wineopenxr"' non-makepkg-build.sh | |
| - name: get/set the soda recipe | |
| working-directory: /home/runner/.config/frogminer/ | |
| run: | | |
| git clone https://github.com/bottlesdevs/build-tools.git /tmp/build-tools | |
| git -C /tmp/build-tools checkout "$BUILD_TOOLS_COMMIT" | |
| cp /tmp/build-tools/runners/vaniglia/wine-tkg-valve.cfg wine-tkg.cfg | |
| sed -i '$a_NOLIB32="false"' wine-tkg.cfg | |
| sed -i "\$a_configure_userargs64=\"SECRET_CFLAGS=-I$GITHUB_WORKSPACE/.soda-secret-amd64/include SECRET_LIBS=-L$GITHUB_WORKSPACE/.soda-secret-amd64/lib\"" wine-tkg.cfg | |
| sed -i "\$a_configure_userargs32=\"--disable-wineopenxr SECRET_CFLAGS=-I$GITHUB_WORKSPACE/.soda-secret-i386/include SECRET_LIBS=-L$GITHUB_WORKSPACE/.soda-secret-i386/lib\"" wine-tkg.cfg | |
| if [[ "${{ steps.identity.outputs.pgo }}" == "true" ]]; then | |
| mkdir -p /tmp/soda-pgo/profiles /tmp/soda-pgo/evidence | |
| sed -i '$a_GCC_FLAGS="-O2 -pipe -msse3 -mfpmath=sse -ftree-vectorize -Wno-error=implicit-function-declaration -Wno-error=incompatible-pointer-types -fprofile-generate=/tmp/soda-pgo/profiles -fprofile-update=prefer-atomic -fprofile-exclude-files=preloader"' wine-tkg.cfg | |
| sed -i '$a_LD_FLAGS="-Wl,-O1,--sort-common,--as-needed -fprofile-generate=/tmp/soda-pgo/profiles"' wine-tkg.cfg | |
| fi | |
| cat wine-tkg.cfg | |
| - name: build PGO training programs | |
| if: steps.identity.outputs.pgo == 'true' | |
| run: | | |
| x86_64-w64-mingw32-gcc .github/soda-pgo-training.c \ | |
| -O2 -municode -ladvapi32 -lgdi32 -o /tmp/soda-pgo/training64.exe | |
| i686-w64-mingw32-gcc .github/soda-pgo-training.c \ | |
| -O2 -municode -ladvapi32 -lgdi32 -o /tmp/soda-pgo/training32.exe | |
| - name: build ICU smoke programs | |
| run: | | |
| mkdir -p /tmp/soda-icu | |
| x86_64-w64-mingw32-gcc .github/soda-icu-smoke.c \ | |
| -O2 -Wall -Wextra -Werror -o /tmp/soda-icu/smoke64.exe | |
| i686-w64-mingw32-gcc .github/soda-icu-smoke.c \ | |
| -O2 -Wall -Wextra -Werror -o /tmp/soda-icu/smoke32.exe | |
| - name: start build | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| run: yes|./non-makepkg-build.sh | |
| - name: verify packaged Unix runtime | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: | | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| for arch in i386 x86_64; do | |
| unix_dir="$runner_dir/lib/wine/$arch-unix" | |
| test -f "$unix_dir/ntdll.so" | |
| test -f "$unix_dir/win32u.so" | |
| test -f "$unix_dir/winebus.so" | |
| test -f "$unix_dir/winevulkan.so" | |
| test -f "$unix_dir/winex11.so" | |
| if ! grep -aFq 'org.winehq.Soda.Identity' "$unix_dir/windows.security.authentication.onlineid.so"; then | |
| printf 'Missing %s identity credential backend\n' "$arch" >&2 | |
| exit 1 | |
| fi | |
| module_count="$(find "$unix_dir" -maxdepth 1 -type f -name '*.so' | wc -l)" | |
| test "$module_count" -ge 30 | |
| printf '%s Unix modules: %s\n' "$arch" "$module_count" | |
| done | |
| - name: train PGO build | |
| if: steps.identity.outputs.pgo == 'true' | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| env: | |
| BASELINE_RUN_ID: ${{ inputs.baseline_run_id || env.PGO_BASELINE_RUN_ID }} | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| test -n "$BASELINE_RUN_ID" | |
| export SODA_RUNNER_DIR="$PWD/$runner_dir" | |
| mkdir -p /tmp/soda-pgo/training-baseline /tmp/soda-pgo/training-baseline-extracted | |
| gh run download "$BASELINE_RUN_ID" --repo "$GITHUB_REPOSITORY" \ | |
| --dir /tmp/soda-pgo/training-baseline | |
| baseline_archive="$(find /tmp/soda-pgo/training-baseline -type f \ | |
| -name 'soda-*-x86_64.tar.xz' -print -quit)" | |
| test -n "$baseline_archive" | |
| tar -C /tmp/soda-pgo/training-baseline-extracted -xJf "$baseline_archive" | |
| baseline_runner="$(find /tmp/soda-pgo/training-baseline-extracted \ | |
| -mindepth 1 -maxdepth 1 -type d -name 'soda-*-x86_64' -print -quit)" | |
| test -n "$baseline_runner" | |
| export BASELINE_RUNNER="$baseline_runner" | |
| printf 'Preparing PGO win64 prefix with baseline runner\n' | |
| timeout 5m xvfb-run -a bash -c ' | |
| export WINEDEBUG=-all | |
| export WINEPREFIX=/tmp/soda-pgo/prefix64 | |
| export WINEARCH=win64 | |
| mkdir -p "$WINEPREFIX" | |
| "$BASELINE_RUNNER/bin/wineboot" -u | |
| "$BASELINE_RUNNER/bin/wineserver" -w | |
| ' | |
| printf 'Training PGO win64 runner\n' | |
| timeout 10m xvfb-run -a bash -c ' | |
| export WINEDEBUG=-all | |
| export WINEPREFIX=/tmp/soda-pgo/prefix64 | |
| export WINEARCH=win64 | |
| "$SODA_RUNNER_DIR/bin/wine" reg add "HKCU\Software\SodaPGO" /v Architecture /d win64 /f | |
| "$SODA_RUNNER_DIR/bin/wine" cmd /c ver | |
| "$SODA_RUNNER_DIR/bin/wine" /tmp/soda-pgo/training64.exe | |
| wineserver_status=0 | |
| "$SODA_RUNNER_DIR/bin/wineserver" -w || wineserver_status=$? | |
| test "$wineserver_status" -le 1 | |
| ' | |
| printf 'Preparing PGO win32 prefix with baseline runner\n' | |
| timeout 5m xvfb-run -a bash -c ' | |
| export WINEDEBUG=-all | |
| export WINEPREFIX=/tmp/soda-pgo/prefix32 | |
| export WINEARCH=win32 | |
| mkdir -p "$WINEPREFIX" | |
| "$BASELINE_RUNNER/bin/wineboot" -u | |
| "$BASELINE_RUNNER/bin/wineserver" -w | |
| ' | |
| printf 'Training PGO win32 runner\n' | |
| timeout 10m xvfb-run -a bash -c ' | |
| export WINEDEBUG=-all | |
| export WINEPREFIX=/tmp/soda-pgo/prefix32 | |
| export WINEARCH=win32 | |
| "$SODA_RUNNER_DIR/bin/wine" reg add "HKCU\Software\SodaPGO" /v Architecture /d win32 /f | |
| "$SODA_RUNNER_DIR/bin/wine" cmd /c ver | |
| "$SODA_RUNNER_DIR/bin/wine" /tmp/soda-pgo/training32.exe | |
| wineserver_status=0 | |
| "$SODA_RUNNER_DIR/bin/wineserver" -w || wineserver_status=$? | |
| test "$wineserver_status" -le 1 | |
| ' | |
| find /tmp/soda-pgo/profiles -type f -name '*conftest*.gcda' \ | |
| -print -delete | sort \ | |
| > /tmp/soda-pgo/evidence/excluded-configure-profiles.txt | |
| test -s /tmp/soda-pgo/evidence/excluded-configure-profiles.txt | |
| find /tmp/soda-pgo/profiles -type f -name '*.gcda' -size +0c \ | |
| -printf '%s %p\n' | sort > /tmp/soda-pgo/evidence/profile-inventory.txt | |
| profile_count="$(wc -l < /tmp/soda-pgo/evidence/profile-inventory.txt)" | |
| test "$profile_count" -gt 0 | |
| grep -E '[#/]+server[#/]+' /tmp/soda-pgo/evidence/profile-inventory.txt | |
| first_profile="$(find /tmp/soda-pgo/profiles -type f -name '*.gcda' -size +0c -print -quit)" | |
| gcov-dump -l "$first_profile" > /tmp/soda-pgo/evidence/profile-dump.txt | |
| grep -Eq 'runs=[1-9]|sum_max=[1-9]' /tmp/soda-pgo/evidence/profile-dump.txt | |
| - name: rebuild with PGO profiles | |
| if: steps.identity.outputs.pgo == 'true' | |
| working-directory: /home/runner/work/ | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| run: | | |
| build_root=/home/runner/work/wine-tkg-git | |
| test "$PWD" = /home/runner/work | |
| test -f "$build_root/wine-tkg-git/non-makepkg-build.sh" | |
| find "$build_root" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} + | |
| git clone https://github.com/Frogging-Family/wine-tkg-git.git | |
| cd wine-tkg-git/wine-tkg-git | |
| git checkout "$WINE_TKG_COMMIT" | |
| sed -i "s/_LOCAL_PRESET=\"\"/_LOCAL_PRESET=\"valve-exp-bleeding\"/g" customization.cfg | |
| sed -i "s|^_bleeding_tag=.*|_bleeding_tag=\"$VALVE_WINE_TAG\"|" wine-tkg-profiles/wine-tkg-valve-exp-bleeding.cfg | |
| sed -i '/^ubuntu_pkgs_64=/ s/libgstreamer-plugins-base1.0-dev/libgstreamer-plugins-base1.0-dev:amd64/' wine-tkg-scripts/deps | |
| cp "$GITHUB_WORKSPACE"/wine-tkg-userpatches/*.mypatch wine-tkg-userpatches/ | |
| sed -i '/ _source_cleanup/a\ "$GITHUB_WORKSPACE/.github/import-msicu.sh" "${srcdir}/${_winesrcdir}"\n "$GITHUB_WORKSPACE/.github/import-wineopenxr.sh" "${srcdir}/${_winesrcdir}" "/tmp/proton/wineopenxr"' non-makepkg-build.sh | |
| recipe=/home/runner/.config/frogminer/wine-tkg.cfg | |
| sed -i '/^_GCC_FLAGS=/d; /^_LD_FLAGS=/d' "$recipe" | |
| sed -i '$a_GCC_FLAGS="-O2 -pipe -msse3 -mfpmath=sse -ftree-vectorize -Wno-error=implicit-function-declaration -Wno-error=incompatible-pointer-types -Wno-missing-profile -fprofile-use=/tmp/soda-pgo/profiles -fprofile-correction -fprofile-partial-training -fprofile-exclude-files=preloader"' "$recipe" | |
| sed -i '$a_LD_FLAGS="-Wl,-O1,--sort-common,--as-needed -fprofile-use=/tmp/soda-pgo/profiles"' "$recipe" | |
| find /tmp/soda-pgo/profiles -type f -name '*.gcda' -exec touch -a -d @1 {} + | |
| touch /tmp/soda-pgo/profile-use-start | |
| set +o pipefail | |
| yes | ./non-makepkg-build.sh 2>&1 | tee /tmp/soda-pgo/evidence/profile-use-build.log | |
| build_status="${PIPESTATUS[1]}" | |
| set -o pipefail | |
| test "$build_status" -eq 0 | |
| find /tmp/soda-pgo/profiles -type f -name '*.gcda' \ | |
| -anewer /tmp/soda-pgo/profile-use-start -printf '%p\n' \ | |
| > /tmp/soda-pgo/evidence/consumed-profiles.txt | |
| consumed_count="$(wc -l < /tmp/soda-pgo/evidence/consumed-profiles.txt)" | |
| test "$consumed_count" -gt 0 | |
| grep -E '[#/]+server[#/]+' /tmp/soda-pgo/evidence/consumed-profiles.txt | |
| - name: verify packaged PGO Unix runtime | |
| if: steps.identity.outputs.pgo == 'true' | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: | | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| for arch in i386 x86_64; do | |
| unix_dir="$runner_dir/lib/wine/$arch-unix" | |
| test -f "$unix_dir/ntdll.so" | |
| test -f "$unix_dir/win32u.so" | |
| test -f "$unix_dir/winebus.so" | |
| test -f "$unix_dir/winevulkan.so" | |
| test -f "$unix_dir/winex11.so" | |
| if ! grep -aFq 'org.winehq.Soda.Identity' "$unix_dir/windows.security.authentication.onlineid.so"; then | |
| printf 'Missing %s identity credential backend\n' "$arch" >&2 | |
| exit 1 | |
| fi | |
| module_count="$(find "$unix_dir" -maxdepth 1 -type f -name '*.so' | wc -l)" | |
| test "$module_count" -ge 30 | |
| printf '%s PGO Unix modules: %s\n' "$arch" "$module_count" | |
| done | |
| - name: bundle Wine Mono | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: | | |
| mono_file="wine-mono-$WINE_MONO_VERSION-x86.msi" | |
| mono_url="https://github.com/wine-mono/wine-mono/releases/download/wine-mono-$WINE_MONO_VERSION/$mono_file" | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| grep -F "#define MONO_VERSION \"$WINE_MONO_VERSION\"" src/ValveSoftware-winegit/dlls/appwiz.cpl/addons.c | |
| grep -F "#define MONO_SHA \"$WINE_MONO_SHA256\"" src/ValveSoftware-winegit/dlls/appwiz.cpl/addons.c | |
| curl --fail --location --retry 3 --output "/tmp/$mono_file" "$mono_url" | |
| echo "$WINE_MONO_SHA256 /tmp/$mono_file" | sha256sum --check - | |
| install -Dm644 "/tmp/$mono_file" "$runner_dir/share/wine/mono/$mono_file" | |
| - name: upload pre-test runner | |
| if: steps.identity.outputs.prerelease == 'true' || steps.identity.outputs.publish == 'false' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: pre-test-${{ steps.identity.outputs.component_name }} | |
| path: /home/runner/work/wine-tkg-git/wine-tkg-git/non-makepkg-builds/wine-tkg-* | |
| if-no-files-found: error | |
| - name: verify prefix username | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: | | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| export WINEDEBUG=-all | |
| export WINEPREFIX=/tmp/soda-prefix | |
| export WINEARCH=win64 | |
| export USER=soda-ci | |
| unset WINEUSERNAME | |
| runtime_log=/tmp/soda-username.log | |
| mkdir -p "$WINEPREFIX" | |
| if ! WINEDEBUG=err+all xvfb-run -a "$runner_dir/bin/wineboot" -u >"$runtime_log" 2>&1; then | |
| cat "$runtime_log" | |
| exit 1 | |
| fi | |
| username_output="$(xvfb-run -a "$runner_dir/bin/wine" cmd /c echo '%USERNAME%' | tr -d '\r')" | |
| username="$(printf '%s\n' "$username_output" | sed -n '/^soda-ci$/p' | tail -1)" | |
| if [[ "$username" != soda-ci ]]; then | |
| printf 'Expected username soda-ci, got:\n%s\n' "$username_output" >&2 | |
| exit 1 | |
| fi | |
| printf 'Windows username: %s\nWindows profile directories:\n' "$username" | |
| find "$WINEPREFIX/drive_c/users" -mindepth 1 -maxdepth 1 -printf '%f\n' | sort | |
| test -d "$WINEPREFIX/drive_c/users/soda-ci" | |
| test ! -e "$WINEPREFIX/drive_c/users/steamuser" | |
| "$runner_dir/bin/wineserver" -w | |
| - name: verify pure 32-bit prefix | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: | | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| export WINEDEBUG=-all | |
| export WINEPREFIX=/tmp/soda-win32-prefix | |
| export WINEARCH=win32 | |
| mkdir -p "$WINEPREFIX" | |
| xvfb-run -a "$runner_dir/bin/wineboot" -u | |
| architecture_output="$(xvfb-run -a "$runner_dir/bin/wine" cmd /c echo '%PROCESSOR_ARCHITECTURE%' | tr -d '\r')" | |
| architecture="$(printf '%s\n' "$architecture_output" | sed -n '/^x86$/p' | tail -1)" | |
| if [[ "$architecture" != x86 ]]; then | |
| printf 'Expected x86, got:\n%s\n' "$architecture_output" >&2 | |
| exit 1 | |
| fi | |
| grep -F '#arch=win32' "$WINEPREFIX/system.reg" | |
| "$runner_dir/bin/wineserver" -w | |
| - name: verify Office WinRT classes | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: | | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| for arch in i386 x86_64; do | |
| test -f "$runner_dir/lib/wine/$arch-windows/windows.applicationmodel.dll" | |
| test -f "$runner_dir/lib/wine/$arch-windows/windows.networking.dll" | |
| test -f "$runner_dir/lib/wine/$arch-windows/windows.security.enterprisedata.dll" | |
| test -f "$runner_dir/lib/wine/$arch-windows/windows.security.authentication.onlineid.dll" | |
| test -f "$runner_dir/lib/wine/$arch-windows/twinapi.appcore.dll" | |
| test -f "$runner_dir/lib/wine/$arch-unix/windows.security.authentication.onlineid.so" | |
| grep -aFq 'org.winehq.Soda.Identity' "$runner_dir/lib/wine/$arch-unix/windows.security.authentication.onlineid.so" | |
| done | |
| x86_64-w64-mingw32-gcc "$GITHUB_WORKSPACE/.github/soda-office-winrt-smoke.c" \ | |
| -O2 -Wall -Wextra -Werror -lole32 -lruntimeobject \ | |
| -o "$RUNNER_TEMP/soda-office-winrt-smoke64.exe" | |
| i686-w64-mingw32-gcc "$GITHUB_WORKSPACE/.github/soda-office-winrt-smoke.c" \ | |
| -O2 -Wall -Wextra -Werror -lole32 -lruntimeobject \ | |
| -o "$RUNNER_TEMP/soda-office-winrt-smoke32.exe" | |
| x86_64-w64-mingw32-gcc "$GITHUB_WORKSPACE/.github/soda-ldap-smoke.c" \ | |
| -O2 -Wall -Wextra -Werror -o "$RUNNER_TEMP/soda-ldap-smoke64.exe" | |
| i686-w64-mingw32-gcc "$GITHUB_WORKSPACE/.github/soda-ldap-smoke.c" \ | |
| -O2 -Wall -Wextra -Werror -o "$RUNNER_TEMP/soda-ldap-smoke32.exe" | |
| run_smoke() { | |
| local arch="$1" | |
| local executable="$2" | |
| local ldap_executable="$3" | |
| local log="$RUNNER_TEMP/soda-office-winrt-$arch.log" | |
| export WINEDEBUG=-all | |
| export WINEPREFIX="$RUNNER_TEMP/soda-office-winrt-prefix-$arch" | |
| export WINEARCH="$arch" | |
| mkdir -p "$WINEPREFIX" | |
| xvfb-run -a "$runner_dir/bin/wineboot" -u | |
| xvfb-run -a "$runner_dir/bin/wine" "$executable" | tr -d '\r' | tee "$log" | |
| grep -Fx 'core_application:00000000' "$log" | |
| grep -Fx 'message_websocket:00000000' "$log" | |
| grep -Fx 'protection_policy:00000000' "$log" | |
| grep -Fx 'retail_info:00000000' "$log" | |
| grep -Fx 'web_authentication_manager:00000000' "$log" | |
| grep -Fx 'composition_effect_source_parameter:00000000' "$log" | |
| xvfb-run -a "$runner_dir/bin/wine" reg add \ | |
| "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\\$(basename "$ldap_executable")" \ | |
| /v GlobalFlag /t REG_DWORD /d 112 /f | |
| xvfb-run -a "$runner_dir/bin/wine" "$ldap_executable" \ | |
| | tr -d '\r' | tee "$log.ldap" | |
| grep -Fx 'ldap_init_checks:1024 failures:0' "$log.ldap" | |
| "$runner_dir/bin/wineserver" -w | |
| } | |
| run_smoke win64 "$RUNNER_TEMP/soda-office-winrt-smoke64.exe" "$RUNNER_TEMP/soda-ldap-smoke64.exe" | |
| run_smoke win32 "$RUNNER_TEMP/soda-office-winrt-smoke32.exe" "$RUNNER_TEMP/soda-ldap-smoke32.exe" | |
| - name: verify MS-ICU runtime | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: | | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| export TZ=America/Denver | |
| export WINEDEBUG=-all | |
| export WINEPREFIX=/tmp/soda-icu-prefix64 | |
| export WINEARCH=win64 | |
| mkdir -p "$WINEPREFIX" | |
| xvfb-run -a "$runner_dir/bin/wineboot" -u | |
| xvfb-run -a "$runner_dir/bin/wine" /tmp/soda-icu/smoke64.exe \ | |
| | tr -d '\r' | tee /tmp/soda-icu/runtime64.log | |
| grep -F 'ICU 72.1 timezone=America/Denver' /tmp/soda-icu/runtime64.log | |
| "$runner_dir/bin/wineserver" -w | |
| export WINEPREFIX=/tmp/soda-icu-prefix32 | |
| export WINEARCH=win32 | |
| mkdir -p "$WINEPREFIX" | |
| xvfb-run -a "$runner_dir/bin/wineboot" -u | |
| xvfb-run -a "$runner_dir/bin/wine" /tmp/soda-icu/smoke32.exe \ | |
| | tr -d '\r' | tee /tmp/soda-icu/runtime32.log | |
| grep -F 'ICU 72.1 timezone=America/Denver' /tmp/soda-icu/runtime32.log | |
| "$runner_dir/bin/wineserver" -w | |
| - name: verify compatibility fixes | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: | | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| Xvfb :97 -screen 0 1024x768x24 >/tmp/soda-compatibility-xvfb.log 2>&1 & | |
| xvfb_pid=$! | |
| trap 'kill "$xvfb_pid" 2>/dev/null || true' EXIT | |
| export DISPLAY=:97 | |
| for attempt in {1..100}; do | |
| test ! -S /tmp/.X11-unix/X97 || break | |
| sleep 0.1 | |
| done | |
| test -S /tmp/.X11-unix/X97 | |
| kill -0 "$xvfb_pid" | |
| grep -F 'winebrowser.exe"" ""%1' src/ValveSoftware-winegit/loader/wine.inf.in | |
| grep -F 'toplevel == hwnd && NtUserGetPresentRect' src/ValveSoftware-winegit/dlls/winex11.drv/init.c | |
| x86_64-w64-mingw32-gcc "$GITHUB_WORKSPACE/.github/soda-compatibility-smoke.c" \ | |
| -O2 -municode -lshell32 -o /tmp/soda-compatibility-smoke.exe | |
| mkdir /tmp/soda-browser-bin | |
| printf '%s\n' '#!/bin/sh' 'printf "%s" "$1" > /tmp/soda-browser-url' > /tmp/soda-browser-bin/xdg-open | |
| chmod +x /tmp/soda-browser-bin/xdg-open | |
| export PATH="/tmp/soda-browser-bin:$PATH" | |
| export WINEDEBUG=-all | |
| export WINEPREFIX=/tmp/soda-url-prefix | |
| export WINEARCH=win64 | |
| mkdir -p "$WINEPREFIX" | |
| "$runner_dir/bin/wineboot" -u | |
| "$runner_dir/bin/wine" reg add 'HKCU\Software\Wine\WineBrowser' /v Browsers /t REG_SZ /d xdg-open /f | |
| long_url="https://soda.invalid/$(printf 'a%.0s' {1..1024})" | |
| "$runner_dir/bin/wine" /tmp/soda-compatibility-smoke.exe "$long_url" | |
| for attempt in {1..50}; do | |
| test ! -f /tmp/soda-browser-url || break | |
| sleep 0.1 | |
| done | |
| test "$(cat /tmp/soda-browser-url)" = "$long_url" | |
| "$runner_dir/bin/wineserver" -w | |
| export WINEPREFIX=/tmp/soda-topology-prefix | |
| export WINE_CPU_TOPOLOGY=2 | |
| mkdir -p "$WINEPREFIX" | |
| "$runner_dir/bin/wineboot" -u | |
| cpu_output="$("$runner_dir/bin/wine" cmd /c echo '%NUMBER_OF_PROCESSORS%' | tr -d '\r')" | |
| cpu_count="$(printf '%s\n' "$cpu_output" | sed -n '/^[0-9][0-9]*$/p' | tail -1)" | |
| if [[ "$cpu_count" != 2 ]]; then | |
| printf 'Expected 2 processors, got:\n%s\n' "$cpu_output" >&2 | |
| exit 1 | |
| fi | |
| "$runner_dir/bin/wineserver" -w | |
| unset WINE_CPU_TOPOLOGY WINEDEBUG | |
| export WINEPREFIX=/tmp/soda-heroes-vii-prefix | |
| mkdir -p "$WINEPREFIX" | |
| cp "$runner_dir/lib/wine/x86_64-windows/cmd.exe" /tmp/MMH7Game-Win64-Shipping.exe | |
| "$runner_dir/bin/wineboot" -u | |
| "$runner_dir/bin/wine" /tmp/MMH7Game-Win64-Shipping.exe /c echo '%NUMBER_OF_PROCESSORS%' \ | |
| >/tmp/soda-heroes-vii-cpus 2>/tmp/soda-heroes-vii.log | |
| grep -F 'HACK: limiting Heroes VII CPU topology to ' /tmp/soda-heroes-vii.log | |
| cpu_count="$(tr -d '\r' </tmp/soda-heroes-vii-cpus | sed -n '/^[0-9][0-9]*$/p' | tail -1)" | |
| test -n "$cpu_count" | |
| test "$cpu_count" -le 8 | |
| "$runner_dir/bin/wineserver" -w | |
| export WINEDEBUG=-all | |
| export WINE_CPU_TOPOLOGY=2 | |
| cpu_output="$("$runner_dir/bin/wine" /tmp/MMH7Game-Win64-Shipping.exe /c echo '%NUMBER_OF_PROCESSORS%' | tr -d '\r')" | |
| cpu_count="$(printf '%s\n' "$cpu_output" | sed -n '/^[0-9][0-9]*$/p' | tail -1)" | |
| if [[ "$cpu_count" != 2 ]]; then | |
| printf 'Expected 2 processors, got:\n%s\n' "$cpu_output" >&2 | |
| exit 1 | |
| fi | |
| "$runner_dir/bin/wineserver" -w | |
| kill "$xvfb_pid" | |
| trap - EXIT | |
| - name: verify file security mappings | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: | | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| x86_64-w64-mingw32-gcc "$GITHUB_WORKSPACE/.github/soda-file-security-smoke.c" \ | |
| -O2 -Wall -Wextra -Werror -ladvapi32 -o /tmp/soda-file-security-smoke.exe | |
| export WINEDEBUG=-all | |
| export WINEPREFIX=/tmp/soda-file-security-prefix | |
| export WINEARCH=win64 | |
| mkdir -p "$WINEPREFIX" | |
| xvfb-run -a "$runner_dir/bin/wineboot" -u | |
| xvfb-run -a "$runner_dir/bin/wine" /tmp/soda-file-security-smoke.exe \ | |
| | tr -d '\r' | tee /tmp/soda-file-security-smoke.log | |
| grep -Fx 'reopen:ok' /tmp/soda-file-security-smoke.log | |
| "$runner_dir/bin/wineserver" -w | |
| - name: verify OpenXR outside Steam | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: | | |
| runner_dir="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| runner_dir="$PWD/$runner_dir" | |
| mkdir -p /tmp/soda-openxr/app /tmp/soda-openxr/runtime /tmp/soda-openxr/xdg/openxr/1 | |
| chmod 700 /tmp/soda-openxr/runtime | |
| cmake -S /tmp/proton/OpenXR-SDK -B /tmp/soda-openxr/loader-build -G Ninja \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_SYSTEM_NAME=Windows \ | |
| -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \ | |
| -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \ | |
| -DCMAKE_RC_COMPILER=x86_64-w64-mingw32-windres \ | |
| -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ | |
| -DBUILD_API_LAYERS=OFF \ | |
| -DBUILD_CONFORMANCE_TESTS=OFF \ | |
| -DBUILD_LOADER=ON \ | |
| -DBUILD_TESTS=OFF \ | |
| -DBUILD_WITH_SYSTEM_JSONCPP=OFF \ | |
| -DDYNAMIC_LOADER=ON | |
| cmake --build /tmp/soda-openxr/loader-build --target openxr_loader --parallel 2 | |
| loader_dll="$(find /tmp/soda-openxr/loader-build -type f -iname '*openxr_loader.dll' -print -quit)" | |
| test -n "$loader_dll" | |
| cp "$loader_dll" /tmp/soda-openxr/app/openxr_loader.dll | |
| for dll in libgcc_s_seh-1.dll libstdc++-6.dll libwinpthread-1.dll; do | |
| source="$(x86_64-w64-mingw32-g++ -print-file-name="$dll")" | |
| test ! -f "$source" || cp "$source" "/tmp/soda-openxr/app/$dll" | |
| done | |
| x86_64-w64-mingw32-gcc "$GITHUB_WORKSPACE/.github/soda-openxr-smoke.c" \ | |
| -I /tmp/proton/OpenXR-SDK/include -O2 -o /tmp/soda-openxr/app/soda-openxr-smoke.exe | |
| monado_manifest=/usr/share/openxr/1/openxr_monado.json | |
| lavapipe_manifest="$(find /usr/share/vulkan/icd.d -type f -name '*lvp*.json' -print -quit)" | |
| test -f "$monado_manifest" | |
| test -n "$lavapipe_manifest" | |
| ln -s "$monado_manifest" /tmp/soda-openxr/xdg/openxr/1/active_runtime.json | |
| export XDG_CONFIG_HOME=/tmp/soda-openxr/xdg | |
| export XDG_RUNTIME_DIR=/tmp/soda-openxr/runtime | |
| export VK_ICD_FILENAMES="$lavapipe_manifest" | |
| export SIMULATED_ENABLE=1 | |
| export XRT_COMPOSITOR_NULL=1 | |
| export XRT_LOG=info | |
| test -z "${XR_RUNTIME_JSON:-}" | |
| mkfifo /tmp/soda-openxr/monado-input | |
| exec 3<>/tmp/soda-openxr/monado-input | |
| monado-service </tmp/soda-openxr/monado-input >/tmp/soda-openxr/monado.log 2>&1 & | |
| monado_pid=$! | |
| trap 'kill "$monado_pid" 2>/dev/null || true; exec 3>&-' EXIT | |
| for attempt in {1..100}; do | |
| test ! -S "$XDG_RUNTIME_DIR/monado_comp_ipc" || break | |
| sleep 0.1 | |
| done | |
| test -S "$XDG_RUNTIME_DIR/monado_comp_ipc" | |
| unset SteamAppId SteamGameId SteamOverlayGameId STEAM_COMPAT_CLIENT_INSTALL_PATH STEAM_COMPAT_DATA_PATH | |
| for process in steam steamwebhelper vrcompositor vrserver; do | |
| if pgrep -x "$process"; then | |
| exit 1 | |
| fi | |
| done | |
| export WINEPREFIX=/tmp/soda-openxr/prefix | |
| export WINEARCH=win64 | |
| export SODA_OPENXR_RUNTIME=host | |
| export WINEDEBUG=+openxr | |
| mkdir -p "$WINEPREFIX" | |
| xvfb-run -a "$runner_dir/bin/wineboot" -u | |
| install -Dm644 /tmp/proton/wineopenxr/wineopenxr64.json \ | |
| "$WINEPREFIX/drive_c/openxr/wineopenxr64.json" | |
| xvfb-run -a "$runner_dir/bin/wine" reg query 'HKLM\Software\Khronos\OpenXR\1' \ | |
| /v ActiveRuntime >/tmp/soda-openxr/registry.log | |
| grep -F 'C:\openxr\wineopenxr64.json' /tmp/soda-openxr/registry.log | |
| ( | |
| cd /tmp/soda-openxr/app | |
| xvfb-run -a "$runner_dir/bin/wine" soda-openxr-smoke.exe | |
| ) >/tmp/soda-openxr/application.log 2>&1 | |
| grep -F 'runtime=Monado' /tmp/soda-openxr/application.log | |
| grep -F 'system=Monado: Simulated HMD' /tmp/soda-openxr/application.log | |
| "$runner_dir/bin/wineserver" -w | |
| - name: verify Valve Wine source | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| run: test "$(git -C src/ValveSoftware-winegit rev-parse HEAD)" = "$VALVE_WINE_COMMIT" | |
| - name: benchmark PGO candidate | |
| if: steps.identity.outputs.pgo == 'true' | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/ | |
| env: | |
| BASELINE_RUN_ID: ${{ inputs.baseline_run_id || env.PGO_BASELINE_RUN_ID }} | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| test -n "$BASELINE_RUN_ID" | |
| pgo_runner="$(find non-makepkg-builds -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$pgo_runner" | |
| pgo_runner="$PWD/$pgo_runner" | |
| mkdir -p /tmp/soda-pgo/baseline /tmp/soda-pgo/baseline-extracted | |
| gh run download "$BASELINE_RUN_ID" --repo "$GITHUB_REPOSITORY" --dir /tmp/soda-pgo/baseline | |
| baseline_archive="$(find /tmp/soda-pgo/baseline -type f -name 'soda-*-x86_64.tar.xz' -print -quit)" | |
| test -n "$baseline_archive" | |
| tar -C /tmp/soda-pgo/baseline-extracted -xJf "$baseline_archive" | |
| baseline_runner="$(find /tmp/soda-pgo/baseline-extracted -mindepth 1 -maxdepth 1 -type d -name 'soda-*-x86_64' -print -quit)" | |
| test -n "$baseline_runner" | |
| export WINEDEBUG=-all | |
| export WINEARCH=win64 | |
| Xvfb :99 -screen 0 1024x768x24 >/tmp/soda-pgo/evidence/xvfb.log 2>&1 & | |
| xvfb_pid=$! | |
| trap 'kill "$xvfb_pid" 2>/dev/null || true' EXIT | |
| export DISPLAY=:99 | |
| mkdir -p /tmp/soda-pgo/benchmark-baseline /tmp/soda-pgo/benchmark-pgo | |
| WINEPREFIX=/tmp/soda-pgo/benchmark-baseline "$baseline_runner/bin/wineboot" -u | |
| WINEPREFIX=/tmp/soda-pgo/benchmark-pgo "$pgo_runner/bin/wineboot" -u | |
| measure() { | |
| local label="$1" | |
| local runner="$2" | |
| local prefix="$3" | |
| local sample | |
| sample="$(WINEPREFIX="$prefix" "$runner/bin/wine" \ | |
| /tmp/soda-pgo/training64.exe --benchmark | tr -d '\r' | \ | |
| sed -n '/^[0-9][0-9]*$/p' | tail -1)" | |
| test -n "$sample" | |
| printf '%s\n' "$sample" >> "/tmp/soda-pgo/evidence/$label-samples.txt" | |
| } | |
| for trial in {1..9}; do | |
| if ((trial % 2)); then | |
| measure baseline "$baseline_runner" /tmp/soda-pgo/benchmark-baseline | |
| measure pgo "$pgo_runner" /tmp/soda-pgo/benchmark-pgo | |
| else | |
| measure pgo "$pgo_runner" /tmp/soda-pgo/benchmark-pgo | |
| measure baseline "$baseline_runner" /tmp/soda-pgo/benchmark-baseline | |
| fi | |
| done | |
| WINEPREFIX=/tmp/soda-pgo/benchmark-baseline "$baseline_runner/bin/wineserver" -w | |
| WINEPREFIX=/tmp/soda-pgo/benchmark-pgo "$pgo_runner/bin/wineserver" -w | |
| baseline_median="$(sort -n /tmp/soda-pgo/evidence/baseline-samples.txt | sed -n '5p')" | |
| pgo_median="$(sort -n /tmp/soda-pgo/evidence/pgo-samples.txt | sed -n '5p')" | |
| median_change="$(awk -v baseline="$baseline_median" -v pgo="$pgo_median" \ | |
| 'BEGIN { printf "%.2f", (pgo - baseline) * 100 / baseline }')" | |
| paste /tmp/soda-pgo/evidence/baseline-samples.txt \ | |
| /tmp/soda-pgo/evidence/pgo-samples.txt \ | |
| | awk '{ printf "%.6f\n", ($2 - $1) * 100 / $1 }' \ | |
| | sort -n > /tmp/soda-pgo/evidence/paired-change-samples.txt | |
| paired_change_median="$(sed -n '5p' /tmp/soda-pgo/evidence/paired-change-samples.txt)" | |
| printf 'baseline_median_us=%s\npgo_median_us=%s\nmedian_change_percent=%s\npaired_change_median_percent=%s\n' \ | |
| "$baseline_median" "$pgo_median" "$median_change" "$paired_change_median" \ | |
| > /tmp/soda-pgo/evidence/benchmark.txt | |
| printf 'PGO benchmark: baseline %s us, candidate %s us, median change %s%%, paired change %s%%\n' \ | |
| "$baseline_median" "$pgo_median" "$median_change" "$paired_change_median" \ | |
| >> "$GITHUB_STEP_SUMMARY" | |
| awk -v median="$median_change" -v paired="$paired_change_median" \ | |
| 'BEGIN { exit !(median <= 2 && paired <= 5) }' | |
| - name: Upload prepare.log on failure | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: failure-logs | |
| path: | | |
| /home/runner/work/wine-tkg-git/wine-tkg-git/prepare.log | |
| /home/runner/work/wine-tkg-git/wine-tkg-git/src/*-build/config.log | |
| /tmp/soda-pgo/evidence | |
| /tmp/soda-*.log | |
| /tmp/soda-openxr/*.log | |
| if-no-files-found: ignore | |
| - name: package | |
| working-directory: /home/runner/work/wine-tkg-git/wine-tkg-git/non-makepkg-builds/ | |
| env: | |
| ARCHIVE_NAME: ${{ steps.identity.outputs.archive_name }} | |
| COMPONENT_NAME: ${{ steps.identity.outputs.component_name }} | |
| run: | | |
| runner_dir="$(find . -mindepth 1 -maxdepth 1 -type d -name 'wine-tkg-*' -print -quit)" | |
| test -n "$runner_dir" | |
| test -f "$runner_dir/lib/wine/x86_64-unix/winegstreamer.so" | |
| test -f "$runner_dir/lib/wine/i386-unix/winegstreamer.so" | |
| test -f "$runner_dir/lib/wine/i386-windows/winegstreamer.dll" | |
| test -f "$runner_dir/lib/wine/x86_64-unix/winscard.so" | |
| test -f "$runner_dir/lib/wine/i386-unix/winscard.so" | |
| test -f "$runner_dir/lib/wine/x86_64-windows/winscard.dll" | |
| test -f "$runner_dir/lib/wine/i386-windows/winscard.dll" | |
| for arch in i386 x86_64; do | |
| test -f "$runner_dir/lib/wine/$arch-windows/windows.security.authentication.onlineid.dll" | |
| test -f "$runner_dir/lib/wine/$arch-windows/twinapi.appcore.dll" | |
| test -f "$runner_dir/lib/wine/$arch-unix/windows.security.authentication.onlineid.so" | |
| done | |
| test -x "$runner_dir/bin/wine" | |
| file "$runner_dir/bin/wine" | grep -F 'x86-64' | |
| file "$runner_dir/lib/wine/x86_64-windows/ntdll.dll" | grep -F 'x86-64' | |
| file "$runner_dir/lib/wine/i386-windows/ntdll.dll" | grep -F 'Intel 80386' | |
| test -f "$runner_dir/lib/wine/x86_64-windows/wineopenxr.dll" | |
| test -f "$runner_dir/lib/wine/x86_64-unix/wineopenxr.so" | |
| install -Dm644 /tmp/proton/wineopenxr/wineopenxr64.json "$runner_dir/share/openxr/wineopenxr64.json" | |
| xvfb-run -a sh "$GITHUB_WORKSPACE/.github/build-eagle.sh" "$runner_dir" "$HOME/artifacts/Soda-$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT" | |
| mv "$runner_dir" "$COMPONENT_NAME" | |
| tar cJvf "$ARCHIVE_NAME" "$COMPONENT_NAME" | |
| mv "$ARCHIVE_NAME" "/tmp/$ARCHIVE_NAME" | |
| - name: upload Eagle test logs | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: eagle-test-logs-${{ github.sha }} | |
| path: | | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/32/*.log | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/64/*.log | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/p32/*.log | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/p64/*.log | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/c32/*.log | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/c64/*.log | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/s32/*.log | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/s64/*.log | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/d/*.log | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/t/*.log | |
| /home/runner/artifacts/Soda-${{ github.run_id }}-${{ github.run_attempt }}/tests/e/*.log | |
| if-no-files-found: ignore | |
| - name: upload | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ steps.identity.outputs.component_name }} | |
| path: /tmp/${{ steps.identity.outputs.archive_name }} | |
| if-no-files-found: error | |
| - name: upload PGO evidence | |
| if: steps.identity.outputs.pgo == 'true' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: pgo-evidence-${{ github.sha }} | |
| path: /tmp/soda-pgo/evidence/*.txt | |
| if-no-files-found: error | |
| arm64: | |
| needs: patches | |
| if: github.event_name == 'push' || inputs.architecture == 'aarch64' | |
| runs-on: ubuntu-24.04-arm | |
| timeout-minutes: 360 | |
| outputs: | |
| archive_name: ${{ steps.identity.outputs.archive_name }} | |
| component_name: ${{ steps.identity.outputs.component_name }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: define build identity | |
| id: identity | |
| run: | | |
| version="$WINE_VERSION-$REVISION" | |
| if [[ "$GITHUB_EVENT_NAME" != "push" || "$GITHUB_REF" != "refs/heads/soda" ]]; then | |
| version="$version-${GITHUB_SHA::7}" | |
| fi | |
| component_name="soda-$version-aarch64" | |
| echo "archive_name=$component_name.tar.xz" >> "$GITHUB_OUTPUT" | |
| echo "component_name=$component_name" >> "$GITHUB_OUTPUT" | |
| - name: setup | |
| run: | | |
| test "$(uname -m)" = aarch64 | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| g++ \ | |
| file \ | |
| gcc-mingw-w64-i686 \ | |
| gcc-mingw-w64-x86-64 \ | |
| xvfb \ | |
| xz-utils | |
| command -v docker | |
| sudo systemctl start docker | |
| docker version | |
| - name: prepare sources | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| run: | | |
| git clone --filter=blob:none --no-checkout https://github.com/ValveSoftware/Proton.git /tmp/proton | |
| git -C /tmp/proton checkout "$PROTON_COMMIT" | |
| test "$(git -C /tmp/proton rev-parse HEAD)" = "$PROTON_COMMIT" | |
| git -C /tmp/proton submodule update --init --recursive wine OpenXR-SDK FEX | |
| test "$(git -C /tmp/proton/FEX rev-parse HEAD)" = "$FEX_COMMIT" | |
| test "$(git -C /tmp/proton/OpenXR-SDK rev-parse HEAD)" = "$OPENXR_SDK_COMMIT" | |
| git -C /tmp/proton/wine fetch --no-tags origin "$VALVE_WINE_TAG" | |
| git -C /tmp/proton/wine checkout --detach "$VALVE_WINE_COMMIT" | |
| test "$(git -C /tmp/proton/wine rev-parse HEAD)" = "$VALVE_WINE_COMMIT" | |
| .github/import-msicu.sh /tmp/proton/wine | |
| for patch in "$GITHUB_WORKSPACE"/wine-tkg-userpatches/*.mypatch; do | |
| if [[ "$patch" == *wineopenxr-host-runtime.mypatch ]]; then | |
| continue | |
| fi | |
| git -C /tmp/proton/wine apply --check "$patch" | |
| git -C /tmp/proton/wine apply "$patch" | |
| done | |
| git -C /tmp/proton/wineopenxr apply --check "$GITHUB_WORKSPACE/.github/wineopenxr-host-runtime-proton.mypatch" | |
| git -C /tmp/proton/wineopenxr apply "$GITHUB_WORKSPACE/.github/wineopenxr-host-runtime-proton.mypatch" | |
| - name: build ICU and Office smoke programs | |
| run: | | |
| mkdir -p /tmp/soda-icu | |
| x86_64-w64-mingw32-gcc .github/soda-icu-smoke.c \ | |
| -O2 -Wall -Wextra -Werror -o /tmp/soda-icu/smoke64.exe | |
| i686-w64-mingw32-gcc .github/soda-icu-smoke.c \ | |
| -O2 -Wall -Wextra -Werror -o /tmp/soda-icu/smoke32.exe | |
| mkdir -p "$RUNNER_TEMP/soda-office-winrt" | |
| x86_64-w64-mingw32-gcc .github/soda-office-winrt-smoke.c \ | |
| -O2 -Wall -Wextra -Werror -lole32 -lruntimeobject \ | |
| -o "$RUNNER_TEMP/soda-office-winrt/smoke64.exe" | |
| i686-w64-mingw32-gcc .github/soda-office-winrt-smoke.c \ | |
| -O2 -Wall -Wextra -Werror -lole32 -lruntimeobject \ | |
| -o "$RUNNER_TEMP/soda-office-winrt/smoke32.exe" | |
| x86_64-w64-mingw32-gcc .github/soda-ldap-smoke.c \ | |
| -O2 -Wall -Wextra -Werror -o "$RUNNER_TEMP/soda-office-winrt/ldap64.exe" | |
| i686-w64-mingw32-gcc .github/soda-ldap-smoke.c \ | |
| -O2 -Wall -Wextra -Werror -o "$RUNNER_TEMP/soda-office-winrt/ldap32.exe" | |
| - name: prepare identity SDK | |
| run: | | |
| docker build --file .github/soda-arm64-sdk.Dockerfile --tag soda-arm64-sdk .github | |
| - name: configure | |
| run: | | |
| mkdir /tmp/proton-build | |
| cd /tmp/proton-build | |
| /tmp/proton/configure.sh --build-name=soda-arm64 --target-arch=arm64 \ | |
| --container-engine=docker --proton-sdk-image=soda-arm64-sdk | |
| - name: build Wine and FEX | |
| working-directory: /tmp/proton-build | |
| run: | | |
| make WINE_DEPENDS= WINE_aarch64_DEPENDS= wine | |
| make WINE_DEPENDS= WINE_aarch64_DEPENDS= fex | |
| make WINE_DEPENDS= WINE_aarch64_DEPENDS= fex_unixlib | |
| make WINE_DEPENDS= WINE_aarch64_DEPENDS= wineopenxr | |
| - name: package | |
| env: | |
| ARCHIVE_NAME: ${{ steps.identity.outputs.archive_name }} | |
| COMPONENT_NAME: ${{ steps.identity.outputs.component_name }} | |
| run: | | |
| runner_dir="/tmp/$COMPONENT_NAME" | |
| proton_files=/tmp/proton-build/dist/files | |
| test -x "$proton_files/bin-arm64/wine" | |
| test -x "$proton_files/bin-arm64/wineserver" | |
| mkdir "$runner_dir" | |
| cp -a "$proton_files"/. "$runner_dir"/ | |
| mv "$runner_dir/bin-arm64" "$runner_dir/bin" | |
| install -Dm644 /tmp/proton/FEX_Config.json "$runner_dir/share/fex-emu/Config.json" | |
| install -Dm644 /tmp/proton/wineopenxr/wineopenxr64.json "$runner_dir/share/openxr/wineopenxr64.json" | |
| mono_file="wine-mono-$WINE_MONO_VERSION-x86.msi" | |
| mono_url="https://github.com/wine-mono/wine-mono/releases/download/wine-mono-$WINE_MONO_VERSION/$mono_file" | |
| curl --fail --location --retry 3 --output "/tmp/$mono_file" "$mono_url" | |
| echo "$WINE_MONO_SHA256 /tmp/$mono_file" | sha256sum --check - | |
| install -Dm644 "/tmp/$mono_file" "$runner_dir/share/wine/mono/$mono_file" | |
| required_files=( | |
| lib/wine/aarch64-unix/ntdll.so | |
| lib/wine/aarch64-windows/ntdll.dll | |
| lib/wine/x86_64-windows/ntdll.dll | |
| lib/wine/i386-windows/icu.dll | |
| lib/wine/x86_64-windows/icu.dll | |
| lib/wine/aarch64-windows/icu.dll | |
| lib/wine/aarch64-windows/libarm64ecfex.dll | |
| lib/wine/aarch64-windows/libwow64fex.dll | |
| lib/wine/aarch64-unix/libarm64ecfex.so | |
| lib/wine/aarch64-unix/libwow64fex.so | |
| lib/wine/aarch64-windows/wineopenxr.dll | |
| lib/wine/x86_64-windows/wineopenxr.dll | |
| lib/wine/i386-windows/windows.security.authentication.onlineid.dll | |
| lib/wine/x86_64-windows/windows.security.authentication.onlineid.dll | |
| lib/wine/aarch64-windows/windows.security.authentication.onlineid.dll | |
| lib/wine/aarch64-unix/windows.security.authentication.onlineid.so | |
| lib/wine/i386-windows/twinapi.appcore.dll | |
| lib/wine/x86_64-windows/twinapi.appcore.dll | |
| lib/wine/aarch64-windows/twinapi.appcore.dll | |
| ) | |
| for required_file in "${required_files[@]}"; do | |
| if ! test -f "$runner_dir/$required_file"; then | |
| echo "Missing required ARM64 runner file: $required_file" >&2 | |
| exit 1 | |
| fi | |
| done | |
| grep -aFq 'org.winehq.Soda.Identity' \ | |
| "$runner_dir/lib/wine/aarch64-unix/windows.security.authentication.onlineid.so" | |
| file "$runner_dir/bin/wine" | grep -F 'ARM aarch64' | |
| if ldd "$runner_dir/bin/wine" | grep -F 'not found'; then | |
| exit 1 | |
| fi | |
| tar -C /tmp -cJf "/tmp/$ARCHIVE_NAME" "$COMPONENT_NAME" | |
| - name: upload | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ steps.identity.outputs.component_name }} | |
| path: /tmp/${{ steps.identity.outputs.archive_name }} | |
| if-no-files-found: error | |
| - name: verify Windows architectures | |
| env: | |
| COMPONENT_NAME: ${{ steps.identity.outputs.component_name }} | |
| run: | | |
| set -o pipefail | |
| runner_dir="/tmp/$COMPONENT_NAME" | |
| export FEX_APP_CONFIG="$runner_dir/share/fex-emu/Config.json" | |
| export FEX_APP_CONFIG_LOCATION="$runner_dir/share/fex-emu" | |
| export WINEARCH=win64 | |
| export WINEDEBUG=+module,+process | |
| export WINEPREFIX=/tmp/soda-arm64-prefix | |
| runtime_log=/tmp/soda-arm64-runtime.log | |
| mkdir -p "$WINEPREFIX" | |
| if ! xvfb-run -a "$runner_dir/bin/wine" wineboot -u >"$runtime_log" 2>&1; then | |
| cat "$runtime_log" | |
| exit 1 | |
| fi | |
| if ! native_arch="$(xvfb-run -a "$runner_dir/bin/wine" cmd /c echo '%PROCESSOR_ARCHITECTURE%' 2>>"$runtime_log" | tr -d '\r' | grep -E '^(ARM64|AMD64|x86)$' | tail -1)"; then | |
| cat "$runtime_log" | |
| exit 1 | |
| fi | |
| if [[ "$native_arch" != ARM64 ]]; then | |
| printf 'Expected ARM64, got: %s\n' "$native_arch" >&2 | |
| cat "$runtime_log" | |
| exit 1 | |
| fi | |
| x64_cmd="$runner_dir/lib/wine/x86_64-windows/cmd.exe" | |
| test -f "$x64_cmd" | |
| if ! x64_arch="$(xvfb-run -a "$runner_dir/bin/wine" "$x64_cmd" /c echo '%PROCESSOR_ARCHITECTURE%' 2>>"$runtime_log" | tr -d '\r' | grep -E '^(ARM64|AMD64|x86)$' | tail -1)"; then | |
| cat "$runtime_log" | |
| exit 1 | |
| fi | |
| if [[ "$x64_arch" != AMD64 ]]; then | |
| printf 'Expected AMD64, got: %s\n' "$x64_arch" >&2 | |
| cat "$runtime_log" | |
| exit 1 | |
| fi | |
| x86_cmd="$runner_dir/lib/wine/i386-windows/cmd.exe" | |
| test -f "$x86_cmd" | |
| if ! x86_arch="$(xvfb-run -a "$runner_dir/bin/wine" "$x86_cmd" /c echo '%PROCESSOR_ARCHITECTURE%' 2>>"$runtime_log" | tr -d '\r' | grep -E '^(ARM64|AMD64|x86)$' | tail -1)"; then | |
| cat "$runtime_log" | |
| exit 1 | |
| fi | |
| if [[ "$x86_arch" != x86 ]]; then | |
| printf 'Expected x86, got: %s\n' "$x86_arch" >&2 | |
| cat "$runtime_log" | |
| exit 1 | |
| fi | |
| printf 'Windows architectures: native=%s, x64=%s, x86=%s\n' \ | |
| "$native_arch" "$x64_arch" "$x86_arch" | tee -a "$GITHUB_STEP_SUMMARY" | |
| export TZ=America/Denver | |
| export WINEDEBUG=-all | |
| "$runner_dir/bin/wine" /tmp/soda-icu/smoke64.exe \ | |
| | tr -d '\r' | tee /tmp/soda-icu/runtime64.log | |
| grep -F 'ICU 72.1 timezone=America/Denver' /tmp/soda-icu/runtime64.log | |
| "$runner_dir/bin/wine" /tmp/soda-icu/smoke32.exe \ | |
| | tr -d '\r' | tee /tmp/soda-icu/runtime32.log | |
| grep -F 'ICU 72.1 timezone=America/Denver' /tmp/soda-icu/runtime32.log | |
| for arch in 64 32; do | |
| "$runner_dir/bin/wine" "$RUNNER_TEMP/soda-office-winrt/smoke$arch.exe" \ | |
| | tr -d '\r' | tee "$RUNNER_TEMP/soda-office-winrt/runtime$arch.log" | |
| for factory in core_application message_websocket protection_policy retail_info web_authentication_manager composition_effect_source_parameter; do | |
| grep -Fx "$factory:00000000" "$RUNNER_TEMP/soda-office-winrt/runtime$arch.log" | |
| done | |
| "$runner_dir/bin/wine" reg add \ | |
| "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ldap$arch.exe" \ | |
| /v GlobalFlag /t REG_DWORD /d 112 /f | |
| "$runner_dir/bin/wine" "$RUNNER_TEMP/soda-office-winrt/ldap$arch.exe" \ | |
| | tr -d '\r' | tee "$RUNNER_TEMP/soda-office-winrt/ldap$arch.log" | |
| grep -Fx 'ldap_init_checks:1024 failures:0' "$RUNNER_TEMP/soda-office-winrt/ldap$arch.log" | |
| done | |
| "$runner_dir/bin/wineserver" -w | |
| recovery: | |
| if: >- | |
| github.event_name == 'workflow_dispatch' && | |
| inputs.recovery_run != '' && | |
| github.ref == 'refs/heads/soda' | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| actions: read | |
| contents: write | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| SOURCE_RUN: ${{ inputs.recovery_run }} | |
| SOURCE_COMMIT: '348313d6426f58cd892fc33a975919c1200f403c' | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: verify completed builds | |
| run: | | |
| [[ "$SOURCE_RUN" =~ ^[0-9]+$ ]] | |
| work="$HOME/artifacts/Soda-$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT" | |
| mkdir -p "$work/t" "$work/release" "$work/logs" | |
| export TMPDIR="$work/t" TMP="$work/t" TEMP="$work/t" | |
| echo "RECOVERY_WORK=$work" >> "$GITHUB_ENV" | |
| echo "TMPDIR=$work/t" >> "$GITHUB_ENV" | |
| echo "TMP=$work/t" >> "$GITHUB_ENV" | |
| echo "TEMP=$work/t" >> "$GITHUB_ENV" | |
| gh api "repos/$GITHUB_REPOSITORY/actions/runs/$SOURCE_RUN" > "$work/run.json" | |
| gh api "repos/$GITHUB_REPOSITORY/actions/runs/$SOURCE_RUN/jobs" > "$work/jobs.json" | |
| python3 - "$work" <<'PYCODE' | |
| import json | |
| import os | |
| from pathlib import Path | |
| import sys | |
| work = Path(sys.argv[1]) | |
| run = json.loads((work / 'run.json').read_text()) | |
| jobs = json.loads((work / 'jobs.json').read_text())['jobs'] | |
| assert run['head_sha'] == os.environ['SOURCE_COMMIT'] | |
| assert run['head_branch'] == 'soda' and run['event'] == 'push' | |
| assert run['status'] == 'completed' and run['conclusion'] == 'failure' | |
| assert run['path'] == '.github/workflows/build-soda.yml' | |
| for name in ('patches', 'arm64'): | |
| assert next(job for job in jobs if job['name'] == name)['conclusion'] == 'success' | |
| steps = next(job for job in jobs if job['name'] == 'build')['steps'] | |
| package = next(i for i, step in enumerate(steps) if step['name'] == 'package') | |
| assert all(step['conclusion'] == 'success' or (step['name'] == 'Upload prepare.log on failure' and step['conclusion'] == 'skipped') for step in steps[:package + 1]) | |
| assert steps[package]['conclusion'] == 'success' | |
| assert [step['name'] for step in steps if step['conclusion'] == 'failure'] == ['upload Eagle test logs'] | |
| print('Completed Wine builds and package tests verified; only log upload failed') | |
| PYCODE | |
| git merge-base --is-ancestor "$SOURCE_COMMIT" "$GITHUB_SHA" | |
| test -z "$(git diff --name-only "$SOURCE_COMMIT" "$GITHUB_SHA" -- . ':(exclude).github/workflows/**')" | |
| - name: setup | |
| working-directory: /home/runner/work/ | |
| run: | | |
| mkdir -p /home/runner/.config/frogminer/ | |
| sudo apt purge -y ubuntu-advantage-tools python3-update-manager | |
| sudo dpkg --add-architecture i386 && sudo apt update | |
| sudo apt-mark hold grub-common grub-efi-amd64-bin python3 python3-apt shim-signed | |
| sudo apt install aptitude | |
| sudo aptitude remove -y '?narrow(?installed,?version(deb.sury.org))' | |
| sudo apt install -f | |
| sudo apt-get install -y -o Dpkg::Options::="--force-overwrite" libpcap-dev:amd64 libpcap-dev:i386 | |
| sudo apt-get install -y libglib2.0-dev-bin libglib2.0-dev:amd64 | |
| sudo aptitude install -y -o Dpkg::Options::="--force-overwrite" \ | |
| libglib2.0-dev-bin:amd64 \ | |
| libgudev-1.0-dev:amd64 \ | |
| libgudev-1.0-dev:i386 \ | |
| libvulkan-dev:amd64 \ | |
| libvulkan-dev:i386 | |
| sudo apt-get install -y -o Dpkg::Options::="--force-overwrite" libpcsclite-dev:amd64 libpcsclite-dev:i386 | |
| sudo apt-get install -y libsecret-1-dev:amd64 libsecret-1-0:i386 | |
| sudo apt-get install -y libfreetype6:amd64 libfreetype6:i386 libfontconfig1:amd64 libfontconfig1:i386 | |
| bash "$GITHUB_WORKSPACE/.github/soda-secret-headers.sh" "$GITHUB_WORKSPACE/.soda-secret-amd64" amd64 | |
| bash "$GITHUB_WORKSPACE/.github/soda-secret-headers.sh" "$GITHUB_WORKSPACE/.soda-secret-i386" i386 | |
| sudo apt-get install -y \ | |
| g++ \ | |
| cmake \ | |
| file \ | |
| g++-mingw-w64-i686 \ | |
| g++-mingw-w64-x86-64 \ | |
| libopenxr-dev:amd64 \ | |
| "libopenxr1-monado=$MONADO_VERSION" \ | |
| mesa-vulkan-drivers \ | |
| "monado-service=$MONADO_VERSION" \ | |
| ninja-build \ | |
| xvfb | |
| sudo apt-get check | |
| - name: package verified Wine artifacts | |
| run: | | |
| work="$RECOVERY_WORK" | |
| component="soda-$WINE_VERSION-$REVISION" | |
| gh run download "$SOURCE_RUN" --repo "$GITHUB_REPOSITORY" \ | |
| --name "pre-test-$component-x86_64" --dir "$work/runner" | |
| wine="$(find "$work/runner" -maxdepth 3 -type f -path '*/bin/wine' -print)" | |
| test "$(printf '%s\n' "$wine" | wc -l)" = 1 | |
| test -n "$wine" | |
| runner="${wine%/bin/wine}" | |
| chmod +x "$runner"/bin/* | |
| for name in msidb msiexec notepad regedit regsvr32 wineboot winecfg wineconsole winedbg winefile winemine winepath; do | |
| cmp "$runner/bin/$name" "$runner/bin/wine" | |
| ln -sf wine "$runner/bin/$name" | |
| done | |
| for name in winecpp wineg++; do | |
| cmp "$runner/bin/$name" "$runner/bin/winegcc" | |
| ln -sf winegcc "$runner/bin/$name" | |
| done | |
| install -d "$runner/share/openxr" | |
| curl -fL "https://raw.githubusercontent.com/ValveSoftware/Proton/$PROTON_COMMIT/wineopenxr/wineopenxr64.json" \ | |
| -o "$runner/share/openxr/wineopenxr64.json" | |
| file "$runner/bin/wine" | grep -F 'x86-64' | |
| for arch in i386 x86_64; do | |
| test -f "$runner/lib/wine/$arch-unix/winegstreamer.so" | |
| test -f "$runner/lib/wine/$arch-unix/winscard.so" | |
| test -f "$runner/lib/wine/$arch-unix/windows.security.authentication.onlineid.so" | |
| done | |
| test -f "$runner/lib/wine/x86_64-unix/wineopenxr.so" | |
| xvfb-run -a sh "$GITHUB_WORKSPACE/.github/build-eagle.sh" "$runner" "$work/eagle" | |
| mv "$runner" "$work/release/$component-x86_64" | |
| tar -C "$work/release" -cJf "$work/release/$component-x86_64.tar.xz" "$component-x86_64" | |
| gh run download "$SOURCE_RUN" --repo "$GITHUB_REPOSITORY" \ | |
| --name "$component-aarch64" --dir "$work/release" | |
| cd "$work/release" | |
| echo 'df670ae214ae7ac6c1934fbf2d4b25efc5753561a27a47cb48ba4a4663725f4a soda-11.0-27-experimental-aarch64.tar.xz' | sha256sum --check - | |
| sha256sum "$component-x86_64.tar.xz" "$component-aarch64.tar.xz" > SHA256SUMS | |
| - name: collect package test logs | |
| if: always() | |
| run: | | |
| work="$RECOVERY_WORK" | |
| for log in "$work"/eagle/tests/{32,64,p32,p64,c32,c64,d,t,e}/*.log; do | |
| test -f "$log" || continue | |
| directory="$(basename "$(dirname "$log")")" | |
| cp "$log" "$work/logs/$directory-$(basename "$log")" | |
| done | |
| - name: upload package test logs | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: eagle-recovery-test-logs-${{ github.sha }} | |
| path: ${{ env.RECOVERY_WORK }}/logs/*.log | |
| if-no-files-found: error | |
| - name: upload verified packages | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: soda-package-recovery-${{ github.sha }} | |
| path: | | |
| ${{ env.RECOVERY_WORK }}/release/*.tar.xz | |
| ${{ env.RECOVERY_WORK }}/release/SHA256SUMS | |
| if-no-files-found: error | |
| - name: release | |
| env: | |
| GH_REPO: ${{ github.repository }} | |
| run: | | |
| component="soda-$WINE_VERSION-$REVISION" | |
| cd "$RECOVERY_WORK/release" | |
| if gh release view "$component" >/dev/null 2>&1; then | |
| echo "Release $component already exists." >&2 | |
| exit 1 | |
| fi | |
| printf '%s\n' "$RELEASE_NOTES" > "$RECOVERY_WORK/notes.md" | |
| gh release create "$component" "$component-x86_64.tar.xz" "$component-aarch64.tar.xz" SHA256SUMS \ | |
| --target "$GITHUB_SHA" --title "Soda $WINE_VERSION-$REVISION" \ | |
| --notes-file "$RECOVERY_WORK/notes.md" --prerelease | |
| release: | |
| needs: | |
| - build | |
| - arm64 | |
| if: needs.build.outputs.publish == 'true' | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: ${{ needs.build.outputs.component_name }} | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: ${{ needs.arm64.outputs.component_name }} | |
| - name: release | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/soda' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| GH_REPO: ${{ github.repository }} | |
| ARCHIVE_NAME: ${{ needs.build.outputs.archive_name }} | |
| ARM64_ARCHIVE_NAME: ${{ needs.arm64.outputs.archive_name }} | |
| run: | | |
| tag="soda-$WINE_VERSION-$REVISION" | |
| title="Soda $WINE_VERSION-$REVISION" | |
| file="$ARCHIVE_NAME" | |
| arm64_file="$ARM64_ARCHIVE_NAME" | |
| release_flags=(--latest) | |
| if [[ -n "$RELEASE_CODENAME" ]]; then | |
| title="$title - $RELEASE_CODENAME" | |
| fi | |
| if [[ "${{ needs.build.outputs.prerelease }}" == "true" ]]; then | |
| release_flags=(--prerelease) | |
| fi | |
| if gh release view "$tag" >/dev/null 2>&1; then | |
| echo "Release $tag already exists." >&2 | |
| exit 1 | |
| fi | |
| sha256sum "$file" "$arm64_file" > SHA256SUMS | |
| gh release create "$tag" "$file" "$arm64_file" SHA256SUMS --target "$GITHUB_SHA" --title "$title" --notes "$RELEASE_NOTES" "${release_flags[@]}" |