Build and Release #1349
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build 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 }} |