scheduled.yaml 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. name: Scheduled
  2. run-name: Scheduled Repository Actions ⏰
  3. on:
  4. workflow_dispatch:
  5. schedule:
  6. - cron: 17 0 * * *
  7. permissions:
  8. contents: write
  9. concurrency:
  10. group: '${{ github.workflow }} @ ${{ github.head_ref || github.ref }}'
  11. cancel-in-progress: true
  12. jobs:
  13. services-availability:
  14. name: Check Service Availability 🛜
  15. if: github.repository_owner == 'obsproject'
  16. runs-on: macos-15
  17. permissions:
  18. checks: write
  19. contents: write
  20. pull-requests: write
  21. steps:
  22. - uses: actions/checkout@v4
  23. with:
  24. fetch-depth: 0
  25. - name: Set Up Homebrew 🍺
  26. uses: Homebrew/actions/setup-homebrew@master
  27. - name: Check for Defunct Services 📉
  28. uses: ./.github/actions/services-validator
  29. with:
  30. repositorySecret: ${{ secrets.GITHUB_TOKEN }}
  31. checkApiSecret: ${{ secrets.CHECK_SERVERS_API_KEY }}
  32. checkApiServers: ${{ secrets.CHECK_SERVERS_LIST }}
  33. runSchemaChecks: false
  34. runServiceChecks: true
  35. createPullRequest: true
  36. cache-cleanup:
  37. name: Cache Cleanup 🧹
  38. runs-on: ubuntu-24.04
  39. permissions:
  40. actions: write
  41. steps:
  42. - name: Remove Stale Ccache Caches
  43. env:
  44. GH_TOKEN: ${{ github.token }}
  45. run: |
  46. : Remove Stale Ccache Caches
  47. # The jq expressions below use multiple 'select' calls to filter
  48. # each item in the array with the 'actions_caches' key.
  49. # First it only selects objects whose 'ref' element has the value
  50. # 'refs/heads/master', of those objects only those whose 'key'
  51. # value matches the specified expression, before finally only
  52. # selecting the 'id' and 'key' elements for a new object.
  53. # The final 'join' command combines both elements with a semicolon
  54. # into a raw string which can then be parsed directly.
  55. echo '::group::Processing master branch cache entries'
  56. while IFS=";" read -r cache_id cache_name; do
  57. if [[ "${cache_name}" ]]; then
  58. result=true
  59. gh api -X DELETE repos/${GITHUB_REPOSITORY}/actions/caches?key=${cache_name} --jq '.total_count' &> /dev/null || result=false
  60. if ${result}; then
  61. echo "Deleted cache entry ${cache_name}"
  62. else
  63. echo "::warning::Unable to delete cache entry ${cache_name}"
  64. fi
  65. fi
  66. done <<< \
  67. "$(gh api repos/${GITHUB_REPOSITORY}/actions/caches \
  68. --jq '.actions_caches.[] | select(.ref|test("refs/heads/master")) | select(.key|test(".*-ccache-*")) | {id, key} | join(";")')"
  69. echo '::endgroup::'
  70. echo '::group::Processing pull request cache entries'
  71. while IFS=";" read -r cache_id cache_name cache_ref; do
  72. if [[ "${cache_name}" ]]; then
  73. result=true
  74. gh api -X DELETE repos/${GITHUB_REPOSITORY}/actions/caches?key=${cache_name} --jq '.total_count' &> /dev/null || result=false
  75. pr_number=$(echo ${cache_ref} | cut -d '/' -f 3)
  76. if ${result}; then
  77. echo "Deleted PR #${pr_number} cache entry ${cache_name}"
  78. else
  79. echo "::warning::Unable to delete PR #${pr_number} cache entry ${cache_name}"
  80. fi
  81. fi
  82. done <<< \
  83. "$(gh api repos/${GITHUB_REPOSITORY}/actions/caches \
  84. --jq '.actions_caches.[] | select(.ref|test("refs/heads/master")|not) | select(.key|test(".*-ccache-*")) | {id, key, ref} | join(";")')"
  85. echo '::endgroup::'
  86. build-project:
  87. name: Build 🧱
  88. uses: ./.github/workflows/build-project.yaml
  89. needs: cache-cleanup
  90. secrets: inherit
  91. analyze-project:
  92. name: Analyze 🔬
  93. uses: ./.github/workflows/analyze-project.yaml
  94. needs: cache-cleanup
  95. secrets: inherit
  96. permissions:
  97. security-events: write
  98. upload-language-files:
  99. name: Upload Language Files 🌐
  100. if: github.repository_owner == 'obsproject' && github.ref_name == 'master'
  101. runs-on: ubuntu-24.04
  102. steps:
  103. - uses: actions/checkout@v4
  104. with:
  105. submodules: recursive
  106. fetch-depth: 0
  107. - name: Check Nightly Runs ☑️
  108. id: nightly-checks
  109. env:
  110. GH_TOKEN: ${{ github.token }}
  111. run: |
  112. : Check Nightly Runs ☑️
  113. if [[ "${RUNNER_DEBUG}" ]]; then set -x; fi
  114. # This 'gh' command retrieves the last 2 runs of the workflow defined
  115. # by 'scheduled.yaml' and retrieves just the 'headSha' value of the
  116. # JSON response payload.
  117. #
  118. # As this job runs in context of the same workflow, the first element
  119. # of the workflow list will be the currently active run.
  120. #
  121. # The jq expression then selects the 'headSha' element of the second
  122. # element in the array, which is the SHA-1 hash of the commit used
  123. # for the immediately prior run of this workflow.
  124. last_nightly=$(gh run list --workflow scheduled.yaml --limit 2 --json headSha --jq '.[1].headSha')
  125. if [[ "${GITHUB_SHA}" == "${last_nightly}" ]]; then
  126. echo "passed=false" >> $GITHUB_OUTPUT
  127. else
  128. echo "passed=true" >> $GITHUB_OUTPUT
  129. echo "lastNightly=${last_nightly}" >> $GITHUB_OUTPUT
  130. fi
  131. - name: Check for Changed Files ✅
  132. if: fromJSON(steps.nightly-checks.outputs.passed)
  133. uses: ./.github/actions/check-changes
  134. id: checks
  135. with:
  136. baseRef: ${{ steps.nightly-checks.outputs.lastNightly }}
  137. checkGlob: '**/en-US.ini'
  138. - name: Upload US English Language Files 🇺🇸
  139. if: steps.checks.outcome == 'success' && fromJSON(steps.checks.outputs.hasChangedFiles)
  140. uses: obsproject/obs-crowdin-sync/upload@430665179ed13233af2d83ec192c2ae8c40a29ae
  141. env:
  142. CROWDIN_PAT: ${{ secrets.CROWDIN_SYNC_CROWDIN_PAT }}
  143. GITHUB_EVENT_BEFORE: ${{ steps.nightly-checks.outputs.lastNightly }}
  144. steam-upload:
  145. name: Upload Steam Builds 🚂
  146. needs: [build-project]
  147. if: github.repository_owner == 'obsproject'
  148. runs-on: macos-15
  149. defaults:
  150. run:
  151. shell: zsh --no-rcs --errexit --pipefail {0}
  152. steps:
  153. - uses: actions/checkout@v4
  154. - name: Check Nightly Runs ☑️
  155. id: checks
  156. env:
  157. GH_TOKEN: ${{ github.token }}
  158. run: |
  159. : Check Nightly Runs ☑️
  160. if (( ${+RUNNER_DEBUG} )) setopt XTRACE
  161. # This 'gh' command retrieves the last 2 runs of the workflow defined
  162. # by 'scheduled.yaml' and retrieves just the 'headSha' value of the
  163. # JSON response payload.
  164. #
  165. # As this job runs in context of the same workflow, the first element
  166. # of the workflow list will be the currently active run.
  167. #
  168. # The jq expression then selects the 'headSha' element of the second
  169. # element in the array, which is the SHA-1 hash of the commit used
  170. # for the immediately prior run of this workflow.
  171. local last_nightly=$(gh run list --workflow scheduled.yaml --limit 2 --json headSha --jq '.[1].headSha')
  172. if [[ "${GITHUB_SHA}" == "${last_nightly}" ]] {
  173. print "passed=false" >> $GITHUB_OUTPUT
  174. } else {
  175. print "passed=true" >> $GITHUB_OUTPUT
  176. }
  177. - uses: ./.github/actions/steam-upload
  178. if: fromJSON(steps.checks.outputs.passed)
  179. with:
  180. steamSecret: ${{ secrets.STEAM_SHARED_SECRET }}
  181. steamUser: ${{ secrets.STEAM_USER }}
  182. steamPassword: ${{ secrets.STEAM_PASSWORD }}
  183. workflowSecret: ${{ secrets.GITHUB_TOKEN }}
  184. preview: ${{ github.repository_owner != 'obsproject' }}