steam.yml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. name: Steam Upload
  2. on:
  3. release:
  4. types:
  5. - published
  6. workflow_dispatch:
  7. inputs:
  8. tag:
  9. description: 'Tag to fetch and upload (nightly if none)'
  10. required: false
  11. win_url_override:
  12. description: 'Windows build to use (.zip only)'
  13. required: false
  14. mac_url_override:
  15. description: 'Mac build to use (.dmg only)'
  16. required: false
  17. mac_arm_url_override:
  18. description: 'Mac ARM build to use (.dmg only)'
  19. required: false
  20. schedule:
  21. - cron: 0 0 * * *
  22. env:
  23. WORKFLOW_ID: 583765
  24. GIT_NIGHTLY_BRANCH: master
  25. STEAM_NIGHTLY_BRANCH: nightly
  26. STEAM_STABLE_BRANCH: staging
  27. STEAM_BETA_BRANCH: beta_staging
  28. STEAM_PLAYTEST_BRANCH: staging
  29. SEVENZIP_HASH: 5290409e7bbe2f133d0bd7e7482548678157ea2be276b0f9cb440600f4be9a2d
  30. jobs:
  31. upload:
  32. name: Steam upload
  33. runs-on: ubuntu-20.04
  34. if: github.repository_owner == 'obsproject'
  35. steps:
  36. - name: Checkout
  37. uses: actions/checkout@v3
  38. with:
  39. path: source
  40. # The 7-Zip version available in the default ubuntu repos (p7zip) is wildly out-of-date and does not properly support DMG files.
  41. - name: Setup 7-Zip
  42. run: |
  43. mkdir 7z && cd 7z
  44. curl -s https://www.7-zip.org/a/7z2200-linux-x64.tar.xz -o 7z.tar.xz
  45. if [[ '${{ env.SEVENZIP_HASH }}' != "$(sha256sum 7z.tar.xz | cut -d " " -f 1)" ]]; then
  46. echo "7-Zip Download hash does not match!"
  47. exit 1
  48. fi
  49. tar -xJf 7z.tar.xz
  50. echo "$(pwd)" >> $GITHUB_PATH
  51. - name: Get build information
  52. id: build-info
  53. run: |
  54. EVENT='${{ github.event_name }}'
  55. if [[ ${EVENT} == 'release' || ( ${EVENT} == 'workflow_dispatch' && -n '${{ github.event.inputs.tag }}') ]]; then
  56. if [[ ${EVENT} == "release" ]]; then
  57. DESC='${{ github.event.release.tag_name }}'
  58. if [[ '${{ github.event.release.prerelease }}' == 'true' ]]; then
  59. BRANCH='${{ env.STEAM_BETA_BRANCH }}'
  60. else
  61. BRANCH='${{ env.STEAM_STABLE_BRANCH }}'
  62. fi
  63. ASSETS_URL='${{ github.event.release.assets_url }}'
  64. else
  65. RELEASE="$(curl -s '${{ github.api_url }}/repos/obsproject/obs-studio/releases/tags/${{ github.event.inputs.tag }}')"
  66. DESC="$(jq -r '.tag_name' <<< ${RELEASE})"
  67. if [[ "$(jq -r '.prerelease' <<< ${RELEASE})" == 'true' ]]; then
  68. BRANCH='${{ env.STEAM_BETA_BRANCH }}'
  69. else
  70. BRANCH='${{ env.STEAM_STABLE_BRANCH }}'
  71. fi
  72. ASSETS_URL="$(jq -r '.assets_url' <<< ${RELEASE})"
  73. fi
  74. ASSETS="$(curl -s "${ASSETS_URL}")"
  75. WIN_ASSET_URL="$(jq -r '.[] | select(.name|test(".*x64.zip")) .browser_download_url' <<< ${ASSETS})"
  76. MAC_ASSET_URL="$(jq -r '.[] | select(.name|test(".*x86_64.*.dmg")) .browser_download_url' <<< ${ASSETS})"
  77. MAC_ARM_ASSET_URL="$(jq -r '.[] | select(.name|test(".*arm64.*.dmg")) .browser_download_url' <<< ${ASSETS})"
  78. TYPE='release'
  79. else
  80. BRANCH='${{ env.STEAM_NIGHTLY_BRANCH }}'
  81. 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 }}')"
  82. ARTIFACTS_URL="$(jq -r '.workflow_runs[].artifacts_url' <<< ${BUILDS})"
  83. DESC="g$(jq -r '.workflow_runs[].head_sha' <<< "${BUILDS}" | cut -c1-9)"
  84. ARTIFACTS="$(curl -s ${ARTIFACTS_URL})"
  85. WIN_ASSET_URL="$(jq -r '.artifacts[] | select(.name|test(".*windows-x64.*")) .archive_download_url' <<< ${ARTIFACTS})"
  86. MAC_ASSET_URL="$(jq -r '.artifacts[] | select(.name|test(".*macos-x86_64.*")) .archive_download_url' <<< ${ARTIFACTS})"
  87. MAC_ARM_ASSET_URL="$(jq -r '.artifacts[] | select(.name|test(".*macos-arm64.*")) .archive_download_url' <<< ${ARTIFACTS})"
  88. TYPE='nightly'
  89. fi
  90. # Apply overrides from workflow_dispatch
  91. if [[ ${EVENT} == 'workflow_dispatch' ]]; then
  92. if [[ -n '${{ github.event.inputs.win_url_override }}' ]]; then
  93. WIN_ASSET_URL='${{ github.event.inputs.win_url_override }}'
  94. fi
  95. if [[ -n '${{ github.event.inputs.mac_url_override }}' ]]; then
  96. MAC_ASSET_URL='${{ github.event.inputs.mac_url_override }}'
  97. fi
  98. if [[ -n '${{ github.event.inputs.mac_arm_url_override }}' ]]; then
  99. MAC_ARM_ASSET_URL='${{ github.event.inputs.mac_arm_url_override }}'
  100. fi
  101. fi
  102. if [[ -z ${WIN_ASSET_URL} || -z ${MAC_ASSET_URL} || -z ${MAC_ARM_ASSET_URL} ]]; then
  103. echo "Missing at least one asset URL!"
  104. exit 1
  105. fi
  106. # set env variables for subsequent steps
  107. echo "type=${TYPE}" >> $GITHUB_OUTPUT
  108. echo "branch=${BRANCH}" >> $GITHUB_OUTPUT
  109. echo "desc=${DESC}" >> $GITHUB_OUTPUT
  110. echo "win_url=${WIN_ASSET_URL}" >> $GITHUB_OUTPUT
  111. echo "mac_intel_url=${MAC_ASSET_URL}" >> $GITHUB_OUTPUT
  112. echo "mac_arm_url=${MAC_ARM_ASSET_URL}" >> $GITHUB_OUTPUT
  113. - name: Restore build cache
  114. id: cache
  115. uses: actions/cache@v3
  116. with:
  117. path: ${{ github.workspace }}/steam/build
  118. key: ${{ steps.build-info.outputs.branch }}-${{ steps.build-info.outputs.desc }}
  119. # Using "restore-keys" will restore the most recent cache for the branch, even if the exact cache doesn't exist.
  120. # This doesn't set cache-hit to true so it won't skip the upload for nightlies.
  121. restore-keys: ${{ steps.build-info.outputs.branch }}
  122. - name: Determine if Steam upload should run
  123. # If the nightly build has already been uploaded and thus a cache exists skip this and the following steps.
  124. # Steam does not prevent us from uploading duplicate builds so this would just pollute the dashboard.
  125. # 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,
  126. # but it's better than nothing!
  127. id: should-run
  128. run: |
  129. if [[ '${{ steps.build-info.outputs.type }}' == 'release' || '${{ steps.cache.outputs.cache-hit }}' != 'true' ]]; then
  130. echo "result=true" >> $GITHUB_OUTPUT
  131. if [[ '${{ steps.build-info.outputs.branch }}' == '${{ env.STEAM_BETA_BRANCH }}' ]]; then
  132. echo "result_playtest=true" >> $GITHUB_OUTPUT
  133. else
  134. echo "result_playtest=false" >> $GITHUB_OUTPUT
  135. fi
  136. else
  137. echo "result=false" >> $GITHUB_OUTPUT
  138. echo "result_playtest=false" >> $GITHUB_OUTPUT
  139. fi
  140. - name: Download and prepare builds
  141. if: steps.should-run.outputs.result == 'true'
  142. run: |
  143. echo "::group::Download Windows build"
  144. if [[ '${{ steps.build-info.outputs.win_url }}' == *'api.github.com'* ]]; then
  145. curl -L -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' '${{ steps.build-info.outputs.win_url }}' -o windows.zip
  146. else
  147. curl -L '${{ steps.build-info.outputs.win_url }}' -o windows.zip
  148. fi
  149. echo "::endgroup::"
  150. echo "::group::Download Mac builds"
  151. if [[ '${{ steps.build-info.outputs.mac_intel_url }}' == *'api.github.com'* ]]; then
  152. curl -L -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' '${{ steps.build-info.outputs.mac_intel_url }}' -o mac_x86.dmg.zip
  153. else
  154. curl -L '${{ steps.build-info.outputs.mac_intel_url }}' -o mac_x86.dmg
  155. fi
  156. if [[ '${{ steps.build-info.outputs.mac_arm_url }}' == *'api.github.com'* ]]; then
  157. curl -L -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' '${{ steps.build-info.outputs.mac_arm_url }}' -o mac_arm64.dmg.zip
  158. else
  159. curl -L '${{ steps.build-info.outputs.mac_arm_url }}' -o mac_arm64.dmg
  160. fi
  161. echo "::endgroup::"
  162. mkdir -p steam && cd steam
  163. echo "::group::Extract and prepare Win64"
  164. mkdir steam-windows
  165. (
  166. cd steam-windows
  167. unzip ../../windows.zip
  168. # CI builds can be double-zipped
  169. if compgen -G "*.zip" > /dev/null; then
  170. unzip *.zip
  171. rm *.zip
  172. fi
  173. # copy install scripts and create sentinel file
  174. cp -r ../../source/CI/steam/scripts_windows scripts
  175. touch disable_updater
  176. )
  177. echo "::endgroup::"
  178. echo "::group::Extract macOS (x86)"
  179. mkdir -p steam-macos/x86
  180. # CI builds are zipped
  181. if [[ -f ../mac_x86.dmg.zip ]]; then
  182. unzip ../mac_x86.dmg.zip
  183. # 7-Zip will have an exit code of 2 due to the "unsafe" 'Applications' symlink.
  184. # GitHub treats this as a failure so ignore non-zero exit codes here.
  185. 7zz x *.dmg -otmp_x86 || true
  186. rm *.dmg
  187. else
  188. 7zz x ../mac_x86.dmg -otmp_x86 || true
  189. fi
  190. if [ -d tmp_x86/OBS.app ]; then
  191. mv tmp_x86/OBS.app steam-macos/x86
  192. else
  193. mv tmp_x86/*/OBS.app steam-macos/x86
  194. fi
  195. echo "::endgroup::"
  196. echo "::group::Extract and prepare macOS (arm64)"
  197. mkdir -p steam-macos/arm64
  198. if [[ -f ../mac_arm64.dmg.zip ]]; then
  199. unzip ../mac_arm64.dmg.zip
  200. 7zz x *.dmg -otmp_arm64 || true
  201. rm *.dmg
  202. else
  203. 7zz x ../mac_arm64.dmg -otmp_arm64 || true
  204. fi
  205. if [ -d tmp_arm64/OBS.app ]; then
  206. mv tmp_arm64/OBS.app steam-macos/arm64
  207. else
  208. mv tmp_arm64/*/OBS.app steam-macos/arm64
  209. fi
  210. cp ../source/CI/steam/scripts_macos/launch.sh steam-macos/launch.sh
  211. echo "::endgroup::"
  212. - name: Setup steamcmd
  213. if: steps.should-run.outputs.result == 'true'
  214. uses: CyberAndrii/setup-steamcmd@e19cd1516315ce46dbfffa47193f92fe42d1419e
  215. - name: Generate Steam auth code
  216. if: steps.should-run.outputs.result == 'true'
  217. id: steam-totp
  218. uses: CyberAndrii/steam-totp@0fc9e59dc5bbf4368d23d5a33956f104248da31a
  219. with:
  220. shared_secret: ${{ secrets.STEAM_SHARED_SECRET }}
  221. - name: Upload to Steam
  222. if: steps.should-run.outputs.result == 'true'
  223. run: |
  224. cd steam
  225. echo "::group::Prepare Steam build script"
  226. # The description in Steamworks for the build will be "github_<branch>-<tag/short hash>", e.g. "github_nightly-gaa73de952"
  227. 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
  228. echo "Generated file:"
  229. cat build.vdf
  230. echo "::endgroup::"
  231. echo "::group::Upload to Steam"
  232. steamcmd +login '${{ secrets.STEAM_USER }}' '${{ secrets.STEAM_PASSWORD }}' '${{ steps.steam-totp.outputs.code }}' +run_app_build "$(pwd)/build.vdf" +quit
  233. echo "::endgroup::"
  234. - name: Generate Steam auth code (Playtest)
  235. if: steps.should-run.outputs.result_playtest == 'true'
  236. id: steam-totp-playtest
  237. uses: CyberAndrii/steam-totp@0fc9e59dc5bbf4368d23d5a33956f104248da31a
  238. with:
  239. shared_secret: ${{ secrets.STEAM_SHARED_SECRET }}
  240. - name: Upload to Steam (Playtest)
  241. if: steps.should-run.outputs.result_playtest == 'true'
  242. run: |
  243. cd steam
  244. echo "::group::Prepare Steam build script"
  245. sed 's/@@DESC@@/${{ steps.build-info.outputs.branch }}-${{ steps.build-info.outputs.desc }}/;s/@@BRANCH@@/${{ env.STEAM_PLAYTEST_BRANCH }}/' ../source/CI/steam/obs_playtest_build.vdf > build_playtest.vdf
  246. echo "Generated file:"
  247. cat build_playtest.vdf
  248. echo "::endgroup::"
  249. echo "::group::Upload to Steam"
  250. steamcmd +login '${{ secrets.STEAM_USER }}' '${{ secrets.STEAM_PASSWORD }}' '${{ steps.steam-totp-playtest.outputs.code }}' +run_app_build "$(pwd)/build_playtest.vdf" +quit
  251. echo "::endgroup::"
  252. - name: Upload Steam build logs
  253. if: steps.should-run.outputs.result == 'true'
  254. uses: actions/upload-artifact@v3
  255. with:
  256. name: steam-build-logs
  257. path: ${{ github.workspace }}/steam/build/*.log