Skip to content

feat(clipboard): out-of-band blob endpoints for large payloads #1361

feat(clipboard): out-of-band blob endpoints for large payloads

feat(clipboard): out-of-band blob endpoints for large payloads #1361

Workflow file for this run

name: Build and Release
on:
pull_request:
branches:
- master
types:
- opened
- synchronize
- reopened
push:
branches:
- master
release:
types: [published]
workflow_dispatch:
concurrency:
group: '${{ github.workflow }}-${{ github.ref }}'
cancel-in-progress: true
# Opt all Node.js 20 actions onto the Node.js 24 runtime. GitHub will
# eventually flip this default itself; setting it explicitly silences the
# `actions/checkout@v4` deprecation warning emitted on every run and keeps
# us forward-compatible with the September 2026 Node 20 removal.
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: '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_auto.outputs.publish_release || steps.setup_release_release.outputs.publish_release || steps.setup_release_manual.outputs.publish_release }}
release_body: ${{ steps.setup_release_auto.outputs.release_body || steps.setup_release_release.outputs.release_body || steps.setup_release_manual.outputs.release_body }}
release_commit: ${{ steps.setup_release_auto.outputs.release_commit || steps.setup_release_release.outputs.release_commit || steps.setup_release_manual.outputs.release_commit }}
release_generate_release_notes: ${{ steps.setup_release_auto.outputs.release_generate_release_notes || steps.setup_release_release.outputs.release_generate_release_notes || steps.setup_release_manual.outputs.release_generate_release_notes }}
release_tag: ${{ steps.setup_release_auto.outputs.release_tag || steps.setup_release_release.outputs.release_tag || steps.setup_release_manual.outputs.release_tag }}
release_version: ${{ steps.setup_release_auto.outputs.release_version || steps.setup_release_release.outputs.release_version || steps.setup_release_manual.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: Debug GitHub Event
run: |
echo "GitHub Event Name: ${{ github.event_name }}"
echo "Has commits field: ${{ contains(toJson(github.event), 'commits') }}"
- name: Setup Release (Auto)
id: setup_release_auto
if: github.event_name != 'workflow_dispatch' && github.event_name != 'release'
uses: LizardByte/setup-release-action@v2025.426.225
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Release (Release event)
id: setup_release_release
if: github.event_name == 'release'
env:
RELEASE_BODY: ${{ github.event.release.body }}
run: |
TAG="${{ github.event.release.tag_name }}"
SUFFIX=$([ "${{ github.event.release.target_commitish }}" = "master" ] && echo "" || echo "-dev")
echo "publish_release=true" >> $GITHUB_OUTPUT
{
echo "release_body<<RELEASE_BODY_EOF"
echo "$RELEASE_BODY"
echo "RELEASE_BODY_EOF"
} >> $GITHUB_OUTPUT
echo "release_commit=${{ github.event.release.target_commitish }}" >> $GITHUB_OUTPUT
echo "release_generate_release_notes=false" >> $GITHUB_OUTPUT
echo "release_tag=${TAG}${SUFFIX}" >> $GITHUB_OUTPUT
echo "release_version=${TAG}${SUFFIX}" >> $GITHUB_OUTPUT
- name: Setup Release (Manual)
id: setup_release_manual
if: github.event_name == 'workflow_dispatch'
run: |
SUFFIX=$([ "${{ github.ref_name }}" = "master" ] && echo "" || echo "-dev")
echo "publish_release=false" >> $GITHUB_OUTPUT
echo "release_body=Manual build (${{ github.ref_name }})" >> $GITHUB_OUTPUT
echo "release_commit=${{ github.sha }}" >> $GITHUB_OUTPUT
echo "release_generate_release_notes=false" >> $GITHUB_OUTPUT
echo "release_tag=manual-$(date +%Y%m%d-%H%M%S)${SUFFIX}" >> $GITHUB_OUTPUT
echo "release_version=manual-$(date +%Y%m%d-%H%M%S)${SUFFIX}" >> $GITHUB_OUTPUT
build_win:
name: Windows
needs: setup_release
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'release' && github.event.release.tag_name || github.sha }}
submodules: recursive
- name: Setup Dependencies Windows
uses: msys2/setup-msys2@v2
with:
msystem: ucrt64
update: true
install: >-
wget
curl
- name: Update Windows dependencies
env:
opus_version: '1.6.1-1'
shell: msys2 {0}
run: |
# download pinned opus version
opus_tarball="mingw-w64-ucrt-x86_64-opus-${opus_version}-any.pkg.tar.zst"
wget https://repo.msys2.org/mingw/ucrt64/${opus_tarball}
# install dependencies
# NOTE: gcc/gcc-libs were previously pinned to 15.1.0-5 to work around
# a broken upstream gcc 15.x. Since msys2 has moved on to gcc 16.x and
# other packages (cmake, etc.) now require gcc-libs 16.x ABI, pinning
# an old gcc-libs causes cmake.exe to silently fail to load (exit 127).
# Let pacman install the full toolchain at the current upstream version.
dependencies=(
"git"
"mingw-w64-ucrt-x86_64-cmake"
"mingw-w64-ucrt-x86_64-ninja"
"mingw-w64-ucrt-x86_64-cppwinrt"
"mingw-w64-ucrt-x86_64-curl-winssl"
"mingw-w64-ucrt-x86_64-graphviz"
"mingw-w64-ucrt-x86_64-MinHook"
"mingw-w64-ucrt-x86_64-miniupnpc"
"mingw-w64-ucrt-x86_64-nlohmann-json"
# "mingw-w64-ucrt-x86_64-nodejs" # Replaced by actions/setup-node (vite 8 requires MSVC Node.js)
# "mingw-w64-ucrt-x86_64-nsis" # Replaced by Inno Setup
"mingw-w64-ucrt-x86_64-onevpl"
"mingw-w64-ucrt-x86_64-openssl"
"mingw-w64-ucrt-x86_64-toolchain"
"mingw-w64-ucrt-x86_64-autotools"
)
pacman -Syu --noconfirm "${dependencies[@]}"
# install pinned opus after Syu to prevent upgrade
pacman --noconfirm -U ${opus_tarball}
- name: Verify Build Tools
shell: msys2 {0}
run: |
echo "Verifying build tools are installed..."
which cmake || (echo "cmake not found" && exit 1)
which ninja || (echo "ninja not found" && exit 1)
which gcc || (echo "gcc not found" && exit 1)
echo "All build tools verified successfully"
echo " CMake: $(cmake --version | head -1)"
echo " Ninja: $(ninja --version)"
echo " GCC: $(gcc --version | head -1)"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Cache npm dependencies
uses: actions/cache@v4
with:
path: node_modules
key: npm-${{ hashFiles('package.json') }}
- name: Build Web UI
shell: pwsh
run: |
npm install
New-Item -ItemType Directory -Force -Path build | Out-Null
$env:SUNSHINE_SOURCE_ASSETS_DIR = "${{ github.workspace }}\src_assets"
$env:SUNSHINE_ASSETS_DIR = "${{ github.workspace }}\build"
npm run build
- name: Build Windows
shell: msys2 {0}
env:
BRANCH: ${{ github.head_ref || github.ref_name }}
BUILD_VERSION: ${{ needs.setup_release.outputs.release_tag }}.杂鱼
COMMIT: ${{ needs.setup_release.outputs.release_commit }}
GITHUB_TOKEN: ${{ secrets.DRIVER_DOWNLOAD_TOKEN }}
run: |
mkdir -p build
cmake \
-B build \
-G Ninja \
-S . \
-DBUILD_DOCS=OFF \
-DBUILD_WEB_UI=OFF \
-DSUNSHINE_ASSETS_DIR=assets \
-DSUNSHINE_PUBLISHER_NAME='${{ github.repository_owner }}' \
-DSUNSHINE_PUBLISHER_WEBSITE='https://github.com/qiin2333/Sunshine-Foundation' \
-DSUNSHINE_PUBLISHER_ISSUE_URL='https://github.com/qiin2333/Sunshine-Foundation/issues'
ninja -C build
- name: Cache Inno Setup
id: inno-cache
uses: actions/cache@v4
with:
path: C:\Program Files (x86)\Inno Setup 6
key: inno-setup-6
- name: Install Inno Setup
if: steps.inno-cache.outputs.cache-hit != 'true'
shell: pwsh
run: |
# Download and install Inno Setup 6 (silent install)
$url = "https://jrsoftware.org/download.php/is.exe"
$installer = "$env:TEMP\innosetup.exe"
Invoke-WebRequest -Uri $url -OutFile $installer
Start-Process -FilePath $installer -ArgumentList '/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-' -Wait
- name: Add Inno Setup to PATH
shell: pwsh
run: |
echo "C:\Program Files (x86)\Inno Setup 6" >> $env:GITHUB_PATH
- name: Package Windows
shell: msys2 {0}
run: |
mkdir -p artifacts
cd build
# package - 生成 Inno Setup 安装包和 ZIP 便携版
# 先安装到 staging 目录
cmake --install . --prefix ./inno_staging
# 运行 Inno Setup 编译器
"/c/Program Files (x86)/Inno Setup 6/ISCC.exe" sunshine_installer.iss
# 生成 ZIP 便携版
cpack -G ZIP --config ./CPackConfig.cmake --verbose
# move
mv ./cpack_artifacts/Sunshine.exe ../artifacts/sunshine-windows-installer.exe
mv ./cpack_artifacts/Sunshine.zip ../artifacts/sunshine-windows-portable.zip
- name: Generate Checksums
shell: pwsh
run: |
# 生成 SHA256 校验和
.\scripts\generate-checksums.ps1 -Path .\artifacts -Output "SHA256SUMS.txt"
- 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: Rename release assets
shell: msys2 {0}
run: |
# Format tag to vYEAR.DATE where DATE is zero-padded to 4 digits
TAG="${{ needs.setup_release.outputs.release_tag }}"
NEWTAG="$TAG"
if [[ "$TAG" =~ ^v([0-9]{4})\.([0-9]+) ]]; then
YEAR="${BASH_REMATCH[1]}"
DATE_PART="${BASH_REMATCH[2]}"
DATE_PADDED=$(printf "%04d" "$DATE_PART")
NEWTAG="v${YEAR}.${DATE_PADDED}"
fi
# 重命名安装包和便携版
mv artifacts/sunshine-windows-installer.exe "artifacts/Sunshine.${NEWTAG}.WindowsInstaller.exe"
mv artifacts/sunshine-windows-portable.zip "artifacts/Sunshine.${NEWTAG}.WindowsPortable.zip"
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: sunshine-windows-r${{ github.run_number }}
path: |
artifacts/Sunshine.*.WindowsInstaller.exe
artifacts/Sunshine.*.WindowsPortable.zip
artifacts/SHA256SUMS.txt
artifacts/checksums.json
if-no-files-found: error
- name: Create/Update GitHub Release
if: needs.setup_release.outputs.publish_release == 'true'
uses: LizardByte/create-release-action@v2025.426.1549
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 }}