ci: use prerelease logic (#2553)

This commit is contained in:
ReenigneArcher 2024-05-23 21:42:06 -04:00 committed by GitHub
parent 26ceec5f3c
commit e898be1b7e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 450 additions and 1194 deletions

View File

@ -24,10 +24,10 @@ body:
required: true
- type: checkboxes
attributes:
label: Is your issue present in the nightly release?
description: Please test the [nightly](https://github.com/LizardByte/Sunshine/releases/tag/nightly-dev) release
label: Is your issue present in the latest beta/pre-release?
description: Please test the latest [pre-release](https://github.com/LizardByte/Sunshine/releases)
options:
- label: This issue is present in the nightly release
- label: This issue is present in the latest pre-release
required: true
- type: textarea
id: description

View File

@ -3,14 +3,14 @@ name: CI
on:
pull_request:
branches: [master, nightly]
branches: [master]
types: [opened, synchronize, reopened]
push:
branches: [master, nightly]
branches: [master]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
jobs:
@ -25,102 +25,23 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
check_changelog:
name: Check Changelog
runs-on: ubuntu-latest
steps:
- name: Checkout
if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }}
uses: actions/checkout@v4
- name: Verify Changelog
id: verify_changelog
if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }}
# base_ref for pull request check, ref for push
uses: LizardByte/.github/actions/verify_changelog@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
outputs:
next_version: ${{ steps.verify_changelog.outputs.changelog_parser_version }}
next_version_bare: ${{ steps.verify_changelog.outputs.changelog_parser_version_bare }}
last_version: ${{ steps.verify_changelog.outputs.latest_release_tag_name }}
release_body: ${{ steps.verify_changelog.outputs.changelog_parser_description }}
# todo - remove this job once versioning is fully automated by cmake
check_versions:
name: Check Versions
runs-on: ubuntu-latest
needs: check_changelog
if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }}
# base_ref for pull request check, ref for push
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check CMakeLists.txt Version
run: |
version=$(grep -o -E '^project\(Sunshine VERSION [0-9]+\.[0-9]+\.[0-9]+' CMakeLists.txt | \
grep -o -E '[0-9]+\.[0-9]+\.[0-9]+')
echo "cmakelists_version=${version}" >> $GITHUB_ENV
- name: Compare CMakeList.txt Version
if: ${{ env.cmakelists_version != needs.check_changelog.outputs.next_version_bare }}
run: |
echo CMakeLists version: "$cmakelists_version"
echo Changelog version: "${{ needs.check_changelog.outputs.next_version_bare }}"
echo Within 'CMakeLists.txt' change "project(Sunshine [VERSION $cmakelists_version]" to \
"project(Sunshine [VERSION ${{ needs.check_changelog.outputs.next_version_bare }}]"
exit 1
setup_release:
name: Setup Release
needs: check_changelog
outputs:
publish_release: ${{ steps.setup_release.outputs.publish_release }}
release_commit: ${{ steps.setup_release.outputs.release_commit }}
release_tag: ${{ steps.setup_release.outputs.release_tag }}
release_version: ${{ steps.setup_release.outputs.release_version }}
runs-on: ubuntu-latest
steps:
- name: Set release details
id: release_details
env:
RELEASE_BODY: ${{ needs.check_changelog.outputs.release_body }}
run: |
# determine to create a release or not
if [[ $GITHUB_EVENT_NAME == "push" ]]; then
RELEASE=true
else
RELEASE=false
fi
- name: Checkout
uses: actions/checkout@v4
# set the release tag
COMMIT=${{ github.sha }}
if [[ $GITHUB_REF == refs/heads/master ]]; then
TAG="${{ needs.check_changelog.outputs.next_version }}"
RELEASE_NAME="${{ needs.check_changelog.outputs.next_version }}"
RELEASE_BODY="$RELEASE_BODY"
PRE_RELEASE="false"
elif [[ $GITHUB_REF == refs/heads/nightly ]]; then
TAG="nightly-dev"
RELEASE_NAME="nightly"
RELEASE_BODY="automated nightly release - $(date -u +'%Y-%m-%dT%H:%M:%SZ') - ${COMMIT}"
PRE_RELEASE="true"
fi
echo "create_release=${RELEASE}" >> $GITHUB_OUTPUT
echo "release_tag=${TAG}" >> $GITHUB_OUTPUT
echo "release_commit=${COMMIT}" >> $GITHUB_OUTPUT
echo "release_name=${RELEASE_NAME}" >> $GITHUB_OUTPUT
echo "pre_release=${PRE_RELEASE}" >> $GITHUB_OUTPUT
# this is stupid but works for multiline strings
echo "RELEASE_BODY<<EOF" >> $GITHUB_ENV
echo "$RELEASE_BODY" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
outputs:
create_release: ${{ steps.release_details.outputs.create_release }}
release_tag: ${{ steps.release_details.outputs.release_tag }}
release_commit: ${{ steps.release_details.outputs.release_commit }}
release_name: ${{ steps.release_details.outputs.release_name }}
release_body: ${{ env.RELEASE_BODY }}
pre_release: ${{ steps.release_details.outputs.pre_release }}
- name: Setup Release
id: setup_release
uses: LizardByte/setup-release-action@v2024.524.1411
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
setup_flatpak_matrix:
name: Setup Flatpak Matrix
@ -131,7 +52,7 @@ jobs:
# https://www.cynkra.com/blog/2020-12-23-dynamic-gha
run: |
# determine which architectures to build
if [[ $GITHUB_EVENT_NAME == "push" ]]; then
if [[ "${{ github.event_name }}" == "push" ]]; then
matrix=$((
echo '{ "arch" : ["x86_64", "aarch64"] }'
) | jq -c .)
@ -158,7 +79,7 @@ jobs:
steps:
- name: Maximize build space
uses: easimon/maximize-build-space@v8
uses: easimon/maximize-build-space@v10
with:
root-reserve-mb: 10240
remove-dotnet: 'true'
@ -194,7 +115,7 @@ jobs:
"
- name: Cache Flatpak build
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ./build/.flatpak-builder
key: flatpak-${{ matrix.arch }}-${{ github.sha }}
@ -204,19 +125,18 @@ jobs:
- name: Configure Flatpak Manifest
run: |
# variables for manifest
branch=${GITHUB_HEAD_REF}
branch=${{ github.head_ref }}
commit=${{ needs.setup_release.outputs.release_commit }}
# check the branch variable
if [ -z "$branch" ]
then
echo "This is a PUSH event"
branch=${{ github.ref_name }}
build_version=${{ needs.check_changelog.outputs.next_version }}
commit=${{ github.sha }}
build_version=${{ needs.setup_release.outputs.release_tag }}
clone_url=${{ github.event.repository.clone_url }}
else
echo "This is a PR event"
commit=${{ github.event.pull_request.head.sha }}
clone_url=${{ github.event.pull_request.head.repo.clone_url }}
fi
echo "Branch: ${branch}"
@ -257,23 +177,21 @@ jobs:
path: artifacts/
- name: Create/Update GitHub Release
if: ${{ needs.setup_release.outputs.create_release == 'true' }}
uses: ncipollo/release-action@v1
if: ${{ needs.setup_release.outputs.publish_release == 'true' }}
uses: LizardByte/create-release-action@v2024.520.211408
with:
name: ${{ needs.setup_release.outputs.release_name }}
tag: ${{ needs.setup_release.outputs.release_tag }}
commit: ${{ needs.setup_release.outputs.release_commit }}
artifacts: "*artifacts/*"
token: ${{ secrets.GH_BOT_TOKEN }}
allowUpdates: true
body: ${{ needs.setup_release.outputs.release_body }}
discussionCategory: announcements
prerelease: ${{ needs.setup_release.outputs.pre_release }}
generateReleaseNotes: true
name: ${{ needs.setup_release.outputs.release_tag }}
prerelease: true
tag: ${{ needs.setup_release.outputs.release_tag }}
token: ${{ secrets.GH_BOT_TOKEN }}
build_linux:
name: Linux ${{ matrix.type }}
runs-on: ubuntu-${{ matrix.dist }}
needs: [check_changelog, setup_release]
needs: [setup_release]
strategy:
fail-fast: false # false to test all, true to fail entire job if any fail
matrix:
@ -284,7 +202,7 @@ jobs:
steps:
- name: Maximize build space
uses: easimon/maximize-build-space@v8
uses: easimon/maximize-build-space@v10
with:
root-reserve-mb: 30720
remove-dotnet: 'true'
@ -403,8 +321,8 @@ jobs:
- name: Build Linux
env:
BRANCH: ${{ github.head_ref || github.ref_name }}
BUILD_VERSION: ${{ needs.check_changelog.outputs.next_version }}
COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
BUILD_VERSION: ${{ needs.setup_release.outputs.release_tag }}
COMMIT: ${{ needs.setup_release.outputs.release_commit }}
timeout-minutes: 10
run: |
echo "nproc: $(nproc)"
@ -430,10 +348,9 @@ jobs:
- name: Set AppImage Version
if: |
matrix.type == 'AppImage' &&
(needs.check_changelog.outputs.next_version_bare != needs.check_changelog.outputs.last_version)
matrix.type == 'AppImage'
run: |
version=${{ needs.check_changelog.outputs.next_version_bare }}
version=${{ needs.setup_release.outputs.release_tag }}
echo "VERSION=${version}" >> $GITHUB_ENV
- name: Package Linux - AppImage
@ -550,21 +467,19 @@ jobs:
verbose: true
- name: Create/Update GitHub Release
if: ${{ needs.setup_release.outputs.create_release == 'true' }}
uses: ncipollo/release-action@v1
if: ${{ needs.setup_release.outputs.publish_release == 'true' }}
uses: LizardByte/create-release-action@v2024.520.211408
with:
name: ${{ needs.setup_release.outputs.release_name }}
tag: ${{ needs.setup_release.outputs.release_tag }}
commit: ${{ needs.setup_release.outputs.release_commit }}
artifacts: "*artifacts/*"
token: ${{ secrets.GH_BOT_TOKEN }}
allowUpdates: true
body: ${{ needs.setup_release.outputs.release_body }}
discussionCategory: announcements
prerelease: ${{ needs.setup_release.outputs.pre_release }}
generateReleaseNotes: true
name: ${{ needs.setup_release.outputs.release_tag }}
prerelease: true
tag: ${{ needs.setup_release.outputs.release_tag }}
token: ${{ secrets.GH_BOT_TOKEN }}
build_mac_brew:
needs: [check_changelog, setup_release]
needs: [setup_release]
strategy:
fail-fast: false # false to test all, true to fail entire job if any fail
matrix:
@ -590,22 +505,21 @@ jobs:
- name: Configure formula
run: |
# variables for formula
branch=${GITHUB_HEAD_REF}
branch=${{ github.head_ref }}
commit=${{ needs.setup_release.outputs.release_commit }}
# check the branch variable
if [ -z "$branch" ]
then
echo "This is a PUSH event"
build_version=${{ needs.check_changelog.outputs.next_version }}
build_version=${{ needs.setup_release.outputs.release_tag }}
clone_url=${{ github.event.repository.clone_url }}
branch="${{ github.ref_name }}"
commit=${{ github.sha }}
default_branch="${{ github.event.repository.default_branch }}"
else
echo "This is a PR event"
clone_url=${{ github.event.pull_request.head.repo.clone_url }}
branch="${{ github.event.pull_request.head.ref }}"
commit=${{ github.event.pull_request.head.sha }}
default_branch="${{ github.event.pull_request.head.repo.default_branch }}"
fi
echo "Branch: ${branch}"
@ -638,32 +552,31 @@ jobs:
name: sunshine-homebrew
path: homebrew/
- name: Should Publish Homebrew Formula
id: homebrew_publish
run: |
PUBLISH=false
if [[ \
"${{ matrix.release }}" == "true" && \
"${{ github.repository_owner }}" == "LizardByte" && \
"${{ needs.setup_release.outputs.create_release }}" == "true" && \
"${{ github.ref }}" == "refs/heads/master" \
]]; then
PUBLISH=true
fi
echo "publish=${PUBLISH}" >> $GITHUB_OUTPUT
- name: Validate and Publish Homebrew Formula
uses: LizardByte/homebrew-release-action@v2024.516.191449
- name: Validate Homebrew Formula
uses: LizardByte/homebrew-release-action@v2024.522.222851
with:
formula_file: ${{ github.workspace }}/homebrew/sunshine.rb
git_email: ${{ secrets.GH_BOT_EMAIL }}
git_username: ${{ secrets.GH_BOT_NAME }}
publish: ${{ steps.homebrew_publish.outputs.publish }}
publish: false
token: ${{ secrets.GH_BOT_TOKEN }}
validate: true
- name: Create/Update GitHub Release
if: ${{ needs.setup_release.outputs.publish_release == 'true' }}
uses: LizardByte/create-release-action@v2024.520.211408
with:
allowUpdates: true
artifacts: '${{ github.workspace }}/homebrew/*'
discussionCategory: announcements
generateReleaseNotes: true
name: ${{ needs.setup_release.outputs.release_tag }}
prerelease: true
tag: ${{ needs.setup_release.outputs.release_tag }}
token: ${{ secrets.GH_BOT_TOKEN }}
build_mac_port:
needs: [check_changelog, setup_release]
needs: [setup_release]
strategy:
fail-fast: false # false to test all, true to fail entire job if any fail
matrix:
@ -708,19 +621,18 @@ jobs:
- name: Configure Portfile
run: |
# variables for Portfile
branch=${GITHUB_HEAD_REF}
branch=${{ github.head_ref }}
commit=${{ needs.setup_release.outputs.release_commit }}
# check the branch variable
if [ -z "$branch" ]
then
echo "This is a PUSH event"
branch="${{ github.ref_name }}"
build_version=${{ needs.check_changelog.outputs.next_version }}
commit=${{ github.sha }}
build_version=${{ needs.setup_release.outputs.release_tag }}
clone_url=${{ github.event.repository.clone_url }}
else
echo "This is a PR event"
commit=${{ github.event.pull_request.head.sha }}
clone_url=${{ github.event.pull_request.head.repo.clone_url }}
fi
echo "Commit: ${commit}"
@ -892,23 +804,21 @@ jobs:
verbose: true
- name: Create/Update GitHub Release
if: ${{ needs.setup_release.outputs.create_release == 'true' && matrix.release }}
uses: ncipollo/release-action@v1
if: ${{ needs.setup_release.outputs.publish_release == 'true' }}
uses: LizardByte/create-release-action@v2024.520.211408
with:
name: ${{ needs.setup_release.outputs.release_name }}
tag: ${{ needs.setup_release.outputs.release_tag }}
commit: ${{ needs.setup_release.outputs.release_commit }}
artifacts: "*artifacts/*"
token: ${{ secrets.GH_BOT_TOKEN }}
allowUpdates: true
body: ${{ needs.setup_release.outputs.release_body }}
discussionCategory: announcements
prerelease: ${{ needs.setup_release.outputs.pre_release }}
generateReleaseNotes: true
name: ${{ needs.setup_release.outputs.release_tag }}
prerelease: true
tag: ${{ needs.setup_release.outputs.release_tag }}
token: ${{ secrets.GH_BOT_TOKEN }}
build_win:
name: Windows
runs-on: windows-2019
needs: [check_changelog, setup_release]
needs: [setup_release]
steps:
- name: Checkout
@ -1069,8 +979,8 @@ jobs:
shell: msys2 {0}
env:
BRANCH: ${{ github.head_ref || github.ref_name }}
BUILD_VERSION: ${{ needs.check_changelog.outputs.next_version }}
COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
BUILD_VERSION: ${{ needs.setup_release.outputs.release_tag }}
COMMIT: ${{ needs.setup_release.outputs.release_commit }}
run: |
mkdir build
cd build
@ -1157,32 +1067,13 @@ jobs:
path: artifacts/
- name: Create/Update GitHub Release
if: ${{ needs.setup_release.outputs.create_release == 'true' }}
uses: ncipollo/release-action@v1
if: ${{ needs.setup_release.outputs.publish_release == 'true' }}
uses: LizardByte/create-release-action@v2024.520.211408
with:
name: ${{ needs.setup_release.outputs.release_name }}
tag: ${{ needs.setup_release.outputs.release_tag }}
commit: ${{ needs.setup_release.outputs.release_commit }}
artifacts: "*artifacts/*"
token: ${{ secrets.GH_BOT_TOKEN }}
allowUpdates: true
body: ${{ needs.setup_release.outputs.release_body }}
discussionCategory: announcements
prerelease: ${{ needs.setup_release.outputs.pre_release }}
release-winget:
name: Release to WinGet
needs: [setup_release, build_win]
if: |
(github.repository_owner == 'LizardByte' &&
needs.setup_release.outputs.create_release == 'true' &&
github.ref == 'refs/heads/master')
runs-on: ubuntu-latest
steps:
- name: Release to WinGet
uses: vedantmgoyal2009/winget-releaser@v2
with:
identifier: LizardByte.Sunshine
release-tag: ${{ needs.setup_release.outputs.release_tag }}
installers-regex: '\.exe$' # only .exe files
generateReleaseNotes: true
name: ${{ needs.setup_release.outputs.release_tag }}
prerelease: true
tag: ${{ needs.setup_release.outputs.release_tag }}
token: ${{ secrets.GH_BOT_TOKEN }}

View File

@ -29,7 +29,7 @@ on:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
jobs:
@ -74,82 +74,49 @@ jobs:
echo $matrix | jq .
echo "matrix=$matrix" >> $GITHUB_OUTPUT
- name: Find dotnet solution file
id: find_dotnet
run: |
solution=$(find . -maxdepth 1 -type f -iname "*.sln")
echo "found solution: ${solution}"
# do not quote to keep this as a single line
echo solution=${solution} >> $GITHUB_OUTPUT
if [[ $solution != "" ]]; then
echo "dotnet=true" >> $GITHUB_OUTPUT
else
echo "dotnet=false" >> $GITHUB_OUTPUT
fi
outputs:
dockerfiles: ${{ steps.find.outputs.dockerfiles }}
matrix: ${{ steps.find.outputs.matrix }}
dotnet: ${{ steps.find_dotnet.outputs.dotnet }}
solution: ${{ steps.find_dotnet.outputs.solution }}
check_changelog:
name: Check Changelog
needs: [check_dockerfiles]
setup_release:
if: ${{ needs.check_dockerfiles.outputs.dockerfiles }}
name: Setup Release
needs:
- check_dockerfiles
outputs:
publish_release: ${{ steps.setup_release.outputs.publish_release }}
release_commit: ${{ steps.setup_release.outputs.release_commit }}
release_tag: ${{ steps.setup_release.outputs.release_tag }}
release_version: ${{ steps.setup_release.outputs.release_version }}
runs-on: ubuntu-latest
steps:
- name: Checkout
if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }}
uses: actions/checkout@v4
- name: Verify Changelog
id: verify_changelog
if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }}
# base_ref for pull request check, ref for push
uses: LizardByte/.github/actions/verify_changelog@master
- name: Setup Release
id: setup_release
uses: LizardByte/setup-release-action@v2024.524.1411
with:
token: ${{ secrets.GITHUB_TOKEN }}
outputs:
next_version: ${{ steps.verify_changelog.outputs.changelog_parser_version }}
next_version_bare: ${{ steps.verify_changelog.outputs.changelog_parser_version_bare }}
last_version: ${{ steps.verify_changelog.outputs.latest_release_tag_name }}
release_body: ${{ steps.verify_changelog.outputs.changelog_parser_description }}
setup_release:
name: Setup Release
needs: check_changelog
runs-on: ubuntu-latest
steps:
- name: Set release details
id: release_details
env:
RELEASE_BODY: ${{ needs.check_changelog.outputs.release_body }}
run: |
# determine to create a release or not
if [[ $GITHUB_EVENT_NAME == "push" ]]; then
RELEASE=true
else
RELEASE=false
fi
# set the release tag
COMMIT=${{ github.sha }}
if [[ $GITHUB_REF == refs/heads/master ]]; then
TAG="${{ needs.check_changelog.outputs.next_version }}"
RELEASE_NAME="${{ needs.check_changelog.outputs.next_version }}"
RELEASE_BODY="$RELEASE_BODY"
PRE_RELEASE="false"
elif [[ $GITHUB_REF == refs/heads/nightly ]]; then
TAG="nightly-dev"
RELEASE_NAME="nightly"
RELEASE_BODY="automated nightly release - $(date -u +'%Y-%m-%dT%H:%M:%SZ') - ${COMMIT}"
PRE_RELEASE="true"
fi
echo "create_release=${RELEASE}" >> $GITHUB_OUTPUT
echo "release_tag=${TAG}" >> $GITHUB_OUTPUT
echo "release_commit=${COMMIT}" >> $GITHUB_OUTPUT
echo "release_name=${RELEASE_NAME}" >> $GITHUB_OUTPUT
echo "pre_release=${PRE_RELEASE}" >> $GITHUB_OUTPUT
# this is stupid but works for multiline strings
echo "RELEASE_BODY<<EOF" >> $GITHUB_ENV
echo "$RELEASE_BODY" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
outputs:
create_release: ${{ steps.release_details.outputs.create_release }}
release_tag: ${{ steps.release_details.outputs.release_tag }}
release_commit: ${{ steps.release_details.outputs.release_commit }}
release_name: ${{ steps.release_details.outputs.release_name }}
release_body: ${{ env.RELEASE_BODY }}
pre_release: ${{ steps.release_details.outputs.pre_release }}
dotnet: ${{ needs.check_dockerfiles.outputs.dotnet }}
github_token: ${{ secrets.GITHUB_TOKEN }}
lint_dockerfile:
needs: [check_dockerfiles]
@ -180,7 +147,7 @@ jobs:
cat "./hadolint.log" >> $GITHUB_STEP_SUMMARY
docker:
needs: [check_dockerfiles, check_changelog, setup_release]
needs: [check_dockerfiles, setup_release]
if: ${{ needs.check_dockerfiles.outputs.dockerfiles }}
runs-on: ubuntu-latest
permissions:
@ -193,7 +160,7 @@ jobs:
steps:
- name: Maximize build space
uses: easimon/maximize-build-space@v8
uses: easimon/maximize-build-space@v10
with:
root-reserve-mb: 30720 # https://github.com/easimon/maximize-build-space#caveats
remove-dotnet: 'true'
@ -210,24 +177,20 @@ jobs:
- name: Prepare
id: prepare
env:
NV: ${{ needs.check_changelog.outputs.next_version }}
NV: ${{ needs.setup_release.outputs.release_tag }}
run: |
# get branch name
BRANCH=${GITHUB_HEAD_REF}
RELEASE=false
RELEASE=${{ needs.setup_release.outputs.publish_release }}
COMMIT=${{ needs.setup_release.outputs.release_commit }}
if [ -z "$BRANCH" ]; then
echo "This is a PUSH event"
BRANCH=${{ github.ref_name }}
COMMIT=${{ github.sha }}
CLONE_URL=${{ github.event.repository.clone_url }}
if [[ $BRANCH == "master" ]]; then
RELEASE=true
fi
else
echo "This is a PULL REQUEST event"
COMMIT=${{ github.event.pull_request.head.sha }}
CLONE_URL=${{ github.event.pull_request.head.repo.clone_url }}
fi
@ -260,7 +223,7 @@ jobs:
# parse custom directives out of dockerfile
# try to get the platforms from the dockerfile custom directive, i.e. `# platforms: xxx,yyy`
# directives for PR event, i.e. not push event
if [[ ${PUSH} == "false" ]]; then
if [[ ${RELEASE} == "false" ]]; then
while read -r line; do
if [[ $line == "# platforms_pr: "* && $PLATFORMS == "" ]]; then
# echo the line and use `sed` to remove the custom directive
@ -299,13 +262,10 @@ jobs:
echo "branch=${BRANCH}" >> $GITHUB_OUTPUT
echo "build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
echo "commit=${COMMIT}" >> $GITHUB_OUTPUT
echo "clone_url=${CLONE_URL}" >> $GITHUB_OUTPUT
echo "release=${RELEASE}" >> $GITHUB_OUTPUT
echo "artifacts=${ARTIFACTS}" >> $GITHUB_OUTPUT
echo "no_cache_filters=${NO_CACHE_FILTERS}" >> $GITHUB_OUTPUT
echo "platforms=${PLATFORMS}" >> $GITHUB_OUTPUT
echo "push=${PUSH}" >> $GITHUB_OUTPUT
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
- name: Set Up QEMU
@ -316,7 +276,7 @@ jobs:
id: buildx
- name: Cache Docker Layers
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: Docker-buildx${{ matrix.tag }}-${{ github.sha }}
@ -324,14 +284,14 @@ jobs:
Docker-buildx${{ matrix.tag }}-
- name: Log in to Docker Hub
if: ${{ steps.prepare.outputs.push == 'true' }} # PRs do not have access to secrets
if: ${{ needs.setup_release.outputs.publish_release == 'true' }} # PRs do not have access to secrets
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Log in to the Container registry
if: ${{ steps.prepare.outputs.push == 'true' }} # PRs do not have access to secrets
if: ${{ needs.setup_release.outputs.publish_release == 'true' }} # PRs do not have access to secrets
uses: docker/login-action@v3
with:
registry: ghcr.io
@ -352,10 +312,10 @@ jobs:
build-args: |
BRANCH=${{ steps.prepare.outputs.branch }}
BUILD_DATE=${{ steps.prepare.outputs.build_date }}
BUILD_VERSION=${{ needs.check_changelog.outputs.next_version }}
COMMIT=${{ steps.prepare.outputs.commit }}
BUILD_VERSION=${{ needs.setup_release.outputs.release_tag }}
COMMIT=${{ needs.setup_release.outputs.release_commit }}
CLONE_URL=${{ steps.prepare.outputs.clone_url }}
RELEASE=${{ steps.prepare.outputs.release }}
RELEASE=${{ needs.setup_release.outputs.publish_release }}
tags: ${{ steps.prepare.outputs.tags }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
@ -367,15 +327,15 @@ jobs:
with:
context: ./
file: ${{ matrix.dockerfile }}
push: ${{ steps.prepare.outputs.push }}
push: ${{ needs.setup_release.outputs.publish_release }}
platforms: ${{ steps.prepare.outputs.platforms }}
build-args: |
BRANCH=${{ steps.prepare.outputs.branch }}
BUILD_DATE=${{ steps.prepare.outputs.build_date }}
BUILD_VERSION=${{ needs.check_changelog.outputs.next_version }}
COMMIT=${{ steps.prepare.outputs.commit }}
BUILD_VERSION=${{ needs.setup_release.outputs.release_tag }}
COMMIT=${{ needs.setup_release.outputs.release_commit }}
CLONE_URL=${{ steps.prepare.outputs.clone_url }}
RELEASE=${{ steps.prepare.outputs.release }}
RELEASE=${{ needs.setup_release.outputs.publish_release }}
tags: ${{ steps.prepare.outputs.tags }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
@ -401,22 +361,21 @@ jobs:
path: artifacts/
- name: Create/Update GitHub Release
if: ${{ needs.setup_release.outputs.create_release == 'true' && steps.prepare.outputs.artifacts == 'true' }}
uses: ncipollo/release-action@v1
if: ${{ needs.setup_release.outputs.publish_release == 'true' && steps.prepare.outputs.artifacts == 'true' }}
uses: LizardByte/create-release-action@v2024.520.211408
with:
name: ${{ needs.setup_release.outputs.release_name }}
tag: ${{ needs.setup_release.outputs.release_tag }}
commit: ${{ needs.setup_release.outputs.release_commit }}
artifacts: "*artifacts/*"
token: ${{ secrets.GH_BOT_TOKEN }}
allowUpdates: true
body: ${{ needs.setup_release.outputs.release_body }}
artifacts: "*artifacts/*"
discussionCategory: announcements
prerelease: ${{ needs.setup_release.outputs.pre_release }}
generateReleaseNotes: true
name: ${{ needs.setup_release.outputs.release_tag }}
prerelease: true
tag: ${{ needs.setup_release.outputs.release_tag }}
token: ${{ secrets.GH_BOT_TOKEN }}
- name: Update Docker Hub Description
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
uses: peter-evans/dockerhub-description@v3
uses: peter-evans/dockerhub-description@v4
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }} # token is not currently supported

View File

@ -3,7 +3,7 @@ name: localize
on:
push:
branches: [nightly]
branches: [master]
paths: # prevents workflow from running unless these files change
- '.github/workflows/localize.yml'
- 'src/**'
@ -85,7 +85,7 @@ jobs:
commit-message: New localization template
branch: localize/update
delete-branch: true
base: nightly
base: master
title: New Babel Updates
body: |
Update report

View File

@ -3,10 +3,15 @@ name: Release Notifications (Moonlight)
on:
release:
types: [published]
types:
- released # this triggers when a release is published, but does not include prereleases or drafts
jobs:
discord:
if: >-
startsWith(github.repository, 'LizardByte/') &&
!github.event.release.prerelease &&
!github.event.release.draft
runs-on: ubuntu-latest
steps:
- name: discord

View File

@ -0,0 +1,71 @@
---
# This action is a candidate to centrally manage in https://github.com/<organization>/.github/
# If more Homebrew applications are developed, consider moving this action to the organization's .github repository,
# using the `homebrew-pkg` repository label to identify repositories that should trigger have this workflow.
# Update Homebrew on release events.
name: Update Homebrew release
on:
release:
types: [created, edited]
concurrency:
group: "${{ github.workflow }}-${{ github.event.release.tag_name }}"
cancel-in-progress: true
jobs:
update-homebrew-release:
if: >-
github.repository_owner == 'LizardByte' &&
!github.event.release.draft && !github.event.release.prerelease
runs-on: ubuntu-latest
steps:
- name: Check if Homebrew repo
env:
TOPIC: homebrew-pkg
id: check
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: Download release asset
id: download
if: >-
steps.check.outputs.hasTopic == 'true'
uses: robinraju/release-downloader@v1.10
with:
repository: "${{ github.repository }}"
tag: "${{ github.event.release.tag_name }}"
fileName: "*.rb"
tarBall: false
zipBall: false
out-file-path: "release_downloads"
extract: false
- name: Publish Homebrew Formula
if: >-
steps.check.outputs.hasTopic == 'true' &&
fromJson(steps.download.outputs.downloaded_files)[0]
uses: LizardByte/homebrew-release-action@v2024.522.222851
with:
formula_file: ${{ fromJson(steps.download.outputs.downloaded_files)[0] }}
git_email: ${{ secrets.GH_BOT_EMAIL }}
git_username: ${{ secrets.GH_BOT_NAME }}
publish: true
token: ${{ secrets.GH_BOT_TOKEN }}
validate: false

View File

@ -3,14 +3,14 @@ name: Build GH-Pages
on:
pull_request:
branches: [master, nightly]
branches: [master]
types: [opened, synchronize, reopened]
push:
branches: [master]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
jobs:

View File

@ -0,0 +1,69 @@
---
# This action is a candidate to centrally manage in https://github.com/<organization>/.github/
# If more Winget applications are developed, consider moving this action to the organization's .github repository,
# using the `winget-pkg` repository label to identify repositories that should trigger have this workflow.
# Update Winget on release events.
name: Update Winget release
on:
release:
types: [created, edited]
concurrency:
group: "${{ github.workflow }}-${{ github.event.release.tag_name }}"
cancel-in-progress: true
jobs:
update-winget-release:
if: >-
github.repository_owner == 'LizardByte' &&
!github.event.release.draft && !github.event.release.prerelease
runs-on: ubuntu-latest
steps:
- name: Check if Winget repo
env:
TOPIC: winget-pkg
id: check
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: Download release asset
id: download
if: >-
steps.check.outputs.hasTopic == 'true'
uses: robinraju/release-downloader@v1.10
with:
repository: "${{ github.repository }}"
tag: "${{ github.event.release.tag_name }}"
fileName: "*.exe"
tarBall: false
zipBall: false
out-file-path: "release_downloads"
extract: false
- name: Release to WinGet
if: >-
steps.check.outputs.hasTopic == 'true' &&
fromJson(steps.download.outputs.downloaded_files)[0]
uses: vedantmgoyal2009/winget-releaser@v2
with:
identifier: "${{ github.repository_owner }}.${{ github.event.repository.name }}"
release-tag: ${{ github.event.release.tag_name }}
installers-regex: '\.exe$'
token: ${{ secrets.GH_BOT_TOKEN }}

View File

@ -1,824 +0,0 @@
# Changelog
## [0.23.1] - 2024-04-20
**Fixed**
- (Capture/Windows) Disable HRD and CBR encoding options by default for AMD GPUs due to video quality regressions in v0.23.0
- (UI) Fix incorrect strings for QuickSync 'fast' and 'faster' presets
- (UI/Linux) Fix update prompt appearing even when running the latest version
- (Input) Fix crash when absolute input events are received prior to the display viewport being set
- (Input/Linux) Fix missing clamping of rumble intensity to valid range
- (Build/Tests) Fix error when attempting to disable compilation of tests
- (Build/Linux) Fix some compilation errors when using Musl libc
- (Logging) Fix broken debug messages for codec capability flags
- (Logging/Linux) Fix log messages to include the correct setcap command for resolving KMS permission errors
**Added**
- (Capture/Linux) Improve frame time consistency for all capture backends
- (UI) Set focus to the PIN textbox when navigating to the PIN tab
**Dependencies**
- Remove libavdevice dependency
**Misc**
- (Linux) Prefer ayatana-appindicator3 over appindicator3 if both are available
## [0.23.0] - 2024-04-06
Attention, this release contains critical security fixes. Please update as soon as possible.
**Breaking**
- (Linux) Drop support for Ubuntu 20.04
- (Linux) No longer provide arm64 rpm packages, due to extreme compile time on GitHub hosted runners
**Fixed**
- (Network) Ensure unpairing takes effect without restart
- (Capture/Linux) Fix logical comparison of texture size
- (Service/Windows) Quote the path to sunshinesvc.exe when launching the termination helper
**Added**
- (WebUI) Localization support
- (Capture/Linux) Populate host latency for kmx/x11 grab
- (Capture/Windows) AMF rate control improvements
- (Linux) Add support for Ubuntu 24.04 (x86_64 only)
**Dependencies**
- Bump rstcheck from 6.2.0 to 6.2.1
- Bump org.flatpak.Builder.BaseApp from 644487f to 6e295e6
- Bump ffmpeg
- Bump @fortawesome/fontawesome-free from 6.5.1 to 6.5.2
**Misc**
- (Style) Refactored video encoder declarations
- (CI) Refactored Linux build in CI
- (CI) Added unit testing and code coverage
- (Docs/macOS) Update curl command for Portfile install
- (Style) Refactor logging initialization
## [0.22.2] - 2024-03-15
**Fixed**
- (Tray/Windows) Fix broken system tray icon on some systems
- (Linux) Fix crash when XDG_CONFIG_HOME or CONFIGURATION_DIRECTORY are set
- (Linux) Fix config migration across filesystems and with non-existent parent directories
## [0.22.1] - 2024-03-13
**Breaking**
- (ArchLinux) Drop support for standalone PKGBUILD files. Use the binary Arch package or install via AUR instead.
- (macOS) Drop support for experimental dmg package. Use Homebrew or MacPorts instead.
**Added**
- (macOS) Added Homebrew support
**Changed**
- (Process/Windows) The working directory is now searched first when the command contains a relative path
- (ArchLinux) The kmsgrab capture backend is now compiled by default to support Wayland capture on non-wlroots-based compositors
- (Capture/Linux) X11 capture is now preferred over kmsgrab for cards that lack atomic modesetting support to ensure cursor capture works
- (Capture/Linux) Kmsgrab will only choose NVENC by default if the display is connected to the Nvidia GPU to avoid possible EGL import failures
**Fixed**
- (Config) Fix unsupported resolution error with some Moonlight clients
- (Capture/Windows) Fix crash when streaming Ryujinx, Red Alert 2, and other apps that use unusually sized monochrome cursors
- (Capture/Linux) Fix crash in KMS cursor capture when running on Arch-based distros
- (Capture/Linux) Fix crash if CUDA GPU has a PCI ID with hexadecimal digits greater than 9
- (Process/Windows) Fix starting apps when the working directory is enclosed in quotes
- (Process/Windows) Fix process tree tracking when the app is launched via a cmd.exe trampoline
- (Installer/Windows) Fix slow operation during ViGEmBus installation that may cause the installer to appear stuck
- (Build/macOS) Fix issues building on macOS 13 and 14
- (Build/Linux) Fix missing install script in the Arch binary package
- (Build/Linux) Fix missing optional dependencies in the Arch binary package
- (Build/Linux) Ensure correct Arch pkg is published to GitHub releases
- (Capture/Linux) Fix mismatched case and unhandled exception in CUDA device lookup
- (Config) Add missing resolution to default config ui
- (Linux) Fix udev rules for uinput access not working until after reboot
- (Linux) Fix wrong path in desktop files
- (Tray) Cache icons to avoid possible DRM issues
- (Tray) Fix attempt to update tray icon after it was destroyed
- (Linux) Migrate old config files to new location if env SUNSHINE_MIGRATE_CONFIG=1 is set (automatically set for Flatpak)
- (Linux/Fedora) Re-enable CUDA support and bump to 12.4.0
**Misc**
- (Build/Windows) Adjust Windows debuginfo artifact to reduce confusion with real release binaries
## [0.22.0] - 2024-03-03
**Breaking**
- (Network) Clients must now be paired with the host before they can use Wake-on-LAN
- (Build/Linux) Drop Fedora 37 support
**Added**
- (Input/Linux) Add native/pen touch support for Linux
- (Capture/Linux) Add HDR streaming support for Linux using KMS capture backend
- (Capture/Linux) Add KMS capture support for Nvidia GPUs running Wayland
- (Network) Add support for full E2E stream encryption, configurable for LAN and WAN independently
- (Process) Add process group tracking to automatically handle launchers that spawn other child processes
- (Capture/Windows) Add setting for controlling GPU power saving and encoding latency tradeoff for NVENC
- (Capture/Windows) Add additional encoding settings for NVENC
- (Process/Windows) Add experimental support for launching URLs and other non-exe files
- (Capture/Windows) Add setting to allow use of slower HEVC encoding on older Intel GPUs
- (Input/Windows) Add settings to control automatic gamepad type selection heuristics
- (Input/Windows) Add setting to allow DS4 back/select button to trigger touchpad click
- (Input) Add setting to disable high resolution scrolling and native pen/touch support
- (Network) Add support for certificates types other than RSA-2048
- (Build/Linux) Add Fedora 39 docker image and rpm package
- (Capture/Linux) Display monitor indexes in logs for wlroots and KMS capture backends
- (UI) Add link to logs inside fatal error container
- (UI) Add hash handler and ids for all configuration categories and settings
**Changed**
- (UI) Several configuration options have been moved to more suitable locations
- (Network) Client-selected bitrate is now adjusted for FEC percentage and other stream overhead
- (Capture/Linux) Improve VAAPI encoding performance on Intel GPUs
- (Capture) Connection establishment delay is reduced by eliminating many encoder probing operations
- (Process) Graceful termination of running processes is attempted first when stopping apps
- (Capture) Improve software encoding performance by enabling multi-threaded color conversion
- (Capture) Adjust default CPU thread count for software encoding from 1 to 2 for improved performance
- (Steam/Windows) Modernized the default Steam app shortcut to avoid depending on Steam's install location and support app termination
- (Linux) Updated desktop files
- (Config) Add 2560x1440 to default resolutions
- (Network) Use the configured ping timeout for the initial launch event timeout
- (UI) Migrate UI to Vite and Vue3, and various UX improvements
- (Logging) Adjust wording and severity of some log messages
- (Build) Use a single submodule for ffmpeg
- (Install/Windows) Skip ViGEmBus installation if a supported version is already installed
- (Build/Linux) Optionally, allow using the system installation of wayland-protocols
- (Build/Linux) Make vaapi optional
- (Windows) Replace boost::json with nlohmann/json
**Fixed**
- (Network/Windows) Fix auto-discovery of hosts by iOS/tvOS clients
- (Network) Fix immediate connection termination when streaming over some Internet connections
- (Capture/Linux) Fix missing mouse cursor when using KMS capture on a GPU with hardware cursor support
- (Capture/Windows) Add workaround for Nvidia driver bug causing Sunshine to crash when RTX HDR is globally enabled
- (Capture/Windows) Add workaround for AMD driver bug on pre-RDNA GPUs causing hardware encoding failure
- (Capture/Windows) Reintroduce support for NVENC on older Nvidia GPU drivers (v456.71-v522.25)
- (Capture/Windows) Fix encoding on old Intel GPUs that don't support low-power H.264 encoding
- (Capture/Linux) Fix GL errors or corrupt video output on GPUs that use aux planes such as Intel Arc
- (Capture/Linux) Fix GL errors or corrupt video output on GPUs that use DRM modifiers on YUV buffers
- (Input/Windows) Fix non-functional duplicate controllers appearing in rare cases
- (Input/Windows) Avoid triggering crash in ViGEmBus when the system goes to sleep
- (Input/Linux) Fix scrolling in applications that don't support high-resolution scrolling
- (Input/Linux) Fix absolute mouse input being interpreted as touch input
- (Capture/Linux) Fix wlroots capture causing GL errors and crashes
- (Capture/Linux) Fix wlroots capture failing when the display scale factor was not 1
- (Capture/Linux) Fix excessive CPU usage when using wlroots capture backend
- (Capture/Linux) Fix capture of virtual displays created by the amdgpu kernel driver
- (Audio/Windows) Fix audio capture failures on Insider Preview versions of Windows 11
- (Capture/Windows) Fix incorrect portrait mode rotation
- (Capture/Windows) Fix capture recovery when a driver update/crash occurs while streaming
- (Capture/Windows) Fix delay displaying UAC dialogs when the mouse cursor is not moving
- (Capture/Linux) Fix corrupt video output or stream disconnections if the display resolution changes while streaming
- (Capture/Linux) Fix color of aspect ratio padding in the capture image with VAAPI
- (Capture/Linux) Fix NVENC initialization error when using X11 capture with some GPUs
- (Tray/Linux) Fix random crash when the tray icon is updating
- (Network) Fix QoS tagging when running in IPv4+IPv6 mode
- (Process) Fix termination of child processes upon app quit when the parent has already terminated
- (Process) Fix notification of graceful termination to connected clients when Sunshine quits
- (Capture) Fix corrupt output or green aspect-ratio padding when using software encoding with some video resolutions
- (Windows) Fix crashes when processing file paths or other strings with certain non-ASCII characters
- (Capture) Ensure user supplied framerates are used exclusively in place of pre-defined framerates
- (CMake/Linux) Skip including unnecessary headers
- (Capture/Linux) Replace vaTerminate method with dl handle
- (Capture/Linux) Fix capture when DRM is enabled and x11 is disabled
- (Tray) Use PROJECT_NAME definition for tooltip
- (CMake) Use GNUInstallDirs to install data and lib directories
- (macOS) Replace deprecated code
- (API) Allow trailing slashes in on API endpoints
- (API) Add additional pin validation
- (Linux) Use XDG spec for fetching config directory
- (CMake) Properly find evdev
- (Config) Properly save global_prep_cmd and fps settings
**Dependencies**
- Bump third-party/wayland-protocols from 681c33c to 46f201b
- Bump third-party/nv-codec-headers from 9402b5a to 22441b5
- Bump third-party/nanors from 395e5ad to e9e242e
- Bump third-party/Simple-Web-Server from 2f29926 to 27b41f5
- Bump ffmpeg
- Bump third-party/tray from 2664388 to 2bf1c61
- Bump actions/setup-python from 4 to 5
- Bump actions/upload-artifact from 3 to 4
- Bump @fortawesome/fontawesome-free from 6.4.2 to 6.5.1
- Bump babel from 2.13.0 to 2.14.0
- Move miniupnpc from submodule to system installed package
- Bump furo from 2023.9.10 to 2024.1.29
- Bump third-party/moonlight-common-c from f78f213 to cbd0ec1
- Bump third-party/ViGEmClient from 1920260 to 8d71f67
- Bump peter-evans/create-pull-request from 5 to 6
- Bump bootstrap from 5.3.2 to 5.3.3
**Misc**
- (Build) Update global workflows
- (Docs/Linux) Add example for setting custom resolution with NVIDIA
- (Docs) Fix broken links
- (Docs/Windows) Add information about disk permissions
- (Docs) Fix failing images
- (Docs) Use glob pattern to match source code docs
- (CI/macOS) Install boost from source
- (Docs) Add reset credentials examples for unique packages
- (Docs) Refactor and general cleanup
- (Docs) Cross-reference config settings to the UI
- (Docs/Docker) Add podman notes
- (Build) Use CMAKE_SOURCE_DIR property everywhere
- (Build/Docker) Add docker toolchain file for CLion
- (macOS) Various code style fixes
- (Deps) Alphabetize git submodules
- (Docs/Examples) Update URI examples
- (Refactor) Refactored some code in preparation for unit testing implementation
- (CMake) Add option to skip cuda inheriting compile options
- (CMake) Add option to error build on warnings
## [0.21.0] - 2023-10-15
**Added**
- (Input) Add support for automatically selecting the emulated controller type based on the physical controller connected to the client
- (Input/Windows) Add support for Applications (context menu) key
- (Input/Windows) Implement touchpad, motion sensors, battery state, and LED control for the emulated DualShock 4 controller
- (Input) Advertise support for new input features to clients
- (Linux/Debian) Added Debian Bookworm package
- (Prep-Commands) Expose connection environment variables
- (Input/Windows) Implement pen and touch support
- (Capture/Windows) Add standalone NVENC encoder
- (Capture) Implement AV1 encoding
- (Network) Implement IPv6 support
- (Capture/Windows) Add option to disable realtime hags
- (Graphics/NVIDIA) Add an option to decrease GPU scheduling priority to workaround HAGS video hang
- (Capture/Linux) Add FFmpeg powerpc64le architecture for self compiling Sunshine
- (Capture/Windows) Add support for capturing rotated displays
- (System Tray) Implement streaming event notifications
- (UI) Add port configuration table
- (Applications) Added option to automatically treat launcher type apps as detached commands
- (Input/Gamepad) Allow the Misc button to work as Guide on emulated Xbox 360 controllers
**Changed**
- (Input) Reduce latency by implementing input batching
- (Logging) Move input packet debug prints off the control stream thread
- (Input) Refactor gamepad emulation code to use DS4 extended report format
- (Graphics/NVIDIA) Modify and restore NVIDIA control panel settings before and after stream, respectively
- (Graphics/NVIDIA) New config page for NVENC
- (Graphics/Windows) Refactor DX shaders
- (Input/Windows) Use our own keycode mapping to avoid installing the US English keyboard layout
**Fixed**
- (UI) Fix update notifications
- (Dependencies/Linux) Replace libboost chrono and thread with standard chrono and thread
- (Input) Increase maximum gamepad limit to 16
- (Network) Allow use of multiple ENet channels
- (Network) Consider link-local addresses on LAN
- (Input) Fixed issue where button may sometimes stick on Windows
- (Input) Fix "ControllerNumber not allocated" warning when a gamepad is removed
- (Input) Fix handling of gamepad feedback with multiple clients connected
- (Input) Fix clamping mouse position to aspect ratio adjusted viewport
- (Graphics/AMD) Fix crash during startup on some older AMD GPUs
- (Logging) Fix crash when non-ASCII characters are logged
- (Prep-Commands) Fix resource exhaustion bug which could occur when many prep commands were used
- (Subprocesses) Fix race condition when inserting new processes
- (Logging) Log error if encoder doesn't produce IDR frame on demand
- (Audio) Improve audio capture logic and logging
- (Logging) Fix AMF logging to match configured log level
- (Logging) Log FFmpeg to log file instead of stdout
- (Capture) Reject codecs that are not supported by display device
- (Capture) Add fallbacks for unsupported codec settings
- (Capture) Avoid probing HEVC or AV1 codecs in some cases
- (Caputre) Remove DwmFlush()
- (Capture/Windows) Improvements to capture sleeps for better frame stability
- (Capture/Windows) Adjust capture rate to better match with display
- (Linux/ArchLinux) Fix package version in PKGBUILD and precompiled package
- (UI) Highlight fatal log messages in web ui
- (Commands) Allow stream if prep command fails
- (Capture/Linux) Fix KMS grab VRAM capture with libva 2.20
- (Capture/macOS) Fix video capture backend
- (Misc/Windows) Don't start the session monitor window when launched in command mode
- (Linux/AppImage) Use the linuxdeploy GTK plugin to correctly deploy GTK3 dependencies
- (Input/Windows) Fix reWASD not recognizing emulated DualShock 4 input
**Dependencies**
- Bump bootstrap from 5.2.3 to 5.3.2
- Bump third-party/moonlight-common-c from c9426a6 to 7a6d12f
- Bump gcc-10 in Ubuntu 20.04 docker image
- Bump furo from 2023.5.20 to 2023.9.10
- Bump sphinx from 7.0.1 to 7.2.6
- Bump cmake from 3.26 to 3.27 in Fedora docker images
- Move third-party/nv-codec-headers from sdk/11.1 branch to sdk/12.0 branch
- Automatic bump ffmpeg
- Bump actions/checkout from 3 to 4
- Bump boost from 1.80 to 1.81 in Macport manifest
- Bump @fortawesome/fontawesome-free from 6.4.0 to 6.4.2
**Misc**
- (Docs) Force badges to use svg
- (Docs) Add Linux SSH example
- (Docs) Add information about mesa for Linux
- (CI) Free additional space on Docker, Flatpak, and AppImage builds due to internal changes on GitHub runners
- (Docs/Logging/UI) Corrected various typos
- (Docs) Add blurb about Gamescope compatibility
- (Installer/Windows) Use system proxy to download ViGEmBus
- (CI) Ignore third-party directory for clang-format
- (Docs/Linux) Add Plasma-Compatible resolution example
- (Docs) Add Sunshine website available at https://app.lizardbyte.dev/Sunshine
- (Build/Windows) Fix audio code build with new MinGW headers
- (Build/Windows) Fix QoS code build with new MinGW headers
- (CI/Windows) Prevent winget action from creating an update when running in a fork
- (CI/Windows) Change winget job to ubuntu-latest runner
- (CI) Add CodeQL analysis
- (CI/Docker) Fix ArchLinux image caching issue
- (Windows) Manifest improvements
- (CI/macOS) Simplify macport build
- (Docs) Remove deprecated options from readthedocs config
- (CI/Docs) Lint rst files
- (Docs) Update localization information (after consolidating Crowdin projects)
- (Cmake) Split CMakelists into modules
- (Docs) Add Linux Headless/SSH Guide
## [0.20.0] - 2023-05-28
**Breaking**
- (Windows) The Windows installer version of Sunshine is now always launched by the Sunshine Service. Manually launching Sunshine.exe from Program Files is no longer supported. This was necessary to address security issues caused by non-admin users having access to Sunshine's config data. If you have set up Task Scheduler or other mechanisms to launch Sunshine automatically, remove those from your system before updating.
- (Windows) The Start Menu shortcut has been redesigned for use with the Sunshine Service. It now launches Sunshine in the background (if not already running) and opens the Web UI, avoiding the persistent Command Prompt window present in prior versions. The Start Menu shortcut is now the recommended method for opening the Web UI and launching Sunshine.
- (Network/UPnP) If the Moonlight Internet Hosting Tool is installed alongside Sunshine, you must remove it or upgrade to v5.6 or later to prevent conflicts with Sunshine's UPnP support. As a reminder, the Moonlight Internet Hosting Tool is not required to stream over the Internet with Sunshine. Instead, simply enable UPnP in the Sunshine Web UI.
- (Windows) If Steam is installed, the Steam Streaming Speakers driver will be automatically installed when starting a stream for the first time. This behavior can be disabled in the Audio/Video tab of the Web UI. This Steam driver enables support for surround sound and muting host audio without requiring any manual configuration.
- (Input) The Back Button Timeout option has been renamed to Guide Button Emulation Timeout and has been disabled by default to ensure long presses on the Back button work by default. The previous behavior can be restored by setting the Guide Button Emulation Timeout to 2000.
- (Windows) The service name of SunshineSvc has been changed to SunshineService to address a false positive in MalwareBytes. If you have any scripts or other logic on your system that is using the service name, you will need to update that for the new name.
- (Windows) To support new installer features, install-service.bat no longer sets the service to auto-start by default. Users executing install-service.bat manually on the Sunshine portable build must also execute autostart-service.bat to start Sunshine on boot. However, installing the service manually like this is not recommended. Instead, use the Sunshine installer which handles service installation and configuration automatically.
- (Linux/Fedora) Fedora 36 builds are removed due to upstream end of support
**Added**
- (Windows) Added an option to launch apps and prep/undo commands as administrator
- (Installer/Windows) Added an option to choose whether Sunshine launches on boot. If not configured to launch on boot, use the Start Menu shortcut to start Sunshine when desired.
- (Input/Windows) Added option to send VK codes instead of scancodes for compatibility with iOS/Android devices using non-English keyboard layouts
- (UI) The Apply/Restart option is now available in the Web UI for all platforms
- (Systray) Added a Restart option to the system tray context menu
- (Video/Windows) Added host latency data to video frames. This requires future updates to Moonlight to display in the on-screen overlay.
- (Audio) Added support for matching Audio Sink and Virtual Sink values on device names
- (Client) Added friendly error messages for clients when streaming fails to start
- (Video/Windows) Added warning log messages when Windows is hiding DRM-protected content from display capture
- (Interop/Windows) Added warning log messages when GeForce Experience is currently using the same ports as Sunshine
- (Linux/Fedora) Fedora 38 builds are now available
**Changed**
- (Video) Encoder selection now happens at each stream start for more reliable GPU detection
- (Video/Windows) The host display now stays on while clients are actively streaming
- (Audio) Streaming will no longer fail if audio capture is unavailable
- (Audio/Windows) Sunshine will automatically switch back to the Virtual Sink if the default audio device is changed while streaming
- (Audio) Changes to the host audio playback option will now take effect when resuming a session from Moonlight
- (Audio/Windows) Sunshine will switch to a different default audio device if Steam Streaming Speakers are the default when Sunshine starts. This handles cases where Sunshine terminates unexpectedly without restoring the default audio device.
- (Apps) The Connection Terminated dialog will no longer appear in Moonlight when the app on the host exits normally
- (Systray/Windows) Quitting Sunshine via the system tray will now stop the Sunshine Service rather than leaving it running and allowing it to restart Sunshine
- (UI) The 100.64.0.0/10 CGN IP address range is now treated as a LAN address range
- (Video) Removed a workaround for some versions of Moonlight prior to mid-2022
- (UI) The PIN field is now cleared after successfully pairing
- (UI) User names are now treated as case-insensitive
- (Linux) Changed udev rule to automatically grant access to virtual input devices
- (UI) Several item descriptions were adjusted to reflect newer configuration recommendations
- (UI) Placeholder text opacity has been reduced to improve contrast with non-placeholder text
- (Video/Windows) Minor capture performance improvements
**Fixed**
- (Video) VRAM usage while streaming is significantly reduced, particularly with higher display resolutions and HDR
- (Network/UPnP) UPnP support was rewritten to fix several major issues handling router restarts, IP address changes, and port forwarding expiration
- (Input) Fixed modifier keys from the software keyboard on Android clients
- (Audio) Fixed handling of default audio device changes while streaming
- (Windows) Fixed streaming after Microsoft Remote Desktop or Fast User Switching has been used
- (Input) Fixed some games not recognizing emulated Guide button presses
- (Video/Windows) Fixed incorrect gamma when using an Advanced Color SDR display on the host
- (Installer/Windows) The installer is no longer blurry on High DPI systems
- (Systray/Windows) Fixed multiple system tray icons appearing if Sunshine exits unexpectedly
- (Systray/Windows) Fixed the system tray icon not appearing in several situations
- (Windows) Fixed hang on shutdown/restart if mDNS registration fails
- (UI) Fixed missing response headers
- (Stability) Fixed several possible crashes in cases where the client did not successfully connect
- (Stability) Fixed several memory leaks
- (Input/Windows) Back/Select input now correctly generates the Share button when emulating DS4 controllers
- (Audio/Windows) Fixed various bugs in audio-info.exe that led to inaccurate output on some systems
- (Video/Windows) Fixed incorrect resolution values from dxgi-info.exe on High DPI systems
- (Video/Linux) Fixed poor quality encoding from H.264 on Intel encoders
- (Config) Fixed a couple of typos in predefined resolutions
**Dependencies**
- Bump sphinx-copybutton from 0.5.1 to 0.5.2
- Bump sphinx from 6.13 to 7.0.1
- Bump third-party/nv-codec-headers from 2055784 to 2cd175b
- Bump furo from 2023.3.27 to 2023.5.20
**Misc**
- (Build/Linux) Add X11 to PLATFORM_LIBARIES when found
- (Build/macOS) Fix compilation with Clang 14
- (Docs) Fix nvlax URL
- (Docs) Add diagrams using graphviz
- (Docs) Improvements to source code documentation
- (Build) Unpin docker dependencies
- (Build/Linux) Honor install prefix for tray icon
- (Build/Windows) Unstripped binaries are now provided as a debuginfo package to support crash dump debugging
- (Config) Config directories are now created recursively
## [0.19.1] - 2023-03-30
**Fixed**
- (Audio) Fixed no audio issue introduced in v0.19.0
## [0.19.0] - 2023-03-29
**Breaking**
- (Linux/Flatpak) Moved Flatpak to org.freedesktop.Platform 22.08 and Cuda 12.0.0
This will drop support for Nvidia GPUs with compute capability 3.5
**Added**
- (Input) Added option to suppress input from gamepads, keyboards, or mice
- (Input/Linux) Added unicode support for remote pasting (may not work on all DEs)
- (Input/Linux) Added XTest input fallback
- (UI) Added version notifications to web UI
- (Linux/Windows) Add system tray icon
- (Windows) Added ability to safely elevate commands that fail due to insufficient permissions when running as a service
- (Config) Added global prep commands, and ability to exclude an app from using global prep commands
- (Installer/Windows) Automatically install ViGEmBus if selected
**Changed**
- (Logging) Changed client verified messages to debug to prevent spamming the log
- (Config) Only save non default config values
- (Service/Linux) Use xdg-desktop-autostart for systemd service
- (Linux) Added config option to force capture method
- (Windows) Execute prep command in context of current user
- (Linux) Allow disconnected X11 outputs
**Fixed**
- (Input/Windows) Fix issue where internation keys were not translated correct, and modifier keys appeared stuck
- (Linux) Fixed startup when /dev/dri didn't exist
- (UI) Changes software encoding settings to select menu instead of text input
- (Initialization) Do not terminate upon failure, allowing access to the web UI
**Dependencies**
- Bump third-party/moonlight-common-c from 07beb0f to c9426a6
- Bump babel from 2.11.0 to 2.12.1
- Bump @fortawesome/fontawesome-free from 6.2.1 to 6.4.0
- Bump third-party/ViGEmClient from 9e842ba to 726404e
- Bump ffmpeg
- Bump third-party/miniupnp from 014c9df to e439318
- Bump furo from 2022.12.7 to 2023.3.27
- Bump third-party/nanors from 395e5ad to e9e242e
**Misc**
- (GitHub) Shared feature request board with Moonlight
- (Docs) Improved application examples
- (Docs) Added WIP documentation for source code using Doxygen and Breathe
- (Build) Fix linux clang build errors
- (Build/Archlinux) Skip irrelevant submodules
- (Build/Archlinux) Disable download timeout
- (Build/macOS) Support compiling for earlier releases of macOS
- (Docs) Add favicon
- (Docs) Add missing config default values
- (Build) Fix compiler warnings due to depreciated elements in C++17
- (Build) Fix libcurl link errors
- (Clang) Adjusted formatting rules
## [0.18.4] - 2023-02-20
**Fixed**
- (Linux/AUR) Drop support of AUR package
- (Docker) General enhancements to docker images
## [0.18.3] - 2023-02-13
**Added**
- (Linux) Added PKGBUILD for Archlinux based distros to releases
- (Linux) Added precompiled package for Archlinux based distros to releases
- (Docker) Added archlinux docker image (x86_64 only)
## [0.18.2] - 2023-02-13
**Fixed**
- (Video/KMV/Linux) Fixed wayland capture on Nvidia for KMS
- (Video/Linux) Implement vaSyncBuffer stuf for libva <2.9.0
- (UI) Fix issue where mime type was not being set for node_modules when using a reverse proxy
- (UI/macOS) Added missing audio sink config options
- (Linux) Specify correct Boost dependency versions
- (Video/AMF) Add missing encoder tunables
## [0.18.1] - 2023-01-31
**Fixed**
- (Linux) Fixed missing dependencies for deb and rpm packages
- (Linux) Use dynamic boost
## [0.18.0] - 2023-01-29
Attention, this release contains critical security fixes. Please update as soon as possible. Additionally, we are
encouraging users to change your Sunshine password, especially if you expose the web UI (i.e. port 47790 by default)
to the internet, or have ever uploaded your logs with verbose output to a public resource.
**Added**
- (Windows) Add support for Intel QuickSync
- (Linux) Added aarch64 deb and rpm packages
- (Windows) Add support for hybrid graphics systems, such as laptops with both integrated and discrete GPUs
- (Linux) Add support for streaming from Steam Deck Gaming Mode
- (Windows) Add HDR support, see https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/usage.html#hdr-support
**Fixed**
- (Network) Refactor code for UPnP port forwarding
- (Video) Enforce 10 FPS encoding frame rate minimum to improve static image quality
- (Linux) deb and rpm packages are now specific to destination distro and version
- (Docs) Add nvidia/nvenc preset migration guide
- (Network) Performance optimizations
- (Video/Windows) Fix streaming to multiple clients from hardware encoder
- (Linux) Fix child process spawning
- (Security) Fix security vulnerability in implementation of SimpleWebServer
- (Misc) Rename "Steam BigPicture" to "Steam Big Picture" in default apps.json
- (Security) Scrub basic authorization header from logs
- (Linux) The systemd service will now restart in the event of a crash
- (Video/KMS/Linux) Fixed error: `couldn't import RGB Image: 00003002 and 00003004`
- (Video/Windows) Fix stream freezing triggered by the resolution changed
- (Installer/Windows) Fixes silent installation and other miscellaneous improvements
- (CPU) Significantly improved CPU usage
## [0.17.0] - 2023-01-08
If you are running Sunshine as a service on Windows, we are strongly urging you to update to v0.17.0 as soon as
possible. Older Windows versions of Sunshine had a security flaw in which the binary was located in a user-writable
location which is problematic when running as a service or on a multi-user system. Additionally, when running Sunshine
as a service, games and applications were launched as SYSTEM. This could lead to issues with save files and other game
settings. In v0.17.0, games now run under your user account without elevated privileges.
**Breaking**
- (Apps) Removed automatic desktop entry (Re-add by adding an empty application named "Desktop" with no commands, "desktop.png" can be added as the image.)
- (Windows) Improved user upgrade experience (Suggest to manually uninstall existing Sunshine version before this upgrade. Do NOT select to remove everything, if prompted. Make a backup of config files before uninstall.)
- (Windows) Move config files to specific directory (files will be migrated automatically if using Windows installer)
- (Dependencies) Fix npm path (breaking change for package maintainers)
**Added**
- (macOS) Added initial support for arm64 on macOS through Macports portfile
- (Input) Added support for foreign keyboard input
- (Misc) Logs inside the WebUI and log to file
- (UI/Windows) Added an Apply button to configuration page when running as a service
- (Input/Windows) Enable Mouse Keys while streaming for systems with no physical mouse
**Fixed**
- (Video) Improved capture performance
- (Audio) Improved audio bitrate and quality handling
- (Apps/Windows) Fixed PATH environment variable handling
- (Apps/Windows) Use the proper environment variable for the Program Files (x86) folder
- (Service/Windows) Fix SunshineSvc hanging if an error occurs during startup
- (Service/Windows) Spawn Sunshine.exe in a job object, so it is terminated if SunshineSvc.exe dies
- (Video) windows/vram: fix fringing in NV12 colour conversion
- (Apps/Windows) Launch games under the correct user account
- (Video) nvenc, amdvce: rework all user presets/options
- (Network) Generate certificates with unique serial numbers
- (Service/Windows) Graceful termination on shutdown, logoff, and service stop
- (Apps/Windows) Fix launching apps when Sunshine is running as admin
- (Misc) Remove/fix calls to std::abort()
- (Misc) Remove prompt to press enter after Sunshine exits
- (Misc) Make log priority consistent for execution messages
- (Apps) Applications in Moonlight clients are now updated automatically after editing
- (Video/Linux) Fix wayland capture on nvidia
- (Audio) Fix 7.1 surround channel mapping
- (Video) Fix NVENC profile values not applying
- (Network) Fix origin_web_ui_allowed binding
- (Service/Windows) Self terminate/restart service if process hangs for 10 seconds
- (Input/Windows) Fix Windows masked cursor blending with GPU encoders
- (Video) Color conversion fixes and BT.2020 support
**Dependencies**
- Bump ffmpeg from 4.4 to 5.1
- ffmpeg_patches: add amfenc delay/buffering fix
- CBS moved to ffmpeg submodules
- Migrate to upstream Simple-Web-Server submodule
- Bump third-party/TPCircularBuffer from `bce9170` to `8833b3a`
- Bump third-party/moonlight-common-c from `8169a31` to `ef9ad52`
- Bump third-party/miniupnp from `6f848ae` to `207cf44`
- Bump third-party/ViGEmClient from `f719a1d` to `9e842ba`
- Bump bootstrap from 5.0.0 to 5.2.3
- Bump @fortawesome/fontawesome-free from 6.2.0 to 6.2.1
## [0.16.0] - 2022-12-13
**Added**
- Add cover finder
- (Docker) Add arm64 docker image
- (Flatpak) Add installation helper scripts
- (Windows) Add support for Unicode input messages
**Fixed**
- (Linux) Reintroduce Ubuntu 20.04 and 22.04 specific deb packages
- (Linux) Fixed udev and systemd file locations
**Dependencies**
- Bump babel from 2.10.3 to 2.11.0
- Bump sphinx-copybutton from 0.5.0 to 0.5.1
- Bump KSXGitHub/github-actions-deploy-aur from 2.5.0 to 2.6.0
- Use npm for web dependencies (breaking change for third-party package maintainers)
- Update moonlight-common-c
- Use pre-built ffmpeg from LizardByte/build-deps for all sunshine builds (breaking change for third-party package maintainers)
- Bump furo from 2022.9.29 to 2022.12.7
**Misc**
- Misc org level workflow updates
- Fix misc typos in docs
- Fix winget release
## [0.15.0] - 2022-10-30
**Added**
- (Windows) Add firewall rules scripts
- (Windows) Automatically add and remove firewall rules at install/uninstall
- (Windows) Automatically add and remove service at install/uninstall
- (Docker) Official image added
- (Linux) Add aarch64 flatpak package
**Changed**
- (Windows/Linux/MacOS) - Move default config and apps file to assets directory
- (MacOS) Bump boost to 1.80 for macport builds
- (Linux) Remove backup and restore of config files
**Fixed**
- (Linux) - Create sunshine config directory if it doesn't exist
- (Linux) Remove portable home and config directories for AppImage
- (Windows) Include service install and uninstall scripts again
- (Windows) Automatically delete start menu entry upon uninstall
- (Windows) Automatically delete program install directory upon uninstall, with user prompt
- (Linux) Handle the case of no default audio sink
- (Windows/Linux/MacOS) Fix default image paths
- (Linux) Fix CUDA RGBA to NV12 conversion
## [0.14.1] - 2022-08-09
**Added**
- (Linux) Flatpak package added
- (Linux) AUR package automated updates
- (Windows) Winget package automated updates
**Changed**
- (General) Moved repo to @LizardByte GitHub org
- (WebUI) Fixed button spacing on home page
- (WebUI) Added Discord WidgetBot Crate
**Fixed**
- (Linux/Mac) Default config and app files now copied to user home directory
- (Windows) Default config and app files now copied to working directory
## [0.14.0] - 2022-06-15
**Added**
- (Documentation) Added Sphinx documentation available at https://sunshinestream.readthedocs.io/en/latest/
- (Development) Initial support for Localization
- (Linux) Add rpm package as release asset
- (macOS) Add Portfile as release asset
- (Windows) Add DwmFlush() call to improve capture
- (Windows) Add Windows installer
**Fixed**
- (AMD) Fixed hwdevice being destroyed before context
- (Linux) Added missing dependencies to AppImage
- (Linux) Fixed rumble events causing game to freeze
- (Linux) Improved Pulse/Pipewire compatibility
- (Linux) Moved to single deb package
- (macOS) Fixed missing TPCircularBuffer submodule
- (Stream) Properly catch exceptions in stream broadcast handlers
- (Stream/Video) AVPacket fix
## [0.13.0] - 2022-02-27
**Added**
- (macOS) Initial support for macOS (#40)
## [0.12.0] - 2022-02-13
**Added**
- New command line argument `--version`
- Custom png poster support
**Changed**
- Correct software bitrate calculation
- Increase vbv-bufsize to 1/10 of requested bitrate
- Improvements to Web UI
## [0.11.1] - 2021-10-04
**Changed**
- (Linux) Fix search path for config file and assets
## [0.11.0] - 2021-10-04
**Added**
- (Linux) Added support for wlroots based compositors on Wayland.
- (Windows) Added an icon for the executable
**Changed**
- Fixed a bug causing segfault when connecting multiple controllers.
- (Linux) Improved NVENC, it now offloads converting images from RGB to NV12
- (Linux) Fixed a bug causes stuttering
## [0.10.1] - 2021-08-21
**Changed**
- (Linux) Re-enabled KMS
## [0.10.0] - 2021-08-20
**Added**
- Added support for Rumble with gamepads.
- Added support for keyboard shortcuts <--- See the README for details.
- (Windows) A very basic script has been added in Sunshine-Windows\tools <-- This will start Sunshine at boot with the highest privileges which is needed to display the login prompt.
**Changed**
- Some cosmetic changes to the WebUI.
- The first time the WebUI is opened, it will request the creation of a username/password pair from the user.
- Fixed audio crackling introduced in version 0.8.0
- (Linux) VAAPI hardware encoding now works on Intel i7-6700 at least. <-- For the best experience, using ffmpeg version 4.3 or higher is recommended.
- (Windows) Installing from debian package shouldn't overwrite your configuration files anymore. <-- It's recommended that you back up `/etc/sunshine/` before testing this.
## [0.9.0] - 2021-07-11
**Added**
- Added audio encryption
- (Linux) Added basic NVENC support on Linux
- (Windows) The Windows version can now capture the lock screen and the UAC prompt as long as it's run through `PsExec.exe` https://docs.microsoft.com/en-us/sysinternals/downloads/psexec
**Changed**
- Sunshine will now accept expired or not-yet-valid certificates, as long as they are signed properly.
- Fixed compatibility with iOS version of Moonlight
- Drastically reduced chance of being forced to skip error correction due to video frame size
- (Linux) sunshine.service will be installed automatically.
## [0.8.0] - 2021-06-30
**Added**
- Added mDNS support: Moonlight will automatically find Sunshine.
- Added UPnP support. It's off by default.
## [0.7.7] - 2021-06-24
**Added**
- (Linux) Added installation package for Debian
**Changed**
- Fixed incorrect scaling for absolute mouse coordinates when using multiple monitors.
- Fixed incorrect colors when scaling for software encoder
## [0.7.1] - 2021-06-18
**Changed**
- (Linux) Fixed an issue where it was impossible to start sunshine on ubuntu 20.04
## [0.7.0] - 2021-06-16
**Added**
- Added a Web Manager. Accessible through: https://localhost:47990 or https://<ip of your pc>:47990
- (Linux) Added hardware encoding support for AMD on Linux
**Changed**
- (Linux) Moved certificates and saved pairings generated during runtime to .config/sunshine on Linux
## [0.6.0] - 2021-05-26
**Added**
- Added support for surround audio
**Changed**
- Maintain aspect ratio when scaling video
- Fix issue where Sunshine is forced to drop frames when they are too large
## [0.5.0] - 2021-05-13
**Added**
- Added support for absolute mouse coordinates
- (Linux) Added support for streaming specific monitor on Linux
- (Windows) Added support for AMF on Windows
## [0.4.0] - 2020-05-03
**Changed**
- prep-cmd is now optional in apps.json
- Fixed bug causing video artifacts
- Fixed bug preventing Moonlight from closing app on exit
- Fixed bug causing preventing keyboard keys from repeating on latest version of Moonlight
- Fixed bug causing segfault when another session of sunshine was already running
- Fixed bug causing crash when monitor has resolution 1366x768
## [0.3.1] - 2020-04-24
**Changed**
- Fix a memory leak.
## [0.3.0] - 2020-04-23
**Changed**
- Hardware acceleration on NVidia GPU's for Video encoding on Windows
## [0.2.0] - 2020-03-21
**Changed**
- Multicasting is now supported: You can set the maximum simultaneous connections with the configurable option: channels
- Configuration variables can be overwritten on the command line: "name=value" --> it can be useful to set min_log_level=debug without modifying the configuration file
- Switches to make testing the pairing mechanism more convenient has been added, see "sunshine --help" for details
## [0.1.1] - 2020-01-30
**Added**
- (Linux) Added deb package and service for Linux
## [0.1.0] - 2020-01-27
**Added**
- The first official release for Sunshine!
[0.1.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.1.0
[0.1.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.1.1
[0.2.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.2.0
[0.3.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.3.0
[0.3.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.3.1
[0.4.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.4.0
[0.5.0]: https://github.com/LizardByte/Sunshine/releases/tag/0.5.0
[0.6.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.6.0
[0.7.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.7.0
[0.7.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.7.1
[0.7.7]: https://github.com/LizardByte/Sunshine/releases/tag/v0.7.7
[0.8.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.8.0
[0.9.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.9.0
[0.10.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.10.0
[0.10.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.10.1
[0.11.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.11.0
[0.11.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.11.1
[0.12.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.12.0
[0.13.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.13.0
[0.14.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.14.0
[0.14.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.14.1
[0.15.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.15.0
[0.16.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.16.0
[0.17.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.17.0
[0.18.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.0
[0.18.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.1
[0.18.2]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.2
[0.18.3]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.3
[0.18.4]: https://github.com/LizardByte/Sunshine/releases/tag/v0.18.4
[0.19.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.19.0
[0.19.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.19.1
[0.20.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.20.0
[0.21.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.21.0
[0.22.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.0
[0.22.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.1
[0.22.2]: https://github.com/LizardByte/Sunshine/releases/tag/v0.22.2
[0.23.0]: https://github.com/LizardByte/Sunshine/releases/tag/v0.23.0
[0.23.1]: https://github.com/LizardByte/Sunshine/releases/tag/v0.23.1

View File

@ -3,8 +3,7 @@ cmake_minimum_required(VERSION 3.18)
# set_source_files_properties requires 3.18
# todo - set this conditionally
# todo - set version to 0.0.0 once confident in automated versioning
project(Sunshine VERSION 0.23.1
project(Sunshine VERSION 0.0.0
DESCRIPTION "Self-hosted game stream host for Moonlight"
HOMEPAGE_URL "https://app.lizardbyte.dev/Sunshine")

View File

@ -19,7 +19,6 @@ ENTRYPOINT steam && sunshine
### SUNSHINE_VERSION
- `latest`, `master`, `vX.X.X`
- `nightly`
- commit hash
### SUNSHINE_OS

View File

@ -67,9 +67,9 @@ Integrations
:alt: GitHub Workflow Status (CI)
:target: https://github.com/LizardByte/Sunshine/actions/workflows/CI.yml?query=branch%3Amaster
.. image:: https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/localize.yml.svg?branch=nightly&label=localize%20build&logo=github&style=for-the-badge
.. image:: https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/localize.yml.svg?branch=master&label=localize%20build&logo=github&style=for-the-badge
:alt: GitHub Workflow Status (localize)
:target: https://github.com/LizardByte/Sunshine/actions/workflows/localize.yml?query=branch%3Anightly
:target: https://github.com/LizardByte/Sunshine/actions/workflows/localize.yml?query=branch%3Amaster
.. image:: https://img.shields.io/readthedocs/sunshinestream.svg?label=Docs&style=for-the-badge&logo=readthedocs
:alt: Read the Docs

View File

@ -5,7 +5,7 @@ if((DEFINED ENV{BRANCH}) AND (DEFINED ENV{BUILD_VERSION}) AND (DEFINED ENV{COMMI
MESSAGE("Got from CI master branch and version $ENV{BUILD_VERSION}")
set(PROJECT_VERSION $ENV{BUILD_VERSION})
elseif((DEFINED ENV{BRANCH}) AND (DEFINED ENV{COMMIT}))
# If BRANCH is set but not BUILD_VERSION we are building nightly, we gather only the commit hash
# If BRANCH is set but not BUILD_VERSION we are building a PR, we gather only the commit hash
MESSAGE("Got from CI $ENV{BRANCH} branch and commit $ENV{COMMIT}")
set(PROJECT_VERSION ${PROJECT_VERSION}.$ENV{COMMIT})
endif()
@ -19,7 +19,6 @@ else()
#Get current Branch
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
#WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE GIT_DESCRIBE_BRANCH
RESULT_VARIABLE GIT_DESCRIBE_ERROR_CODE
OUTPUT_STRIP_TRAILING_WHITESPACE
@ -27,7 +26,6 @@ else()
# Gather current commit
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
#WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE GIT_DESCRIBE_VERSION
RESULT_VARIABLE GIT_DESCRIBE_ERROR_CODE
OUTPUT_STRIP_TRAILING_WHITESPACE
@ -35,7 +33,6 @@ else()
# Check if Dirty
execute_process(
COMMAND ${GIT_EXECUTABLE} diff --quiet --exit-code
#WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE GIT_IS_DIRTY
OUTPUT_STRIP_TRAILING_WHITESPACE
)

View File

@ -1,6 +1,6 @@
---
codecov:
branch: nightly
branch: master
coverage:
status:

View File

@ -160,6 +160,20 @@ editing the `conf` file in a text editor. Use the examples as reference.
global_prep_cmd = [{"do":"nircmd.exe setdisplay 1280 720 32 144","undo":"nircmd.exe setdisplay 2560 1440 32 144"}]
`notify_pre_releases <https://localhost:47990/config/#notify_pre_releases>`__
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Description**
Whether to be notified of new pre-release versions of Sunshine.
**Default**
``disabled``
**Example**
.. code-block:: text
notify_pre_releases = disabled
`Input <https://localhost:47990/config/#input>`__
-------------------------------------------------

View File

@ -74,7 +74,7 @@ html_theme = 'furo'
html_theme_options = {
"top_of_page_button": "edit",
"source_edit_link": "https://github.com/lizardbyte/sunshine/tree/nightly/docs/source/{filename}",
"source_edit_link": "https://github.com/lizardbyte/sunshine/tree/master/docs/source/{filename}",
}
# extension config options

View File

@ -24,8 +24,8 @@ localization there.
When a change is made to sunshine source code, a workflow generates new translation templates
that get pushed to CrowdIn automatically.
When translations are updated on CrowdIn, a push gets made to the `l10n_nightly` branch and a PR is made against the
`nightly` branch. Once PR is merged, all updated translations are part of the project and will be included in the
When translations are updated on CrowdIn, a push gets made to the `l10n_master` branch and a PR is made against the
`master` branch. Once PR is merged, all updated translations are part of the project and will be included in the
next release.
Extraction
@ -86,7 +86,7 @@ Extraction
Strings are automatically extracted from the code to the `locale/sunshine.po` template file. The generated file is
used by CrowdIn to generate language specific template files. The file is generated using the
`.github/workflows/localize.yml` workflow and is run on any push event into the `nightly` branch. Jobs are only run if
`.github/workflows/localize.yml` workflow and is run on any push event into the `master` branch. Jobs are only run if
any of the following paths are modified.
.. code-block:: yaml

View File

@ -1 +1,17 @@
.. mdinclude:: ../../../CHANGELOG.md
Changelog
=========
.. only:: epub
You can view the changelog in the
`online version <https://github.com/LizardByte/Sunshine/changelog/CHANGELOG.md>`__.
.. only:: html
.. raw:: html
<script type="module" src="https://md-block.verou.me/md-block.js"></script>
<md-block
hmin="2"
src="https://raw.githubusercontent.com/LizardByte/Sunshine/changelog/CHANGELOG.md">
</md-block>

View File

@ -292,18 +292,22 @@
</div>
</div>
<div class="card-footer p-3 ms-3">
<a class="btn btn-outline-light me-3 mb-3" href="https://github.com/LizardByte/Sunshine/releases/latest" target="_blank">
<a class="latest-button btn btn-outline-light me-3 mb-3 d-none" href="https://github.com/LizardByte/Sunshine/releases/latest" target="_blank">
<i class="fa-fw fab fa-github"></i>
Latest
Latest: <span id="latest-version"></span>
</a>
<a class="btn btn-outline-light me-3 mb-3" href="https://github.com/LizardByte/Sunshine/releases/tag/nightly-dev" target="_blank">
<i class="fa-fw fas fa-infinity"></i>
Nightly
<a class="beta-button btn btn-outline-light me-3 mb-3 d-none" href="#" target="_blank">
<i class="fa-fw fas fa-flask"></i>
Beta: <span id="beta-version"></span>
</a>
<a class="btn btn-outline-light me-3 mb-3" href="https://hub.docker.com/r/lizardbyte/sunshine" target="_blank">
<i class="fa-fw fab fa-docker"></i>
Docker
</a>
<a class="btn btn-outline-light me-3 mb-3" href="https://github.com/LizardByte/homebrew-homebrew" target="_blank">
<i class="fa-fw fas fa-beer-mug-empty"></i>
Homebrew
</a>
</div>
</div>
</section>
@ -408,5 +412,53 @@
<script src="https://app.lizardbyte.dev/js/footer.js"></script>
<!-- Discord WidgetBot -->
<script src="https://app.lizardbyte.dev/js/discord.js"></script>
<!-- TODO: Move this to website repo, and make it accept arguments for the repo name -->
<script>
// Fetch the releases from the GitHub API
fetch('https://api.github.com/repos/LizardByte/Sunshine/releases')
.then(response => response.json())
.then(data => {
// Filter the releases to get only the pre-releases
const preReleases = data.filter(release => release.prerelease);
// Filter the releases to get only the stable releases
const stableReleases = data.filter(release => !release.prerelease);
// If there are no stable releases, hide the latest download button
if (stableReleases.length === 0) {
document.querySelector('.latest-button').classList.add('d-none');
} else {
// Show the latest download button
document.querySelector('.latest-button').classList.remove('d-none');
// Get the latest stable release
const latestStableRelease = stableReleases[0];
document.querySelector('#latest-version').textContent = latestStableRelease.tag_name;
// If there is a pre-release, update the href attribute of the anchor tag
if (preReleases.length > 0) {
const latestPreRelease = preReleases[0];
// Compare the date of the latest pre-release with the date of the latest stable release
const preReleaseDate = new Date(latestPreRelease.published_at);
const stableReleaseDate = new Date(latestStableRelease.published_at);
// If the pre-release is newer, update the href attribute of the anchor tag
if (preReleaseDate > stableReleaseDate) {
document.querySelector('.beta-button').href = latestPreRelease.html_url;
document.querySelector('#beta-version').textContent = latestPreRelease.tag_name;
document.querySelector('.beta-button').classList.remove('d-none');
} else {
// If the pre-release is older, hide the button
document.querySelector('.beta-button').classList.add('d-none');
}
} else {
// If there is no pre-release, hide the button
document.querySelector('.beta-button').classList.add('d-none');
}
}
});
</script>
</body>
</html>

View File

@ -1,4 +1,4 @@
# Edit on github: https://github.com/LizardByte/Sunshine/blob/nightly/packaging/linux/Arch/PKGBUILD
# Edit on github: https://github.com/LizardByte/Sunshine/blob/master/packaging/linux/Arch/PKGBUILD
# Reference: https://wiki.archlinux.org/title/PKGBUILD
pkgname='sunshine'

View File

@ -462,6 +462,7 @@ namespace config {
47989, // Base port number
"ipv4", // Address family
platf::appdata().string() + "/sunshine.log", // log file
false, // notify_pre_releases
{}, // prep commands
};
@ -1099,6 +1100,8 @@ namespace config {
bool_f(vars, "high_resolution_scrolling", input.high_resolution_scrolling);
bool_f(vars, "native_pen_touch", input.native_pen_touch);
bool_f(vars, "notify_pre_releases", sunshine.notify_pre_releases);
int port = sunshine.port;
int_between_f(vars, "port"s, port, { 1024 + nvhttp::PORT_HTTPS, 65535 - rtsp_stream::RTSP_SETUP_PORT });
sunshine.port = (std::uint16_t) port;

View File

@ -182,7 +182,7 @@ namespace config {
std::string address_family;
std::string log_file;
bool notify_pre_releases;
std::vector<prep_cmd_t> prep_cmds;
};

View File

@ -147,6 +147,7 @@
"sunshine_name": "",
"min_log_level": 2,
"global_prep_cmd": "[]",
"notify_pre_releases": "disabled",
},
},
{

View File

@ -127,6 +127,16 @@ function removeCmd(index) {
&plus; {{ $t('config.add') }}
</button>
</div>
<!-- Notify Pre-Releases -->
<div class="mb-3">
<label for="notify_pre_releases" class="form-label">{{ $t('config.notify_pre_releases') }}</label>
<select id="notify_pre_releases" class="form-select" v-model="config.notify_pre_releases">
<option value="disabled">{{ $t('_common.disabled') }}</option>
<option value="enabled">{{ $t('_common.enabled') }}</option>
</select>
<div class="form-text">{{ $t('config.notify_pre_releases_desc') }}</div>
</div>
</div>
</template>

View File

@ -32,29 +32,28 @@
<div class="alert alert-success" v-if="buildVersionIsDirty">
{{ $t('index.version_dirty') }} 🌇
</div>
<div v-else-if="!nightlyBuildAvailable && !stableBuildAvailable && !buildVersionIsDirty">
<div v-else-if="!preReleaseBuildAvailable && !stableBuildAvailable && !buildVersionIsDirty">
<div class="alert alert-success">
{{ $t('index.version_latest') }}
</div>
</div>
<div v-if="nightlyBuildAvailable">
<div v-if="notifyPreReleases && preReleaseBuildAvailable">
<div class="alert alert-warning">
<div class="d-flex justify-content-between">
<div class="my-2">
<p v-html="$t('index.new_nightly')"></p>
<p>{{ $t('index.new_pre_release') }}</p>
</div>
<a class="btn btn-success m-1" href="https://github.com/LizardByte/Sunshine/releases/nightly-dev"
target="_blank">Download</a>
<a class="btn btn-success m-1" :href="preReleaseVersion.html_url" target="_blank">{{ $t('index.download') }}</a>
</div>
<pre><b>{{nightlyData.head_sha}}</b></pre>
<pre>{{nightlyData.display_title}}</pre>
<pre><b>{{preReleaseVersion.name}}</b></pre>
<pre>{{preReleaseVersion.body}}</pre>
</div>
</div>
<div v-if="stableBuildAvailable">
<div class="alert alert-warning">
<div class="d-flex justify-content-between">
<div class="my-2">
<p v-html="$t('index.new_stable')"></p>
<p>{{ $t('index.new_stable') }}</p>
</div>
<a class="btn btn-success m-1" :href="githubVersion.html_url" target="_blank">{{ $t('index.download') }}</a>
</div>
@ -87,18 +86,19 @@
return {
version: null,
githubVersion: null,
nightlyData: null,
notifyPreReleases: false,
preReleaseVersion: null,
loading: true,
logs: null,
}
},
async created() {
try {
this.version = (await fetch("/api/config").then((r) => r.json())).version;
let config = await fetch("/api/config").then((r) => r.json());
this.notifyPreReleases = config.notify_pre_releases;
this.version = config.version;
this.githubVersion = (await fetch("https://api.github.com/repos/LizardByte/Sunshine/releases/latest").then((r) => r.json()));
if (this.buildVersionIsNightly) {
this.nightlyData = (await fetch("https://api.github.com/repos/LizardByte/Sunshine/actions/workflows/CI.yml/runs?branch=nightly&event=push&exclude_pull_requests=true&per_page=1").then((r) => r.json())).workflow_runs[0];
}
this.githubPreRelease = (await fetch("https://api.github.com/repos/LizardByte/Sunshine/releases").then((r) => r.json())).find(release => release.prerelease);
} catch (e) {
}
try {
@ -110,49 +110,41 @@
},
computed: {
stableBuildAvailable() {
// If we can't get versions, return false
if (!this.githubVersion || !this.version) return false;
// Get the GitHub version tag
let v_github = this.githubVersion.name;
// If the version starts with a v, remove it
if (v_github.indexOf("v") === 0) v_github = v_github.substring(1);
// Get the current version
let v_this = this.version;
// If the version starts with a v, remove it
if (v_this.indexOf("v") === 0) v_this = v_this.substring(1);
// if nightly or dirty, we do an additional check to make sure it's an actual upgrade.
if (this.buildVersionIsNightly || this.buildVersionIsDirty) {
const stableVersion = this.version.split('.').slice(0, 3).join('.');
return this.githubVersion.tag_name.substring(1) > stableVersion;
if (!this.githubVersion || !this.version) {
return false;
}
let v_github = this.githubVersion.name;
if (v_github.indexOf("v") === 0) {
v_github = v_github.substring(1);
}
let v_this = this.version;
if (v_this.indexOf("v") === 0) {
v_this = v_this.substring(1);
}
// return true if the version is different, otherwise false
return v_github !== v_this;
},
nightlyBuildAvailable() {
// Verify nightly data is available and the build version is not stable
// This is important to ensure the UI does not try to load undefined values.
if (!this.nightlyData || this.buildVersionIsStable) return false;
// If built with dirty git tree, return false
if (this.buildVersionIsDirty) return false;
// Get the commit hash
let commit = this.version?.split(".").pop();
// return true if the commit hash is different, otherwise false
return this.nightlyData.head_sha.indexOf(commit) !== 0;
preReleaseBuildAvailable() {
if (!this.githubPreRelease || !this.githubVersion || !this.version) {
return false;
}
let v_github_pre = this.githubPreRelease.name;
if (v_github_pre.indexOf("v") === 0) {
v_github_pre = v_github_pre.substring(1);
}
let v_github_stable = this.githubVersion.name;
if (v_github_stable.indexOf("v") === 0) {
v_github_stable = v_github_stable.substring(1);
}
let v_this = this.version;
if (v_this.indexOf("v") === 0) {
v_this = v_this.substring(1);
}
return v_github_pre !== v_this && new Date(this.githubPreRelease.published_at) > new Date(this.githubVersion.published_at);
},
buildVersionIsDirty() {
return this.version?.split(".").length === 5 &&
this.version.indexOf("dirty") !== -1
},
buildVersionIsNightly() {
return this.version?.split(".").length === 4
},
buildVersionIsStable() {
return this.version?.split(".").length === 3
},
/** Parse the text errors, calculating the text, the timestamp and the level */
fancyLogs() {
if (!this.logs) return [];

View File

@ -215,6 +215,8 @@
"mouse_desc": "Allows guests to control the host system with the mouse",
"native_pen_touch": "Native Pen/Touch Support",
"native_pen_touch_desc": "When enabled, Sunshine will pass through native pen/touch events from Moonlight clients. This can be useful to disable for older applications without native pen/touch support.",
"notify_pre_releases": "PreRelease Notifications",
"notify_pre_releases_desc": "Whether to be notified of new pre-release versions of Sunshine",
"nvenc_h264_cavlc": "Prefer CAVLC over CABAC in H.264",
"nvenc_h264_cavlc_desc": "Simpler form of entropy coding. CAVLC needs around 10% more bitrate for same quality. Only relevant for really old decoding devices.",
"nvenc_latency_over_power": "Prefer lower encoding latency over power savings",
@ -321,8 +323,8 @@
"description": "Sunshine is a self-hosted game stream host for Moonlight.",
"download": "Download",
"loading_latest": "Loading latest release...",
"new_nightly": "A new <b>Nightly</b> Version is Available!",
"new_stable": "A new <b>Stable</b> Version is Available!",
"new_pre_release": "A new Pre-Release Version is Available!",
"new_stable": "A new Stable Version is Available!",
"startup_errors": "<b>Attention!</b> Sunshine detected these errors during startup. We <b>STRONGLY RECOMMEND</b> fixing them before streaming.",
"version_dirty": "Thank you for helping to make Sunshine a better software!",
"version_latest": "You are running the latest version of Sunshine",