Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 215 additions & 0 deletions .github/workflows/steam.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
name: Steam Upload

on:
release:
types:
- published
workflow_dispatch:
inputs:
tag:
description: 'Tag to fetch and upload (nightly if none)'
required: false
win_url_override:
description: 'Windows build to use (.zip only)'
required: false
mac_url_override:
description: 'Mac build to use (.dmg only)'
required: false
schedule:
- cron: 0 0 * * *

env:
WORKFLOW_ID: 583765
GIT_NIGHTLY_BRANCH: master
STEAM_NIGHTLY_BRANCH: nightly
STEAM_STABLE_BRANCH: staging
STEAM_BETA_BRANCH: beta_staging

jobs:
upload:
name: Steam upload
runs-on: ubuntu-20.04

steps:
- name: Checkout
uses: actions/checkout@v3
with:
path: source

- name: Setup 7-Zip (PPA)
# The 7-Zip version available in the default ubuntu repos (p7zip) is wildly out-of-date and does not properly support DMG files.
run: |
sudo add-apt-repository -y ppa:spvkgn/sevenzip
sudo apt update -y
sudo apt install -y 7-zip

- name: Get build information
id: build-info
run: |
EVENT='${{ github.event_name }}'
if [[ ${EVENT} == 'release' || ( ${EVENT} == 'workflow_dispatch' && -n '${{ github.event.inputs.tag }}') ]]; then
if [[ ${EVENT} == "release" ]]; then
DESC='${{ github.event.release.tag_name }}'
if [[ '${{ github.event.release.prerelease }}' == 'true' ]]; then
BRANCH='${{ env.STEAM_BETA_BRANCH }}'
else
BRANCH='${{ env.STEAM_STABLE_BRANCH }}'
fi
ASSETS_URL='${{ github.event.release.assets_url }}'
else
RELEASE="$(curl -s '${{ github.api_url }}/repos/obsproject/obs-studio/releases/tags/${{ github.event.inputs.tag }}')"

DESC="$(jq -r '.tag_name' <<< ${RELEASE})"
if [[ "$(jq -r '.prerelease' <<< ${RELEASE})" == 'true' ]]; then
BRANCH='${{ env.STEAM_BETA_BRANCH }}'
else
BRANCH='${{ env.STEAM_STABLE_BRANCH }}'
fi
ASSETS_URL="$(jq -r '.assets_url' <<< ${RELEASE})"
fi

ASSETS="$(curl -s "${ASSETS_URL}")"
WIN_ASSET_URL="$(jq -r '.[] | select(.name|test(".*x64.zip")) .browser_download_url' <<< ${ASSETS})"
MAC_ASSET_URL="$(jq -r '.[] | select(.name|test(".*.dmg")) .browser_download_url' <<< ${ASSETS})"
TYPE='release'
else
BRANCH='${{ env.STEAM_NIGHTLY_BRANCH }}'
BUILDS="$(curl -s '${{ github.api_url }}/repos/obsproject/obs-studio/actions/workflows/${{ env.WORKFLOW_ID }}/runs?per_page=1&event=push&status=success&branch=${{ env.GIT_NIGHTLY_BRANCH }}')"
ARTIFACTS_URL="$(jq -r '.workflow_runs[].artifacts_url' <<< ${BUILDS})"
DESC="g$(jq -r '.workflow_runs[].head_sha' <<< "${BUILDS}" | cut -c1-9)"

ARTIFACTS="$(curl -s ${ARTIFACTS_URL})"
WIN_ASSET_URL="$(jq -r '.artifacts[] | select(.name|test(".*win-x64.*")) .archive_download_url' <<< ${ARTIFACTS})"
MAC_ASSET_URL="$(jq -r '.artifacts[] | select(.name|test(".*macos-x86_64.*")) .archive_download_url' <<< ${ARTIFACTS})"
TYPE='nightly'
fi

# Apply overrides from workflow_dispatch
if [[ ${EVENT} == 'workflow_dispatch' ]]; then
if [[ -n '${{ github.event.inputs.win_url_override }}' ]]; then
WIN_ASSET_URL='${{ github.event.inputs.win_url_override }}'
fi

if [[ -n '${{ github.event.inputs.mac_url_override }}' ]]; then
MAC_ASSET_URL='${{ github.event.inputs.mac_url_override }}'
fi
fi

if [[ -z ${WIN_ASSET_URL} || -z ${MAC_ASSET_URL} ]]; then
echo "Missing at least one asset URL!"
exit 1
fi

# set env variables for subsequent steps
echo "::set-output name=type::${TYPE}"
echo "::set-output name=branch::${BRANCH}"
echo "::set-output name=desc::${DESC}"
echo "::set-output name=win_url::${WIN_ASSET_URL}"
echo "::set-output name=mac_intel_url::${MAC_ASSET_URL}"

- name: Restore build cache
id: cache
uses: actions/cache@v3
with:
path: ${{ github.workspace }}/steam/build
key: ${{ steps.build-info.outputs.branch }}-${{ steps.build-info.outputs.desc }}
# Using "restore-keys" will restore the most recent cache for the branch, even if the exact cache doesn't exist.
# This doesn't set cache-hit to true so it won't skip the upload for nightlies.
restore-keys: ${{ steps.build-info.outputs.branch }}

- name: Determine if Steam upload should run
# If the nightly build has already been uploaded and thus a cache exists skip this and the following steps.
# Steam does not prevent us from uploading duplicate builds so this would just pollute the dashboard.
# This is a bit of a hack and can fail to work if our cache has been evicted or we somehow have no commits for 7 days,
# but it's better than nothing!
id: should-run
run: |
if [[ '${{ steps.build-info.outputs.type }}' == 'release' || '${{ steps.cache.outputs.cache-hit }}' != 'true' ]]; then
echo "::set-output name=result::true"
else
echo "::set-output name=result::false"
fi

- name: Download and prepare builds
if: steps.should-run.outputs.result == 'true'
run: |
echo "::group::Download Windows build"
if [[ '${{ steps.build-info.outputs.win_url }}' == *'api.github.com'* ]]; then
curl -L -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' '${{ steps.build-info.outputs.win_url }}' -o windows.zip
else
curl -L '${{ steps.build-info.outputs.win_url }}' -o windows.zip
fi
echo "::endgroup::"

echo "::group::Download Mac build"
if [[ '${{ steps.build-info.outputs.mac_intel_url }}' == *'api.github.com'* ]]; then
curl -L -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' '${{ steps.build-info.outputs.mac_intel_url }}' -o mac_x86.dmg.zip
else
curl -L '${{ steps.build-info.outputs.mac_intel_url }}' -o mac_x86.dmg
fi
echo "::endgroup::"

mkdir -p steam && cd steam

echo "::group::Extract and prepare Win64"
mkdir steam-windows
(
cd steam-windows
unzip ../../windows.zip
# CI builds can be double-zipped
if compgen -G "*.zip" > /dev/null; then
unzip *.zip
rm *.zip
fi
# copy install scripts and create sentinel file
cp -r ../../source/CI/steam/scripts scripts
touch disable_updater
)
echo "::endgroup::"

echo "::group::Extract macOS (x86)"
mkdir steam-macos
# CI builds are zipped
if [[ -f ../mac_x86.dmg.zip ]]; then
unzip ../mac_x86.dmg.zip
# 7-Zip will have an exit code of 2 due to the "unsafe" 'Applications' symlink.
# GitHub treats this as a failure so ignore non-zero exit codes here.
7zz x *.dmg -otmp || true
else
7zz x ../mac_x86.dmg -otmp || true
fi

mv tmp/*/OBS.app steam-macos
echo "::endgroup::"

- name: Setup steamcmd
if: steps.should-run.outputs.result == 'true'
uses: CyberAndrii/setup-steamcmd@e19cd1516315ce46dbfffa47193f92fe42d1419e

- name: Generate Steam auth code
if: steps.should-run.outputs.result == 'true'
id: steam-totp
uses: CyberAndrii/steam-totp@0fc9e59dc5bbf4368d23d5a33956f104248da31a
with:
shared_secret: ${{ secrets.STEAM_SHARED_SECRET }}

- name: Upload to Steam
if: steps.should-run.outputs.result == 'true'
run: |
cd steam
echo "::group::Prepare Steam build script"
# The description in Steamworks for the build will be "github_<branch>-<tag/short hash>", e.g. "github_nightly-gaa73de952"
sed 's/@@DESC@@/${{ steps.build-info.outputs.branch }}-${{ steps.build-info.outputs.desc }}/;s/@@BRANCH@@/${{ steps.build-info.outputs.branch }}/' ../source/CI/steam/obs_build.vdf > build.vdf
echo "Generated file:"
cat build.vdf
echo "::endgroup::"
echo "::group::Upload to Steam"
steamcmd +login '${{ secrets.STEAM_USER }}' '${{ secrets.STEAM_PASSWORD }}' '${{ steps.steam-totp.outputs.code }}' +run_app_build "$(pwd)/build.vdf" +quit
echo "::endgroup::"

- name: Upload Steam build logs
if: steps.should-run.outputs.result == 'true'
uses: actions/upload-artifact@v2
with:
name: steam-build-logs
path: ${{ github.workspace }}/steam/build/*.log
36 changes: 36 additions & 0 deletions CI/steam/obs_build.vdf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"AppBuild"
{
"AppID" "1905180"
"Desc" "github_@@DESC@@"

"ContentRoot" "./"
"BuildOutput" "build/"

"SetLive" "@@BRANCH@@"

"Depots"
{
"1905181" // Windows
{
"ContentRoot" "./steam-windows"
"InstallScript" "scripts/installscript.vdf"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
}

"1905182" // Mac
{
"ContentRoot" "./steam-macos"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
}
}
}
85 changes: 85 additions & 0 deletions CI/steam/scripts/install.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
@echo off
@cd /d "%~dp0"

goto checkAdmin


:checkAdmin
net session >nul 2>&1
if %errorLevel% == 0 (
echo.
) else (
echo Administrative rights are required. Please re-run this script as Administrator.
goto end
)

:writeRegistry
reg add "HKLM\SOFTWARE\OBS Studio" /f /t REG_SZ /d %1 /reg:32
reg add "HKLM\SOFTWARE\OBS Studio" /f /t REG_SZ /d %1 /reg:64

:setupProgramData
:: Required for UWP applications
mkdir "%PROGRAMDATA%\obs-studio-hook"
icacls "%PROGRAMDATA%\obs-studio-hook" /grant "ALL APPLICATION PACKAGES":(OI)(CI)(GR,GE)

:checkDLL
echo Checking for 32-bit Virtual Cam registration...
reg query "HKLM\SOFTWARE\Classes\CLSID\{A3FCE0F5-3493-419F-958A-ABA1250EC20B}" >nul 2>&1 /reg:32
if %errorLevel% == 0 (
echo 32-bit Virtual Cam found, skipping install...
echo.
) else (
echo 32-bit Virtual Cam not found, installing...
goto install32DLL
)

:CheckDLLContinue
echo Checking for 64-bit Virtual Cam registration...
reg query "HKLM\SOFTWARE\Classes\CLSID\{A3FCE0F5-3493-419F-958A-ABA1250EC20B}" >nul 2>&1 /reg:64
if %errorLevel% == 0 (
echo 64-bit Virtual Cam found, skipping install...
echo.
) else (
echo 64-bit Virtual Cam not found, installing...
goto install64DLL
)
goto endSuccess

:install32DLL
echo Installing 32-bit Virtual Cam...
regsvr32.exe /i /s %1\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll
reg query "HKLM\SOFTWARE\Classes\CLSID\{A3FCE0F5-3493-419F-958A-ABA1250EC20B}" >nul 2>&1 /reg:32
if %errorLevel% == 0 (
echo 32-bit Virtual Cam successfully installed
echo.
) else (
echo 32-bit Virtual Cam installation failed
echo.
goto endFail
)
goto checkDLLContinue

:install64DLL
echo Installing 64-bit Virtual Cam...
regsvr32.exe /i /s %1\data\obs-plugins\win-dshow\obs-virtualcam-module64.dll
reg query "HKLM\SOFTWARE\Classes\CLSID\{A3FCE0F5-3493-419F-958A-ABA1250EC20B}" >nul 2>&1 /reg:64
if %errorLevel% == 0 (
echo 64-bit Virtual Cam successfully installed
echo.
goto endSuccess
) else (
echo 64-bit Virtual Cam installation failed
echo.
goto endFail
)

:endFail
echo Something failed, please report this on the OBS Discord or Forums!
goto end

:endSuccess
echo Virtual Cam installed!
echo.

:end
exit
20 changes: 20 additions & 0 deletions CI/steam/scripts/installscript.vdf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"InstallScript"
{
"Run Process"
{
"install"
{
"process 1" "scripts\\install.bat"
"command 1" "\"%INSTALLDIR%\""
}
}

"Run Process On Uninstall"
{
"uninstall"
{
"process 1" "scripts\\uninstall.bat"
"command 1" "\"%INSTALLDIR%\""
}
}
}
33 changes: 33 additions & 0 deletions CI/steam/scripts/uninstall.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@echo off
@cd /d "%~dp0"
goto checkAdmin

:checkAdmin
net session >nul 2>&1
if %errorLevel% == 0 (
echo.
) else (
echo Administrative rights are required. Please re-run this script as Administrator.
goto end
)

:clearRegistry
reg delete "HKLM\SOFTWARE\OBS Studio" /f /reg:32
reg delete "HKLM\SOFTWARE\OBS Studio" /f /reg:64
:: Vulkan layer keys
reg delete "HKLM\SOFTWARE\Khronos\Vulkan\ImplicitLayers" /f /v "%PROGRAMDATA%\obs-studio-hook\obs-vulkan64.json" /reg:32
reg delete "HKLM\SOFTWARE\Khronos\Vulkan\ImplicitLayers" /f /v "%PROGRAMDATA%\obs-studio-hook\obs-vulkan32.json" /reg:64

:deleteProgramDataFolder
RMDIR /S /Q "%PROGRAMDATA%\obs-studio-hook"

:uninstallDLLs
regsvr32.exe /u /s %1\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll
regsvr32.exe /u /s %1\data\obs-plugins\win-dshow\obs-virtualcam-module64.dll

:endSuccess
echo Virtual Cam uninstalled!
echo.

:end
exit