build-project.yaml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. name: Build Project
  2. on:
  3. workflow_call:
  4. jobs:
  5. check-event:
  6. name: Event Data 🔎
  7. runs-on: ubuntu-24.04
  8. defaults:
  9. run:
  10. shell: bash
  11. outputs:
  12. package: ${{ steps.setup.outputs.package }}
  13. codesign: ${{ steps.setup.outputs.codesign }}
  14. notarize: ${{ steps.setup.outputs.notarize }}
  15. config: ${{ steps.setup.outputs.config }}
  16. commitHash: ${{ steps.setup.outputs.commitHash }}
  17. steps:
  18. - uses: actions/checkout@v4
  19. with:
  20. fetch-depth: 0
  21. - name: Check Event Data ☑️
  22. id: setup
  23. env:
  24. GH_TOKEN: ${{ github.token }}
  25. run: |
  26. : Check Event Data ☑️
  27. if [[ "${RUNNER_DEBUG}" ]]; then set -x; fi
  28. case "${GITHUB_EVENT_NAME}" in
  29. pull_request)
  30. config_data=('codesign:false' 'notarize:false' 'package:false' 'config:RelWithDebInfo')
  31. if gh pr view ${{ github.event.number }} --json labels \
  32. | jq -e -r '.labels[] | select(.name == "Seeking Testers")' > /dev/null; then
  33. config_data[0]='codesign:true'
  34. config_data[2]='package:true'
  35. fi
  36. ;;
  37. push)
  38. config_data=('codesign:true' 'notarize:false' 'package:true' 'config:RelWithDebInfo')
  39. if [[ ${GITHUB_REF_NAME} =~ [0-9]+.[0-9]+.[0-9]+(-(rc|beta).+)? ]]; then
  40. config_data[1]='notarize:true'
  41. config_data[3]='config:Release'
  42. fi
  43. ;;
  44. workflow_dispatch)
  45. config_data=('codesign:true' 'notarize:false' 'package:false' 'config:RelWithDebInfo')
  46. ;;
  47. schedule)
  48. config_data=('codesign:true' 'notarize:false' 'package:true' 'config:RelWithDebInfo')
  49. ;;
  50. *) ;;
  51. esac
  52. for config in "${config_data[@]}"; do
  53. IFS=':' read -r key value <<< "${config}"
  54. echo "${key}=${value}" >> $GITHUB_OUTPUT
  55. done
  56. echo "commitHash=${GITHUB_SHA:0:9}" >> $GITHUB_OUTPUT
  57. macos-build:
  58. name: macOS 🍏
  59. runs-on: macos-15
  60. needs: check-event
  61. strategy:
  62. fail-fast: false
  63. matrix:
  64. target: [arm64, x86_64]
  65. defaults:
  66. run:
  67. shell: zsh --no-rcs --errexit --pipefail {0}
  68. steps:
  69. - uses: actions/checkout@v4
  70. with:
  71. submodules: recursive
  72. fetch-depth: 0
  73. - name: Set Up Environment 🔧
  74. id: setup
  75. run: |
  76. : Set Up Environment 🔧
  77. if (( ${+RUNNER_DEBUG} )) setopt XTRACE
  78. print '::group::Enable Xcode 26.1'
  79. sudo xcode-select --switch /Applications/Xcode_26.1.app/Contents/Developer
  80. print '::endgroup::'
  81. print '::group::Clean Homebrew Environment'
  82. local -a unwanted_formulas=()
  83. local -a remove_formulas=()
  84. for formula (${unwanted_formulas}) {
  85. if [[ -d ${HOMEBREW_PREFIX}/Cellar/${formula} ]] remove_formulas+=(${formula})
  86. }
  87. if (( #remove_formulas )) brew uninstall --ignore-dependencies ${remove_formulas}
  88. print '::endgroup::'
  89. local -A arch_names=(x86_64 intel arm64 apple)
  90. print "cpuName=${arch_names[${{ matrix.target }}]}" >> $GITHUB_OUTPUT
  91. local xcode_cas_path="${HOME}/Library/Developer/Xcode/DerivedData/CompilationCache.noindex"
  92. if ! [[ -d ${xcode_cas_path} ]] mkdir -p ${xcode_cas_path}
  93. print "xcodeCasPath=${xcode_cas_path}" >> $GITHUB_OUTPUT
  94. - uses: actions/cache/restore@v4
  95. id: xcode-cache
  96. with:
  97. path: ${{ steps.setup.outputs.xcodeCasPath }}
  98. key: ${{ runner.os }}-xcode-${{ matrix.target }}-${{ needs.check-event.outputs.config }}
  99. restore-keys: |
  100. ${{ runner.os }}-xcode-${{ matrix.target }}-
  101. - name: Set Up Code Signing 🔑
  102. uses: ./.github/actions/setup-macos-codesigning
  103. if: fromJSON(needs.check-event.outputs.codesign)
  104. id: codesign
  105. with:
  106. codesignIdentity: ${{ secrets.MACOS_SIGNING_IDENTITY }}
  107. codesignCertificate: ${{ secrets.MACOS_SIGNING_CERT }}
  108. certificatePassword: ${{ secrets.MACOS_SIGNING_CERT_PASSWORD }}
  109. keychainPassword: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }}
  110. provisioningProfile: ${{ secrets.MACOS_SIGNING_PROVISIONING_PROFILE }}
  111. notarizationUser: ${{ secrets.MACOS_NOTARIZATION_USERNAME }}
  112. notarizationPassword: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }}
  113. - name: Build OBS Studio 🧱
  114. uses: ./.github/actions/build-obs
  115. env:
  116. TWITCH_CLIENTID: ${{ secrets.TWITCH_CLIENT_ID }}
  117. TWITCH_HASH: ${{ secrets.TWITCH_HASH }}
  118. RESTREAM_CLIENTID: ${{ secrets.RESTREAM_CLIENTID }}
  119. RESTREAM_HASH: ${{ secrets.RESTREAM_HASH }}
  120. YOUTUBE_CLIENTID: ${{ secrets.YOUTUBE_CLIENTID }}
  121. YOUTUBE_CLIENTID_HASH: ${{ secrets.YOUTUBE_CLIENTID_HASH }}
  122. YOUTUBE_SECRET: ${{ secrets.YOUTUBE_SECRET }}
  123. YOUTUBE_SECRET_HASH: ${{ secrets.YOUTUBE_SECRET_HASH }}
  124. XCODE_CAS_PATH: ${{ steps.setup.outputs.xcodeCasPath }}
  125. with:
  126. target: ${{ matrix.target }}
  127. config: ${{ needs.check-event.outputs.config }}
  128. codesign: ${{ fromJSON(needs.check-event.outputs.codesign) }}
  129. codesignIdent: ${{ steps.codesign.outputs.codesignIdent }}
  130. codesignTeam: ${{ steps.codesign.outputs.codesignTeam }}
  131. provisioningProfileUUID: ${{ steps.codesign.outputs.provisioningProfileUUID }}
  132. - name: Package OBS Studio 📀
  133. uses: ./.github/actions/package-obs
  134. with:
  135. target: ${{ matrix.target }}
  136. config: ${{ needs.check-event.outputs.config }}
  137. package: ${{ fromJSON(needs.check-event.outputs.package) }}
  138. codesign: ${{ fromJSON(needs.check-event.outputs.codesign) && fromJSON(steps.codesign.outputs.haveCodesignIdent) }}
  139. codesignIdent: ${{ steps.codesign.outputs.codesignIdent }}
  140. notarize: ${{ fromJSON(needs.check-event.outputs.notarize) && fromJSON(steps.codesign.outputs.haveNotarizationUser) }}
  141. codesignUser: ${{ secrets.MACOS_NOTARIZATION_USERNAME }}
  142. codesignPass: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }}
  143. - name: Upload Artifacts 📡
  144. uses: actions/upload-artifact@v4
  145. with:
  146. name: obs-studio-macos-${{ matrix.target }}-${{ needs.check-event.outputs.commitHash }}
  147. path: ${{ github.workspace }}/build_macos/obs-studio-*-macos-${{ steps.setup.outputs.cpuName }}.*
  148. - name: Upload Debug Symbol Artifacts 🪲
  149. uses: actions/upload-artifact@v4
  150. if: ${{ needs.check-event.outputs.config == 'Release' }}
  151. with:
  152. name: obs-studio-macos-${{ matrix.target }}-${{ needs.check-event.outputs.commitHash }}-dSYMs
  153. path: ${{ github.workspace }}/build_macos/obs-studio-*-macos-${{ steps.setup.outputs.cpuName }}-dSYMs.tar.xz
  154. - uses: actions/cache/save@v4
  155. if: github.event_name != 'pull_request' && steps.xcode-cache.outputs.cache-hit != 'true'
  156. with:
  157. path: ${{ steps.setup.outputs.xcodeCasPath }}
  158. key: ${{ runner.os }}-xcode-${{ matrix.target }}-${{ needs.check-event.outputs.config }}
  159. ubuntu-build:
  160. name: Ubuntu 🐧
  161. strategy:
  162. matrix:
  163. os: [ubuntu-24.04]
  164. runs-on: ${{ matrix.os }}
  165. needs: check-event
  166. defaults:
  167. run:
  168. shell: bash
  169. steps:
  170. - uses: actions/checkout@v4
  171. with:
  172. submodules: recursive
  173. fetch-depth: 0
  174. - uses: actions/cache/restore@v4
  175. id: ccache-cache
  176. with:
  177. path: ${{ github.workspace }}/.ccache
  178. key: ${{ runner.os }}-${{ matrix.os }}-ccache-x86_64-${{ needs.check-event.outputs.config }}
  179. restore-keys: |
  180. ${{ runner.os }}-${{ matrix.os }}-ccache-x86_64-
  181. - name: Build OBS Studio 🧱
  182. uses: ./.github/actions/build-obs
  183. env:
  184. TWITCH_CLIENTID: ${{ secrets.TWITCH_CLIENT_ID }}
  185. TWITCH_HASH: ${{ secrets.TWITCH_HASH }}
  186. RESTREAM_CLIENTID: ${{ secrets.RESTREAM_CLIENTID }}
  187. RESTREAM_HASH: ${{ secrets.RESTREAM_HASH }}
  188. YOUTUBE_CLIENTID: ${{ secrets.YOUTUBE_CLIENTID }}
  189. YOUTUBE_CLIENTID_HASH: ${{ secrets.YOUTUBE_CLIENTID_HASH }}
  190. YOUTUBE_SECRET: ${{ secrets.YOUTUBE_SECRET }}
  191. YOUTUBE_SECRET_HASH: ${{ secrets.YOUTUBE_SECRET_HASH }}
  192. with:
  193. target: x86_64
  194. config: ${{ needs.check-event.outputs.config }}
  195. - name: Package OBS Studio 📀
  196. uses: ./.github/actions/package-obs
  197. with:
  198. target: x86_64
  199. config: ${{ needs.check-event.outputs.config }}
  200. package: ${{ fromJSON(needs.check-event.outputs.package) }}
  201. - name: Upload Source Tarball 🗜️
  202. uses: actions/upload-artifact@v4
  203. with:
  204. name: obs-studio-${{ matrix.os }}-sources-${{ needs.check-event.outputs.commitHash }}
  205. path: ${{ github.workspace }}/build_ubuntu/obs-studio-*-sources.*
  206. - name: Upload Artifacts 📡
  207. uses: actions/upload-artifact@v4
  208. with:
  209. name: obs-studio-${{ matrix.os }}-x86_64-${{ needs.check-event.outputs.commitHash }}
  210. path: ${{ github.workspace }}/build_ubuntu/obs-studio-*-x86_64-ubuntu-gnu.*
  211. - name: Upload Debug Symbol Artifacts 🪲
  212. uses: actions/upload-artifact@v4
  213. if: ${{ fromJSON(needs.check-event.outputs.package) }}
  214. with:
  215. name: obs-studio-${{ matrix.os }}-x86_64-${{ needs.check-event.outputs.commitHash }}-dbgsym
  216. path: ${{ github.workspace }}/build_ubuntu/obs-studio-*-x86_64-ubuntu-gnu-dbgsym.ddeb
  217. - uses: actions/cache/save@v4
  218. if: github.event_name != 'pull_request' && steps.ccache-cache.outputs.cache-hit != 'true'
  219. with:
  220. path: ${{ github.workspace }}/.ccache
  221. key: ${{ runner.os }}-${{ matrix.os }}-ccache-x86_64-${{ needs.check-event.outputs.config }}
  222. flatpak-build:
  223. name: Flatpak 📦
  224. runs-on: ubuntu-24.04
  225. needs: check-event
  226. defaults:
  227. run:
  228. shell: bash
  229. env:
  230. FLATPAK_BUILD_SHARE_PATH: flatpak_app/files/share
  231. container:
  232. image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08
  233. options: --privileged
  234. volumes:
  235. - /usr/local/lib/android:/to_clean/android
  236. - /opt/hostedtoolcache/CodeQL:/to_clean/codeql
  237. - /usr/local/.ghcup:/to_clean/ghcup
  238. - /opt/hostedtoolcache/Python:/to_clean/python
  239. - /usr/share/swift:/to_clean/swift
  240. - /usr/share/dotnet:/to_clean/dotnet
  241. steps:
  242. - name: Prepare build space
  243. shell: bash
  244. run: |
  245. : Prepare build space
  246. echo ::group::Available storage
  247. df -h
  248. echo ::endgroup::
  249. echo ::group::Remove Android stuff
  250. rm -rf /to_clean/android/*
  251. echo ::endgroup::
  252. echo ::group::Remove CodeQL stuff
  253. rm -rf /to_clean/codeql/*
  254. echo ::endgroup::
  255. echo ::group::Remove GHCup stuff
  256. rm -rf /to_clean/ghcup/*
  257. echo ::endgroup::
  258. echo ::group::Remove Python stuff
  259. rm -rf /to_clean/python/*
  260. echo ::endgroup::
  261. echo ::group::Remove Swift stuff
  262. rm -rf /to_clean/swift/*
  263. echo ::endgroup::
  264. echo ::group::Remove .NET stuff
  265. rm -rf /to_clean/dotnet/*
  266. echo ::endgroup::
  267. echo ::group::Available storage
  268. df -h
  269. echo ::endgroup::
  270. - uses: actions/checkout@v4
  271. with:
  272. submodules: recursive
  273. fetch-depth: 0
  274. set-safe-directory: ${{ env.GITHUB_WORKSPACE }}
  275. - name: Set Up Environment 🔧
  276. id: setup
  277. env:
  278. GH_TOKEN: ${{ github.token }}
  279. run: |
  280. : Set Up Environment 🔧
  281. if [[ "${RUNNER_DEBUG}" ]]; then set -x; fi
  282. git config --global --add safe.directory "${GITHUB_WORKSPACE}"
  283. cache_key='flatpak-builder-${{ hashFiles('build-aux/com.obsproject.Studio.json') }}'
  284. cache_ref='master'
  285. read -r id key size unit created accessed <<< \
  286. "$(gh cache list --ref "refs/heads/${cache_ref}" --key "${cache_key}-x86_64" | head -1)"
  287. if [[ "${key}" ]]; then
  288. echo "cacheHit=true" >> $GITHUB_OUTPUT
  289. else
  290. echo "cacheHit=false" >> $GITHUB_OUTPUT
  291. fi
  292. echo "cacheKey=${cache_key}" >> $GITHUB_OUTPUT
  293. - name: Validate Flatpak manifest
  294. uses: ./.github/actions/flatpak-builder-lint
  295. with:
  296. artifact: manifest
  297. path: build-aux/com.obsproject.Studio.json
  298. - name: Build Flatpak Manifest 🧾
  299. uses: flatpak/flatpak-github-actions/flatpak-builder@b8a638469ea7ec62844d7b6e487b697e6f249576
  300. with:
  301. build-bundle: ${{ fromJSON(needs.check-event.outputs.package) }}
  302. bundle: obs-studio-flatpak-${{ needs.check-event.outputs.commitHash }}.flatpak
  303. manifest-path: ${{ github.workspace }}/build-aux/com.obsproject.Studio.json
  304. cache: ${{ fromJSON(steps.setup.outputs.cacheHit) || (github.event_name == 'push' && github.ref_name == 'master')}}
  305. restore-cache: ${{ fromJSON(steps.setup.outputs.cacheHit) }}
  306. cache-key: ${{ steps.setup.outputs.cacheKey }}
  307. mirror-screenshots-url: https://dl.flathub.org/media
  308. - name: Validate AppStream
  309. uses: ./.github/actions/flatpak-builder-lint
  310. with:
  311. artifact: appstream
  312. path: ${{ env.FLATPAK_BUILD_SHARE_PATH }}/metainfo/com.obsproject.Studio.metainfo.xml
  313. - name: Verify Icon and Metadata in app-info
  314. working-directory: ${{ env.FLATPAK_BUILD_SHARE_PATH }}
  315. run: |
  316. : Verify Icon and Metadata in app-info
  317. test -f app-info/icons/flatpak/128x128/com.obsproject.Studio.png || { echo "::error::Missing 128x128 icon in app-info"; exit 1; }
  318. test -f app-info/xmls/com.obsproject.Studio.xml.gz || { echo "::error::Missing com.obsproject.Studio.xml.gz in app-info"; exit 1; }
  319. - name: Validate build directory
  320. uses: ./.github/actions/flatpak-builder-lint
  321. with:
  322. artifact: builddir
  323. path: flatpak_app
  324. - name: Validate repository
  325. uses: ./.github/actions/flatpak-builder-lint
  326. with:
  327. artifact: repo
  328. path: repo
  329. windows-build:
  330. name: Windows 🪟
  331. strategy:
  332. matrix:
  333. architecture: [x64, arm64]
  334. runs-on: windows-2022
  335. needs: check-event
  336. defaults:
  337. run:
  338. shell: pwsh
  339. steps:
  340. - uses: actions/checkout@v4
  341. with:
  342. submodules: recursive
  343. fetch-depth: 0
  344. - name: Build OBS Studio 🧱
  345. uses: ./.github/actions/build-obs
  346. env:
  347. TWITCH_CLIENTID: ${{ secrets.TWITCH_CLIENT_ID }}
  348. TWITCH_HASH: ${{ secrets.TWITCH_HASH }}
  349. RESTREAM_CLIENTID: ${{ secrets.RESTREAM_CLIENTID }}
  350. RESTREAM_HASH: ${{ secrets.RESTREAM_HASH }}
  351. YOUTUBE_CLIENTID: ${{ secrets.YOUTUBE_CLIENTID }}
  352. YOUTUBE_CLIENTID_HASH: ${{ secrets.YOUTUBE_CLIENTID_HASH }}
  353. YOUTUBE_SECRET: ${{ secrets.YOUTUBE_SECRET }}
  354. YOUTUBE_SECRET_HASH: ${{ secrets.YOUTUBE_SECRET_HASH }}
  355. GPU_PRIORITY_VAL: ${{ secrets.GPU_PRIORITY_VAL }}
  356. with:
  357. target: ${{ matrix.architecture }}
  358. config: ${{ needs.check-event.outputs.config }}
  359. - name: Package OBS Studio 📀
  360. uses: ./.github/actions/package-obs
  361. with:
  362. target: ${{ matrix.architecture }}
  363. config: ${{ needs.check-event.outputs.config }}
  364. package: ${{ fromJSON(needs.check-event.outputs.package) }}
  365. - name: Upload Artifacts 📡
  366. uses: actions/upload-artifact@v4
  367. with:
  368. name: obs-studio-windows-${{ matrix.architecture }}-${{ needs.check-event.outputs.commitHash }}
  369. path: ${{ github.workspace }}/build_${{ matrix.architecture }}/obs-studio-*-windows-${{ matrix.architecture }}.zip