From 60f5b10cee0cf0f72e2a897d4f0770363911c9a0 Mon Sep 17 00:00:00 2001 From: LizardByte-bot <108553330+LizardByte-bot@users.noreply.github.com> Date: Sat, 21 Sep 2024 00:50:31 -0400 Subject: [PATCH 01/18] chore: update global workflows (#3210) --- .github/dependabot.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b736c94c..75b9d1db 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -18,6 +18,20 @@ updates: interval: "daily" time: "08:30" open-pull-requests-limit: 10 + groups: + docker-actions: + applies-to: version-updates + patterns: + - "docker/*" + github-actions: + applies-to: version-updates + patterns: + - "actions/*" + - "github/*" + lizardbyte-actions: + applies-to: version-updates + patterns: + - "LizardByte/*" - package-ecosystem: "npm" directory: "/" @@ -25,6 +39,10 @@ updates: interval: "daily" time: "09:00" open-pull-requests-limit: 10 + groups: + dev-dependencies: + applies-to: version-updates + dependency-type: "development" - package-ecosystem: "nuget" directory: "/" @@ -39,6 +57,11 @@ updates: interval: "daily" time: "10:00" open-pull-requests-limit: 10 + groups: + pytest-dependencies: + applies-to: version-updates + patterns: + - "pytest*" - package-ecosystem: "gitsubmodule" directory: "/" From 68eb8d2fbb04b35c3cbe522a14649c2b29d84289 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sat, 21 Sep 2024 21:03:53 -0400 Subject: [PATCH 02/18] ci(l10n): fix pr title for babel updates (#3216) --- .github/workflows/localize.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/localize.yml b/.github/workflows/localize.yml index a0c3738e..f31a3aa5 100644 --- a/.github/workflows/localize.yml +++ b/.github/workflows/localize.yml @@ -82,11 +82,11 @@ jobs: add-paths: | locale/*.po token: ${{ secrets.GH_BOT_TOKEN }} # must trigger PR tests - commit-message: New localization template + commit-message: "chore(l10n): new babel updates" branch: localize/update delete-branch: true base: master - title: New Babel Updates + title: "chore(l10n): new babel updates" body: | Update report - Updated ${{ steps.date.outputs.date }} From e10b24ae3f1a622e758138a05315f069ba3f07ef Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Fri, 27 Sep 2024 22:38:59 -0400 Subject: [PATCH 03/18] ci(windows): use boost from source (#3231) --- .codeql-prebuild-cpp-Windows.sh | 1 - .github/workflows/CI.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.codeql-prebuild-cpp-Windows.sh b/.codeql-prebuild-cpp-Windows.sh index 0ada468e..31ee6cd9 100644 --- a/.codeql-prebuild-cpp-Windows.sh +++ b/.codeql-prebuild-cpp-Windows.sh @@ -19,7 +19,6 @@ pacman -Syu --noconfirm --ignore=mingw-w64-ucrt-x86_64-curl \ gcc \ git \ make \ - mingw-w64-ucrt-x86_64-boost \ mingw-w64-ucrt-x86_64-cmake \ mingw-w64-ucrt-x86_64-cppwinrt \ mingw-w64-ucrt-x86_64-graphviz \ diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c022d193..9dae2525 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1033,7 +1033,6 @@ jobs: pacman -Syu --noconfirm \ --ignore=mingw-w64-ucrt-x86_64-curl \ git \ - mingw-w64-ucrt-x86_64-boost \ mingw-w64-ucrt-x86_64-cmake \ mingw-w64-ucrt-x86_64-cppwinrt \ mingw-w64-ucrt-x86_64-graphviz \ @@ -1144,6 +1143,7 @@ jobs: --exclude-unreachable-branches \ --exclude '.*tests/.*' \ --exclude '.*third-party/.*' \ + --exclude '.*_deps/.*' \ --xml-pretty \ -o coverage.xml From e03c5980944a70edd6e9d40d86de326cd1b892ec Mon Sep 17 00:00:00 2001 From: LizardByte-bot <108553330+LizardByte-bot@users.noreply.github.com> Date: Fri, 27 Sep 2024 23:49:47 -0400 Subject: [PATCH 04/18] chore: update global workflows (#3228) --- .github/ISSUE_TEMPLATE/config.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..e9faf5e9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,13 @@ +--- +# This file is centrally managed in https://github.com//.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. + +blank_issues_enabled: false +contact_links: + - name: Support Center + url: https://app.lizardbyte.dev/support + about: Official LizardByte support + - name: Discussions + url: https://github.com/orgs/LizardByte/discussions + about: Community discussions, questions, and feature requests From 1071f132595136d6e4cece4eb985931180f43a90 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sat, 28 Sep 2024 00:56:39 -0400 Subject: [PATCH 05/18] test(coverage): ignore _deps directory (#3233) --- .github/workflows/CI.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 9dae2525..aa07292a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -430,6 +430,7 @@ jobs: --exclude-noncode-lines \ --exclude-throw-branches \ --exclude-unreachable-branches \ + --exclude '.*_deps/.*' \ --exclude '.*tests/.*' \ --exclude '.*third-party/.*' \ --xml-pretty \ @@ -865,6 +866,7 @@ jobs: --exclude-noncode-lines \ --exclude-throw-branches \ --exclude-unreachable-branches \ + --exclude '.*${dir}/_deps/.*' \ --exclude '.*${dir}/tests/.*' \ --exclude '.*${dir}/third-party/.*' \ --gcov-object-directory $(pwd) \ @@ -1141,9 +1143,9 @@ jobs: --exclude-noncode-lines \ --exclude-throw-branches \ --exclude-unreachable-branches \ + --exclude '.*_deps/.*' \ --exclude '.*tests/.*' \ --exclude '.*third-party/.*' \ - --exclude '.*_deps/.*' \ --xml-pretty \ -o coverage.xml From b01ba38774501b2233ac48812401e73e0172fa54 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sat, 28 Sep 2024 15:02:34 -0400 Subject: [PATCH 06/18] build(script): fix missing sudo for dnf group install (#3227) --- scripts/linux_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/linux_build.sh b/scripts/linux_build.sh index f0cd3d7f..fc423a2d 100644 --- a/scripts/linux_build.sh +++ b/scripts/linux_build.sh @@ -304,7 +304,7 @@ function run_install() { add_ubuntu_deps elif [ "$distro" == "fedora" ]; then add_fedora_deps - dnf group install "Development Tools" -y + ${sudo_cmd} dnf group install "Development Tools" -y fi # Install the dependencies From ec506bbb2f63b481a7ae3d766a946a5e7ef20d23 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sat, 28 Sep 2024 23:36:03 -0400 Subject: [PATCH 07/18] fix(web-ui): broken url (#3238) --- src_assets/common/assets/web/ResourceCard.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_assets/common/assets/web/ResourceCard.vue b/src_assets/common/assets/web/ResourceCard.vue index aee83768..43dc3479 100644 --- a/src_assets/common/assets/web/ResourceCard.vue +++ b/src_assets/common/assets/web/ResourceCard.vue @@ -9,7 +9,7 @@ {{ $t('resource_card.lizardbyte_website') }} Discord - + {{ $t('resource_card.github_discussions') }} From 5bc32cdeb355d16e871dc47ef6048c644831475f Mon Sep 17 00:00:00 2001 From: BayLee4 <63376748+BayLee4@users.noreply.github.com> Date: Sun, 29 Sep 2024 17:59:20 +0200 Subject: [PATCH 08/18] fix(macos): Touch input broken (#3240) --- src/platform/macos/input.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platform/macos/input.cpp b/src/platform/macos/input.cpp index 83c668eb..6be72233 100644 --- a/src/platform/macos/input.cpp +++ b/src/platform/macos/input.cpp @@ -362,6 +362,9 @@ const KeyCodeMap kKeyCodesMap[] = { CGEventSetDoubleValueField(event, kCGMouseEventDeltaY, deltaY); CGEventPost(kCGHIDEventTap, event); + // For why this is here, see: + // https://stackoverflow.com/questions/15194409/simulated-mouseevent-not-working-properly-osx + CGWarpMouseCursorPosition(location); } inline CGEventType From fceda35d443f7b90236c2ede14fac1d8f000885b Mon Sep 17 00:00:00 2001 From: Chase Payne Date: Sun, 29 Sep 2024 15:32:34 -0500 Subject: [PATCH 09/18] fix: automatic selection for hybrid GPU and IDDSampleDriver users (#3002) * Fix frame capture and output duplication for dual GPU setups and virtual displays - Added `test_frame_capture` function to verify if frames are successfully captured and not empty. - Fixes issues with virtual displays such as IDDSampleDriver when using more than one GPU. Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Co-authored-by: Cameron Gutman --- src/platform/windows/display_base.cpp | 98 +++++++++------ tools/ddprobe.cpp | 175 ++++++++++++++++++++++++-- 2 files changed, 222 insertions(+), 51 deletions(-) diff --git a/src/platform/windows/display_base.cpp b/src/platform/windows/display_base.cpp index 3d178daf..7058b77b 100644 --- a/src/platform/windows/display_base.cpp +++ b/src/platform/windows/display_base.cpp @@ -6,6 +6,7 @@ #include #include +#include #include // We have to include boost/process.hpp before display.h due to WinSock.h, @@ -351,6 +352,52 @@ namespace platf::dxgi { return true; } + bool + validate_and_test_gpu_preference(const std::string &display_name, bool verify_frame_capture) { + std::string cmd = "tools\\ddprobe.exe"; + + // We start at 1 because 0 is automatic selection which can be overridden by + // the GPU driver control panel options. Since ddprobe.exe can have different + // GPU driver overrides than Sunshine.exe, we want to avoid a scenario where + // autoselection might work for ddprobe.exe but not for us. + for (int i = 1; i < 5; i++) { + // Run the probe tool. It returns the status of DuplicateOutput(). + // + // Arg format: [GPU preference] [Display name] [--verify-frame-capture] + HRESULT result; + std::vector args = { std::to_string(i), display_name }; + try { + if (verify_frame_capture) { + args.emplace_back("--verify-frame-capture"); + } + result = bp::system(cmd, bp::args(args), bp::std_out > bp::null, bp::std_err > bp::null); + } + catch (bp::process_error &e) { + BOOST_LOG(error) << "Failed to start ddprobe.exe: "sv << e.what(); + return false; + } + + BOOST_LOG(info) << "ddprobe.exe " << boost::algorithm::join(args, " ") << " returned 0x" + << util::hex(result).to_string_view(); + + // E_ACCESSDENIED can happen at the login screen. If we get this error, + // we know capture would have been supported, because DXGI_ERROR_UNSUPPORTED + // would have been raised first if it wasn't. + if (result == S_OK || result == E_ACCESSDENIED) { + // We found a working GPU preference, so set ourselves to use that. + if (set_gpu_preference_on_self(i)) { + return true; + } + else { + return false; + } + } + } + + // If no valid configuration was found, return false + return false; + } + // On hybrid graphics systems, Windows will change the order of GPUs reported by // DXGI in accordance with the user's GPU preference. If the selected GPU is a // render-only device with no displays, DXGI will add virtual outputs to the @@ -363,53 +410,24 @@ namespace platf::dxgi { // we spawn a helper tool to probe for us before we set our own GPU preference. bool probe_for_gpu_preference(const std::string &display_name) { - // If we've already been through here, there's nothing to do this time. static bool set_gpu_preference = false; + + // If we've already been through here, there's nothing to do this time. if (set_gpu_preference) { return true; } - std::string cmd = "tools\\ddprobe.exe"; - - // We start at 1 because 0 is automatic selection which can be overridden by - // the GPU driver control panel options. Since ddprobe.exe can have different - // GPU driver overrides than Sunshine.exe, we want to avoid a scenario where - // autoselection might work for ddprobe.exe but not for us. - for (int i = 1; i < 5; i++) { - // Run the probe tool. It returns the status of DuplicateOutput(). - // - // Arg format: [GPU preference] [Display name] - HRESULT result; - try { - result = bp::system(cmd, std::to_string(i), display_name, bp::std_out > bp::null, bp::std_err > bp::null); - } - catch (bp::process_error &e) { - BOOST_LOG(error) << "Failed to start ddprobe.exe: "sv << e.what(); - return false; - } - - BOOST_LOG(info) << "ddprobe.exe ["sv << i << "] ["sv << display_name << "] returned: 0x"sv << util::hex(result).to_string_view(); - - // E_ACCESSDENIED can happen at the login screen. If we get this error, - // we know capture would have been supported, because DXGI_ERROR_UNSUPPORTED - // would have been raised first if it wasn't. - if (result == S_OK || result == E_ACCESSDENIED) { - // We found a working GPU preference, so set ourselves to use that. - if (set_gpu_preference_on_self(i)) { - set_gpu_preference = true; - return true; - } - else { - return false; - } - } - else { - // This configuration didn't work, so continue testing others - continue; - } + // Try probing with different GPU preferences and verify_frame_capture flag + if (validate_and_test_gpu_preference(display_name, true)) { + return true; } - // If none of the manual options worked, leave the GPU preference alone + // If no valid configuration was found, try again with verify_frame_capture == false + if (validate_and_test_gpu_preference(display_name, false)) { + return true; + } + + // If neither worked, return false return false; } diff --git a/tools/ddprobe.cpp b/tools/ddprobe.cpp index a30b2f41..3c2eb057 100644 --- a/tools/ddprobe.cpp +++ b/tools/ddprobe.cpp @@ -9,9 +9,11 @@ #include #include #include +#include #include "src/utility.h" +using Microsoft::WRL::ComPtr; using namespace std::literals; namespace dxgi { template @@ -69,8 +71,128 @@ syncThreadDesktop() { CloseDesktop(hDesk); } +/** + * @brief Determines if a given frame is valid by checking if it contains any non-dark pixels. + * + * This function analyzes the provided frame to determine if it contains any pixels that exceed a specified darkness threshold. + * It iterates over all pixels in the frame, comparing each pixel's RGB values to the defined darkness threshold. + * If any pixel's RGB values exceed this threshold, the function concludes that the frame is valid (i.e., not entirely dark) and returns `true`. + * If all pixels are below or equal to the threshold, indicating a completely dark frame, the function returns `false`. + + * @param mappedResource A reference to a `D3D11_MAPPED_SUBRESOURCE` structure containing the mapped subresource data of the frame to be analyzed. + * @param frameDesc A reference to a `D3D11_TEXTURE2D_DESC` structure describing the texture properties, including width and height. + * @param darknessThreshold A floating-point value representing the threshold above which a pixel's RGB values are considered dark. The value ranges from 0.0f to 1.0f, with a default value of 0.1f. + * @return Returns `true` if the frame contains any non-dark pixels, indicating it is valid; otherwise, returns `false`. + */ +bool +is_valid_frame(const D3D11_MAPPED_SUBRESOURCE &mappedResource, const D3D11_TEXTURE2D_DESC &frameDesc, float darknessThreshold = 0.1f) { + const auto *pixels = static_cast(mappedResource.pData); + const int bytesPerPixel = 4; // (8 bits per channel, excluding alpha). Factoring HDR is not needed because it doesn't cause black levels to raise enough to be a concern. + const int stride = mappedResource.RowPitch; + const int width = frameDesc.Width; + const int height = frameDesc.Height; + + // Convert the darkness threshold to an integer value for comparison + const auto threshold = static_cast(darknessThreshold * 255); + + // Iterate over each pixel in the frame + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + const uint8_t *pixel = pixels + y * stride + x * bytesPerPixel; + // Check if any RGB channel exceeds the darkness threshold + if (pixel[0] > threshold || pixel[1] > threshold || pixel[2] > threshold) { + // Frame is not dark + return true; + } + } + } + // Frame is entirely dark + return false; +} + +/** + * @brief Captures and verifies the contents of up to 10 consecutive frames from a DXGI output duplication. + * + * This function attempts to acquire and analyze up to 10 frames from a DXGI output duplication object (`dup`). + * It checks if each frame is non-empty (not entirely dark) by using the `is_valid_frame` function. + * If any non-empty frame is found, the function returns `S_OK`. + * If all 10 frames are empty, it returns `E_FAIL`, suggesting potential issues with the capture process. + * If any error occurs during the frame acquisition or analysis process, the corresponding `HRESULT` error code is returned. + * + * @param dup A reference to the DXGI output duplication object (`dxgi::dup_t&`) used to acquire frames. + * @param device A ComPtr to the ID3D11Device interface representing the device associated with the Direct3D context. + * @return Returns `S_OK` if a non-empty frame is captured successfully, `E_FAIL` if all frames are empty, or an error code if any failure occurs during the process. + */ HRESULT -test_dxgi_duplication(dxgi::adapter_t &adapter, dxgi::output_t &output) { +test_frame_capture(dxgi::dup_t &dup, ComPtr device) { + for (int i = 0; i < 10; ++i) { + std::cout << "Attempting to acquire frame " << (i + 1) << " of 10..." << std::endl; + ComPtr frameResource; + DXGI_OUTDUPL_FRAME_INFO frameInfo; + ComPtr context; + ComPtr stagingTexture; + + HRESULT status = dup->AcquireNextFrame(500, &frameInfo, &frameResource); + device->GetImmediateContext(&context); + + if (FAILED(status)) { + std::cout << "Error: Failed to acquire next frame [0x"sv << util::hex(status).to_string_view() << ']' << std::endl; + return status; + } + + auto cleanup = util::fail_guard([&dup]() { + dup->ReleaseFrame(); + }); + + std::cout << "Frame acquired successfully." << std::endl; + + ComPtr frameTexture; + status = frameResource->QueryInterface(IID_PPV_ARGS(&frameTexture)); + if (FAILED(status)) { + std::cout << "Error: Failed to query texture interface from frame resource [0x"sv << util::hex(status).to_string_view() << ']' << std::endl; + return status; + } + + D3D11_TEXTURE2D_DESC frameDesc; + frameTexture->GetDesc(&frameDesc); + frameDesc.Usage = D3D11_USAGE_STAGING; + frameDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + frameDesc.BindFlags = 0; + frameDesc.MiscFlags = 0; + + status = device->CreateTexture2D(&frameDesc, nullptr, &stagingTexture); + if (FAILED(status)) { + std::cout << "Error: Failed to create staging texture [0x"sv << util::hex(status).to_string_view() << ']' << std::endl; + return status; + } + + context->CopyResource(stagingTexture.Get(), frameTexture.Get()); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + status = context->Map(stagingTexture.Get(), 0, D3D11_MAP_READ, 0, &mappedResource); + if (FAILED(status)) { + std::cout << "Error: Failed to map the staging texture for inspection [0x"sv << util::hex(status).to_string_view() << ']' << std::endl; + return status; + } + + auto contextCleanup = util::fail_guard([&context, &stagingTexture]() { + context->Unmap(stagingTexture.Get(), 0); + }); + + if (is_valid_frame(mappedResource, frameDesc)) { + std::cout << "Frame " << (i + 1) << " is non-empty (contains visible content)." << std::endl; + return S_OK; + } + + std::cout << "Frame " << (i + 1) << " is empty (no visible content)." << std::endl; + } + + // All frames were empty, indicating potential capture issues. + return E_FAIL; +} + +HRESULT +test_dxgi_duplication(dxgi::adapter_t &adapter, dxgi::output_t &output, bool verify_frame_capture) { D3D_FEATURE_LEVEL featureLevels[] { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, @@ -107,29 +229,60 @@ test_dxgi_duplication(dxgi::adapter_t &adapter, dxgi::output_t &output) { // Ensure we can duplicate the current display syncThreadDesktop(); - // Return the result of DuplicateOutput() to Sunshine + // Attempt to duplicate the output dxgi::dup_t dup; - return output1->DuplicateOutput((IUnknown *) device.get(), &dup); + ComPtr device_ptr(device.get()); + HRESULT result = output1->DuplicateOutput(device_ptr.Get(), &dup); + + if (FAILED(result)) { + std::cout << "Failed to duplicate output [0x"sv << util::hex(result).to_string_view() << "]" << std::endl; + return result; + } + + // To prevent false negatives, we'll make it optional to test for frame capture. + if (verify_frame_capture) { + HRESULT captureResult = test_frame_capture(dup, device_ptr.Get()); + if (FAILED(captureResult)) { + std::cout << "Frame capture test failed [0x"sv << util::hex(captureResult).to_string_view() << "]" << std::endl; + return captureResult; + } + } + + return S_OK; } int main(int argc, char *argv[]) { HRESULT status; - // Display name may be omitted - if (argc != 2 && argc != 3) { - std::cout << "ddprobe.exe [GPU preference value] [display name]"sv << std::endl; + // Usage message + if (argc < 2 || argc > 4) { + std::cout << "Usage: ddprobe.exe [GPU preference value] [display name] [--verify-frame-capture]"sv << std::endl; return -1; } std::wstring display_name; - if (argc == 3) { - std::wstring_convert, wchar_t> converter; - display_name = converter.from_bytes(argv[2]); + bool verify_frame_capture = false; + + // Parse GPU preference value (required) + int gpu_preference = atoi(argv[1]); + + // Parse optional arguments + for (int i = 2; i < argc; ++i) { + std::string arg = argv[i]; + + if (arg == "--verify-frame-capture") { + verify_frame_capture = true; + } + else { + // Assume any other argument is the display name + std::wstring_convert, wchar_t> converter; + display_name = converter.from_bytes(arg); + } } // We must set the GPU preference before making any DXGI/D3D calls - status = set_gpu_preference(atoi(argv[1])); + status = set_gpu_preference(gpu_preference); if (status != ERROR_SUCCESS) { return status; } @@ -173,7 +326,7 @@ main(int argc, char *argv[]) { } // We found the matching output. Test it and return the result. - return test_dxgi_duplication(adapter, output); + return test_dxgi_duplication(adapter, output, verify_frame_capture); } } From 434b7e06ce4d451a199cfb192156ab478999a8ae Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 29 Sep 2024 17:37:57 -0400 Subject: [PATCH 10/18] chore(macos)!: drop monterey support (#3236) --- .github/workflows/CI.yml | 5 +---- README.md | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index aa07292a..c1b6620b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -471,8 +471,6 @@ jobs: 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: "12" - os_name: "macos" - os_version: "13" os_name: "macos" - os_version: "14" @@ -650,9 +648,8 @@ jobs: 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: "12" - release: true - os_version: "13" + release: true - os_version: "14" name: Macports (macOS-${{ matrix.os_version }}) runs-on: macos-${{ matrix.os_version }} diff --git a/README.md b/README.md index 6c182058..b2ce7143 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ the local server or any mobile device. Windows: 10+ (Windows Server does not support virtual gamepads) - macOS: 12+ + macOS: 13+ Linux/Debian: 12+ (bookworm) From 1839d594926cb0fbaaf064b90e73a150b6570ef3 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 29 Sep 2024 18:25:23 -0400 Subject: [PATCH 11/18] feat(apps): order apps alphabetically (#3223) --- src/confighttp.cpp | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/confighttp.cpp b/src/confighttp.cpp index 6d802206..886008dd 100644 --- a/src/confighttp.cpp +++ b/src/confighttp.cpp @@ -393,18 +393,35 @@ namespace confighttp { // Unfortunately Boost PT does not allow to directly edit the array, copy should do the trick pt::ptree newApps; int i = 0; - for (const auto &kv : apps_node) { + for (const auto &[k, v] : apps_node) { if (i == index) { newApps.push_back(std::make_pair("", inputTree)); } else { - newApps.push_back(std::make_pair("", kv.second)); + newApps.push_back(std::make_pair("", v)); } i++; } fileTree.erase("apps"); fileTree.push_back(std::make_pair("apps", newApps)); } + + // Sort the apps array by name + std::vector apps_vector; + for (const auto &[k, v] : fileTree.get_child("apps")) { + apps_vector.push_back(v); + } + std::ranges::sort(apps_vector, [](const pt::ptree &a, const pt::ptree &b) { + return a.get("name") < b.get("name"); + }); + + pt::ptree sorted_apps; + for (const auto &app : apps_vector) { + sorted_apps.push_back(std::make_pair("", app)); + } + fileTree.erase("apps"); + fileTree.add_child("apps", sorted_apps); + pt::write_json(config::stream.file_apps, fileTree); } catch (std::exception &e) { @@ -447,9 +464,9 @@ namespace confighttp { // Unfortunately Boost PT does not allow to directly edit the array, copy should do the trick pt::ptree newApps; int i = 0; - for (const auto &kv : apps_node) { + for (const auto &[k, v] : apps_node) { if (i++ != index) { - newApps.push_back(std::make_pair("", kv.second)); + newApps.push_back(std::make_pair("", v)); } } fileTree.erase("apps"); @@ -591,11 +608,11 @@ namespace confighttp { try { // TODO: Input Validation pt::read_json(ss, inputTree); - for (const auto &kv : inputTree) { - std::string value = inputTree.get(kv.first); + for (const auto &[k, v] : inputTree) { + std::string value = inputTree.get(k); if (value.length() == 0 || value.compare("null") == 0) continue; - configStream << kv.first << " = " << value << std::endl; + configStream << k << " = " << value << std::endl; } file_handler::write_file(config::sunshine.config_file.c_str(), configStream.str()); } From fb712e30a06eb5824d1d8803c5886871aeb21231 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 29 Sep 2024 19:48:10 -0400 Subject: [PATCH 12/18] fix(curl): use stronger SSL and TLS versions (#3241) --- src/httpcommon.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/httpcommon.cpp b/src/httpcommon.cpp index 355ab6e9..5be5d9ba 100644 --- a/src/httpcommon.cpp +++ b/src/httpcommon.cpp @@ -217,6 +217,7 @@ namespace http { curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); #ifdef _WIN32 curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); #endif From fa654c12ef93dc2606de529c3c1a423bd9f8c9af Mon Sep 17 00:00:00 2001 From: ns6089 <61738816+ns6089@users.noreply.github.com> Date: Tue, 1 Oct 2024 00:40:46 +0300 Subject: [PATCH 13/18] fix(win/cmake): use cmake_path(CONVERT TO_NATIVE_PATH_LIST) (#3152) Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> --- CMakeLists.txt | 5 +++-- cmake/packaging/windows.cmake | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90822a36..ea145ced 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.20) # `CMAKE_CUDA_ARCHITECTURES` requires 3.18 -# set_source_files_properties requires 3.18 +# `set_source_files_properties` requires 3.18 +# `cmake_path(CONVERT ... TO_NATIVE_PATH_LIST ...)` requires 3.20 # todo - set this conditionally project(Sunshine VERSION 0.0.0 diff --git a/cmake/packaging/windows.cmake b/cmake/packaging/windows.cmake index e17c971a..f8df493d 100644 --- a/cmake/packaging/windows.cmake +++ b/cmake/packaging/windows.cmake @@ -45,8 +45,9 @@ file(COPY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/" DESTINATION "${CMAKE_BINARY_DIR}/assets" PATTERN "shaders" EXCLUDE) # use junction for shaders directory -file(TO_NATIVE_PATH "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/shaders" shaders_in_build_src_native) -file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/assets/shaders" shaders_in_build_dest_native) +cmake_path(CONVERT "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/shaders" + TO_NATIVE_PATH_LIST shaders_in_build_src_native) +cmake_path(CONVERT "${CMAKE_BINARY_DIR}/assets/shaders" TO_NATIVE_PATH_LIST shaders_in_build_dest_native) execute_process(COMMAND cmd.exe /c mklink /J "${shaders_in_build_dest_native}" "${shaders_in_build_src_native}") # set(CPACK_NSIS_MUI_HEADERIMAGE "") # TODO: image should be 150x57 bmp From 9cc8bc8f62d5dfd6236d0b8ec44b6b9978bcbe87 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Tue, 1 Oct 2024 20:02:14 -0400 Subject: [PATCH 14/18] build(deps): migrate from curl to curl-winssl on Windows (#3246) --- .codeql-prebuild-cpp-Windows.sh | 13 +++--------- .github/workflows/CI.yml | 36 ++++++++++++--------------------- docs/building.md | 2 +- src/httpcommon.cpp | 14 ++++++++----- 4 files changed, 26 insertions(+), 39 deletions(-) diff --git a/.codeql-prebuild-cpp-Windows.sh b/.codeql-prebuild-cpp-Windows.sh index 31ee6cd9..04986c85 100644 --- a/.codeql-prebuild-cpp-Windows.sh +++ b/.codeql-prebuild-cpp-Windows.sh @@ -2,18 +2,10 @@ set -e # update pacman -pacman --noconfirm -Suy - -# install wget -pacman --noconfirm -S \ - wget - -# download working curl -wget https://repo.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-curl-8.8.0-1-any.pkg.tar.zst +pacman --noconfirm -Syu # install dependencies -pacman -U --noconfirm mingw-w64-ucrt-x86_64-curl-8.8.0-1-any.pkg.tar.zst -pacman -Syu --noconfirm --ignore=mingw-w64-ucrt-x86_64-curl \ +pacman -S --noconfirm \ base-devel \ diffutils \ gcc \ @@ -21,6 +13,7 @@ pacman -Syu --noconfirm --ignore=mingw-w64-ucrt-x86_64-curl \ make \ mingw-w64-ucrt-x86_64-cmake \ mingw-w64-ucrt-x86_64-cppwinrt \ + mingw-w64-ucrt-x86_64-curl-winssl \ mingw-w64-ucrt-x86_64-graphviz \ mingw-w64-ucrt-x86_64-miniupnpc \ mingw-w64-ucrt-x86_64-nlohmann-json \ diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c1b6620b..5bdc25d4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1019,30 +1019,20 @@ jobs: msystem: ucrt64 update: true install: >- - wget - - - name: Update Windows dependencies - shell: msys2 {0} - run: | - # download working curl - wget https://repo.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-curl-8.8.0-1-any.pkg.tar.zst - - # install dependencies - pacman -U --noconfirm mingw-w64-ucrt-x86_64-curl-8.8.0-1-any.pkg.tar.zst - pacman -Syu --noconfirm \ - --ignore=mingw-w64-ucrt-x86_64-curl \ - git \ - mingw-w64-ucrt-x86_64-cmake \ - mingw-w64-ucrt-x86_64-cppwinrt \ - mingw-w64-ucrt-x86_64-graphviz \ - mingw-w64-ucrt-x86_64-miniupnpc \ - mingw-w64-ucrt-x86_64-nlohmann-json \ - mingw-w64-ucrt-x86_64-nodejs \ - mingw-w64-ucrt-x86_64-nsis \ - mingw-w64-ucrt-x86_64-onevpl \ - mingw-w64-ucrt-x86_64-openssl \ - mingw-w64-ucrt-x86_64-opus \ + git + mingw-w64-ucrt-x86_64-cmake + mingw-w64-ucrt-x86_64-cppwinrt + mingw-w64-ucrt-x86_64-curl-winssl + mingw-w64-ucrt-x86_64-graphviz + mingw-w64-ucrt-x86_64-miniupnpc + mingw-w64-ucrt-x86_64-nlohmann-json + mingw-w64-ucrt-x86_64-nodejs + mingw-w64-ucrt-x86_64-nsis + mingw-w64-ucrt-x86_64-onevpl + mingw-w64-ucrt-x86_64-openssl + mingw-w64-ucrt-x86_64-opus mingw-w64-ucrt-x86_64-toolchain + wget - name: Install Doxygen # GCC compiled doxygen has issues when running graphviz diff --git a/docs/building.md b/docs/building.md index 6d0e7c47..83861943 100644 --- a/docs/building.md +++ b/docs/building.md @@ -86,7 +86,7 @@ dependencies=( "mingw-w64-ucrt-x86_64-boost" # Optional "mingw-w64-ucrt-x86_64-cmake" "mingw-w64-ucrt-x86_64-cppwinrt" - "mingw-w64-ucrt-x86_64-curl" + "mingw-w64-ucrt-x86_64-curl-winssl" "mingw-w64-ucrt-x86_64-graphviz" # Optional, for docs "mingw-w64-ucrt-x86_64-miniupnpc" "mingw-w64-ucrt-x86_64-nlohmann-json" diff --git a/src/httpcommon.cpp b/src/httpcommon.cpp index 5be5d9ba..419ca6dd 100644 --- a/src/httpcommon.cpp +++ b/src/httpcommon.cpp @@ -196,7 +196,12 @@ namespace http { bool download_file(const std::string &url, const std::string &file) { CURL *curl = curl_easy_init(); - if (!curl) { + if (curl) { + // sonar complains about weak ssl and tls versions + // ideally, the setopts should go after the early returns; however sonar cannot detect the fix + curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); + } + else { BOOST_LOG(error) << "Couldn't create CURL instance"; return false; } @@ -214,17 +219,16 @@ namespace http { curl_easy_cleanup(curl); return false; } + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); - curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); -#ifdef _WIN32 - curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA); -#endif + CURLcode result = curl_easy_perform(curl); if (result != CURLE_OK) { BOOST_LOG(error) << "Couldn't download ["sv << url << ", code:" << result << ']'; } + curl_easy_cleanup(curl); fclose(fp); return result == CURLE_OK; From 024bd8f8b6118af697c62338c9583c31a983a1d2 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Tue, 1 Oct 2024 21:12:40 -0400 Subject: [PATCH 15/18] ci(codeql): migrate builds to ninja (#3250) --- .codeql-prebuild-cpp-Windows.sh | 42 ++++++++++++++++----------------- .codeql-prebuild-cpp-macOS.sh | 26 ++++++++++++-------- docs/building.md | 8 ++++--- toolchain-mingw64.cmake | 19 --------------- 4 files changed, 41 insertions(+), 54 deletions(-) delete mode 100644 toolchain-mingw64.cmake diff --git a/.codeql-prebuild-cpp-Windows.sh b/.codeql-prebuild-cpp-Windows.sh index 04986c85..f4c7f54d 100644 --- a/.codeql-prebuild-cpp-Windows.sh +++ b/.codeql-prebuild-cpp-Windows.sh @@ -5,33 +5,31 @@ set -e pacman --noconfirm -Syu # install dependencies -pacman -S --noconfirm \ - base-devel \ - diffutils \ - gcc \ - git \ - make \ - mingw-w64-ucrt-x86_64-cmake \ - mingw-w64-ucrt-x86_64-cppwinrt \ - mingw-w64-ucrt-x86_64-curl-winssl \ - mingw-w64-ucrt-x86_64-graphviz \ - mingw-w64-ucrt-x86_64-miniupnpc \ - mingw-w64-ucrt-x86_64-nlohmann-json \ - mingw-w64-ucrt-x86_64-nodejs \ - mingw-w64-ucrt-x86_64-nsis \ - mingw-w64-ucrt-x86_64-onevpl \ - mingw-w64-ucrt-x86_64-openssl \ - mingw-w64-ucrt-x86_64-opus \ - mingw-w64-ucrt-x86_64-rust \ - mingw-w64-ucrt-x86_64-toolchain +dependencies=( + "git" + "mingw-w64-ucrt-x86_64-cmake" + "mingw-w64-ucrt-x86_64-cppwinrt" + "mingw-w64-ucrt-x86_64-curl-winssl" + "mingw-w64-ucrt-x86_64-miniupnpc" + "mingw-w64-ucrt-x86_64-nlohmann-json" + "mingw-w64-ucrt-x86_64-nodejs" + "mingw-w64-ucrt-x86_64-nsis" + "mingw-w64-ucrt-x86_64-onevpl" + "mingw-w64-ucrt-x86_64-openssl" + "mingw-w64-ucrt-x86_64-opus" + "mingw-w64-ucrt-x86_64-toolchain" +) +pacman -S --noconfirm "${dependencies[@]}" # build mkdir -p build -cd build || exit 1 cmake \ + -B build \ + -G Ninja \ + -S . \ -DBUILD_DOCS=OFF \ - -G "MinGW Makefiles" .. -mingw32-make -j"$(nproc)" + -DBUILD_WERROR=ON +ninja -C build # skip autobuild echo "skip_autobuild=true" >> "$GITHUB_OUTPUT" diff --git a/.codeql-prebuild-cpp-macOS.sh b/.codeql-prebuild-cpp-macOS.sh index 0a505136..7fbc090a 100644 --- a/.codeql-prebuild-cpp-macOS.sh +++ b/.codeql-prebuild-cpp-macOS.sh @@ -2,22 +2,28 @@ set -e # install dependencies -brew install \ - boost \ - cmake \ - miniupnpc \ - node \ - opus \ - pkg-config +dependencies=( + "boost" + "cmake" + "miniupnpc" + "ninja" + "node" + "openssl@3" + "opus" + "pkg-config" +) +brew install "${dependencies[@]}" # build mkdir -p build -cd build || exit 1 cmake \ + -B build \ + -G Ninja \ + -S . \ -DBOOST_USE_STATIC=OFF \ -DBUILD_DOCS=OFF \ - -G "Unix Makefiles" .. -make -j"$(sysctl -n hw.logicalcpu)" + -DBUILD_WERROR=ON +ninja -C build # skip autobuild echo "skip_autobuild=true" >> "$GITHUB_OUTPUT" diff --git a/docs/building.md b/docs/building.md index 83861943..851b21b1 100644 --- a/docs/building.md +++ b/docs/building.md @@ -34,12 +34,13 @@ dependencies=( "graphviz" # Optional, for docs "icu4c" # Optional, if boost is not installed "miniupnpc" + "ninja" "node" "openssl@3" "opus" "pkg-config" ) -brew install ${dependencies[@]} +brew install "${dependencies[@]}" ``` If there are issues with an SSL header that is not found: @@ -63,10 +64,11 @@ dependencies=( "graphviz" # Optional, for docs "libopus" "miniupnpc" + "ninja" "npm9" "pkgconfig" ) -sudo port install ${dependencies[@]} +sudo port install "${dependencies[@]}" ``` #### Windows @@ -97,7 +99,7 @@ dependencies=( "mingw-w64-ucrt-x86_64-opus" "mingw-w64-ucrt-x86_64-toolchain" ) -pacman -S ${dependencies[@]} +pacman -S "${dependencies[@]}" ``` ### Clone diff --git a/toolchain-mingw64.cmake b/toolchain-mingw64.cmake deleted file mode 100644 index a090f58f..00000000 --- a/toolchain-mingw64.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# the name of the target operating system -SET(CMAKE_SYSTEM_NAME Windows) - -# which compilers to use for C and C++ -SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) -SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) -SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) - -# here is the target environment located -SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) -#SET(CMAKE_SYSROOT ${CMAKE_FIND_ROOT_PATH}) -#SET(CMAKE_EXE_LINKER_FLAGS "-static ${CMAKE_EXE_LINKER_FLAGS}") - -# adjust the default behaviour of the FIND_XXX() commands: -# search headers and libraries in the target environment, search -# programs in the host environment -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) From 2c050d1cb04d9e3ac43c244f5af6dcab63216589 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Thu, 3 Oct 2024 13:54:42 -0400 Subject: [PATCH 16/18] ci(homebrew): don't update tap for forks (#3255) --- .github/workflows/CI.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 5bdc25d4..3c7b477a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -629,6 +629,7 @@ jobs: - name: Upload Homebrew Beta Formula if: >- + github.repository_owner == 'LizardByte' && matrix.release && needs.setup_release.outputs.publish_release == 'true' uses: LizardByte/homebrew-release-action@v2024.919.145818 From e90b71ce62b7744bb18ffc7823b1e895786ffb0a Mon Sep 17 00:00:00 2001 From: Lukas Senionis Date: Fri, 4 Oct 2024 04:42:16 +0300 Subject: [PATCH 17/18] fix(boost)!: migrate boost to 1.86 (#3256) --- .codeql-prebuild-cpp-Windows.sh | 1 + .github/workflows/CI.yml | 1 + cmake/dependencies/Boost_Sunshine.cmake | 8 ++++---- src/platform/common.h | 8 ++++---- src/platform/linux/misc.cpp | 4 ++-- src/platform/macos/misc.mm | 4 ++-- src/platform/windows/display_base.cpp | 4 ++-- src/platform/windows/misc.cpp | 4 ++-- src/process.cpp | 12 ++++++------ src/process.h | 12 ++++++------ src/system_tray.cpp | 2 +- 11 files changed, 31 insertions(+), 29 deletions(-) diff --git a/.codeql-prebuild-cpp-Windows.sh b/.codeql-prebuild-cpp-Windows.sh index f4c7f54d..b0c7b4cc 100644 --- a/.codeql-prebuild-cpp-Windows.sh +++ b/.codeql-prebuild-cpp-Windows.sh @@ -7,6 +7,7 @@ pacman --noconfirm -Syu # install dependencies dependencies=( "git" + "mingw-w64-ucrt-x86_64-boost" "mingw-w64-ucrt-x86_64-cmake" "mingw-w64-ucrt-x86_64-cppwinrt" "mingw-w64-ucrt-x86_64-curl-winssl" diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3c7b477a..57e3f3dc 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1021,6 +1021,7 @@ jobs: update: true install: >- git + mingw-w64-ucrt-x86_64-boost mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-cppwinrt mingw-w64-ucrt-x86_64-curl-winssl diff --git a/cmake/dependencies/Boost_Sunshine.cmake b/cmake/dependencies/Boost_Sunshine.cmake index 6615a389..72ab5443 100644 --- a/cmake/dependencies/Boost_Sunshine.cmake +++ b/cmake/dependencies/Boost_Sunshine.cmake @@ -3,7 +3,7 @@ # include_guard(GLOBAL) -set(BOOST_VERSION 1.85) +set(BOOST_VERSION 1.86) set(BOOST_COMPONENTS filesystem locale @@ -15,7 +15,7 @@ if(BOOST_USE_STATIC) set(Boost_USE_STATIC_LIBS ON) # cmake-lint: disable=C0103 endif() -find_package(Boost ${BOOST_VERSION} COMPONENTS ${BOOST_COMPONENTS}) +find_package(Boost CONFIG ${BOOST_VERSION} COMPONENTS ${BOOST_COMPONENTS}) if(NOT Boost_FOUND) message(STATUS "Boost v${BOOST_VERSION}.x package not found in the system. Falling back to FetchContent.") include(FetchContent) @@ -39,9 +39,9 @@ if(NOT Boost_FOUND) set(BOOST_INCLUDE_LIBRARIES ${BOOST_COMPONENTS}) set(BOOST_URL - "https://github.com/boostorg/boost/releases/download/boost-1.85.0/boost-1.85.0-cmake.tar.xz") + "https://github.com/boostorg/boost/releases/download/boost-1.86.0/boost-1.86.0-cmake.tar.xz") set(BOOST_HASH - "MD5=BADEA970931766604D4D5F8F4090B176") + "MD5=D02759931CEDC02ADED80402906C5EB6") if(CMAKE_VERSION VERSION_LESS "3.24.0") FetchContent_Declare( diff --git a/src/platform/common.h b/src/platform/common.h index 5c319dce..368bc733 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -47,13 +47,13 @@ namespace boost { namespace filesystem { class path; } - namespace process { + namespace process::inline v1 { class child; class group; template class basic_environment; typedef basic_environment environment; - } // namespace process + } // namespace process::inline v1 } // namespace boost #endif namespace video { @@ -597,8 +597,8 @@ namespace platf { bool needs_encoder_reenumeration(); - boost::process::child - run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const boost::process::environment &env, FILE *file, std::error_code &ec, boost::process::group *group); + boost::process::v1::child + run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const boost::process::v1::environment &env, FILE *file, std::error_code &ec, boost::process::v1::group *group); enum class thread_priority_e : int { low, ///< Low priority diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index 3ac9670a..b7a57c33 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -15,7 +15,7 @@ // lib includes #include #include -#include +#include #include #include #include @@ -269,7 +269,7 @@ namespace platf { auto working_dir = boost::filesystem::path(std::getenv("HOME")); std::string cmd = R"(xdg-open ")" + url + R"(")"; - boost::process::environment _env = boost::this_process::environment(); + boost::process::v1::environment _env = boost::this_process::environment(); std::error_code ec; auto child = run_command(false, false, cmd, working_dir, _env, nullptr, ec, nullptr); if (ec) { diff --git a/src/platform/macos/misc.mm b/src/platform/macos/misc.mm index 6eca7d2e..5366fdb2 100644 --- a/src/platform/macos/misc.mm +++ b/src/platform/macos/misc.mm @@ -23,7 +23,7 @@ #include "src/platform/common.h" #include -#include +#include using namespace std::literals; namespace fs = std::filesystem; @@ -197,7 +197,7 @@ namespace platf { boost::filesystem::path working_dir; std::string cmd = R"(open ")" + url + R"(")"; - boost::process::environment _env = boost::this_process::environment(); + boost::process::v1::environment _env = boost::this_process::environment(); std::error_code ec; auto child = run_command(false, false, cmd, working_dir, _env, nullptr, ec, nullptr); if (ec) { diff --git a/src/platform/windows/display_base.cpp b/src/platform/windows/display_base.cpp index 7058b77b..d4731c0e 100644 --- a/src/platform/windows/display_base.cpp +++ b/src/platform/windows/display_base.cpp @@ -7,9 +7,9 @@ #include #include -#include +#include -// We have to include boost/process.hpp before display.h due to WinSock.h, +// We have to include boost/process/v1.hpp before display.h due to WinSock.h, // but that prevents the definition of NTSTATUS so we must define it ourself. typedef long NTSTATUS; diff --git a/src/platform/windows/misc.cpp b/src/platform/windows/misc.cpp index 657807fa..21fe8b90 100644 --- a/src/platform/windows/misc.cpp +++ b/src/platform/windows/misc.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include // prevent clang format from "optimizing" the header include order @@ -1071,7 +1071,7 @@ namespace platf { */ void open_url(const std::string &url) { - boost::process::environment _env = boost::this_process::environment(); + boost::process::v1::environment _env = boost::this_process::environment(); auto working_dir = boost::filesystem::path(); std::error_code ec; diff --git a/src/process.cpp b/src/process.cpp index 6ab6b317..c6cf48b2 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -57,7 +57,7 @@ namespace proc { } void - terminate_process_group(boost::process::child &proc, boost::process::group &group, std::chrono::seconds exit_timeout) { + terminate_process_group(boost::process::v1::child &proc, boost::process::v1::group &group, std::chrono::seconds exit_timeout) { if (group.valid() && platf::process_group_running((std::uintptr_t) group.native_handle())) { if (exit_timeout.count() > 0) { // Request processes in the group to exit gracefully @@ -98,7 +98,7 @@ namespace proc { } boost::filesystem::path - find_working_directory(const std::string &cmd, boost::process::environment &env) { + find_working_directory(const std::string &cmd, boost::process::v1::environment &env) { // Parse the raw command string into parts to get the actual command portion #ifdef _WIN32 auto parts = boost::program_options::split_winmain(cmd); @@ -120,7 +120,7 @@ namespace proc { // If the cmd path is not an absolute path, resolve it using our PATH variable boost::filesystem::path cmd_path(parts.at(0)); if (!cmd_path.is_absolute()) { - cmd_path = boost::process::search_path(parts.at(0)); + cmd_path = boost::process::v1::search_path(parts.at(0)); if (cmd_path.empty()) { BOOST_LOG(error) << "Unable to find executable ["sv << parts.at(0) << "]. Is it in your PATH?"sv; return boost::filesystem::path(); @@ -301,8 +301,8 @@ namespace proc { std::error_code ec; placebo = false; terminate_process_group(_process, _process_group, _app.exit_timeout); - _process = boost::process::child(); - _process_group = boost::process::group(); + _process = boost::process::v1::child(); + _process_group = boost::process::v1::group(); for (; _app_prep_it != _app_prep_begin; --_app_prep_it) { auto &cmd = *(_app_prep_it - 1); @@ -403,7 +403,7 @@ namespace proc { } std::string - parse_env_val(boost::process::native_environment &env, const std::string_view &val_raw) { + parse_env_val(boost::process::v1::native_environment &env, const std::string_view &val_raw) { auto pos = std::begin(val_raw); auto dollar = std::find(pos, std::end(val_raw), '$'); diff --git a/src/process.h b/src/process.h index 29abaa88..2b0ba8b9 100644 --- a/src/process.h +++ b/src/process.h @@ -11,7 +11,7 @@ #include #include -#include +#include #include "config.h" #include "platform/common.h" @@ -68,7 +68,7 @@ namespace proc { KITTY_DEFAULT_CONSTR_MOVE_THROW(proc_t) proc_t( - boost::process::environment &&env, + boost::process::v1::environment &&env, std::vector &&apps): _app_id(0), _env(std::move(env)), @@ -99,7 +99,7 @@ namespace proc { private: int _app_id; - boost::process::environment _env; + boost::process::v1::environment _env; std::vector _apps; ctx_t _app; std::chrono::steady_clock::time_point _app_launch_time; @@ -107,8 +107,8 @@ namespace proc { // If no command associated with _app_id, yet it's still running bool placebo {}; - boost::process::child _process; - boost::process::group _process_group; + boost::process::v1::child _process; + boost::process::v1::group _process_group; file_t _pipe; std::vector::const_iterator _app_prep_it; @@ -143,7 +143,7 @@ namespace proc { * @param exit_timeout The timeout to wait for the process group to gracefully exit. */ void - terminate_process_group(boost::process::child &proc, boost::process::group &group, std::chrono::seconds exit_timeout); + terminate_process_group(boost::process::v1::child &proc, boost::process::v1::group &group, std::chrono::seconds exit_timeout); extern proc_t proc; } // namespace proc diff --git a/src/system_tray.cpp b/src/system_tray.cpp index e949ff57..d742816d 100644 --- a/src/system_tray.cpp +++ b/src/system_tray.cpp @@ -33,7 +33,7 @@ // lib includes #include "tray/src/tray.h" #include - #include + #include // local includes #include "confighttp.h" From 0107ca44d7ecce3ce1c46102decdf891d81e6816 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Fri, 4 Oct 2024 21:47:04 -0400 Subject: [PATCH 18/18] ci(flatpak): sync with flathub (#3259) --- .github/workflows/CI.yml | 80 +++++++- .github/workflows/update-flathub-repo.yml | 187 ++++++++++++++++++ .github/workflows/update-homebrew-release.yml | 11 +- .github/workflows/update-pacman-repo.yml | 33 ++-- .github/workflows/update-winget-release.yml | 11 +- .gitmodules | 4 + README.md | 4 +- cmake/compile_definitions/linux.cmake | 8 + cmake/prep/options.cmake | 1 + .../prep/special_package_configuration.cmake | 4 + cmake/targets/common.cmake | 9 +- docs/getting_started.md | 35 ++-- docs/third_party_packages.md | 3 - package.json | 6 +- packaging/linux/flatpak/README.md | 13 ++ .../linux/flatpak/deps/flatpak-builder-tools | 1 + .../dev.lizardbyte.app.Sunshine.metainfo.xml | 21 +- .../flatpak/dev.lizardbyte.app.Sunshine.yml | 44 ++--- packaging/linux/flatpak/flathub.json | 3 + packaging/linux/flatpak/modules/boost.json | 16 ++ packaging/linux/flatpak/modules/cuda.json | 8 +- tests/fixtures/http/hello-redirect.txt | 1 + tests/fixtures/http/hello.txt | 1 + tests/unit/test_httpcommon.cpp | 13 +- 24 files changed, 415 insertions(+), 102 deletions(-) create mode 100644 .github/workflows/update-flathub-repo.yml create mode 100644 packaging/linux/flatpak/README.md create mode 160000 packaging/linux/flatpak/deps/flatpak-builder-tools create mode 100644 packaging/linux/flatpak/flathub.json create mode 100644 packaging/linux/flatpak/modules/boost.json create mode 100644 tests/fixtures/http/hello-redirect.txt create mode 100644 tests/fixtures/http/hello.txt diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 57e3f3dc..2ea0b316 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -74,6 +74,8 @@ jobs: build_linux_flatpak: env: APP_ID: dev.lizardbyte.app.Sunshine + NODE_VERSION: "20" + PLATFORM_VERSION: "23.08" name: Linux Flatpak runs-on: ubuntu-22.04 needs: [setup_release, setup_flatpak_matrix] @@ -97,10 +99,30 @@ jobs: with: submodules: recursive - - name: Setup Dependencies Linux Flatpak - env: - PLATFORM_VERSION: "22.08" + - 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 \ @@ -114,10 +136,20 @@ jobs: org.flatpak.Builder \ org.freedesktop.Platform/${{ matrix.arch }}/${PLATFORM_VERSION} \ org.freedesktop.Sdk/${{ matrix.arch }}/${PLATFORM_VERSION} \ - org.freedesktop.Sdk.Extension.node18/${{ matrix.arch }}/${PLATFORM_VERSION} \ - org.freedesktop.Sdk.Extension.vala/${{ 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: @@ -167,16 +199,29 @@ jobs: - name: Build Linux Flatpak working-directory: build run: | - sudo su $(whoami) -c "flatpak run org.flatpak.Builder --arch=${{ matrix.arch }} --repo=repo --force-clean \ + 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 }} --repo=repo --force-clean \ + 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 \ + 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 \ + sudo su $(whoami) -c "flatpak build-bundle \ + --runtime \ + --arch=${{ matrix.arch }} \ + ./repo \ ../artifacts/sunshine_debug_${{ matrix.arch }}.flatpak ${APP_ID}.Debug" - name: Lint Flatpak @@ -229,6 +274,23 @@ jobs: # exit with the correct code exit $exit_code + - 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: diff --git a/.github/workflows/update-flathub-repo.yml b/.github/workflows/update-flathub-repo.yml new file mode 100644 index 00000000..15580f23 --- /dev/null +++ b/.github/workflows/update-flathub-repo.yml @@ -0,0 +1,187 @@ +--- +# This action is a candidate to centrally manage in https://github.com//.github/ +# If more Flathub applications are developed, consider moving this action to the organization's .github repository, +# using the `flathub-pkg` repository label to identify repositories that should trigger this workflow. + +# Update Flathub on release events. + +name: Update flathub repo + +on: + release: + types: [released] + +concurrency: + group: "${{ github.workflow }}-${{ github.event.release.tag_name }}" + cancel-in-progress: true + +jobs: + update-flathub-repo: + env: + FLATHUB_PKG: dev.lizardbyte.app.${{ github.event.repository.name }} + if: >- + github.repository_owner == 'LizardByte' + runs-on: ubuntu-latest + steps: + - name: Check if flathub repo + env: + TOPIC: flathub-pkg + id: check-label + uses: actions/github-script@v7 + with: + script: | + const topic = process.env.TOPIC; + console.log(`Checking if repo has topic: ${topic}`); + + const repoTopics = await github.rest.repos.getAllTopics({ + owner: context.repo.owner, + repo: context.repo.repo + }); + console.log(`Repo topics: ${repoTopics.data.names}`); + + const hasTopic = repoTopics.data.names.includes(topic); + console.log(`Has topic: ${hasTopic}`); + + core.setOutput('hasTopic', hasTopic); + + - name: Check if latest GitHub release + id: check-release + if: >- + steps.check-label.outputs.hasTopic == 'true' + uses: actions/github-script@v7 + with: + script: | + const latestRelease = await github.rest.repos.getLatestRelease({ + owner: context.repo.owner, + repo: context.repo.repo + }); + + core.setOutput('isLatestRelease', latestRelease.data.tag_name === context.payload.release.tag_name); + + - name: Checkout + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + uses: actions/checkout@v4 + + - name: Checkout flathub-repo + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + uses: actions/checkout@v4 + with: + repository: "flathub/${{ env.FLATHUB_PKG }}" + path: "flathub/${{ env.FLATHUB_PKG }}" + + - name: Clean up legacy files + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + working-directory: flathub/${{ env.FLATHUB_PKG }} + run: | + rm -rf ./* + + - name: Copy github files + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + working-directory: flathub/${{ env.FLATHUB_PKG }} + run: | + mkdir -p .github/ISSUE_TEMPLATE + + # sponsors + curl -sSL https://github.com/LizardByte/.github/raw/refs/heads/master/.github/FUNDING.yml \ + -o .github/FUNDING.yml + # pull request template + curl -sSL https://github.com/LizardByte/.github/raw/refs/heads/master/.github/pull_request_template.md \ + -o .github/pull_request_template.md + # issue config + curl -sSL https://github.com/LizardByte/.github/raw/refs/heads/master/.github/ISSUE_TEMPLATE/config.yml \ + -o .github/ISSUE_TEMPLATE/config.yml + + - name: Download release asset + id: download + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + uses: robinraju/release-downloader@v1.11 + with: + repository: "${{ github.repository }}" + tag: "${{ github.event.release.tag_name }}" + fileName: "flathub.tar.gz" + tarBall: false + zipBall: false + out-file-path: "flathub/${{ env.FLATHUB_PKG }}" + extract: true + + - name: Delete arhive + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + run: | + rm -f flathub/${{ env.FLATHUB_PKG }}/flathub.tar.gz + + - name: Update metainfo.xml + id: update_metainfo + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + run: | + xml_file="flathub/${{ env.FLATHUB_PKG }}/${{ env.FLATHUB_PKG }}.metainfo.xml" + + # Extract release information + version="${{ github.event.release.tag_name }}" && version="${version#v}" + date="${{ github.event.release.published_at }}" && date="${date%%T*}" + changelog="${{ github.event.release.body }}" && changelog="${changelog//&/&}" && \ + changelog="${changelog///>}" + + # Store the old release information into a temp file to be used for precise replacement + tmpfile=$(mktemp) + + # Match the existing block, replace it with the new data + awk -v version="$version" -v date="$date" -v changelog="$changelog" ' + BEGIN { replaced = 0 } + // { + if (!replaced) { + print "" + print "

" changelog "

" + print "
" + replaced = 1 + } + } + !// && !/<\/release>/ { print $0 } + ' "$xml_file" > "$tmpfile" + + # Move the updated file back to the original location + mv "$tmpfile" "$xml_file" + + - name: Update submodule + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' + run: | + # Get the current commit of the submodule in the main repository + git submodule update --init packaging/linux/flatpak/deps/shared-modules + cd ${{ github.workspace }}/packaging/linux/flatpak/deps/shared-modules + main_commit=$(git rev-parse HEAD) + + # update submodules + cd ${{ github.workspace }}/flathub/${{ env.FLATHUB_PKG }} + git submodule update --init shared-modules + cd shared-modules + git checkout $main_commit + + - name: Create/Update Pull Request + if: >- + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' && + fromJson(steps.download.outputs.downloaded_files)[0] + uses: peter-evans/create-pull-request@v7 + with: + path: "flathub/${{ env.FLATHUB_PKG }}" + token: ${{ secrets.GH_BOT_TOKEN }} + commit-message: Update ${{ env.FLATHUB_PKG }} to ${{ github.event.release.tag_name }} + branch: bot/bump-${{ env.FLATHUB_PKG }}-${{ github.event.release.tag_name }} + delete-branch: true + title: "chore: Update ${{ env.FLATHUB_PKG }} to ${{ github.event.release.tag_name }}" + body: ${{ github.event.release.body }} diff --git a/.github/workflows/update-homebrew-release.yml b/.github/workflows/update-homebrew-release.yml index d6acf476..16796cb8 100644 --- a/.github/workflows/update-homebrew-release.yml +++ b/.github/workflows/update-homebrew-release.yml @@ -9,7 +9,7 @@ name: Update Homebrew release on: release: - types: [created, edited] + types: [released] concurrency: group: "${{ github.workflow }}-${{ github.event.release.tag_name }}" @@ -18,14 +18,13 @@ concurrency: jobs: update-homebrew-release: if: >- - github.repository_owner == 'LizardByte' && - !github.event.release.draft && !github.event.release.prerelease + github.repository_owner == 'LizardByte' runs-on: ubuntu-latest steps: - name: Check if Homebrew repo env: TOPIC: homebrew-pkg - id: check + id: check-label uses: actions/github-script@v7 with: script: | @@ -46,7 +45,7 @@ jobs: - name: Download release asset id: download if: >- - steps.check.outputs.hasTopic == 'true' + steps.check-label.outputs.hasTopic == 'true' uses: robinraju/release-downloader@v1.11 with: repository: "${{ github.repository }}" @@ -59,7 +58,7 @@ jobs: - name: Publish Homebrew Formula if: >- - steps.check.outputs.hasTopic == 'true' && + steps.check-label.outputs.hasTopic == 'true' && fromJson(steps.download.outputs.downloaded_files)[0] uses: LizardByte/homebrew-release-action@v2024.919.145818 with: diff --git a/.github/workflows/update-pacman-repo.yml b/.github/workflows/update-pacman-repo.yml index 946bf07f..c95f7cda 100644 --- a/.github/workflows/update-pacman-repo.yml +++ b/.github/workflows/update-pacman-repo.yml @@ -9,7 +9,7 @@ name: Update pacman repo on: release: - types: [created, edited] + types: [released] concurrency: group: "${{ github.workflow }}-${{ github.event.release.tag_name }}" @@ -18,14 +18,13 @@ concurrency: jobs: update-homebrew-release: if: >- - github.repository_owner == 'LizardByte' && - !github.event.release.draft && !github.event.release.prerelease + github.repository_owner == 'LizardByte' runs-on: ubuntu-latest steps: - name: Check if pacman repo env: TOPIC: pacman-pkg - id: check + id: check-label uses: actions/github-script@v7 with: script: | @@ -43,11 +42,10 @@ jobs: core.setOutput('hasTopic', hasTopic); - - name: Check if edited release is latest GitHub release - id: check + - name: Check if latest GitHub release + id: check-release if: >- - github.event_name == 'release' && - github.event.action == 'edited' + steps.check-label.outputs.hasTopic == 'true' uses: actions/github-script@v7 with: script: | @@ -60,8 +58,8 @@ jobs: - name: Checkout pacman-repo if: >- - steps.check.outputs.hasTopic == 'true' && - steps.check.outputs.isLatestRelease == 'true' + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' uses: actions/checkout@v4 with: repository: ${{ github.repository_owner }}/pacman-repo @@ -69,16 +67,16 @@ jobs: - name: Prep id: prep if: >- - steps.check.outputs.hasTopic == 'true' && - steps.check.outputs.isLatestRelease == 'true' + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' run: | echo "pkg_name=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT - name: Download release asset id: download if: >- - steps.check.outputs.hasTopic == 'true' && - steps.check.outputs.isLatestRelease == 'true' + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' uses: robinraju/release-downloader@v1.11 with: repository: "${{ github.repository }}" @@ -91,8 +89,8 @@ jobs: - name: Create/Update Pull Request if: >- - steps.check.outputs.hasTopic == 'true'&& - steps.check.outputs.isLatestRelease == 'true' && + steps.check-label.outputs.hasTopic == 'true' && + steps.check-release.outputs.isLatestRelease == 'true' && fromJson(steps.download.outputs.downloaded_files)[0] uses: peter-evans/create-pull-request@v7 with: @@ -102,8 +100,7 @@ jobs: commit-message: Update ${{ github.repository }} to ${{ github.event.release.tag_name }} branch: bot/bump-${{ github.repository }}-${{ github.event.release.tag_name }} delete-branch: true - base: master - title: Update ${{ github.repository }} to ${{ github.event.release.tag_name }} + title: "chore: Update ${{ github.repository }} to ${{ github.event.release.tag_name }}" body: ${{ github.event.release.body }} labels: | auto-approve diff --git a/.github/workflows/update-winget-release.yml b/.github/workflows/update-winget-release.yml index 9e3278ec..c004dcdd 100644 --- a/.github/workflows/update-winget-release.yml +++ b/.github/workflows/update-winget-release.yml @@ -9,7 +9,7 @@ name: Update Winget release on: release: - types: [created, edited] + types: [released] concurrency: group: "${{ github.workflow }}-${{ github.event.release.tag_name }}" @@ -18,14 +18,13 @@ concurrency: jobs: update-winget-release: if: >- - github.repository_owner == 'LizardByte' && - !github.event.release.draft && !github.event.release.prerelease + github.repository_owner == 'LizardByte' runs-on: ubuntu-latest steps: - name: Check if Winget repo env: TOPIC: winget-pkg - id: check + id: check-label uses: actions/github-script@v7 with: script: | @@ -46,7 +45,7 @@ jobs: - name: Download release asset id: download if: >- - steps.check.outputs.hasTopic == 'true' + steps.check-label.outputs.hasTopic == 'true' uses: robinraju/release-downloader@v1.11 with: repository: "${{ github.repository }}" @@ -59,7 +58,7 @@ jobs: - name: Release to WinGet if: >- - steps.check.outputs.hasTopic == 'true' && + steps.check-label.outputs.hasTopic == 'true' && fromJson(steps.download.outputs.downloaded_files)[0] uses: vedantmgoyal2009/winget-releaser@v2 with: diff --git a/.gitmodules b/.gitmodules index 88198314..ed6ec248 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ +[submodule "packaging/linux/flatpak/deps/flatpak-builder-tools"] + path = packaging/linux/flatpak/deps/flatpak-builder-tools + url = https://github.com/flatpak/flatpak-builder-tools.git + branch = master [submodule "packaging/linux/flatpak/deps/shared-modules"] path = packaging/linux/flatpak/deps/shared-modules url = https://github.com/flathub/shared-modules diff --git a/README.md b/README.md index b2ce7143..61461576 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,10 @@ [![GitHub stars](https://img.shields.io/github/stars/lizardbyte/sunshine.svg?logo=github&style=for-the-badge)](https://github.com/LizardByte/Sunshine) [![GitHub Releases](https://img.shields.io/github/downloads/lizardbyte/sunshine/total.svg?style=for-the-badge&logo=github)](https://github.com/LizardByte/Sunshine/releases/latest) [![Docker](https://img.shields.io/docker/pulls/lizardbyte/sunshine.svg?style=for-the-badge&logo=docker)](https://hub.docker.com/r/lizardbyte/sunshine) +[![Flathub installs](https://img.shields.io/flathub/downloads/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=flathub)](https://flathub.org/apps/dev.lizardbyte.app.Sunshine) +[![Flathub Version](https://img.shields.io/flathub/v/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=flathub)](https://flathub.org/apps/dev.lizardbyte.app.Sunshine) [![GHCR](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fipitio.github.io%2Fbackage%2FLizardByte%2FSunshine%2Fsunshine.json&query=%24.downloads&label=ghcr%20pulls&style=for-the-badge&logo=github)](https://github.com/LizardByte/Sunshine/pkgs/container/sunshine) -[![Winget Version](https://img.shields.io/badge/dynamic/json.svg?color=orange&label=Winget&style=for-the-badge&prefix=v&query=$[-1:].name&url=https%3A%2F%2Fapi.github.com%2Frepos%2Fmicrosoft%2Fwinget-pkgs%2Fcontents%2Fmanifests%2Fl%2FLizardByte%2FSunshine&logo=microsoft)](https://github.com/microsoft/winget-pkgs/tree/master/manifests/l/LizardByte/Sunshine) +[![Winget Version](https://img.shields.io/badge/dynamic/json.svg?color=orange&label=Winget&style=for-the-badge&prefix=v&query=$[-1:].name&url=https%3A%2F%2Fapi.github.com%2Frepos%2Fmicrosoft%2Fwinget-pkgs%2Fcontents%2Fmanifests%2Fl%2FLizardByte%2FSunshine&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHuSURBVFhH7ZfNTtRQGIYZiMDwN/IrCAqIhMSNKxcmymVwG+5dcDVsWHgDrtxwCYQVl+BChzDEwSnPY+eQ0sxoOz1mQuBNnpyvTdvz9jun5/SrjfxnJUkyQbMEz2ELduF1l0YUA3QyTrMAa2AnPtyOXsELeAYNyKtV2EC3k3lYgTOwg09ghy/BTp7CKBRV844BOpmmMV2+ySb4BmInG7AKY7AHH+EYqqhZo9PPBG/BVDlOizAD/XQFmnoPXzxRQX8M/CCYS48L6RIc4ygGHK9WGg9HZSZMUNRPVwNJGg5Hg2Qgqh4N3FsDsb6EmgYm07iwwvUxstdxJTwgmILf4CfZ6bb5OHANX8GN5x20IVxnG8ge94pt2xpwU3GnCwayF4Q2G2vgFLzHndFzQdk4q77nNfCdwL28qNyMtmEf3A1/QV5FjDiPWo5jrwf8TWZChTlgJvL4F9QL50/A43qVidTvLcuoM2wDQ1+IkgefgUpLcYwMVBqCKNJA2b0gKNocOIITOIef8C/F/CdMbh/GklynsSawKLHS8d9/B1x2LUqsfFyy3TMsWj5A1cLkotDbYO4JjWWZlZEGv8EbOIR1CAVN2eG8W5oNKgxaeC6DmTJjZs7ixUxpznLPLT+v4sXpoMLcLI3mzFSonDXIEI/M3QCIO4YuimBJ/gAAAABJRU5ErkJggg==)](https://github.com/microsoft/winget-pkgs/tree/master/manifests/l/LizardByte/Sunshine) [![GitHub Workflow Status (CI)](https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/CI.yml.svg?branch=master&label=CI%20build&logo=github&style=for-the-badge)](https://github.com/LizardByte/Sunshine/actions/workflows/CI.yml?query=branch%3Amaster) [![GitHub Workflow Status (localize)](https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/localize.yml.svg?branch=master&label=localize%20build&logo=github&style=for-the-badge)](https://github.com/LizardByte/Sunshine/actions/workflows/localize.yml?query=branch%3Amaster) [![Read the Docs](https://img.shields.io/readthedocs/sunshinestream.svg?label=Docs&style=for-the-badge&logo=readthedocs)](http://sunshinestream.readthedocs.io) diff --git a/cmake/compile_definitions/linux.cmake b/cmake/compile_definitions/linux.cmake index d90f5dc6..94465abe 100644 --- a/cmake/compile_definitions/linux.cmake +++ b/cmake/compile_definitions/linux.cmake @@ -227,6 +227,14 @@ else() endif() endif() +# AppImage and Flatpak +if (${SUNSHINE_BUILD_APPIMAGE}) + list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_BUILD_APPIMAGE=1) +endif () +if (${SUNSHINE_BUILD_FLATPAK}) + list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_BUILD_FLATPAK=1) +endif () + list(APPEND PLATFORM_TARGET_FILES "${CMAKE_SOURCE_DIR}/src/platform/linux/publish.cpp" "${CMAKE_SOURCE_DIR}/src/platform/linux/graphics.h" diff --git a/cmake/prep/options.cmake b/cmake/prep/options.cmake index f1b33f08..2914c4db 100644 --- a/cmake/prep/options.cmake +++ b/cmake/prep/options.cmake @@ -9,6 +9,7 @@ set(SUNSHINE_PUBLISHER_ISSUE_URL "https://app.lizardbyte.dev/support" option(BUILD_DOCS "Build documentation" ON) option(BUILD_TESTS "Build tests" ON) +option(NPM_OFFLINE "Use offline npm packages. You must ensure packages are in your npm cache." OFF) option(TESTS_ENABLE_PYTHON_TESTS "Enable Python tests" ON) # DirectX11 is not available in GitHub runners, so even software encoding fails diff --git a/cmake/prep/special_package_configuration.cmake b/cmake/prep/special_package_configuration.cmake index 3e5c5d9c..df1bbb36 100644 --- a/cmake/prep/special_package_configuration.cmake +++ b/cmake/prep/special_package_configuration.cmake @@ -40,8 +40,12 @@ elseif(UNIX) # configure the flatpak manifest if(${SUNSHINE_CONFIGURE_FLATPAK_MAN}) configure_file(packaging/linux/flatpak/${PROJECT_FQDN}.yml ${PROJECT_FQDN}.yml @ONLY) + configure_file(packaging/linux/flatpak/${PROJECT_FQDN}.metainfo.xml + ${PROJECT_FQDN}.metainfo.xml @ONLY) file(COPY packaging/linux/flatpak/deps/ DESTINATION ${CMAKE_BINARY_DIR}) file(COPY packaging/linux/flatpak/modules DESTINATION ${CMAKE_BINARY_DIR}) + file(COPY generated-sources.json DESTINATION ${CMAKE_BINARY_DIR}) + file(COPY package-lock.json DESTINATION ${CMAKE_BINARY_DIR}) endif() endif() diff --git a/cmake/targets/common.cmake b/cmake/targets/common.cmake index b086bdd7..e928b2c5 100644 --- a/cmake/targets/common.cmake +++ b/cmake/targets/common.cmake @@ -53,10 +53,17 @@ endif() #WebUI build find_program(NPM npm REQUIRED) + +if (NPM_OFFLINE) + set(NPM_INSTALL_FLAGS "--offline") +else() + set(NPM_INSTALL_FLAGS "") +endif() + add_custom_target(web-ui ALL WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" COMMENT "Installing NPM Dependencies and Building the Web UI" - COMMAND "$<$:cmd;/C>" "${NPM}" install + COMMAND "$<$:cmd;/C>" "${NPM}" install ${NPM_INSTALL_FLAGS} COMMAND "${CMAKE_COMMAND}" -E env "SUNSHINE_BUILD_HOMEBREW=${NPM_BUILD_HOMEBREW}" "SUNSHINE_SOURCE_ASSETS_DIR=${NPM_SOURCE_ASSETS_DIR}" "SUNSHINE_ASSETS_DIR=${NPM_ASSETS_DIR}" "$<$:cmd;/C>" "${NPM}" run build # cmake-lint: disable=C0301 COMMAND_EXPAND_LISTS VERBATIM) diff --git a/docs/getting_started.md b/docs/getting_started.md index d121813e..534aa5f2 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -53,22 +53,24 @@ CUDA is used for NVFBC capture. sunshine-ubuntu-24.04-{arch}.deb - 12.0.0 - 525.60.13 + 12.0.0 + 525.60.13 50;52;60;61;62;70;72;75;80;86;87;89;90 - sunshine_{arch}.flatpak - - sunshine-debian-bookworm-{arch}.deb - 12.4.0 + 12.4.0 sunshine-fedora-39-{arch}.rpm - 12.5.1 + 12.5.1 sunshine.pkg.tar.zst + + 12.6.2 + 560.35.03 + sunshine_{arch}.flatpak + n/a n/a @@ -188,21 +190,30 @@ sudo dnf remove sunshine #### Flatpak @caution{Use distro-specific packages instead of the Flatpak if they are available.} -@important{The instructions provided here are for the version supplied in the [latest release][latest-release], -which does not necessarily match the version in the Flathub repository!} - Using this package requires that you have [Flatpak](https://flatpak.org/setup) installed. -##### Download +##### Download (local option) 1. Download `sunshine_{arch}.flatpak` and run the following command. @note{Replace `{arch}` with your system architecture.} -##### Install (system level) +##### Install (system level) +**Flathub** +```bash +flatpak install --system flathub dev.lizardbyte.app.Sunshine +``` + +**Local** ```bash flatpak install --system ./sunshine_{arch}.flatpak ``` ##### Install (user level) +**Flathub** +```bash +flatpak install --user flathub dev.lizardbyte.app.Sunshine +``` + +**Local** ```bash flatpak install --user ./sunshine_{arch}.flatpak ``` diff --git a/docs/third_party_packages.md b/docs/third_party_packages.md index 1793b4ce..14867299 100644 --- a/docs/third_party_packages.md +++ b/docs/third_party_packages.md @@ -5,9 +5,6 @@ ## Chocolatey [![Chocolatey](https://img.shields.io/badge/dynamic/xml.svg?color=orange&label=chocolatey&style=for-the-badge&prefix=v&query=%2F%2Ftr%5B%40id%3D%27chocolatey%27%5D%2Ftd%5B3%5D%2Fspan%2Fa&url=https%3A%2F%2Frepology.org%2Fproject%2Fsunshine%2Fversions&logo=chocolatey)](https://community.chocolatey.org/packages/sunshine) -## Flathub -[![Flathub](https://img.shields.io/flathub/v/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=Flathub)](https://flathub.org/apps/dev.lizardbyte.app.Sunshine) - ## nixpkgs [![nixpkgs](https://img.shields.io/badge/dynamic/xml.svg?color=orange&label=nixpkgs&style=for-the-badge&prefix=v&query=%2F%2Ftr%5B%40id%3D%27nix_unstable%27%5D%2Ftd%5B3%5D%2Fspan%2Fa&url=https%3A%2F%2Frepology.org%2Fproject%2Fsunshine%2Fversions&logo=nixos)](https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/servers/sunshine/default.nix) diff --git a/package.json b/package.json index a379c67e..d93d9629 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,11 @@ { + "name": "sunshine", + "version": "0.0.0", "scripts": { "build": "vite build --debug", "build-clean": "vite build --debug --emptyOutDir", - "dev": "vite build --watch" + "dev": "vite build --watch", + "serve": "serve ./tests/fixtures/http --no-port-switching" }, "dependencies": { "@lizardbyte/shared-web": "2024.901.195233", @@ -11,6 +14,7 @@ }, "devDependencies": { "@vitejs/plugin-vue": "4.6.2", + "serve": "14.2.3", "vite": "4.5.2", "vite-plugin-ejs": "1.6.4" } diff --git a/packaging/linux/flatpak/README.md b/packaging/linux/flatpak/README.md new file mode 100644 index 00000000..9b358b79 --- /dev/null +++ b/packaging/linux/flatpak/README.md @@ -0,0 +1,13 @@ +# Overview + +[![Flathub installs](https://img.shields.io/flathub/downloads/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=flathub)](https://flathub.org/apps/dev.lizardbyte.app.Sunshine) +[![Flathub Version](https://img.shields.io/flathub/v/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=flathub)](https://flathub.org/apps/dev.lizardbyte.app.Sunshine) + +LizardByte has the full documentation hosted on [Read the Docs](https://sunshinestream.readthedocs.io). + +## About + +Sunshine is a self-hosted game stream host for Moonlight. + +This repo is synced from the upstream [Sunshine](https://github.com/LizardByte/Sunshine) repo. +Please report issues and contribute to the upstream repo. diff --git a/packaging/linux/flatpak/deps/flatpak-builder-tools b/packaging/linux/flatpak/deps/flatpak-builder-tools new file mode 160000 index 00000000..9a48b5e3 --- /dev/null +++ b/packaging/linux/flatpak/deps/flatpak-builder-tools @@ -0,0 +1 @@ +Subproject commit 9a48b5e30a53715f1e71a5b804ff99fa46c430a3 diff --git a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml index 8cbbd5a5..7b4f1f18 100644 --- a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml +++ b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.metainfo.xml @@ -28,26 +28,15 @@ @PROJECT_LONG_DESCRIPTION@

-

NOTE: Allow Sunshine Virtual Input (Required)

-

sudo chown $USER /dev/uinput && echo 'KERNEL=="uinput", SUBSYSTEM=="misc", - OPTIONS+="static_node=uinput", TAG+="uaccess"' | sudo tee - /etc/udev/rules.d/60-sunshine-input.rules

-

NOTE: Sunshine uses a self-signed certificate. The web browser will report it as not secure, - but it is safe.

+

NOTE: Sunshine requires additional installation steps.

+

flatpak run --command=additional-install.sh @PROJECT_FQDN@

+

NOTE: Sunshine uses a self-signed certificate. The web browser will report it as not secure, but it is safe.

NOTE: KMS Grab (Optional)

-

sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') - flatpak run @PROJECT_FQDN@

+

sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') flatpak run @PROJECT_FQDN@

- - - - - - - - + LizardByte diff --git a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml index 156b40c5..3313ed25 100644 --- a/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml +++ b/packaging/linux/flatpak/dev.lizardbyte.app.Sunshine.yml @@ -1,11 +1,10 @@ --- app-id: "@PROJECT_FQDN@" runtime: org.freedesktop.Platform -runtime-version: "22.08" +runtime-version: "23.08" # requires CUDA >= 12.2 sdk: org.freedesktop.Sdk sdk-extensions: - - org.freedesktop.Sdk.Extension.node18 - - org.freedesktop.Sdk.Extension.vala + - org.freedesktop.Sdk.Extension.node20 command: sunshine separate-locales: false finish-args: @@ -29,10 +28,6 @@ cleanup: - /lib/*.a - /share/man -build-options: - append-path: /usr/lib/sdk/vala/bin - prepend-ld-library-path: /usr/lib/sdk/vala/lib - modules: # Test dependencies - "modules/xvfb/xvfb.json" @@ -40,6 +35,7 @@ modules: # Runtime dependencies - shared-modules/libappindicator/libappindicator-gtk3-12.10.json - "modules/avahi.json" + - "modules/boost.json" - "modules/libevdev.json" - "modules/libnotify.json" - "modules/miniupnpc.json" @@ -49,23 +45,21 @@ modules: - "modules/cuda.json" - name: sunshine - disabled: false - buildsystem: cmake-ninja - no-make-install: false builddir: true build-options: - append-path: /usr/lib/sdk/node18/bin - build-args: - - --share=network - test-args: - - --share=network + append-path: /usr/lib/sdk/node20/bin env: BUILD_VERSION: "@BUILD_VERSION@" BRANCH: "@GITHUB_BRANCH@" COMMIT: "@GITHUB_COMMIT@" - npm_config_nodedir: /usr/lib/sdk/node18 + XDG_CACHE_HOME: /run/build/sunshine/flatpak-node/cache + npm_config_cache: /run/build/sunshine/flatpak-node/npm-cache + npm_config_nodedir: /usr/lib/sdk/node20 + npm_config_offline: 'true' NPM_CONFIG_LOGLEVEL: info + buildsystem: cmake-ninja config-opts: + - -DBOOST_USE_STATIC=OFF - -DBUILD_DOCS=OFF - -DBUILD_WERROR=ON - -DCMAKE_BUILD_TYPE=Release @@ -78,16 +72,20 @@ modules: - -DSUNSHINE_ENABLE_DRM=ON - -DSUNSHINE_ENABLE_CUDA=ON - -DSUNSHINE_PUBLISHER_NAME='LizardByte' - -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' - -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support' - sources: - - type: git - url: "@GITHUB_CLONE_URL@" - commit: "@GITHUB_COMMIT@" + - -DSUNSHINE_PUBLISHER_WEBSITE='https://app.lizardbyte.dev' + - -DSUNSHINE_PUBLISHER_ISSUE_URL='https://app.lizardbyte.dev/support' + no-make-install: false post-install: - install -D $FLATPAK_BUILDER_BUILDDIR/packaging/linux/flatpak/scripts/* /app/bin - install -D $FLATPAK_BUILDER_BUILDDIR/packaging/linux/flatpak/apps.json /app/share/sunshine/apps.json run-tests: true test-rule: "" # empty to disable test-commands: - - xvfb-run tests/test_sunshine --gtest_color=yes + - npm run serve & xvfb-run tests/test_sunshine --gtest_color=yes + sources: + - generated-sources.json + - type: git + url: "@GITHUB_CLONE_URL@" + commit: "@GITHUB_COMMIT@" + - type: file + path: package-lock.json diff --git a/packaging/linux/flatpak/flathub.json b/packaging/linux/flatpak/flathub.json new file mode 100644 index 00000000..2de28147 --- /dev/null +++ b/packaging/linux/flatpak/flathub.json @@ -0,0 +1,3 @@ +{ + "disable-external-data-checker": true +} diff --git a/packaging/linux/flatpak/modules/boost.json b/packaging/linux/flatpak/modules/boost.json new file mode 100644 index 00000000..da111f64 --- /dev/null +++ b/packaging/linux/flatpak/modules/boost.json @@ -0,0 +1,16 @@ +{ + "name": "boost", + "buildsystem": "simple", + "build-commands": [ + "cd tools/build && bison -y -d -o src/engine/jamgram.cpp src/engine/jamgram.y", + "./bootstrap.sh --prefix=$FLATPAK_DEST --with-libraries=filesystem,locale,log,program_options,system", + "./b2 install variant=release link=shared runtime-link=shared cxxflags=\"$CXXFLAGS\"" + ], + "sources": [ + { + "type": "archive", + "url": "https://github.com/boostorg/boost/releases/download/boost-1.86.0/boost-1.86.0-cmake.tar.xz", + "sha256": "2c5ec5edcdff47ff55e27ed9560b0a0b94b07bd07ed9928b476150e16b0efc57" + } + ] +} diff --git a/packaging/linux/flatpak/modules/cuda.json b/packaging/linux/flatpak/modules/cuda.json index 53a38c0c..3e10f2fb 100644 --- a/packaging/linux/flatpak/modules/cuda.json +++ b/packaging/linux/flatpak/modules/cuda.json @@ -19,8 +19,8 @@ "only-arches": [ "x86_64" ], - "url": "https://developer.download.nvidia.com/compute/cuda/12.0.0/local_installers/cuda_12.0.0_525.60.13_linux.run", - "sha256": "905e9b9516900839fb76064719db752439f38b8cb730b49335d8bd53ddfad392", + "url": "https://developer.download.nvidia.com/compute/cuda/12.6.2/local_installers/cuda_12.6.2_560.35.03_linux.run", + "sha256": "3729a89cb58f7ca6a46719cff110d6292aec7577585a8d71340f0dbac54fb237", "dest-filename": "cuda.run" }, { @@ -28,8 +28,8 @@ "only-arches": [ "aarch64" ], - "url": "https://developer.download.nvidia.com/compute/cuda/12.0.0/local_installers/cuda_12.0.0_525.60.13_linux_sbsa.run", - "sha256": "cd13e9c65d4c8f895a968706f46064d536be09f9706bce081cc864b7e4fa4544", + "url": "https://developer.download.nvidia.com/compute/cuda/12.6.2/local_installers/cuda_12.6.2_560.35.03_linux_sbsa.run", + "sha256": "2249408848b705c18b9eadfb5161b52e4e36fcc5753647329cce93db141e5466", "dest-filename": "cuda.run" } ] diff --git a/tests/fixtures/http/hello-redirect.txt b/tests/fixtures/http/hello-redirect.txt new file mode 100644 index 00000000..64a358d9 --- /dev/null +++ b/tests/fixtures/http/hello-redirect.txt @@ -0,0 +1 @@ +hello-redirect.txt diff --git a/tests/fixtures/http/hello.txt b/tests/fixtures/http/hello.txt new file mode 100644 index 00000000..f0ad0dec --- /dev/null +++ b/tests/fixtures/http/hello.txt @@ -0,0 +1 @@ +hello.txt diff --git a/tests/unit/test_httpcommon.cpp b/tests/unit/test_httpcommon.cpp index bb0bb562..3b2b37e3 100644 --- a/tests/unit/test_httpcommon.cpp +++ b/tests/unit/test_httpcommon.cpp @@ -45,9 +45,18 @@ TEST_P(DownloadFileTest, Run) { ASSERT_TRUE(http::download_file(url, path)); } +#ifdef SUNSHINE_BUILD_FLATPAK +// requires running `npm run serve` prior to running the tests +constexpr const char *URL_1 = "http://0.0.0.0:3000/hello.txt"; +constexpr const char *URL_2 = "http://0.0.0.0:3000/hello-redirect.txt"; +#else +constexpr const char *URL_1 = "https://httpbin.org/base64/aGVsbG8h"; +constexpr const char *URL_2 = "https://httpbin.org/redirect-to?url=/base64/aGVsbG8h"; +#endif + INSTANTIATE_TEST_SUITE_P( DownloadFileTests, DownloadFileTest, testing::Values( - std::make_tuple("https://httpbin.org/base64/aGVsbG8h", "hello.txt"), - std::make_tuple("https://httpbin.org/redirect-to?url=/base64/aGVsbG8h", "hello-redirect.txt"))); + std::make_tuple(URL_1, "hello.txt"), + std::make_tuple(URL_2, "hello-redirect.txt")));