backend.yml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. name: backend
  2. on:
  3. push:
  4. branches:
  5. - master
  6. pull_request:
  7. # Cancel in progress workflows on pull_requests.
  8. # https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
  9. concurrency:
  10. group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  11. cancel-in-progress: true
  12. # hack for https://github.com/actions/cache/issues/810#issuecomment-1222550359
  13. env:
  14. SEGMENT_DOWNLOAD_TIMEOUT_MINS: 3
  15. jobs:
  16. files-changed:
  17. name: detect what files changed
  18. runs-on: ubuntu-20.04
  19. timeout-minutes: 3
  20. # Map a step output to a job output
  21. outputs:
  22. api_docs: ${{ steps.changes.outputs.api_docs }}
  23. backend: ${{ steps.changes.outputs.backend_all }}
  24. backend_dependencies: ${{ steps.changes.outputs.backend_dependencies }}
  25. backend_any_type: ${{ steps.changes.outputs.backend_any_type }}
  26. migration_lockfile: ${{ steps.changes.outputs.migration_lockfile }}
  27. steps:
  28. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  29. - name: Check for backend file changes
  30. uses: getsentry/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
  31. id: changes
  32. with:
  33. token: ${{ github.token }}
  34. filters: .github/file-filters.yml
  35. api-docs:
  36. if: needs.files-changed.outputs.api_docs == 'true'
  37. needs: files-changed
  38. name: api docs test
  39. runs-on: ubuntu-20.04
  40. steps:
  41. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  42. - uses: getsentry/action-setup-volta@54775a59c41065f54ecc76d1dd5f2cdc7a1550cb # v1.1.0
  43. - name: Setup sentry python env
  44. uses: ./.github/actions/setup-sentry
  45. id: setup
  46. with:
  47. snuba: true
  48. - name: Run API docs tests
  49. # install ts-node for ts build scripts to execute properly without potentially installing
  50. # conflicting deps when running scripts locally
  51. # see: https://github.com/getsentry/sentry/pull/32328/files
  52. run: |
  53. yarn add ts-node && make test-api-docs
  54. backend-test:
  55. if: needs.files-changed.outputs.backend == 'true'
  56. needs: files-changed
  57. name: backend test
  58. runs-on: ubuntu-20.04
  59. timeout-minutes: 40
  60. strategy:
  61. # This helps not having to run multiple jobs because one fails, thus, reducing resource usage
  62. # and reducing the risk that one of many runs would turn red again (read: intermittent tests)
  63. fail-fast: false
  64. matrix:
  65. # XXX: When updating this, make sure you also update MATRIX_INSTANCE_TOTAL.
  66. instance: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  67. pg-version: ['14']
  68. # it's not possible to change settings.DATABASE after django startup, so
  69. # unfortunately these tests must be run seperately. References:
  70. # * https://docs.djangoproject.com/en/4.2/topics/testing/tools/#overriding-settings
  71. # * https://code.djangoproject.com/ticket/19031
  72. # * https://github.com/pombredanne/django-database-constraints/blob/master/runtests.py#L61-L77
  73. make-target: [ "test-python-ci", "test-python-ci-monolith-dbs" ]
  74. env:
  75. # XXX: `MATRIX_INSTANCE_TOTAL` must be hardcoded to the length of `strategy.matrix.instance`.
  76. # If this increases, make sure to also increase `flags.backend.after_n_builds` in `codecov.yml`.
  77. MATRIX_INSTANCE_TOTAL: 11
  78. steps:
  79. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  80. with:
  81. # Avoid codecov error message related to SHA resolution:
  82. # https://github.com/codecov/codecov-bash/blob/7100762afbc822b91806a6574658129fe0d23a7d/codecov#L891
  83. fetch-depth: '2'
  84. - name: Setup sentry env
  85. uses: ./.github/actions/setup-sentry
  86. id: setup
  87. with:
  88. kafka: true
  89. snuba: true
  90. symbolicator: true
  91. # Right now, we run so few bigtable related tests that the
  92. # overhead of running bigtable in all backend tests
  93. # is way smaller than the time it would take to run in its own job.
  94. bigtable: true
  95. pg-version: ${{ matrix.pg-version }}
  96. - name: Run backend test (${{ steps.setup.outputs.matrix-instance-number }} of ${{ steps.setup.outputs.matrix-instance-total }})
  97. run: |
  98. make test-python-ci
  99. # Upload coverage data even if running the tests step fails since
  100. # it reduces large coverage fluctuations
  101. - name: Handle artifacts
  102. if: ${{ always() }}
  103. uses: ./.github/actions/artifacts
  104. with:
  105. token: ${{ secrets.CODECOV_TOKEN }}
  106. backend-migration-tests:
  107. if: needs.files-changed.outputs.backend == 'true'
  108. needs: files-changed
  109. name: backend migration tests
  110. runs-on: ubuntu-20.04
  111. timeout-minutes: 30
  112. strategy:
  113. matrix:
  114. pg-version: ['14']
  115. steps:
  116. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  117. with:
  118. # Avoid codecov error message related to SHA resolution:
  119. # https://github.com/codecov/codecov-bash/blob/7100762afbc822b91806a6574658129fe0d23a7d/codecov#L891
  120. fetch-depth: '2'
  121. - name: Setup sentry env
  122. uses: ./.github/actions/setup-sentry
  123. id: setup
  124. with:
  125. snuba: true
  126. pg-version: ${{ matrix.pg-version }}
  127. - name: run tests
  128. run: |
  129. MIGRATIONS_TEST_MIGRATE=1 PYTEST_ADDOPTS="$PYTEST_ADDOPTS -m migrations" make test-python-ci
  130. # Upload coverage data even if running the tests step fails since
  131. # it reduces large coverage fluctuations
  132. - name: Handle artifacts
  133. if: ${{ always() }}
  134. uses: ./.github/actions/artifacts
  135. with:
  136. token: ${{ secrets.CODECOV_TOKEN }}
  137. cli:
  138. if: needs.files-changed.outputs.backend == 'true'
  139. needs: files-changed
  140. name: cli test
  141. runs-on: ubuntu-20.04
  142. timeout-minutes: 10
  143. strategy:
  144. matrix:
  145. pg-version: ['14']
  146. steps:
  147. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  148. - name: Setup sentry env
  149. uses: ./.github/actions/setup-sentry
  150. id: setup
  151. with:
  152. pg-version: ${{ matrix.pg-version }}
  153. - name: Run test
  154. run: |
  155. make test-cli
  156. # Upload coverage data even if running the tests step fails since
  157. # it reduces large coverage fluctuations
  158. - name: Handle artifacts
  159. if: ${{ always() }}
  160. uses: ./.github/actions/artifacts
  161. with:
  162. token: ${{ secrets.CODECOV_TOKEN }}
  163. requirements:
  164. if: needs.files-changed.outputs.backend_dependencies == 'true'
  165. needs: files-changed
  166. name: requirements check
  167. runs-on: ubuntu-20.04
  168. timeout-minutes: 3
  169. steps:
  170. - uses: getsentry/action-github-app-token@97c9e23528286821f97fba885c1b1123284b29cc # v2.0.0
  171. id: token
  172. continue-on-error: true
  173. with:
  174. app_id: ${{ vars.SENTRY_INTERNAL_APP_ID }}
  175. private_key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
  176. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  177. - uses: getsentry/action-setup-venv@9e3bbae3836b1b6f129955bf55a19e1d99a61c67 # v1.0.5
  178. with:
  179. python-version: 3.8.16
  180. cache-depedency: requirements-dev-frozen.txt
  181. install-cmd: pip install -q --constraint requirements-dev-frozen.txt pip-tools
  182. - name: check requirements
  183. run: |
  184. python -S -m tools.freeze_requirements
  185. if ! git diff --exit-code; then
  186. echo $'\n\nrun `make freeze-requirements` locally to update requirements'
  187. exit 1
  188. fi
  189. - name: apply any requirements changes
  190. if: steps.token.outcome == 'success' && github.ref != 'refs/heads/master' && always()
  191. uses: getsentry/action-github-commit@748c31dd78cffe76f51bef49a0be856b6effeda7 # v1.1.0
  192. with:
  193. github-token: ${{ steps.token.outputs.token }}
  194. message: ':snowflake: re-freeze requirements'
  195. migration:
  196. if: needs.files-changed.outputs.migration_lockfile == 'true'
  197. needs: files-changed
  198. name: check migration
  199. runs-on: ubuntu-20.04
  200. strategy:
  201. matrix:
  202. pg-version: ['14']
  203. steps:
  204. - name: Checkout sentry
  205. uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  206. - name: Setup sentry env
  207. uses: ./.github/actions/setup-sentry
  208. id: setup
  209. with:
  210. pg-version: ${{ matrix.pg-version }}
  211. - name: Migration & lockfile checks
  212. env:
  213. SENTRY_LOG_LEVEL: ERROR
  214. PGPASSWORD: postgres
  215. run: |
  216. ./.github/workflows/scripts/migration-check.sh
  217. typing:
  218. if: needs.files-changed.outputs.backend == 'true'
  219. needs: files-changed
  220. name: backend typing
  221. runs-on: ubuntu-20.04
  222. timeout-minutes: 20
  223. steps:
  224. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  225. - uses: getsentry/action-setup-venv@9e3bbae3836b1b6f129955bf55a19e1d99a61c67 # v1.0.5
  226. with:
  227. python-version: 3.8.16
  228. cache-dependency-path: requirements-dev-frozen.txt
  229. install-cmd: pip install -r requirements-dev-frozen.txt
  230. - name: setup sentry (lite)
  231. run: |
  232. SENTRY_LIGHT_BUILD=1 pip install --no-deps -e .
  233. sentry init
  234. - run: mypy
  235. id: run
  236. - run: |
  237. # mypy does not have granular codes so don't allow specific messages to regress
  238. ! grep 'Exception type must be derived from BaseException' .artifacts/mypy-all
  239. ! grep "'Settings' object has no attribute" .artifacts/mypy-all
  240. ! grep 'Cannot override class variable' .artifacts/mypy-all
  241. - uses: getsentry/action-github-app-token@97c9e23528286821f97fba885c1b1123284b29cc # v2.0.0
  242. id: token
  243. continue-on-error: true
  244. with:
  245. app_id: ${{ vars.SENTRY_INTERNAL_APP_ID }}
  246. private_key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
  247. # only if `mypy` succeeds should we try and trim the blocklist
  248. - run: |
  249. python3 -m tools.mypy_helpers.make_module_ignores
  250. git diff --exit-code
  251. - name: apply blocklist changes
  252. if: steps.token.outcome == 'success' && steps.run.outcome == 'success' && github.ref != 'refs/heads/master' && always()
  253. uses: getsentry/action-github-commit@748c31dd78cffe76f51bef49a0be856b6effeda7 # v1.1.0
  254. with:
  255. github-token: ${{ steps.token.outputs.token }}
  256. message: ':knife: regenerate mypy module blocklist'
  257. # This check runs once all dependent jobs have passed
  258. # It symbolizes that all required Backend checks have succesfully passed (Or skipped)
  259. # This step is the only required backend check
  260. backend-required-check:
  261. needs:
  262. [
  263. api-docs,
  264. backend-test,
  265. backend-migration-tests,
  266. cli,
  267. files-changed,
  268. requirements,
  269. migration,
  270. typing,
  271. ]
  272. name: Backend
  273. # This is necessary since a failed/skipped dependent job would cause this job to be skipped
  274. if: always()
  275. runs-on: ubuntu-20.04
  276. steps:
  277. # If any jobs we depend on fail, we will fail since this is a required check
  278. # NOTE: A timeout is considered a failure
  279. - name: Check for failures
  280. if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
  281. run: |
  282. echo "One of the dependent jobs have failed. You may need to re-run it." && exit 1