diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml deleted file mode 100644 index 062745275e9..00000000000 --- a/.github/workflows/CI.yml +++ /dev/null @@ -1,1088 +0,0 @@ ---- -name: CI -permissions: - contents: read - -on: - pull_request: - branches: - - master - types: - - opened - - synchronize - - reopened - push: - branches: - - master - workflow_dispatch: - -concurrency: - group: "${{ github.workflow }}-${{ github.ref }}" - cancel-in-progress: true - -jobs: - github_env: - name: GitHub Env Debug - runs-on: ubuntu-latest - steps: - - name: Dump github context - run: echo "$GITHUB_CONTEXT" - shell: bash - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - - setup_release: - name: Setup Release - outputs: - publish_release: ${{ steps.setup_release.outputs.publish_release }} - release_body: ${{ steps.setup_release.outputs.release_body }} - release_commit: ${{ steps.setup_release.outputs.release_commit }} - release_generate_release_notes: ${{ steps.setup_release.outputs.release_generate_release_notes }} - release_tag: ${{ steps.setup_release.outputs.release_tag }} - release_version: ${{ steps.setup_release.outputs.release_version }} - permissions: - contents: write # read does not work to check squash and merge details - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Release - id: setup_release - uses: LizardByte/setup-release-action@v2025.612.120948 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - - build_linux_flatpak: - name: Linux Flatpak - env: - APP_ID: dev.lizardbyte.app.Sunshine - NODE_VERSION: "20" - PLATFORM_VERSION: "23.08" - needs: setup_release - runs-on: ${{ matrix.runner }} - strategy: - fail-fast: false # false to test all, true to fail entire job if any fail - matrix: - include: - - arch: x86_64 - runner: ubuntu-22.04 - - arch: aarch64 - runner: ubuntu-22.04-arm - steps: - - name: Maximize build space - if: matrix.arch == 'x86_64' - uses: easimon/maximize-build-space@v10 - with: - root-reserve-mb: 10240 - remove-dotnet: 'true' - remove-android: 'true' - remove-haskell: 'true' - remove-codeql: 'true' - remove-docker-images: 'true' - - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Setup node - id: node - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install npm dependencies - run: npm install --package-lock-only - - - name: Debug package-lock.json - run: cat package-lock.json - - - name: Setup python - id: python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Setup Dependencies Linux Flatpak - run: | - python -m pip install ./packaging/linux/flatpak/deps/flatpak-builder-tools/node - - sudo apt-get update -y - sudo apt-get install -y \ - cmake \ - flatpak - - sudo su $(whoami) -c "flatpak --user remote-add --if-not-exists flathub \ - https://flathub.org/repo/flathub.flatpakrepo" - - sudo su $(whoami) -c "flatpak --user install -y flathub \ - org.flatpak.Builder \ - org.freedesktop.Platform/${{ matrix.arch }}/${PLATFORM_VERSION} \ - org.freedesktop.Sdk/${{ matrix.arch }}/${PLATFORM_VERSION} \ - org.freedesktop.Sdk.Extension.node${NODE_VERSION}/${{ matrix.arch }}/${PLATFORM_VERSION} \ - " - - flatpak run org.flatpak.Builder --version - - - name: flatpak node generator - # https://github.com/flatpak/flatpak-builder-tools/blob/master/node/README.md - run: flatpak-node-generator npm package-lock.json - - - name: Debug generated-sources.json - run: cat generated-sources.json - - - name: Cache Flatpak build - uses: actions/cache@v4 - with: - path: ./build/.flatpak-builder - key: flatpak-${{ matrix.arch }}-${{ github.sha }} - restore-keys: | - flatpak-${{ matrix.arch }}- - - - name: Configure Flatpak Manifest - run: | - # variables for manifest - branch="${{ github.head_ref }}" - commit=${{ needs.setup_release.outputs.release_commit }} - - # check the branch variable - if [ -z "$branch" ] - then - echo "This is a PUSH event" - branch=${{ github.ref_name }} - build_version=${{ needs.setup_release.outputs.release_tag }} - clone_url=${{ github.event.repository.clone_url }} - else - echo "This is a PR event" - clone_url=${{ github.event.pull_request.head.repo.clone_url }} - fi - echo "Branch: ${branch}" - echo "Commit: ${commit}" - echo "Clone URL: ${clone_url}" - - mkdir -p build - mkdir -p artifacts - - cmake -DGITHUB_CLONE_URL=${clone_url} \ - -B build \ - -S . \ - -DBUILD_VERSION=${build_version} \ - -DGITHUB_BRANCH=${branch} \ - -DGITHUB_COMMIT=${commit} \ - -DSUNSHINE_CONFIGURE_FLATPAK_MAN=ON \ - -DSUNSHINE_CONFIGURE_ONLY=ON - - - name: Debug Manifest - working-directory: build - run: cat ${APP_ID}.yml - - - name: Build Linux Flatpak - working-directory: build - run: | - sudo su $(whoami) -c "flatpak run org.flatpak.Builder \ - --arch=${{ matrix.arch }} \ - --force-clean \ - --repo=repo \ - --sandbox \ - --stop-at=cuda build-sunshine ${APP_ID}.yml" - cp -r .flatpak-builder copy-of-flatpak-builder - sudo su $(whoami) -c "flatpak run org.flatpak.Builder \ - --arch=${{ matrix.arch }} \ - --force-clean \ - --repo=repo \ - --sandbox \ - build-sunshine ${APP_ID}.yml" - rm -rf .flatpak-builder - mv copy-of-flatpak-builder .flatpak-builder - sudo su $(whoami) -c "flatpak build-bundle \ - --arch=${{ matrix.arch }} \ - ./repo \ - ../artifacts/sunshine_${{ matrix.arch }}.flatpak ${APP_ID}" - sudo su $(whoami) -c "flatpak build-bundle \ - --runtime \ - --arch=${{ matrix.arch }} \ - ./repo \ - ../artifacts/sunshine_debug_${{ matrix.arch }}.flatpak ${APP_ID}.Debug" - - - name: Lint Flatpak - working-directory: build - run: | - exceptions_file="${{ github.workspace }}/packaging/linux/flatpak/exceptions.json" - - echo "Linting flatpak manifest" - flatpak run --command=flatpak-builder-lint org.flatpak.Builder \ - --exceptions \ - --user-exceptions "${exceptions_file}" \ - manifest \ - ${APP_ID}.yml - - echo "Linting flatpak repo" - # TODO: add arg - # --mirror-screenshots-url=https://dl.flathub.org/media \ - flatpak run --command=flatpak-builder-lint org.flatpak.Builder \ - --exceptions \ - --user-exceptions "${exceptions_file}" \ - repo \ - repo - - - name: Package Flathub repo archive - # copy files required to generate the Flathub repo - if: matrix.arch == 'x86_64' - run: | - mkdir -p flathub/modules - cp ./build/generated-sources.json ./flathub/ - cp ./build/package-lock.json ./flathub/ - cp ./build/${APP_ID}.yml ./flathub/ - cp ./build/${APP_ID}.metainfo.xml ./flathub/ - cp ./packaging/linux/flatpak/README.md ./flathub/ - cp ./packaging/linux/flatpak/flathub.json ./flathub/ - cp -r ./packaging/linux/flatpak/modules/. ./flathub/modules/ - # submodules will need to be handled in the workflow that creates the PR - - # create the archive - tar -czf ./artifacts/flathub.tar.gz -C ./flathub . - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: sunshine-linux-flatpak-${{ matrix.arch }} - path: artifacts/ - if-no-files-found: error - - - name: Create/Update GitHub Release - if: needs.setup_release.outputs.publish_release == 'true' - uses: LizardByte/create-release-action@v2025.612.13419 - with: - allowUpdates: true - body: ${{ needs.setup_release.outputs.release_body }} - generateReleaseNotes: ${{ needs.setup_release.outputs.release_generate_release_notes }} - name: ${{ needs.setup_release.outputs.release_tag }} - prerelease: true - tag: ${{ needs.setup_release.outputs.release_tag }} - token: ${{ secrets.GH_BOT_TOKEN }} - - build_linux: - name: Linux ${{ matrix.type }} - env: - APP_ID: dev.lizardbyte.app.Sunshine - runs-on: ubuntu-${{ matrix.dist }} - needs: setup_release - strategy: - fail-fast: false # false to test all, true to fail entire job if any fail - matrix: - include: # package these differently - - type: AppImage - EXTRA_ARGS: '--appimage-build' - dist: 22.04 - steps: - - name: Maximize build space - uses: easimon/maximize-build-space@v10 - with: - root-reserve-mb: 30720 - remove-dotnet: 'true' - remove-android: 'true' - remove-haskell: 'true' - remove-codeql: 'true' - remove-docker-images: 'true' - - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Setup Dependencies Linux - timeout-minutes: 5 - run: | - # create the artifacts directory - mkdir -p artifacts - - # allow libfuse2 for appimage on 22.04+ - sudo add-apt-repository universe - - sudo apt-get install -y \ - libdrm-dev \ - libfuse2 \ - libgl-dev \ - libwayland-dev \ - libx11-xcb-dev \ - libxcb-dri3-dev \ - libxfixes-dev - - - name: Setup python - id: python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Build latest libva - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - timeout-minutes: 5 - run: | - gh release download --archive=tar.gz --repo=intel/libva - tar xzf libva-*.tar.gz && rm libva-*.tar.gz - cd libva-* - ./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu \ - --enable-drm \ - --enable-x11 \ - --enable-glx \ - --enable-wayland \ - --without-legacy # emgd, nvctrl, fglrx - make -j $(nproc) - sudo make install - cd .. && rm -rf libva-* - - - name: Build Linux - env: - BRANCH: ${{ github.head_ref || github.ref_name }} - BUILD_VERSION: ${{ needs.setup_release.outputs.release_tag }} - COMMIT: ${{ needs.setup_release.outputs.release_commit }} - run: | - chmod +x ./scripts/linux_build.sh - ./scripts/linux_build.sh \ - --publisher-name='${{ github.repository_owner }}' \ - --publisher-website='https://app.lizardbyte.dev' \ - --publisher-issue-url='https://app.lizardbyte.dev/support' \ - --skip-cleanup \ - --skip-package \ - --ubuntu-test-repo ${{ matrix.EXTRA_ARGS }} - - - name: Set AppImage Version - if: matrix.type == 'AppImage' - run: | - version=${{ needs.setup_release.outputs.release_tag }} - echo "VERSION=${version}" >> $GITHUB_ENV - - - name: Package Linux - AppImage - if: matrix.type == 'AppImage' - working-directory: build - run: | - # install sunshine to the DESTDIR - DESTDIR=AppDir ninja install - - # custom AppRun file - cp -f ../packaging/linux/AppImage/AppRun ./AppDir/ - chmod +x ./AppDir/AppRun - - # variables - DESKTOP_FILE="${DESKTOP_FILE:-${APP_ID}.desktop}" - ICON_FILE="${ICON_FILE:-sunshine.png}" - - # AppImage - # https://docs.appimage.org/packaging-guide/index.html - wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage - chmod +x linuxdeploy-x86_64.AppImage - - # https://github.com/linuxdeploy/linuxdeploy-plugin-gtk - sudo apt-get install libgtk-3-dev librsvg2-dev -y - wget -q https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh - chmod +x linuxdeploy-plugin-gtk.sh - export DEPLOY_GTK_VERSION=3 - - ./linuxdeploy-x86_64.AppImage \ - --appdir ./AppDir \ - --plugin gtk \ - --executable ./sunshine \ - --icon-file "../$ICON_FILE" \ - --desktop-file "./$DESKTOP_FILE" \ - --output appimage - - # move - mv Sunshine*.AppImage ../artifacts/sunshine.AppImage - - # permissions - chmod +x ../artifacts/sunshine.AppImage - - - name: Delete CUDA - # free up space on the runner - run: | - rm -rf ./build/cuda - - - name: Verify AppImage - if: matrix.type == 'AppImage' - run: | - wget https://github.com/TheAssassin/appimagelint/releases/download/continuous/appimagelint-x86_64.AppImage - chmod +x appimagelint-x86_64.AppImage - - ./appimagelint-x86_64.AppImage ./artifacts/sunshine.AppImage - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: sunshine-linux-${{ matrix.type }}-${{ matrix.dist }} - path: artifacts/ - if-no-files-found: error - - - name: Install test deps - run: | - sudo apt-get update -y - sudo apt-get install -y \ - x11-xserver-utils \ - xvfb - - # clean apt cache - sudo apt-get clean - sudo rm -rf /var/lib/apt/lists/* - - - name: Run tests - id: test - working-directory: build/tests - run: | - export DISPLAY=:1 - Xvfb ${DISPLAY} -screen 0 1024x768x24 & - sleep 5 # give Xvfb time to start - - ./test_sunshine --gtest_color=yes --gtest_output=xml:test_results.xml - - - name: Generate gcov report - id: test_report - # any except canceled or skipped - if: >- - always() && - (steps.test.outcome == 'success' || steps.test.outcome == 'failure') - working-directory: build - run: | - ${{ steps.python.outputs.python-path }} -m pip install gcovr - ${{ steps.python.outputs.python-path }} -m gcovr . -r ../src \ - --exclude-noncode-lines \ - --exclude-throw-branches \ - --exclude-unreachable-branches \ - --verbose \ - --xml-pretty \ - -o coverage.xml - - - name: Upload test results to Codecov - # any except canceled or skipped - if: >- - always() && - (steps.test.outcome == 'success' || steps.test.outcome == 'failure') && - startsWith(github.repository, 'LizardByte/') - uses: codecov/test-results-action@v1 - with: - disable_search: true - fail_ci_if_error: true - files: ./build/tests/test_results.xml - flags: ${{ runner.os }} - handle_no_reports_found: true - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - - - name: Upload coverage - # any except canceled or skipped - if: >- - always() && - (steps.test_report.outcome == 'success') && - startsWith(github.repository, 'LizardByte/') - uses: codecov/codecov-action@v5 - with: - disable_search: true - fail_ci_if_error: true - files: ./build/coverage.xml - flags: ${{ runner.os }} - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - - - name: Create/Update GitHub Release - if: needs.setup_release.outputs.publish_release == 'true' - uses: LizardByte/create-release-action@v2025.612.13419 - with: - allowUpdates: true - body: ${{ needs.setup_release.outputs.release_body }} - generateReleaseNotes: ${{ needs.setup_release.outputs.release_generate_release_notes }} - name: ${{ needs.setup_release.outputs.release_tag }} - prerelease: true - tag: ${{ needs.setup_release.outputs.release_tag }} - token: ${{ secrets.GH_BOT_TOKEN }} - - build_homebrew: - name: Homebrew (${{ matrix.os_name }}-${{ matrix.os_version }}${{ matrix.release == true && ' (Release)' || '' }}) - needs: setup_release - strategy: - fail-fast: false # false to test all, true to fail entire job if any fail - matrix: - include: - # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories - # while GitHub has larger macOS runners, they are not available for our repos :( - - os_version: "13" - os_name: "macos" - - os_version: "14" - os_name: "macos" - - os_version: "15" - os_name: "macos" - - os_version: "latest" - os_name: "ubuntu" - - os_version: "latest" # this job will only configure the formula for release, no validation - os_name: "ubuntu" - release: true - runs-on: ${{ matrix.os_name }}-${{ matrix.os_version }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Fix homebrew python - if: matrix.os_name == 'macos' && matrix.os_version == '13' - run: | - rm '/usr/local/bin/2to3' - rm '/usr/local/bin/2to3-3.12' - rm '/usr/local/bin/idle3' - rm '/usr/local/bin/idle3.12' - rm '/usr/local/bin/idle3.13' - rm '/usr/local/bin/pip3.12' - rm '/usr/local/bin/pip3.13' - rm '/usr/local/bin/pydoc3' - rm '/usr/local/bin/pydoc3.12' - rm '/usr/local/bin/pydoc3.13' - rm '/usr/local/bin/python3' - rm '/usr/local/bin/python3.12' - rm '/usr/local/bin/python3.13' - rm '/usr/local/bin/python3-config' - rm '/usr/local/bin/python3.12-config' - rm '/usr/local/bin/python3.13-config' - brew install python3 - - - name: Configure formula - run: | - # variables for formula - branch="${{ github.head_ref }}" - commit=${{ needs.setup_release.outputs.release_commit }} - - # check the branch variable - if [ -z "$branch" ] - then - echo "This is a PUSH event" - build_version=${{ needs.setup_release.outputs.release_tag }} - clone_url=${{ github.event.repository.clone_url }} - branch="${{ github.ref_name }}" - default_branch="${{ github.event.repository.default_branch }}" - - if [ "${{ matrix.release }}" == "true" ]; then - # we will publish the formula with the release tag - tag="${{ needs.setup_release.outputs.release_tag }}" - version="${{ needs.setup_release.outputs.release_version }}" - else - tag="${{ github.ref_name }}" - version="0.0.${{ github.run_number }}" - fi - else - echo "This is a PR event" - build_version="0.0.${{ github.event.number }}" - clone_url=${{ github.event.pull_request.head.repo.clone_url }} - branch="${{ github.event.pull_request.head.ref }}" - default_branch="${{ github.event.pull_request.head.repo.default_branch }}" - tag="${{ github.event.pull_request.head.ref }}" - version="0.0.${{ github.event.number }}" - fi - echo "Branch: ${branch}" - echo "Clone URL: ${clone_url}" - echo "Tag: ${tag}" - - mkdir -p build - cmake \ - -B build \ - -S . \ - -DBUILD_VERSION="${build_version}" \ - -DFORMULA_VERSION="${version}" \ - -DGITHUB_BRANCH="${branch}" \ - -DGITHUB_COMMIT="${commit}" \ - -DGITHUB_CLONE_URL="${clone_url}" \ - -DGITHUB_DEFAULT_BRANCH="${default_branch}" \ - -DGITHUB_TAG="${tag}" \ - -DSUNSHINE_CONFIGURE_HOMEBREW=ON \ - -DSUNSHINE_CONFIGURE_ONLY=ON - - # copy formula to artifacts - mkdir -p homebrew - cp -f ./build/sunshine.rb ./homebrew/sunshine.rb - - # testing - cat ./homebrew/sunshine.rb - - - name: Upload Artifacts - if: matrix.release - uses: actions/upload-artifact@v4 - with: - name: sunshine-homebrew - path: homebrew/ - if-no-files-found: error - - - name: Setup Xvfb - if: matrix.release != true && runner.os == 'Linux' - run: | - sudo apt-get update -y - sudo apt-get install -y \ - xvfb - - export DISPLAY=:1 - Xvfb ${DISPLAY} -screen 0 1024x768x24 & - - echo "DISPLAY=${DISPLAY}" >> $GITHUB_ENV - - - name: Validate Homebrew Formula - id: test - if: matrix.release != true - uses: LizardByte/homebrew-release-action@v2025.612.123332 - with: - formula_file: ${{ github.workspace }}/homebrew/sunshine.rb - git_email: ${{ secrets.GH_BOT_EMAIL }} - git_username: ${{ secrets.GH_BOT_NAME }} - publish: false - token: ${{ secrets.GH_BOT_TOKEN }} - validate: true - - - name: Setup python - id: python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Generate gcov report - id: test_report - # any except canceled or skipped - # TODO: fix coverage, no .gcno files are being created - # TODO: .gcno files are supposed to be created next to .o files - if: false - # if: >- - # always() && - # matrix.release != true && - # (steps.test.outcome == 'success' || steps.test.outcome == 'failure') - run: | - cp -rf ${{ steps.test.outputs.buildpath }}/build/ ./build/ - cd build - ls -Ra - - ${{ steps.python.outputs.python-path }} -m pip install gcovr - ${{ steps.python.outputs.python-path }} -m gcovr . -r ../src \ - --exclude-noncode-lines \ - --exclude-throw-branches \ - --exclude-unreachable-branches \ - --verbose \ - --xml-pretty \ - -o coverage.xml - - - name: Upload test results to Codecov - # any except canceled or skipped - if: >- - always() && - matrix.release != true && - (steps.test.outcome == 'success' || steps.test.outcome == 'failure') && - startsWith(github.repository, 'LizardByte/') - uses: codecov/test-results-action@v1 - with: - disable_search: true - fail_ci_if_error: true - files: ${{ steps.test.outputs.testpath }}/test_results.xml - flags: ${{ matrix.os_name }}-${{ matrix.os_version }} (Homebrew) - handle_no_reports_found: true - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - - - name: Upload coverage - # any except canceled or skipped - # TODO: enable this once coverage report is fixed - if: false - # if: >- - # always() && - # matrix.release != true && - # (steps.test_report.outcome == 'success') && - # startsWith(github.repository, 'LizardByte/') - uses: codecov/codecov-action@v5 - with: - disable_search: true - fail_ci_if_error: true - files: ./build/coverage.xml - flags: ${{ matrix.os_name }}-${{ matrix.os_version }} (Homebrew) - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - - - name: Create/Update GitHub Release - if: >- - matrix.release && - needs.setup_release.outputs.publish_release == 'true' - uses: LizardByte/create-release-action@v2025.612.13419 - with: - allowUpdates: true - artifacts: '${{ github.workspace }}/homebrew/*' - body: ${{ needs.setup_release.outputs.release_body }} - generateReleaseNotes: ${{ needs.setup_release.outputs.release_generate_release_notes }} - name: ${{ needs.setup_release.outputs.release_tag }} - prerelease: true - tag: ${{ needs.setup_release.outputs.release_tag }} - token: ${{ secrets.GH_BOT_TOKEN }} - - - name: Patch homebrew formula - # create beta version of the formula - # don't run this on macOS, as the sed command fails - if: matrix.release - run: | - # variables - formula_file="homebrew/sunshine-beta.rb" - - # rename the file - mv homebrew/sunshine.rb $formula_file - - # update the formula - sed -i 's/class Sunshine < Formula/class SunshineBeta < Formula/' $formula_file - sed -i 's/# conflicts_with/conflicts_with/' $formula_file - - # print new file - echo "New formula:" - cat $formula_file - - - name: Upload Homebrew Beta Formula - if: >- - github.repository_owner == 'LizardByte' && - matrix.release && - needs.setup_release.outputs.publish_release == 'true' - uses: LizardByte/homebrew-release-action@v2025.612.123332 - with: - formula_file: ${{ github.workspace }}/homebrew/sunshine-beta.rb - git_email: ${{ secrets.GH_BOT_EMAIL }} - git_username: ${{ secrets.GH_BOT_NAME }} - publish: true - token: ${{ secrets.GH_BOT_TOKEN }} - validate: false - - build_win: - name: Windows - needs: setup_release - runs-on: windows-2022 - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Prepare tests - id: prepare-tests - if: false # todo: DirectX11 is not available, so even software encoder fails - run: | - # function to download and extract a zip file - function DownloadAndExtract { - param ( - [string]$Uri, - [string]$OutFile - ) - - $maxRetries = 5 - $retryCount = 0 - $success = $false - - while (-not $success -and $retryCount -lt $maxRetries) { - $retryCount++ - Write-Host "Downloading $Uri to $OutFile, attempt $retryCount of $maxRetries" - try { - Invoke-WebRequest -Uri $Uri -OutFile $OutFile - $success = $true - } catch { - Write-Host "Attempt $retryCount of $maxRetries failed with error: $($_.Exception.Message). Retrying..." - Start-Sleep -Seconds 5 - } - } - - if (-not $success) { - Write-Host "Failed to download the file after $maxRetries attempts." - exit 1 - } - - # use .NET to get the base name of the file - $baseName = (Get-Item $OutFile).BaseName - - # Extract the zip file - Expand-Archive -Path $OutFile -DestinationPath $baseName - } - - # virtual display driver - DownloadAndExtract ` - -Uri "https://www.amyuni.com/downloads/usbmmidd_v2.zip" ` - -OutFile "usbmmidd_v2.zip" - - # install - Set-Location -Path usbmmidd_v2/usbmmidd_v2 - ./deviceinstaller64 install usbmmidd.inf usbmmidd - - # create the virtual display - ./deviceinstaller64 enableidd 1 - - # move up a directory - Set-Location -Path ../.. - - # install devcon - DownloadAndExtract ` - -Uri "https://github.com/Drawbackz/DevCon-Installer/releases/download/1.4-rc/Devcon.Installer.zip" ` - -OutFile "Devcon.Installer.zip" - Set-Location -Path Devcon.Installer - # hash needs to match OS version - # https://github.com/Drawbackz/DevCon-Installer/blob/master/devcon_sources.json - Start-Process -FilePath "./Devcon Installer.exe" -Wait -ArgumentList ` - 'install', ` - '-hash', '54004C83EE34F6A55380528A8B29F4C400E61FBB947A19E0AB9E5A193D7D961E', ` - '-addpath', ` - '-update', ` - '-dir', 'C:\Windows\System32' - - # disable Hyper-V Video - # https://stackoverflow.com/a/59490940 - C:\Windows\System32\devcon.exe disable "VMBUS\{da0a7802-e377-4aac-8e77-0558eb1073f8}" - - # move up a directory - Set-Location -Path .. - - # multi monitor tool - DownloadAndExtract ` - -Uri "http://www.nirsoft.net/utils/multimonitortool-x64.zip" ` - -OutFile "multimonitortool.zip" - - # enable the virtual display - # http://www.nirsoft.net/utils/multi_monitor_tool.html - Set-Location -Path multimonitortool - - # Original Hyper-V is \\.\DISPLAY1, it will recreate itself as \\.\DISPLAY6 (or something higher than 2) - # USB Mobile Monitor Virtual Display is \\.\DISPLAY2 - - # these don't seem to work if not using runAs - # todo: do they work if not using runAs? - Start-Process powershell -Verb runAs -ArgumentList '-Command ./MultiMonitorTool.exe /enable \\.\DISPLAY2' - Start-Process powershell -Verb runAs -ArgumentList '-Command ./MultiMonitorTool.exe /SetPrimary \\.\DISPLAY2' - - # wait a few seconds - Start-Sleep -s 5 - - # list monitors - ./MultiMonitorTool.exe /stext monitor_list.txt - - # wait a few seconds - Start-Sleep -s 5 - - # print the monitor list - Get-Content -Path monitor_list.txt - - - name: Setup Dependencies Windows - # if a dependency needs to be pinned, see https://github.com/LizardByte/build-deps/pull/186 - uses: msys2/setup-msys2@v2 - with: - msystem: ucrt64 - update: true - install: >- - wget - - - name: Update Windows dependencies - env: - MSYSTEM: "ucrt64" - TOOLCHAIN: "ucrt-x86_64" - shell: msys2 {0} - run: | - # variables - declare -A pinned_deps - - # dependencies - dependencies=( - "git" - "mingw-w64-${TOOLCHAIN}-cmake" - "mingw-w64-${TOOLCHAIN}-cppwinrt" - "mingw-w64-${TOOLCHAIN}-curl-winssl" - "mingw-w64-${TOOLCHAIN}-gcc" - "mingw-w64-${TOOLCHAIN}-graphviz" - "mingw-w64-${TOOLCHAIN}-MinHook" - "mingw-w64-${TOOLCHAIN}-miniupnpc" - "mingw-w64-${TOOLCHAIN}-nlohmann-json" - "mingw-w64-${TOOLCHAIN}-nodejs" - "mingw-w64-${TOOLCHAIN}-nsis" - "mingw-w64-${TOOLCHAIN}-onevpl" - "mingw-w64-${TOOLCHAIN}-openssl" - "mingw-w64-${TOOLCHAIN}-opus" - "mingw-w64-${TOOLCHAIN}-toolchain" - ) - - # do not modify below this line - - ignore_packages=() - tarballs="" - for pkg in "${!pinned_deps[@]}"; do - ignore_packages+=("${pkg}") - version="${pinned_deps[$pkg]}" - tarball="${pkg}-${version}-any.pkg.tar.zst" - - # download working version - wget "https://repo.msys2.org/mingw/${MSYSTEM}/${tarball}" - - tarballs="${tarballs} ${tarball}" - done - - # Create the ignore string for pacman - ignore_list=$(IFS=,; echo "${ignore_packages[*]}") - - # install pinned dependencies - if [ -n "$tarballs" ]; then - pacman -U --noconfirm ${tarballs} - fi - - # Only add --ignore if we have packages to ignore - if [ -n "$ignore_list" ]; then - pacman -Syu --noconfirm --ignore="${ignore_list}" "${dependencies[@]}" - else - pacman -Syu --noconfirm "${dependencies[@]}" - fi - - - name: Install Doxygen - # GCC compiled doxygen has issues when running graphviz - env: - DOXYGEN_VERSION: "1.11.0" - run: | - # Set version variables - $doxy_ver = $env:DOXYGEN_VERSION - $_doxy_ver = $doxy_ver.Replace(".", "_") - - # Download the Doxygen installer - Invoke-WebRequest -Uri ` - "https://github.com/doxygen/doxygen/releases/download/Release_${_doxy_ver}/doxygen-${doxy_ver}-setup.exe" ` - -OutFile "doxygen-setup.exe" - - # Run the installer - Start-Process ` - -FilePath .\doxygen-setup.exe ` - -ArgumentList ` - '/VERYSILENT' ` - -Wait ` - -NoNewWindow - - # Clean up - Remove-Item -Path doxygen-setup.exe - - - name: Setup python - id: setup-python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Python Path - id: python-path - shell: msys2 {0} - run: | - # replace backslashes with double backslashes - python_path=$(echo "${{ steps.setup-python.outputs.python-path }}" | sed 's/\\/\\\\/g') - - # step output - echo "python-path=${python_path}" - echo "python-path=${python_path}" >> $GITHUB_OUTPUT - - - name: Build Windows - shell: msys2 {0} - env: - BRANCH: ${{ github.head_ref || github.ref_name }} - BUILD_VERSION: ${{ needs.setup_release.outputs.release_tag }} - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - COMMIT: ${{ needs.setup_release.outputs.release_commit }} - run: | - mkdir -p build - cmake \ - -B build \ - -G Ninja \ - -S . \ - -DBUILD_WERROR=ON \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DSUNSHINE_ASSETS_DIR=assets \ - -DSUNSHINE_PUBLISHER_NAME='${{ github.repository_owner }}' \ - -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' \ - -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support' - ninja -C build - - - name: Package Windows - shell: msys2 {0} - run: | - mkdir -p artifacts - cd build - - # package - cpack -G NSIS - cpack -G ZIP - - # move - mv ./cpack_artifacts/Sunshine.exe ../artifacts/sunshine-windows-installer.exe - mv ./cpack_artifacts/Sunshine.zip ../artifacts/sunshine-windows-portable.zip - - - name: Run tests - id: test - shell: msys2 {0} - working-directory: build/tests - run: | - ./test_sunshine.exe --gtest_color=yes --gtest_output=xml:test_results.xml - - - name: Generate gcov report - id: test_report - # any except canceled or skipped - if: always() && (steps.test.outcome == 'success' || steps.test.outcome == 'failure') - shell: msys2 {0} - working-directory: build - run: | - ${{ steps.python-path.outputs.python-path }} -m pip install gcovr - ${{ steps.python-path.outputs.python-path }} -m gcovr . -r ../src \ - --exclude-noncode-lines \ - --exclude-throw-branches \ - --exclude-unreachable-branches \ - --verbose \ - --xml-pretty \ - -o coverage.xml - - - name: Upload test results to Codecov - # any except canceled or skipped - if: >- - always() && - (steps.test.outcome == 'success' || steps.test.outcome == 'failure') && - startsWith(github.repository, 'LizardByte/') - uses: codecov/test-results-action@v1 - with: - disable_search: true - fail_ci_if_error: true - files: ./build/tests/test_results.xml - flags: ${{ runner.os }} - handle_no_reports_found: true - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - - - name: Upload coverage - # any except canceled or skipped - if: >- - always() && - (steps.test_report.outcome == 'success') && - startsWith(github.repository, 'LizardByte/') - uses: codecov/codecov-action@v5 - with: - disable_search: true - fail_ci_if_error: true - files: ./build/coverage.xml - flags: ${{ runner.os }} - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - - - name: Package Windows Debug Info - working-directory: build - run: | - # use .dbg file extension for binaries to avoid confusion with real packages - Get-ChildItem -File -Recurse | ` - % { Rename-Item -Path $_.PSPath -NewName $_.Name.Replace(".exe",".dbg") } - - # save the binaries with debug info - 7z -r ` - "-xr!CMakeFiles" ` - "-xr!cpack_artifacts" ` - a "../artifacts/sunshine-win32-debuginfo.7z" "*.dbg" - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: sunshine-windows - path: artifacts/ - if-no-files-found: error - - - name: Create/Update GitHub Release - if: needs.setup_release.outputs.publish_release == 'true' - uses: LizardByte/create-release-action@v2025.612.13419 - with: - allowUpdates: true - body: ${{ needs.setup_release.outputs.release_body }} - generateReleaseNotes: ${{ needs.setup_release.outputs.release_generate_release_notes }} - name: ${{ needs.setup_release.outputs.release_tag }} - prerelease: true - tag: ${{ needs.setup_release.outputs.release_tag }} - token: ${{ secrets.GH_BOT_TOKEN }} diff --git a/.github/workflows/_docker.yml b/.github/workflows/_docker.yml deleted file mode 100644 index f9cd482f09b..00000000000 --- a/.github/workflows/_docker.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -# This workflow is centrally managed in https://github.com/LizardByte/.github/ -# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in -# the above-mentioned repo. - -name: Docker -permissions: - contents: write - packages: write - -on: - pull_request: - branches: - - master - types: - - opened - - synchronize - - reopened - push: - branches: - - master - workflow_dispatch: - -concurrency: - group: "${{ github.workflow }}-${{ github.ref }}" - cancel-in-progress: true - -jobs: - call-docker: - name: Docker - uses: LizardByte/.github/.github/workflows/__call-docker.yml@master - if: ${{ github.repository != 'LizardByte/.github' }} - secrets: - DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} - DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }} - DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - GH_BOT_NAME: ${{ secrets.GH_BOT_NAME }} - GH_BOT_TOKEN: ${{ secrets.GH_BOT_TOKEN }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci-flatpak.yml b/.github/workflows/ci-flatpak.yml new file mode 100644 index 00000000000..647335f98d4 --- /dev/null +++ b/.github/workflows/ci-flatpak.yml @@ -0,0 +1,211 @@ +--- +name: CI-Flatpak +permissions: + contents: read + +on: + workflow_call: + inputs: + release_commit: + required: true + type: string + release_tag: + required: true + type: string + +jobs: + build_linux_flatpak: + name: ${{ matrix.arch }} + env: + APP_ID: dev.lizardbyte.app.Sunshine + NODE_VERSION: "20" + PLATFORM_VERSION: "23.08" + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - arch: x86_64 + runner: ubuntu-22.04 + - arch: aarch64 + runner: ubuntu-22.04-arm + steps: + - name: Maximize build space + if: matrix.arch == 'x86_64' + uses: easimon/maximize-build-space@v10 + with: + root-reserve-mb: 10240 + remove-dotnet: 'true' + remove-android: 'true' + remove-haskell: 'true' + remove-codeql: 'true' + remove-docker-images: 'true' + + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Setup node + id: node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Install npm dependencies + run: npm install --package-lock-only + + - name: Debug package-lock.json + run: cat package-lock.json + + - name: Setup python + id: python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Setup Dependencies Linux Flatpak + run: | + python -m pip install ./packaging/linux/flatpak/deps/flatpak-builder-tools/node + + sudo apt-get update -y + sudo apt-get install -y \ + cmake \ + flatpak + + sudo su $(whoami) -c "flatpak --user remote-add --if-not-exists flathub \ + https://flathub.org/repo/flathub.flatpakrepo" + + sudo su $(whoami) -c "flatpak --user install -y flathub \ + org.flatpak.Builder \ + org.freedesktop.Platform/${{ matrix.arch }}/${PLATFORM_VERSION} \ + org.freedesktop.Sdk/${{ matrix.arch }}/${PLATFORM_VERSION} \ + org.freedesktop.Sdk.Extension.node${NODE_VERSION}/${{ matrix.arch }}/${PLATFORM_VERSION} \ + " + + flatpak run org.flatpak.Builder --version + + - name: flatpak node generator + # https://github.com/flatpak/flatpak-builder-tools/blob/master/node/README.md + run: flatpak-node-generator npm package-lock.json + + - name: Debug generated-sources.json + run: cat generated-sources.json + + - name: Cache Flatpak build + uses: actions/cache@v4 + with: + path: ./build/.flatpak-builder + key: flatpak-${{ matrix.arch }}-${{ github.sha }} + restore-keys: | + flatpak-${{ matrix.arch }}- + + - name: Configure Flatpak Manifest + run: | + # variables for manifest + branch="${{ github.head_ref }}" + commit=${{ inputs.release_commit }} + + # check the branch variable + if [ -z "$branch" ] + then + echo "This is a PUSH event" + branch=${{ github.ref_name }} + build_version=${{ inputs.release_tag }} + clone_url=${{ github.event.repository.clone_url }} + else + echo "This is a PR event" + clone_url=${{ github.event.pull_request.head.repo.clone_url }} + fi + echo "Branch: ${branch}" + echo "Commit: ${commit}" + echo "Clone URL: ${clone_url}" + + mkdir -p build + mkdir -p artifacts + + cmake -DGITHUB_CLONE_URL=${clone_url} \ + -B build \ + -S . \ + -DBUILD_VERSION=${build_version} \ + -DGITHUB_BRANCH=${branch} \ + -DGITHUB_COMMIT=${commit} \ + -DSUNSHINE_CONFIGURE_FLATPAK_MAN=ON \ + -DSUNSHINE_CONFIGURE_ONLY=ON + + - name: Debug Manifest + working-directory: build + run: cat ${APP_ID}.yml + + - name: Build Linux Flatpak + working-directory: build + run: | + sudo su $(whoami) -c "flatpak run org.flatpak.Builder \ + --arch=${{ matrix.arch }} \ + --force-clean \ + --repo=repo \ + --sandbox \ + --stop-at=cuda build-sunshine ${APP_ID}.yml" + cp -r .flatpak-builder copy-of-flatpak-builder + sudo su $(whoami) -c "flatpak run org.flatpak.Builder \ + --arch=${{ matrix.arch }} \ + --force-clean \ + --repo=repo \ + --sandbox \ + build-sunshine ${APP_ID}.yml" + rm -rf .flatpak-builder + mv copy-of-flatpak-builder .flatpak-builder + sudo su $(whoami) -c "flatpak build-bundle \ + --arch=${{ matrix.arch }} \ + ./repo \ + ../artifacts/sunshine_${{ matrix.arch }}.flatpak ${APP_ID}" + sudo su $(whoami) -c "flatpak build-bundle \ + --runtime \ + --arch=${{ matrix.arch }} \ + ./repo \ + ../artifacts/sunshine_debug_${{ matrix.arch }}.flatpak ${APP_ID}.Debug" + + - name: Lint Flatpak + working-directory: build + run: | + exceptions_file="${{ github.workspace }}/packaging/linux/flatpak/exceptions.json" + + echo "Linting flatpak manifest" + flatpak run --command=flatpak-builder-lint org.flatpak.Builder \ + --exceptions \ + --user-exceptions "${exceptions_file}" \ + manifest \ + ${APP_ID}.yml + + echo "Linting flatpak repo" + # TODO: add arg + # --mirror-screenshots-url=https://dl.flathub.org/media \ + flatpak run --command=flatpak-builder-lint org.flatpak.Builder \ + --exceptions \ + --user-exceptions "${exceptions_file}" \ + repo \ + repo + + - name: Package Flathub repo archive + # copy files required to generate the Flathub repo + if: matrix.arch == 'x86_64' + run: | + mkdir -p flathub/modules + cp ./build/generated-sources.json ./flathub/ + cp ./build/package-lock.json ./flathub/ + cp ./build/${APP_ID}.yml ./flathub/ + cp ./build/${APP_ID}.metainfo.xml ./flathub/ + cp ./packaging/linux/flatpak/README.md ./flathub/ + cp ./packaging/linux/flatpak/flathub.json ./flathub/ + cp -r ./packaging/linux/flatpak/modules/. ./flathub/modules/ + # submodules will need to be handled in the workflow that creates the PR + + # create the archive + tar -czf ./artifacts/flathub.tar.gz -C ./flathub . + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: build-Linux-Flatpak-${{ matrix.arch }} + path: artifacts/ + if-no-files-found: error diff --git a/.github/workflows/ci-homebrew.yml b/.github/workflows/ci-homebrew.yml new file mode 100644 index 00000000000..4b1cb3c7b61 --- /dev/null +++ b/.github/workflows/ci-homebrew.yml @@ -0,0 +1,239 @@ +--- +name: CI-Homebrew +permissions: + contents: read + +on: + workflow_call: + inputs: + publish_release: + required: true + type: string + release_commit: + required: true + type: string + release_tag: + required: true + type: string + release_version: + required: true + type: string + secrets: + GH_TOKEN: + required: true + GIT_EMAIL: + required: true + GIT_USERNAME: + required: true + +jobs: + build_homebrew: + name: ${{ matrix.os_name }}-${{ matrix.os_version }}${{ matrix.release == true && ' (Release)' || '' }} + runs-on: ${{ matrix.os_name }}-${{ matrix.os_version }} + strategy: + fail-fast: false + matrix: + include: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories + # while GitHub has larger macOS runners, they are not available for our repos :( + - os_version: "13" + os_name: "macos" + - os_version: "14" + os_name: "macos" + - os_version: "15" + os_name: "macos" + - os_version: "latest" + os_name: "ubuntu" + - os_version: "latest" # this job will only configure the formula for release, no validation + os_name: "ubuntu" + release: true + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Fix homebrew python + if: matrix.os_name == 'macos' && matrix.os_version == '13' + run: | + rm '/usr/local/bin/2to3' + rm '/usr/local/bin/2to3-3.12' + rm '/usr/local/bin/idle3' + rm '/usr/local/bin/idle3.12' + rm '/usr/local/bin/idle3.13' + rm '/usr/local/bin/pip3.12' + rm '/usr/local/bin/pip3.13' + rm '/usr/local/bin/pydoc3' + rm '/usr/local/bin/pydoc3.12' + rm '/usr/local/bin/pydoc3.13' + rm '/usr/local/bin/python3' + rm '/usr/local/bin/python3.12' + rm '/usr/local/bin/python3.13' + rm '/usr/local/bin/python3-config' + rm '/usr/local/bin/python3.12-config' + rm '/usr/local/bin/python3.13-config' + brew install python3 + + - name: Configure formula + run: | + # variables for formula + branch="${{ github.head_ref }}" + commit=${{ inputs.release_commit }} + + # check the branch variable + if [ -z "$branch" ] + then + echo "This is a PUSH event" + build_version=${{ inputs.release_tag }} + clone_url=${{ github.event.repository.clone_url }} + branch="${{ github.ref_name }}" + default_branch="${{ github.event.repository.default_branch }}" + + if [ "${{ matrix.release }}" == "true" ]; then + # we will publish the formula with the release tag + tag="${{ inputs.release_tag }}" + version="${{ inputs.release_version }}" + else + tag="${{ github.ref_name }}" + version="0.0.${{ github.run_number }}" + fi + else + echo "This is a PR event" + build_version="0.0.${{ github.event.number }}" + clone_url=${{ github.event.pull_request.head.repo.clone_url }} + branch="${{ github.event.pull_request.head.ref }}" + default_branch="${{ github.event.pull_request.head.repo.default_branch }}" + tag="${{ github.event.pull_request.head.ref }}" + version="0.0.${{ github.event.number }}" + fi + echo "Branch: ${branch}" + echo "Clone URL: ${clone_url}" + echo "Tag: ${tag}" + + mkdir -p build + cmake \ + -B build \ + -S . \ + -DBUILD_VERSION="${build_version}" \ + -DFORMULA_VERSION="${version}" \ + -DGITHUB_BRANCH="${branch}" \ + -DGITHUB_COMMIT="${commit}" \ + -DGITHUB_CLONE_URL="${clone_url}" \ + -DGITHUB_DEFAULT_BRANCH="${default_branch}" \ + -DGITHUB_TAG="${tag}" \ + -DSUNSHINE_CONFIGURE_HOMEBREW=ON \ + -DSUNSHINE_CONFIGURE_ONLY=ON + + # copy formula to artifacts + mkdir -p homebrew + cp -f ./build/sunshine.rb ./homebrew/sunshine.rb + + # testing + cat ./homebrew/sunshine.rb + + - name: Upload Artifacts + if: matrix.release + uses: actions/upload-artifact@v4 + with: + name: build-Homebrew + path: homebrew/ + if-no-files-found: error + + - name: Setup Xvfb + if: matrix.release != true && runner.os == 'Linux' + run: | + sudo apt-get update -y + sudo apt-get install -y \ + xvfb + + export DISPLAY=:1 + Xvfb ${DISPLAY} -screen 0 1024x768x24 & + + echo "DISPLAY=${DISPLAY}" >> $GITHUB_ENV + + - name: Validate Homebrew Formula + id: test + if: matrix.release != true + uses: LizardByte/actions/actions/release_homebrew@v2025.627.30023 + with: + formula_file: ${{ github.workspace }}/homebrew/sunshine.rb + git_email: ${{ secrets.GIT_EMAIL }} + git_username: ${{ secrets.GIT_USERNAME }} + publish: false + token: ${{ secrets.GH_TOKEN }} + validate: true + + - name: Setup python + id: python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Generate gcov report + id: test_report + # any except canceled or skipped + # TODO: fix coverage, no .gcno files are being created + # TODO: .gcno files are supposed to be created next to .o files + if: false + # if: >- + # always() && + # matrix.release != true && + # (steps.test.outcome == 'success' || steps.test.outcome == 'failure') + run: | + cp -rf ${{ steps.test.outputs.buildpath }}/build/ ./build/ + cd build + ls -Ra + + ${{ steps.python.outputs.python-path }} -m pip install gcovr + ${{ steps.python.outputs.python-path }} -m gcovr . -r ../src \ + --exclude-noncode-lines \ + --exclude-throw-branches \ + --exclude-unreachable-branches \ + --verbose \ + --xml-pretty \ + -o coverage.xml + + - name: Upload coverage artifact + if: >- + always() && + matrix.release != true && + (steps.test.outcome == 'success' || steps.test.outcome == 'failure') && + startsWith(github.repository, 'LizardByte/') + uses: actions/upload-artifact@v4 + with: + name: coverage-Homebrew-${{ matrix.os_name }}-${{ matrix.os_version }} + path: | + build/coverage.xml + ${{ steps.test.outputs.testpath }}/test_results.xml + if-no-files-found: error + + - name: Patch homebrew formula + # create beta version of the formula + # don't run this on macOS, as the sed command fails + if: matrix.release + run: | + # variables + formula_file="homebrew/sunshine-beta.rb" + + # rename the file + mv homebrew/sunshine.rb $formula_file + + # update the formula + sed -i 's/class Sunshine < Formula/class SunshineBeta < Formula/' $formula_file + sed -i 's/# conflicts_with/conflicts_with/' $formula_file + + # print new file + echo "New formula:" + cat $formula_file + + - name: Upload Homebrew Beta Formula + if: >- + github.repository_owner == 'LizardByte' && + matrix.release && + inputs.publish_release == 'true' + uses: LizardByte/actions/actions/release_homebrew@v2025.627.30023 + with: + formula_file: ${{ github.workspace }}/homebrew/sunshine-beta.rb + git_email: ${{ secrets.GIT_EMAIL }} + git_username: ${{ secrets.GIT_USERNAME }} + publish: true + token: ${{ secrets.GH_TOKEN }} + validate: false diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml new file mode 100644 index 00000000000..afd163905bd --- /dev/null +++ b/.github/workflows/ci-linux.yml @@ -0,0 +1,216 @@ +--- +name: CI-Linux +permissions: + contents: read + +on: + workflow_call: + inputs: + release_commit: + required: true + type: string + release_tag: + required: true + type: string + +jobs: + build_linux: + name: ${{ matrix.name }} + env: + APP_ID: dev.lizardbyte.app.Sunshine + runs-on: ubuntu-${{ matrix.dist }} + strategy: + fail-fast: false + matrix: + include: + - name: AppImage + EXTRA_ARGS: '--appimage-build' + dist: 22.04 + steps: + - name: Maximize build space + uses: easimon/maximize-build-space@v10 + with: + root-reserve-mb: 30720 + remove-dotnet: 'true' + remove-android: 'true' + remove-haskell: 'true' + remove-codeql: 'true' + remove-docker-images: 'true' + + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Setup Dependencies Linux + timeout-minutes: 5 + run: | + # create the artifacts directory + mkdir -p artifacts + + # allow libfuse2 for appimage on 22.04+ + sudo add-apt-repository universe + + sudo apt-get install -y \ + libdrm-dev \ + libfuse2 \ + libgl-dev \ + libwayland-dev \ + libx11-xcb-dev \ + libxcb-dri3-dev \ + libxfixes-dev + + - name: Setup python + id: python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Build latest libva + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 5 + run: | + gh release download --archive=tar.gz --repo=intel/libva + tar xzf libva-*.tar.gz && rm libva-*.tar.gz + cd libva-* + ./autogen.sh --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu \ + --enable-drm \ + --enable-x11 \ + --enable-glx \ + --enable-wayland \ + --without-legacy # emgd, nvctrl, fglrx + make -j $(nproc) + sudo make install + cd .. && rm -rf libva-* + + - name: Build Linux + env: + BRANCH: ${{ github.head_ref || github.ref_name }} + BUILD_VERSION: ${{ inputs.release_tag }} + COMMIT: ${{ inputs.release_commit }} + run: | + chmod +x ./scripts/linux_build.sh + ./scripts/linux_build.sh \ + --publisher-name='${{ github.repository_owner }}' \ + --publisher-website='https://app.lizardbyte.dev' \ + --publisher-issue-url='https://app.lizardbyte.dev/support' \ + --skip-cleanup \ + --skip-package \ + --ubuntu-test-repo ${{ matrix.EXTRA_ARGS }} + + - name: Set AppImage Version + if: matrix.name == 'AppImage' + run: | + version=${{ inputs.release_tag }} + echo "VERSION=${version}" >> $GITHUB_ENV + + - name: Package Linux - AppImage + if: matrix.name == 'AppImage' + working-directory: build + run: | + # install sunshine to the DESTDIR + DESTDIR=AppDir ninja install + + # custom AppRun file + cp -f ../packaging/linux/AppImage/AppRun ./AppDir/ + chmod +x ./AppDir/AppRun + + # variables + DESKTOP_FILE="${DESKTOP_FILE:-${APP_ID}.desktop}" + ICON_FILE="${ICON_FILE:-sunshine.png}" + + # AppImage + # https://docs.appimage.org/packaging-guide/index.html + wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage + chmod +x linuxdeploy-x86_64.AppImage + + # https://github.com/linuxdeploy/linuxdeploy-plugin-gtk + sudo apt-get install libgtk-3-dev librsvg2-dev -y + wget -q https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh + chmod +x linuxdeploy-plugin-gtk.sh + export DEPLOY_GTK_VERSION=3 + + ./linuxdeploy-x86_64.AppImage \ + --appdir ./AppDir \ + --plugin gtk \ + --executable ./sunshine \ + --icon-file "../$ICON_FILE" \ + --desktop-file "./$DESKTOP_FILE" \ + --output appimage + + # move + mv Sunshine*.AppImage ../artifacts/sunshine.AppImage + + # permissions + chmod +x ../artifacts/sunshine.AppImage + + - name: Delete CUDA + # free up space on the runner + run: | + rm -rf ./build/cuda + + - name: Verify AppImage + if: matrix.name == 'AppImage' + run: | + wget https://github.com/TheAssassin/appimagelint/releases/download/continuous/appimagelint-x86_64.AppImage + chmod +x appimagelint-x86_64.AppImage + + ./appimagelint-x86_64.AppImage ./artifacts/sunshine.AppImage + + - name: Install test deps + run: | + sudo apt-get update -y + sudo apt-get install -y \ + x11-xserver-utils \ + xvfb + + # clean apt cache + sudo apt-get clean + sudo rm -rf /var/lib/apt/lists/* + + - name: Run tests + id: test + working-directory: build/tests + run: | + export DISPLAY=:1 + Xvfb ${DISPLAY} -screen 0 1024x768x24 & + sleep 5 # give Xvfb time to start + + ./test_sunshine --gtest_color=yes --gtest_output=xml:test_results.xml + + - name: Generate gcov report + id: test_report + # any except canceled or skipped + if: >- + always() && + (steps.test.outcome == 'success' || steps.test.outcome == 'failure') + working-directory: build + run: | + ${{ steps.python.outputs.python-path }} -m pip install gcovr + ${{ steps.python.outputs.python-path }} -m gcovr . -r ../src \ + --exclude-noncode-lines \ + --exclude-throw-branches \ + --exclude-unreachable-branches \ + --verbose \ + --xml-pretty \ + -o coverage.xml + + - name: Upload coverage artifact + if: >- + always() && + (steps.test_report.outcome == 'success') + uses: actions/upload-artifact@v4 + with: + name: coverage-Linux-${{ matrix.name }} + path: | + build/coverage.xml + build/tests/test_results.xml + if-no-files-found: error + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: build-Linux-${{ matrix.name }} + path: artifacts/ + if-no-files-found: error diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml new file mode 100644 index 00000000000..23b8a588a3f --- /dev/null +++ b/.github/workflows/ci-windows.yml @@ -0,0 +1,345 @@ +--- +name: CI-Windows +permissions: + contents: read + +on: + workflow_call: + inputs: + release_commit: + required: true + type: string + release_tag: + required: true + type: string + secrets: + CODECOV_TOKEN: + required: false + +jobs: + build_windows: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + defaults: + run: + shell: msys2 {0} + strategy: + fail-fast: false + matrix: + include: + - name: Windows-AMD64 + os: windows-2022 + arch: x86_64 + msystem: ucrt64 + toolchain: ucrt-x86_64 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Prepare tests + id: prepare-tests + if: false # todo: DirectX11 is not available, so even software encoder fails + shell: pwsh + run: | + # function to download and extract a zip file + function DownloadAndExtract { + param ( + [string]$Uri, + [string]$OutFile + ) + + $maxRetries = 5 + $retryCount = 0 + $success = $false + + while (-not $success -and $retryCount -lt $maxRetries) { + $retryCount++ + Write-Host "Downloading $Uri to $OutFile, attempt $retryCount of $maxRetries" + try { + Invoke-WebRequest -Uri $Uri -OutFile $OutFile + $success = $true + } catch { + Write-Host "Attempt $retryCount of $maxRetries failed with error: $($_.Exception.Message). Retrying..." + Start-Sleep -Seconds 5 + } + } + + if (-not $success) { + Write-Host "Failed to download the file after $maxRetries attempts." + exit 1 + } + + # use .NET to get the base name of the file + $baseName = (Get-Item $OutFile).BaseName + + # Extract the zip file + Expand-Archive -Path $OutFile -DestinationPath $baseName + } + + # virtual display driver + DownloadAndExtract ` + -Uri "https://www.amyuni.com/downloads/usbmmidd_v2.zip" ` + -OutFile "usbmmidd_v2.zip" + + # install + Set-Location -Path usbmmidd_v2/usbmmidd_v2 + ./deviceinstaller64 install usbmmidd.inf usbmmidd + + # create the virtual display + ./deviceinstaller64 enableidd 1 + + # move up a directory + Set-Location -Path ../.. + + # install devcon + DownloadAndExtract ` + -Uri "https://github.com/Drawbackz/DevCon-Installer/releases/download/1.4-rc/Devcon.Installer.zip" ` + -OutFile "Devcon.Installer.zip" + Set-Location -Path Devcon.Installer + # hash needs to match OS version + # https://github.com/Drawbackz/DevCon-Installer/blob/master/devcon_sources.json + Start-Process -FilePath "./Devcon Installer.exe" -Wait -ArgumentList ` + 'install', ` + '-hash', '54004C83EE34F6A55380528A8B29F4C400E61FBB947A19E0AB9E5A193D7D961E', ` + '-addpath', ` + '-update', ` + '-dir', 'C:\Windows\System32' + + # disable Hyper-V Video + # https://stackoverflow.com/a/59490940 + C:\Windows\System32\devcon.exe disable "VMBUS\{da0a7802-e377-4aac-8e77-0558eb1073f8}" + + # move up a directory + Set-Location -Path .. + + # multi monitor tool + DownloadAndExtract ` + -Uri "http://www.nirsoft.net/utils/multimonitortool-x64.zip" ` + -OutFile "multimonitortool.zip" + + # enable the virtual display + # http://www.nirsoft.net/utils/multi_monitor_tool.html + Set-Location -Path multimonitortool + + # Original Hyper-V is \\.\DISPLAY1, it will recreate itself as \\.\DISPLAY6 (or something higher than 2) + # USB Mobile Monitor Virtual Display is \\.\DISPLAY2 + + # these don't seem to work if not using runAs + # todo: do they work if not using runAs? + Start-Process powershell -Verb runAs -ArgumentList '-Command ./MultiMonitorTool.exe /enable \\.\DISPLAY2' + Start-Process powershell -Verb runAs -ArgumentList '-Command ./MultiMonitorTool.exe /SetPrimary \\.\DISPLAY2' + + # wait a few seconds + Start-Sleep -s 5 + + # list monitors + ./MultiMonitorTool.exe /stext monitor_list.txt + + # wait a few seconds + Start-Sleep -s 5 + + # print the monitor list + Get-Content -Path monitor_list.txt + + - name: Setup Dependencies Windows + # if a dependency needs to be pinned, see https://github.com/LizardByte/build-deps/pull/186 + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ matrix.msystem }} + update: true + install: >- + wget + + - name: Update Windows dependencies + env: + MSYSTEM: ${{ matrix.msystem }} + TOOLCHAIN: ${{ matrix.toolchain }} + shell: msys2 {0} + run: | + # variables + declare -A pinned_deps + + # dependencies + dependencies=( + "git" + "mingw-w64-${TOOLCHAIN}-cmake" + "mingw-w64-${TOOLCHAIN}-cppwinrt" + "mingw-w64-${TOOLCHAIN}-curl-winssl" + "mingw-w64-${TOOLCHAIN}-gcc" + "mingw-w64-${TOOLCHAIN}-graphviz" + "mingw-w64-${TOOLCHAIN}-MinHook" + "mingw-w64-${TOOLCHAIN}-miniupnpc" + "mingw-w64-${TOOLCHAIN}-nlohmann-json" + "mingw-w64-${TOOLCHAIN}-nodejs" + "mingw-w64-${TOOLCHAIN}-nsis" + "mingw-w64-${TOOLCHAIN}-onevpl" + "mingw-w64-${TOOLCHAIN}-openssl" + "mingw-w64-${TOOLCHAIN}-opus" + "mingw-w64-${TOOLCHAIN}-toolchain" + ) + + # do not modify below this line + + ignore_packages=() + tarballs="" + for pkg in "${!pinned_deps[@]}"; do + ignore_packages+=("${pkg}") + version="${pinned_deps[$pkg]}" + tarball="${pkg}-${version}-any.pkg.tar.zst" + + # download working version + wget "https://repo.msys2.org/mingw/${MSYSTEM}/${tarball}" + + tarballs="${tarballs} ${tarball}" + done + + # Create the ignore string for pacman + ignore_list=$(IFS=,; echo "${ignore_packages[*]}") + + # install pinned dependencies + if [ -n "$tarballs" ]; then + pacman -U --noconfirm ${tarballs} + fi + + # Only add --ignore if we have packages to ignore + if [ -n "$ignore_list" ]; then + pacman -Syu --noconfirm --ignore="${ignore_list}" "${dependencies[@]}" + else + pacman -Syu --noconfirm "${dependencies[@]}" + fi + + - name: Install Doxygen + # GCC compiled doxygen has issues when running graphviz + env: + DOXYGEN_VERSION: "1.11.0" + shell: pwsh + run: | + # Set version variables + $doxy_ver = $env:DOXYGEN_VERSION + $_doxy_ver = $doxy_ver.Replace(".", "_") + + # Download the Doxygen installer + Invoke-WebRequest -Uri ` + "https://github.com/doxygen/doxygen/releases/download/Release_${_doxy_ver}/doxygen-${doxy_ver}-setup.exe" ` + -OutFile "doxygen-setup.exe" + + # Run the installer + Start-Process ` + -FilePath .\doxygen-setup.exe ` + -ArgumentList ` + '/VERYSILENT' ` + -Wait ` + -NoNewWindow + + # Clean up + Remove-Item -Path doxygen-setup.exe + + - name: Setup python + id: setup-python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Python Path + id: python-path + shell: msys2 {0} + run: | + # replace backslashes with double backslashes + python_path=$(echo "${{ steps.setup-python.outputs.python-path }}" | sed 's/\\/\\\\/g') + + # step output + echo "python-path=${python_path}" + echo "python-path=${python_path}" >> $GITHUB_OUTPUT + + - name: Build Windows + shell: msys2 {0} + env: + BRANCH: ${{ github.head_ref || github.ref_name }} + BUILD_VERSION: ${{ inputs.release_tag }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + COMMIT: ${{ inputs.release_commit }} + run: | + mkdir -p build + cmake \ + -B build \ + -G Ninja \ + -S . \ + -DBUILD_WERROR=ON \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DSUNSHINE_ASSETS_DIR=assets \ + -DSUNSHINE_PUBLISHER_NAME='${{ github.repository_owner }}' \ + -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' \ + -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support' + ninja -C build + + - name: Package Windows + shell: msys2 {0} + run: | + mkdir -p artifacts + cd build + + # package + cpack -G NSIS + cpack -G ZIP + + # move + mv ./cpack_artifacts/Sunshine.exe ../artifacts/Sunshine-${{ matrix.name }}-installer.exe + mv ./cpack_artifacts/Sunshine.zip ../artifacts/Sunshine-${{ matrix.name }}-portable.zip + + - name: Run tests + id: test + shell: msys2 {0} + working-directory: build/tests + run: | + ./test_sunshine.exe --gtest_color=yes --gtest_output=xml:test_results.xml + + - name: Generate gcov report + id: test_report + # any except canceled or skipped + if: always() && (steps.test.outcome == 'success' || steps.test.outcome == 'failure') + shell: msys2 {0} + working-directory: build + run: | + ${{ steps.python-path.outputs.python-path }} -m pip install gcovr + ${{ steps.python-path.outputs.python-path }} -m gcovr . -r ../src \ + --exclude-noncode-lines \ + --exclude-throw-branches \ + --exclude-unreachable-branches \ + --verbose \ + --xml-pretty \ + -o coverage.xml + + - name: Upload coverage artifact + if: >- + always() && + (steps.test_report.outcome == 'success') + uses: actions/upload-artifact@v4 + with: + name: coverage-${{ matrix.name }} + path: | + build/coverage.xml + build/tests/test_results.xml + if-no-files-found: error + + - name: Package Windows Debug Info + shell: pwsh + working-directory: build + run: | + # use .dbg file extension for binaries to avoid confusion with real packages + Get-ChildItem -File -Recurse | ` + % { Rename-Item -Path $_.PSPath -NewName $_.Name.Replace(".exe",".dbg") } + + # save the binaries with debug info + 7z -r ` + "-xr!CMakeFiles" ` + "-xr!cpack_artifacts" ` + a "../artifacts/Sunshine-${{ matrix.name }}-debuginfo.7z" "*.dbg" + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: build-${{ matrix.name }} + path: artifacts/ + if-no-files-found: error diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000000..577c6b618b9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,202 @@ +--- +name: CI +permissions: + contents: read + +on: + pull_request: + branches: + - master + types: + - opened + - synchronize + - reopened + push: + branches: + - master + workflow_dispatch: + +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + +jobs: + github-env: + name: GitHub Env Debug + uses: LizardByte/.github/.github/workflows/__call-github-env.yml@master + + release-setup: + name: Release Setup + outputs: + publish_release: ${{ steps.release-setup.outputs.publish_release }} + release_body: ${{ steps.release-setup.outputs.release_body }} + release_commit: ${{ steps.release-setup.outputs.release_commit }} + release_generate_release_notes: ${{ steps.release-setup.outputs.release_generate_release_notes }} + release_tag: ${{ steps.release-setup.outputs.release_tag }} + release_version: ${{ steps.release-setup.outputs.release_version }} + permissions: + contents: write + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Release Setup + id: release-setup + uses: LizardByte/actions/actions/release_setup@v2025.627.30023 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + + build-docker: + name: Docker + needs: release-setup + permissions: + contents: read + packages: write + uses: LizardByte/.github/.github/workflows/__call-docker.yml@master + with: + maximize_build_space: true + publish_release: ${{ needs.release-setup.outputs.publish_release }} + release_commit: ${{ needs.release-setup.outputs.release_commit }} + release_tag: ${{ needs.release-setup.outputs.release_tag }} + secrets: + DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} + DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }} + DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + GH_BOT_NAME: ${{ secrets.GH_BOT_NAME }} + GH_BOT_TOKEN: ${{ secrets.GH_BOT_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build_homebrew: + name: Homebrew + needs: release-setup + uses: ./.github/workflows/ci-homebrew.yml + with: + publish_release: ${{ needs.release-setup.outputs.publish_release }} + release_commit: ${{ needs.release-setup.outputs.release_commit }} + release_tag: ${{ needs.release-setup.outputs.release_tag }} + release_version: ${{ needs.release-setup.outputs.release_version }} + secrets: + GH_TOKEN: ${{ secrets.GH_BOT_TOKEN }} + GIT_EMAIL: ${{ secrets.GH_BOT_EMAIL }} + GIT_USERNAME: ${{ secrets.GH_BOT_NAME }} + + build_linux_flatpak: + name: Linux Flatpak + needs: release-setup + uses: ./.github/workflows/ci-flatpak.yml + with: + release_commit: ${{ needs.release-setup.outputs.release_commit }} + release_tag: ${{ needs.release-setup.outputs.release_tag }} + + build_linux: + name: Linux + needs: release-setup + uses: ./.github/workflows/ci-linux.yml + with: + release_commit: ${{ needs.release-setup.outputs.release_commit }} + release_tag: ${{ needs.release-setup.outputs.release_tag }} + + build_windows: + name: Windows + needs: release-setup + uses: ./.github/workflows/ci-windows.yml + with: + release_commit: ${{ needs.release-setup.outputs.release_commit }} + release_tag: ${{ needs.release-setup.outputs.release_tag }} + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + coverage: + name: Coverage-${{ matrix.name }} + if: >- + always() && + !cancelled() && + startsWith(github.repository, 'LizardByte/') + needs: + - build_linux + - build_linux_flatpak + - build_homebrew + - build_windows + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - name: Linux-AppImage + coverage: true + - name: Homebrew-macos-13 + coverage: false + - name: Homebrew-macos-14 + coverage: false + - name: Homebrew-macos-15 + coverage: false + - name: Homebrew-ubuntu-latest + coverage: false + - name: Windows-AMD64 + coverage: true + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download coverage artifact + uses: actions/download-artifact@v4 + with: + name: coverage-${{ matrix.name }} + path: _coverage + + - name: Upload test results + uses: codecov/test-results-action@v1 + with: + disable_search: true + fail_ci_if_error: true + files: ./_coverage/tests/test_results.xml + flags: ${{ matrix.name }} + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + + - name: Upload coverage + uses: codecov/codecov-action@v5 + if: matrix.coverage != false + with: + disable_search: true + fail_ci_if_error: true + files: ./_coverage/coverage.xml + flags: ${{ matrix.name }} + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + + release: + name: Release + if: + needs.release-setup.outputs.publish_release == 'true' && + startsWith(github.repository, 'LizardByte/') + needs: + - release-setup + - build-docker + - build_linux + - build_linux_flatpak + - build_homebrew + - build_windows + runs-on: ubuntu-latest + steps: + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + pattern: build-* + merge-multiple: true + + - name: Debug artifacts + run: ls -l artifacts + + - name: Create/Update GitHub Release + uses: LizardByte/actions/actions/release_create@v2025.627.30023 + with: + allowUpdates: false + body: ${{ needs.release-setup.outputs.release_body }} + generateReleaseNotes: ${{ needs.release-setup.outputs.release_generate_release_notes }} + name: ${{ needs.release-setup.outputs.release_tag }} + prerelease: true + tag: ${{ needs.release-setup.outputs.release_tag }} + token: ${{ secrets.GH_BOT_TOKEN }} diff --git a/docker/archlinux.dockerfile b/docker/archlinux.dockerfile index f628ac075ab..3a55dbbe84f 100644 --- a/docker/archlinux.dockerfile +++ b/docker/archlinux.dockerfile @@ -114,14 +114,13 @@ rm -f /build/sunshine/pkg/sunshine-debug*.pkg.tar.zst ls -a _PKGBUILD -FROM scratch AS artifacts +FROM sunshine-base AS sunshine COPY --link --from=sunshine-build /build/sunshine/pkg/sunshine*.pkg.tar.zst /sunshine.pkg.tar.zst -COPY --link --from=sunshine-build /build/sunshine/sunshine.pkg.tar.gz /sunshine.pkg.tar.gz - -FROM sunshine-base AS sunshine -COPY --link --from=artifacts /sunshine.pkg.tar.zst / +# artifacts to be extracted in CI +COPY --link --from=sunshine-build /build/sunshine/pkg/sunshine*.pkg.tar.zst /artifacts/sunshine.pkg.tar.zst +COPY --link --from=sunshine-build /build/sunshine/sunshine.pkg.tar.gz /artifacts/sunshine.pkg.tar.gz # install sunshine RUN <<_INSTALL_SUNSHINE diff --git a/docker/debian-bookworm.dockerfile b/docker/debian-bookworm.dockerfile index 84edc4c909f..f88cea0534c 100644 --- a/docker/debian-bookworm.dockerfile +++ b/docker/debian-bookworm.dockerfile @@ -51,16 +51,17 @@ Xvfb ${DISPLAY} -screen 0 1024x768x24 & ./test_sunshine --gtest_color=yes _TEST -FROM scratch AS artifacts +FROM sunshine-base AS sunshine + ARG BASE ARG TAG ARG TARGETARCH -COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb -FROM sunshine-base AS sunshine +# artifacts to be extracted in CI +COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /artifacts/sunshine-${BASE}-${TAG}-${TARGETARCH}.deb # copy deb from builder -COPY --link --from=artifacts /sunshine*.deb /sunshine.deb +COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine.deb # install sunshine RUN <<_INSTALL_SUNSHINE diff --git a/docker/ubuntu-22.04.dockerfile b/docker/ubuntu-22.04.dockerfile index 24ceda2be25..7bb24eb8bb7 100644 --- a/docker/ubuntu-22.04.dockerfile +++ b/docker/ubuntu-22.04.dockerfile @@ -51,16 +51,17 @@ Xvfb ${DISPLAY} -screen 0 1024x768x24 & ./test_sunshine --gtest_color=yes _TEST -FROM scratch AS artifacts +FROM sunshine-base AS sunshine + ARG BASE ARG TAG ARG TARGETARCH -COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb -FROM sunshine-base AS sunshine +# artifacts to be extracted in CI +COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /artifacts/sunshine-${BASE}-${TAG}-${TARGETARCH}.deb # copy deb from builder -COPY --link --from=artifacts /sunshine*.deb /sunshine.deb +COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine.deb # install sunshine RUN <<_INSTALL_SUNSHINE diff --git a/docker/ubuntu-24.04.dockerfile b/docker/ubuntu-24.04.dockerfile index 1b7c0d6edc2..984cfdcb157 100644 --- a/docker/ubuntu-24.04.dockerfile +++ b/docker/ubuntu-24.04.dockerfile @@ -51,16 +51,17 @@ Xvfb ${DISPLAY} -screen 0 1024x768x24 & ./test_sunshine --gtest_color=yes _TEST -FROM scratch AS artifacts +FROM sunshine-base AS sunshine + ARG BASE ARG TAG ARG TARGETARCH -COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine-${BASE}-${TAG}-${TARGETARCH}.deb -FROM sunshine-base AS sunshine +# artifacts to be extracted in CI +COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /artifacts/sunshine-${BASE}-${TAG}-${TARGETARCH}.deb # copy deb from builder -COPY --link --from=artifacts /sunshine*.deb /sunshine.deb +COPY --link --from=sunshine-build /build/sunshine/build/cpack_artifacts/Sunshine.deb /sunshine.deb # install sunshine RUN <<_INSTALL_SUNSHINE diff --git a/docs/getting_started.md b/docs/getting_started.md index 299a733788c..f30362390c5 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -284,7 +284,7 @@ brew uninstall sunshine #### Installer (recommended) 1. Download and install - [sunshine-windows-installer.exe](https://github.com/LizardByte/Sunshine/releases/latest/download/sunshine-windows-installer.exe) + [Sunshine-Windows-AMD64-installer.exe](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-Windows-AMD64-installer.exe) @attention{You should carefully select or unselect the options you want to install. Do not blindly install or enable features.} @@ -298,7 +298,7 @@ overflow menu. Different versions of Windows may provide slightly different step recommended for most users. No support will be provided!} 1. Download and extract - [sunshine-windows-portable.zip](https://github.com/LizardByte/Sunshine/releases/latest/download/sunshine-windows-portable.zip) + [Sunshine-Windows-AMD64-portable.zip](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-Windows-AMD64-portable.zip) 2. Open command prompt as administrator 3. Firewall rules