Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
0e0a55a
feat(stream): redesign Ctrl+G overlay with tabs and controller suppor…
zortos293 Jul 10, 2026
8b27533
refactor: split oversized modules into focused files (#626)
zortos293 Jul 11, 2026
d568a55
feat(renderer): polish queue shaders and Motion animations (#628)
zortos293 Jul 12, 2026
818a44c
feat(native): internal one-window renderer with external fallback (#619)
zortos293 Jul 12, 2026
fafc52d
Stabilize WebRTC streaming and native window behavior (#635)
zortos293 Jul 12, 2026
ea74dd8
fix(native): honor Windows DPI scaling (#637)
zortos293 Jul 12, 2026
96c268c
feat: add nightly builds and opt-in update channel (#638)
zortos293 Jul 12, 2026
f36da83
fix(updater): Preserve nested macOS signatures (#631)
luizkowalski Jul 12, 2026
9d86e5e
fix(build): configure relocated GStreamer plugins
zortos293 Jul 12, 2026
4c16f22
fix(ci): use supported macOS runner size
zortos293 Jul 12, 2026
ecbc7ce
fix(native): mark Objective-C selectors thread-safe
zortos293 Jul 12, 2026
95921a7
fix(build): sign unsigned nested macOS bundles
zortos293 Jul 12, 2026
5d83e68
fix(build): sign nested macOS Mach-O code
zortos293 Jul 12, 2026
782a275
fix(build): enforce nested macOS signing order
zortos293 Jul 12, 2026
c22228b
fix(release): upload assets before publishing
zortos293 Jul 12, 2026
b03ebe5
fix(release): target repository when publishing
zortos293 Jul 13, 2026
1661df2
fix(native): stabilize high-FPS Vulkan streaming and input (#639)
zortos293 Jul 15, 2026
ed585d1
fix(native): enable DX11 tearing and VRR presentation (#640)
zortos293 Jul 15, 2026
b42edba
fix: align settings/library UI and preserve GFN auth/library ownershi…
zortos293 Jul 16, 2026
b3aca8c
fix(ui): repair settings interactions and accessibility (#649)
zortos293 Jul 17, 2026
4f1eb86
fix(ui): smooth animation lifecycles (#651)
zortos293 Jul 17, 2026
9dcd0a9
feat(streaming): add 90 FPS mode (#652)
zortos293 Jul 18, 2026
1ba6ed5
fix(ci): preserve LF endings for patch files (#653)
zortos293 Jul 18, 2026
b227eec
fix(ci): build only patched D3D11 target (#654)
zortos293 Jul 18, 2026
8accfc3
fix(ci): align Windows GStreamer Vulkan runtime (#655)
zortos293 Jul 18, 2026
6b5b5af
fix(ci): bundle and verify Vulkan loader (#656)
zortos293 Jul 18, 2026
a1e931f
feat(input): Scandinavian keyboard layouts (#624) (#660)
zortos293 Jul 19, 2026
d3188f9
fix(controller): make bottom hint overlay clickable with mouse (#620)…
zortos293 Jul 19, 2026
304dee0
fix(streaming): stop synthesizing 90 FPS from entitlements (#662)
zortos293 Jul 19, 2026
6afaee1
feat(gfn): add Identify as Steam Deck option for Deck modes and 90 FP…
zortos293 Jul 19, 2026
77199a7
fix: Mac missing fullscreen (#642)
anderson-oki Jul 19, 2026
3c3a325
fix(deps): update dependencies and clear npm audit vulnerabilities (#…
zortos293 Jul 19, 2026
54bd133
feat: PostHog telemetry, consent, and in-app feedback (#668)
zortos293 Jul 21, 2026
004fa84
fix(build): restore macOS plist packaging compatibility
zortos293 Jul 21, 2026
8c5de59
fix(native): bundle Windows DLL dependency closure (#676)
zortos293 Jul 25, 2026
db4bb72
feat(native): add Linux and Raspberry Pi codec support (#679)
zortos293 Jul 25, 2026
d386d1e
refactor(settings): centralize platform defaults (#683)
zortos293 Jul 27, 2026
fa86f04
refactor(settings): split stream settings modules (#685)
zortos293 Jul 27, 2026
74abf75
refactor(stream): decompose StreamView runtime (#686)
zortos293 Jul 27, 2026
7abb8c8
refactor(gfn): modularize NVST RTSP probe (#682)
zortos293 Jul 27, 2026
98f5f53
refactor(native): extract streamer runtime helpers (#684)
zortos293 Jul 27, 2026
c27e010
refactor(renderer): extract App stream runtime orchestration (#690)
zortos293 Jul 27, 2026
e1006c2
refactor(gfn): decompose auth service (#689)
zortos293 Jul 27, 2026
b8f3c7f
refactor(gfn): split input protocol modules (#688)
zortos293 Jul 27, 2026
4905d5c
refactor(gfn): modularize SDP transformations (#687)
zortos293 Jul 27, 2026
9062245
refactor(gfn): compose WebRTC client from focused controllers (#691)
zortos293 Jul 27, 2026
43438db
feat(discord): show game artwork in rich presence (#681)
zortos293 Jul 28, 2026
6b271bd
Merge main into dev
zortos293 Jul 29, 2026
710d05e
fix(security): verify signaling TLS certificates
zortos293 Jul 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
opennow-stable/src/main/gfn/games.ts whitespace=blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol
opennow-stable/src/main/ipc/accountCatalogHandlers.ts whitespace=blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol
opennow-stable/src/renderer/src/components/HomePage.tsx whitespace=blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol
*.patch text eol=lf
35 changes: 34 additions & 1 deletion .github/workflows/auto-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ jobs:
const isPullRequest = eventName === "pull_request";
const isDevValidationPullRequest = isPullRequest && baseRef === "dev";
const include = isDevValidationPullRequest
? builds.filter(({ label }) => label === "windows-x64" || label === "linux-x64")
? builds.filter(({ label }) =>
label === "windows-x64" || label === "linux-x64" || label === "linux-arm64")
: builds;

fs.appendFileSync(process.env.GITHUB_OUTPUT, `matrix=${JSON.stringify({ include })}\n`);
Expand Down Expand Up @@ -122,6 +123,32 @@ jobs:
with:
bun-version: 1.3.14

- name: Setup Rust
if: runner.os == 'Linux'
uses: dtolnay/rust-toolchain@stable

- name: Install Linux native streamer dependencies
if: runner.os == 'Linux'
env:
DEBIAN_FRONTEND: noninteractive
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential \
pkg-config \
libx11-dev \
libglib2.0-dev \
libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \
libgstreamer-plugins-bad1.0-dev \
gstreamer1.0-libav \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-nice \
gstreamer1.0-gl \
gstreamer1.0-x

- name: Install dependencies
run: bun install --frozen-lockfile

Expand All @@ -137,6 +164,12 @@ jobs:
id: test
run: npm test

- name: Test and build Linux native streamer
if: runner.os == 'Linux'
run: |
cargo test --manifest-path ../native/opennow-streamer/Cargo.toml --features gstreamer
npm run native:build

- name: CI summary
if: always()
working-directory: .
Expand Down
143 changes: 113 additions & 30 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ name: release
on:
workflow_dispatch:
inputs:
release_type:
description: Publish a stable release or a test-only nightly from dev
required: true
default: stable
type: choice
options:
- stable
- nightly
version:
description: Version to release, e.g. 1.2.3 or v1.2.3
description: Target version (for a nightly, use the next stable version, e.g. 1.2.3)
required: true
type: string
push:
Expand All @@ -22,13 +30,15 @@ permissions:
jobs:
preflight:
name: preflight
runs-on: blacksmith-2vcpu-ubuntu-2404
runs-on: blacksmith-4vcpu-ubuntu-2404
outputs:
version: ${{ steps.release.outputs.version }}
prerelease: ${{ steps.release.outputs.prerelease }}
make_latest: ${{ steps.release.outputs.make_latest }}
release_tag: ${{ steps.release.outputs.release_tag }}
source_ref: ${{ steps.release.outputs.source_ref }}
release_type: ${{ steps.release.outputs.release_type }}
release_name: ${{ steps.release.outputs.release_name }}

steps:
- name: Checkout
Expand All @@ -55,8 +65,16 @@ jobs:
env:
INPUT_VERSION: ${{ inputs.version }}
REF_NAME: ${{ github.ref_name }}
REF_TYPE: ${{ github.ref_type }}
EVENT_NAME: ${{ github.event_name }}
RELEASE_TYPE: ${{ inputs.release_type }}
RUN_NUMBER: ${{ github.run_number }}
RUN_ATTEMPT: ${{ github.run_attempt }}
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail

release_type="${RELEASE_TYPE:-stable}"
raw="${INPUT_VERSION:-$REF_NAME}"
case "$raw" in
opennow-stable-v*) version="${raw#opennow-stable-v}" ;;
Expand All @@ -69,6 +87,33 @@ jobs:
exit 1
fi

release_name="OpenNOW v${version}"
if [[ "$release_type" == "nightly" ]]; then
if [[ "$EVENT_NAME" != "workflow_dispatch" || "$REF_TYPE" != "branch" || "$REF_NAME" != "dev" ]]; then
echo "Nightly releases must be manually dispatched from the dev branch." >&2
exit 1
fi
if [[ "$version" == *-* || "$version" == *+* ]]; then
echo "Nightly target version must be a stable semver such as 1.2.3; the nightly suffix is added automatically." >&2
exit 1
fi
latest_tag="$(gh api "repos/${GITHUB_REPOSITORY}/releases/latest" --jq .tag_name)"
latest_version="${latest_tag#opennow-stable-v}"
latest_version="${latest_version#v}"
if [[ "$latest_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
highest_version="$(printf '%s\n%s\n' "$latest_version" "$version" | sort -V | tail -n 1)"
if [[ "$version" == "$latest_version" || "$highest_version" != "$version" ]]; then
echo "Nightly target $version must be newer than the latest stable release $latest_version." >&2
exit 1
fi
fi
version="${version}-nightly.${RUN_NUMBER}.${RUN_ATTEMPT}"
release_name="OpenNOW Nightly v${version}"
elif [[ "$release_type" != "stable" ]]; then
echo "Unsupported release type: $release_type" >&2
exit 1
fi

prerelease=false
if [[ "$version" == *-* ]]; then
prerelease=true
Expand All @@ -93,11 +138,13 @@ jobs:
echo "make_latest=$make_latest"
echo "release_tag=$release_tag"
echo "source_ref=$source_ref"
echo "release_type=$release_type"
echo "release_name=$release_name"
} >> "$GITHUB_OUTPUT"

prepare-source:
name: prepare-source
runs-on: blacksmith-2vcpu-ubuntu-2404
runs-on: blacksmith-4vcpu-ubuntu-2404
needs: preflight
permissions:
contents: write
Expand All @@ -120,7 +167,14 @@ jobs:
REF_TYPE: ${{ github.ref_type }}
RELEASE_VERSION: ${{ needs.preflight.outputs.version }}
SOURCE_REF: ${{ needs.preflight.outputs.source_ref }}
RELEASE_TYPE: ${{ needs.preflight.outputs.release_type }}
run: |
if [[ "$RELEASE_TYPE" == "nightly" ]]; then
echo "Nightly version is applied only inside build jobs; dev remains unchanged."
echo "release_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
exit 0
fi

if [[ "$EVENT_NAME" != "workflow_dispatch" ]]; then
node opennow-stable/scripts/sync-release-version.mjs --check "$RELEASE_VERSION"
echo "release_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -155,7 +209,7 @@ jobs:
matrix:
include:
- label: windows-x64
os: blacksmith-2vcpu-windows-2025
os: blacksmith-4vcpu-windows-2025
builder_args: "--win nsis portable --x64"
native_build: "true"
bundle_gstreamer: "1"
Expand All @@ -166,7 +220,7 @@ jobs:
opennow-stable/dist-release/latest*.yml
opennow-stable/dist-release/*.blockmap
- label: windows-arm64
os: blacksmith-2vcpu-windows-2025
os: blacksmith-4vcpu-windows-2025
builder_args: "--win nsis portable --arm64"
native_build: "false"
bundle_gstreamer: "0"
Expand Down Expand Up @@ -199,7 +253,7 @@ jobs:
opennow-stable/dist-release/*-arm64.zip
opennow-stable/dist-release/latest-mac-arm64.yml
- label: linux-x64
os: blacksmith-2vcpu-ubuntu-2404
os: blacksmith-4vcpu-ubuntu-2404
builder_args: "--linux AppImage deb --x64"
native_build: "true"
bundle_gstreamer: "0"
Expand All @@ -210,7 +264,7 @@ jobs:
opennow-stable/dist-release/*-amd64.deb
opennow-stable/dist-release/latest-linux.yml
- label: linux-arm64
os: blacksmith-2vcpu-ubuntu-2404-arm
os: blacksmith-4vcpu-ubuntu-2404-arm
builder_args: "--linux AppImage deb --arm64"
native_build: "true"
bundle_gstreamer: "0"
Expand All @@ -232,7 +286,7 @@ jobs:
npm_config_audit: "false"
npm_config_fund: "false"
GSTREAMER_VERSION: "1.28.2"
GSTREAMER_WINDOWS_VERSION: "1.26.8"
GSTREAMER_WINDOWS_VERSION: "1.28.3"
CARGO_NET_RETRY: "10"
CARGO_HTTP_MULTIPLEXING: "false"
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
Expand Down Expand Up @@ -294,6 +348,7 @@ jobs:
rpm \
build-essential \
pkg-config \
libx11-dev \
libglib2.0-dev \
libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \
Expand All @@ -304,8 +359,10 @@ jobs:
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
gstreamer1.0-nice \
gstreamer1.0-vaapi \
gstreamer1.0-gl \
gstreamer1.0-x \
libva2 \
libva-drm2 \
libvulkan1 \
Expand Down Expand Up @@ -365,15 +422,14 @@ jobs:
if: matrix.native_build == 'true' && runner.os == 'Windows'
shell: pwsh
run: |
$installBase = "C:\gstreamer"
$installRoot = "C:\gstreamer\1.0\msvc_x86_64"
$roots = @(
"C:\gstreamer\1.0\msvc_x86_64",
$installRoot,
"C:\Program Files\gstreamer\1.0\msvc_x86_64"
)
$searchBases = @("C:\gstreamer", "C:\Program Files\gstreamer")
$script:gstreamerPcPaths = @()
$script:lastRuntimeMsiExitCode = $null
$script:lastDevelMsiExitCode = $null
$script:lastInstallerExitCode = $null
function Test-GStreamerRoot([string] $candidate) {
return [bool]($candidate -and
(Test-Path (Join-Path $candidate "lib\pkgconfig\gstreamer-1.0.pc")) -and
Expand All @@ -395,7 +451,7 @@ jobs:
}
return $null
}
function Get-GStreamerMsi([string] $fileName, [string] $downloadDir, [string[]] $urlBases) {
function Get-GStreamerInstaller([string] $fileName, [string] $downloadDir, [string[]] $urlBases) {
New-Item -ItemType Directory -Force -Path $downloadDir | Out-Null
$output = Join-Path $downloadDir $fileName
$partial = "$output.part"
Expand Down Expand Up @@ -431,33 +487,34 @@ jobs:
}
return $null
}
function Install-GStreamerMsiSdk([string] $version) {
function Install-GStreamerSdk([string] $version) {
$urlBases = @(
"https://gstreamer.freedesktop.org/data/pkg/windows/$version/msvc",
"https://gstreamer.freedesktop.org/pkg/windows/$version/msvc"
)
$downloadDir = Join-Path $env:GITHUB_WORKSPACE ".cache\gstreamer-windows\$version"
$runtime = Get-GStreamerMsi "gstreamer-1.0-msvc-x86_64-$version.msi" $downloadDir $urlBases
if (-not $runtime) { return $false }
$devel = Get-GStreamerMsi "gstreamer-1.0-devel-msvc-x86_64-$version.msi" $downloadDir $urlBases
if (-not $devel) { return $false }
$runtimeInstall = Start-Process msiexec.exe -ArgumentList @("/i", $runtime, "/qn", "/norestart", "INSTALLDIR=$installBase", "ADDLOCAL=ALL") -Wait -PassThru
$script:lastRuntimeMsiExitCode = $runtimeInstall.ExitCode
if ($runtimeInstall.ExitCode -ne 0) { return $false }
$develInstall = Start-Process msiexec.exe -ArgumentList @("/i", $devel, "/qn", "/norestart", "INSTALLDIR=$installBase", "ADDLOCAL=ALL") -Wait -PassThru
$script:lastDevelMsiExitCode = $develInstall.ExitCode
if ($develInstall.ExitCode -ne 0) { return $false }
$installer = Get-GStreamerInstaller "gstreamer-1.0-msvc-x86_64-$version.exe" $downloadDir $urlBases
if (-not $installer) { return $false }
$install = Start-Process -FilePath $installer -ArgumentList @(
"/VERYSILENT",
"/SUPPRESSMSGBOXES",
"/NORESTART",
"/TYPE=devel",
"/DIR=$installRoot"
) -Wait -PassThru -NoNewWindow
$script:lastInstallerExitCode = $install.ExitCode
if ($install.ExitCode -ne 0) { return $false }
return [bool](Find-GStreamerRoot)
}
$root = Find-GStreamerRoot
if ($root) {
Write-Host "Using cached GStreamer Windows SDK: $root"
} elseif (-not (Install-GStreamerMsiSdk $env:GSTREAMER_WINDOWS_VERSION)) {
} elseif (-not (Install-GStreamerSdk $env:GSTREAMER_WINDOWS_VERSION)) {
[void](Find-GStreamerRoot)
Write-Host "GStreamer explicit roots searched: $($roots -join ', ')"
Write-Host "GStreamer recursive search bases: $($searchBases -join ', ')"
Write-Host "Discovered gstreamer-1.0.pc paths: $(if ($script:gstreamerPcPaths.Count) { $script:gstreamerPcPaths -join ', ' } else { 'none' })"
Write-Error "Failed to install/discover GStreamer Windows MSI SDK version $env:GSTREAMER_WINDOWS_VERSION. Runtime MSI exit code: $script:lastRuntimeMsiExitCode; devel MSI exit code: $script:lastDevelMsiExitCode."
Write-Error "Failed to install/discover GStreamer Windows SDK version $env:GSTREAMER_WINDOWS_VERSION. Installer exit code: $script:lastInstallerExitCode."
exit 1
}
$root = Find-GStreamerRoot
Expand Down Expand Up @@ -488,9 +545,17 @@ jobs:
Write-Error "GStreamer Windows SDK installed, but no H.264 decoder plugins were found among: $($h264Decoders -join ', ')"
exit 1
}
# Official Cerbero Windows packages disable gstvulkan. OpenNOW injects a
# vendored Vulkan plugin into the private runtime after bundling.
Write-Host "Skipping base-SDK Vulkan element checks; Vulkan is injected into the private OpenNOW runtime bundle."
"GSTREAMER_1_0_ROOT_MSVC_X86_64=$root" | Out-File -FilePath $env:GITHUB_ENV -Append
"$root\bin" | Out-File -FilePath $env:GITHUB_PATH -Append

- name: Build patched Windows GStreamer D3D11 plugin
if: matrix.native_build == 'true' && runner.os == 'Windows'
shell: pwsh
run: ./scripts/build-patched-gstreamer-d3d11.ps1 -GStreamerRoot "$env:GSTREAMER_1_0_ROOT_MSVC_X86_64" -Version "$env:GSTREAMER_WINDOWS_VERSION"

- name: Install FPM for arm64 deb builds
if: matrix.label == 'linux-arm64'
run: sudo apt-get install -y ruby ruby-dev build-essential && sudo gem install fpm
Expand Down Expand Up @@ -557,7 +622,7 @@ jobs:

release:
name: publish-release
runs-on: blacksmith-2vcpu-ubuntu-2404
runs-on: blacksmith-4vcpu-ubuntu-2404
needs:
- preflight
- prepare-source
Expand Down Expand Up @@ -621,20 +686,38 @@ jobs:
mv /tmp/merged.yml "$x64_feed"
rm "$arm64_feed"

- name: Publish GitHub release
- name: Stage GitHub release draft
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.preflight.outputs.release_tag }}
target_commitish: ${{ needs.prepare-source.outputs.release_sha }}
name: OpenNOW v${{ needs.preflight.outputs.version }}
name: ${{ needs.preflight.outputs.release_name }}
draft: true
prerelease: ${{ needs.preflight.outputs.prerelease }}
make_latest: ${{ needs.preflight.outputs.make_latest }}
generate_release_notes: true
files: release-artifacts/**/*

- name: Publish completed GitHub release
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_REPOSITORY: ${{ github.repository }}
RELEASE_TAG: ${{ needs.preflight.outputs.release_tag }}
PRERELEASE: ${{ needs.preflight.outputs.prerelease }}
MAKE_LATEST: ${{ needs.preflight.outputs.make_latest }}
run: |
set -euo pipefail
args=(release edit "$RELEASE_TAG" --repo "$RELEASE_REPOSITORY" "--draft=false" "--prerelease=$PRERELEASE")
if [[ "$MAKE_LATEST" == "true" ]]; then
args+=(--latest)
fi
gh "${args[@]}"

finalize:
name: finalize-version-bump
runs-on: blacksmith-2vcpu-ubuntu-2404
if: needs.preflight.outputs.release_type != 'nightly'
runs-on: blacksmith-4vcpu-ubuntu-2404
needs:
- preflight
- release
Expand Down
Loading
Loading