backend.yml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  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. plugins: ${{ steps.changes.outputs.plugins }}
  28. steps:
  29. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  30. - name: Check for backend file changes
  31. uses: getsentry/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
  32. id: changes
  33. with:
  34. token: ${{ github.token }}
  35. filters: .github/file-filters.yml
  36. api-docs:
  37. if: needs.files-changed.outputs.api_docs == 'true'
  38. needs: files-changed
  39. name: api docs test
  40. runs-on: ubuntu-20.04
  41. steps:
  42. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  43. - uses: getsentry/action-setup-volta@54775a59c41065f54ecc76d1dd5f2cdc7a1550cb # v1.1.0
  44. - name: Setup sentry python env
  45. uses: ./.github/actions/setup-sentry
  46. id: setup
  47. with:
  48. snuba: true
  49. - name: Run API docs tests
  50. # install ts-node for ts build scripts to execute properly without potentially installing
  51. # conflicting deps when running scripts locally
  52. # see: https://github.com/getsentry/sentry/pull/32328/files
  53. run: |
  54. yarn add ts-node && make test-api-docs
  55. backend-test:
  56. if: needs.files-changed.outputs.backend == 'true'
  57. needs: files-changed
  58. name: backend test
  59. runs-on: ubuntu-20.04
  60. timeout-minutes: 40
  61. strategy:
  62. # This helps not having to run multiple jobs because one fails, thus, reducing resource usage
  63. # and reducing the risk that one of many runs would turn red again (read: intermittent tests)
  64. fail-fast: false
  65. matrix:
  66. # XXX: When updating this, make sure you also update MATRIX_INSTANCE_TOTAL.
  67. instance: [0, 1, 2, 3, 4, 5, 6]
  68. pg-version: ['14']
  69. env:
  70. # XXX: `MATRIX_INSTANCE_TOTAL` must be hardcoded to the length of `strategy.matrix.instance`.
  71. # If this increases, make sure to also increase `flags.backend.after_n_builds` in `codecov.yml`.
  72. MATRIX_INSTANCE_TOTAL: 7
  73. steps:
  74. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  75. with:
  76. # Avoid codecov error message related to SHA resolution:
  77. # https://github.com/codecov/codecov-bash/blob/7100762afbc822b91806a6574658129fe0d23a7d/codecov#L891
  78. fetch-depth: '2'
  79. - name: Update environment for silo databases
  80. if: |
  81. contains( github.event.pull_request.labels.*.name, 'Trigger: Silo db' )
  82. run: |
  83. echo "SENTRY_USE_SPLIT_DBS=1" >> "$GITHUB_ENV"
  84. - name: Setup sentry env
  85. uses: ./.github/actions/setup-sentry
  86. id: setup
  87. with:
  88. snuba: true
  89. # Right now, we run so few bigtable related tests that the
  90. # overhead of running bigtable in all backend tests
  91. # is way smaller than the time it would take to run in its own job.
  92. bigtable: true
  93. pg-version: ${{ matrix.pg-version }}
  94. - name: Run backend test (${{ steps.setup.outputs.matrix-instance-number }} of ${{ steps.setup.outputs.matrix-instance-total }})
  95. run: |
  96. make test-python-ci
  97. # Upload coverage data even if running the tests step fails since
  98. # it reduces large coverage fluctuations
  99. - name: Handle artifacts
  100. if: ${{ always() }}
  101. uses: ./.github/actions/artifacts
  102. with:
  103. token: ${{ secrets.CODECOV_TOKEN }}
  104. backend-migration-tests:
  105. if: needs.files-changed.outputs.backend == 'true'
  106. needs: files-changed
  107. name: backend migration tests
  108. runs-on: ubuntu-20.04
  109. timeout-minutes: 30
  110. strategy:
  111. matrix:
  112. pg-version: ['14']
  113. steps:
  114. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  115. with:
  116. # Avoid codecov error message related to SHA resolution:
  117. # https://github.com/codecov/codecov-bash/blob/7100762afbc822b91806a6574658129fe0d23a7d/codecov#L891
  118. fetch-depth: '2'
  119. - name: Update environment for silo databases
  120. id: silo_env
  121. if: |
  122. contains( github.event.pull_request.labels.*.name, 'Trigger: Silo db' )
  123. run: |
  124. echo "SENTRY_USE_SPLIT_DBS=1" >> "$GITHUB_ENV"
  125. - name: Setup sentry env
  126. uses: ./.github/actions/setup-sentry
  127. id: setup
  128. with:
  129. snuba: true
  130. pg-version: ${{ matrix.pg-version }}
  131. - name: run tests
  132. run: |
  133. MIGRATIONS_TEST_MIGRATE=1 PYTEST_ADDOPTS="$PYTEST_ADDOPTS -m migrations" make test-python-ci
  134. # Upload coverage data even if running the tests step fails since
  135. # it reduces large coverage fluctuations
  136. - name: Handle artifacts
  137. if: ${{ always() }}
  138. uses: ./.github/actions/artifacts
  139. with:
  140. token: ${{ secrets.CODECOV_TOKEN }}
  141. cli:
  142. if: needs.files-changed.outputs.backend == 'true'
  143. needs: files-changed
  144. name: cli test
  145. runs-on: ubuntu-20.04
  146. timeout-minutes: 10
  147. strategy:
  148. matrix:
  149. pg-version: ['14']
  150. steps:
  151. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  152. - name: Update environment for silo databases
  153. if: |
  154. contains( github.event.pull_request.labels.*.name, 'Trigger: Silo db' )
  155. run: |
  156. echo "SENTRY_USE_SPLIT_DBS=1" >> "$GITHUB_ENV"
  157. - name: Setup sentry env
  158. uses: ./.github/actions/setup-sentry
  159. id: setup
  160. with:
  161. pg-version: ${{ matrix.pg-version }}
  162. - name: Run test
  163. run: |
  164. make test-cli
  165. # Upload coverage data even if running the tests step fails since
  166. # it reduces large coverage fluctuations
  167. - name: Handle artifacts
  168. if: ${{ always() }}
  169. uses: ./.github/actions/artifacts
  170. with:
  171. token: ${{ secrets.CODECOV_TOKEN }}
  172. requirements:
  173. if: needs.files-changed.outputs.backend_dependencies == 'true'
  174. needs: files-changed
  175. name: requirements check
  176. runs-on: ubuntu-20.04
  177. timeout-minutes: 3
  178. steps:
  179. - uses: getsentry/action-github-app-token@97c9e23528286821f97fba885c1b1123284b29cc # v2.0.0
  180. id: token
  181. continue-on-error: true
  182. with:
  183. app_id: ${{ vars.SENTRY_INTERNAL_APP_ID }}
  184. private_key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
  185. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  186. - uses: getsentry/action-setup-venv@9e3bbae3836b1b6f129955bf55a19e1d99a61c67 # v1.0.5
  187. with:
  188. python-version: 3.8.16
  189. cache-depedency: requirements-dev-frozen.txt
  190. install-cmd: pip install -q --constraint requirements-dev-frozen.txt pip-tools
  191. - name: check requirements
  192. run: |
  193. python -S -m tools.freeze_requirements
  194. if ! git diff --exit-code; then
  195. echo $'\n\nrun `make freeze-requirements` locally to update requirements'
  196. exit 1
  197. fi
  198. - name: apply any requirements changes
  199. if: steps.token.outcome == 'success' && github.ref != 'refs/heads/master' && always()
  200. uses: getsentry/action-github-commit@748c31dd78cffe76f51bef49a0be856b6effeda7 # v1.1.0
  201. with:
  202. github-token: ${{ steps.token.outputs.token }}
  203. message: ':snowflake: re-freeze requirements'
  204. lint:
  205. if: needs.files-changed.outputs.backend == 'true'
  206. needs: files-changed
  207. name: backend lint
  208. runs-on: ubuntu-20.04
  209. timeout-minutes: 10
  210. steps:
  211. - uses: getsentry/action-github-app-token@97c9e23528286821f97fba885c1b1123284b29cc # v2.0.0
  212. id: token
  213. continue-on-error: true
  214. with:
  215. app_id: ${{ vars.SENTRY_INTERNAL_APP_ID }}
  216. private_key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
  217. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  218. - uses: getsentry/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
  219. id: files
  220. with:
  221. # Enable listing of files matching each filter.
  222. # Paths to files will be available in `${FILTER_NAME}_files` output variable.
  223. # Paths will be escaped and space-delimited.
  224. # Output is usable as command line argument list in linux shell
  225. list-files: shell
  226. # It doesn't make sense to lint deleted files.
  227. # Therefore we specify we are only interested in added or modified files.
  228. filters: |
  229. all:
  230. - added|modified: '**/*.py'
  231. - added|modified: 'requirements-*.txt'
  232. - uses: getsentry/action-setup-venv@9e3bbae3836b1b6f129955bf55a19e1d99a61c67 # v1.0.5
  233. with:
  234. python-version: 3.8.16
  235. cache-dependency-path: |
  236. requirements-dev.txt
  237. requirements-dev-frozen.txt
  238. install-cmd: pip install -r requirements-dev.txt -c requirements-dev-frozen.txt
  239. - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
  240. with:
  241. path: ~/.cache/pre-commit
  242. key: cache-epoch-1|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}
  243. - name: Setup pre-commit
  244. # We don't use make setup-git because we're only interested in installing
  245. # requirements-dev.txt as a fast path.
  246. # We don't need pre-commit install --install-hooks since we're just interested
  247. # in running the hooks.
  248. run: |
  249. pre-commit install-hooks
  250. - name: Run pre-commit on changed files
  251. run: |
  252. # Run pre-commit to lint and format check files that were changed (but not deleted) compared to master.
  253. # XXX: there is a very small chance that it'll expand to exceed Linux's limits
  254. # `getconf ARG_MAX` - max # bytes of args + environ for exec()
  255. pre-commit run --files ${{ steps.files.outputs.all_files }}
  256. - name: Apply any pre-commit fixed files
  257. if: steps.token.outcome == 'success' && github.ref != 'refs/heads/master' && always()
  258. uses: getsentry/action-github-commit@748c31dd78cffe76f51bef49a0be856b6effeda7 # v1.1.0
  259. with:
  260. github-token: ${{ steps.token.outputs.token }}
  261. message: ':hammer_and_wrench: apply pre-commit fixes'
  262. migration:
  263. if: needs.files-changed.outputs.migration_lockfile == 'true'
  264. needs: files-changed
  265. name: check migration
  266. runs-on: ubuntu-20.04
  267. strategy:
  268. matrix:
  269. pg-version: ['14']
  270. steps:
  271. - name: Checkout sentry
  272. uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  273. - name: Setup sentry env
  274. uses: ./.github/actions/setup-sentry
  275. id: setup
  276. with:
  277. pg-version: ${{ matrix.pg-version }}
  278. - name: Migration & lockfile checks
  279. env:
  280. SENTRY_LOG_LEVEL: ERROR
  281. PGPASSWORD: postgres
  282. run: |
  283. ./.github/workflows/scripts/migration-check.sh
  284. plugins:
  285. if: needs.files-changed.outputs.plugins == 'true'
  286. needs: files-changed
  287. name: plugins test
  288. runs-on: ubuntu-20.04
  289. timeout-minutes: 10
  290. steps:
  291. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  292. - name: Update environment for silo databases
  293. if: |
  294. contains( github.event.pull_request.labels.*.name, 'Trigger: Silo db' )
  295. run: |
  296. echo "SENTRY_USE_SPLIT_DBS=1" >> "$GITHUB_ENV"
  297. - name: Setup sentry env
  298. uses: ./.github/actions/setup-sentry
  299. id: setup
  300. with:
  301. snuba: true
  302. - name: Run test
  303. run: |
  304. make test-plugins
  305. relay:
  306. if: needs.files-changed.outputs.backend == 'true'
  307. needs: files-changed
  308. name: relay test
  309. runs-on: ubuntu-20.04
  310. timeout-minutes: 30
  311. steps:
  312. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  313. with:
  314. # Avoid codecov error message related to SHA resolution:
  315. # https://github.com/codecov/codecov-bash/blob/7100762afbc822b91806a6574658129fe0d23a7d/codecov#L891
  316. fetch-depth: '2'
  317. - name: Update environment for silo databases
  318. if: |
  319. contains( github.event.pull_request.labels.*.name, 'Trigger: Silo db' )
  320. run: |
  321. echo "SENTRY_USE_SPLIT_DBS=1" >> "$GITHUB_ENV"
  322. - name: Setup sentry env
  323. uses: ./.github/actions/setup-sentry
  324. id: setup
  325. with:
  326. snuba: true
  327. kafka: true
  328. - name: Pull relay image
  329. run: |
  330. # pull relay we'll run and kill it for each test
  331. docker pull us.gcr.io/sentryio/relay:nightly
  332. docker ps -a
  333. - name: Run test
  334. run: |
  335. make test-relay-integration
  336. # Upload coverage data even if running the tests step fails since
  337. # it reduces large coverage fluctuations
  338. - name: Handle artifacts
  339. if: ${{ always() }}
  340. uses: ./.github/actions/artifacts
  341. with:
  342. token: ${{ secrets.CODECOV_TOKEN }}
  343. snuba:
  344. if: needs.files-changed.outputs.backend == 'true'
  345. needs: files-changed
  346. name: snuba test
  347. runs-on: ubuntu-20.04
  348. timeout-minutes: 30
  349. strategy:
  350. # This helps not having to run multiple jobs because one fails, thus, reducing resource usage
  351. # and reducing the risk that one of many runs would turn red again (read: intermittent tests)
  352. fail-fast: false
  353. matrix:
  354. # XXX: When updating this, make sure you also update MATRIX_INSTANCE_TOTAL.
  355. instance: [0, 1, 2]
  356. env:
  357. # XXX: MATRIX_INSTANCE_TOTAL must be hardcoded to the length of strategy.matrix.instance.
  358. MATRIX_INSTANCE_TOTAL: 3
  359. steps:
  360. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  361. with:
  362. # Avoid codecov error message related to SHA resolution:
  363. # https://github.com/codecov/codecov-bash/blob/7100762afbc822b91806a6574658129fe0d23a7d/codecov#L891
  364. fetch-depth: '2'
  365. - name: Update environment for silo databases
  366. if: |
  367. contains( github.event.pull_request.labels.*.name, 'Trigger: Silo db' )
  368. run: |
  369. echo "SENTRY_USE_SPLIT_DBS=1" >> "$GITHUB_ENV"
  370. - name: Setup sentry env
  371. uses: ./.github/actions/setup-sentry
  372. id: setup
  373. with:
  374. snuba: true
  375. kafka: true
  376. - name: Run snuba test (${{ steps.setup.outputs.matrix-instance-number }} of ${{ steps.setup.outputs.matrix-instance-total }})
  377. run: |
  378. make test-snuba
  379. # Upload coverage data even if running the tests step fails since
  380. # it reduces large coverage fluctuations
  381. - name: Handle artifacts
  382. if: ${{ always() }}
  383. uses: ./.github/actions/artifacts
  384. with:
  385. token: ${{ secrets.CODECOV_TOKEN }}
  386. symbolicator:
  387. if: needs.files-changed.outputs.backend == 'true'
  388. needs: files-changed
  389. name: symbolicator test
  390. runs-on: ubuntu-20.04
  391. timeout-minutes: 20
  392. steps:
  393. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  394. with:
  395. # Avoid codecov error message related to SHA resolution:
  396. # https://github.com/codecov/codecov-bash/blob/7100762afbc822b91806a6574658129fe0d23a7d/codecov#L891
  397. fetch-depth: '2'
  398. - name: Setup sentry env
  399. uses: ./.github/actions/setup-sentry
  400. id: setup
  401. with:
  402. snuba: true
  403. kafka: true
  404. - name: Start symbolicator
  405. run: |
  406. echo $PWD
  407. docker run \
  408. -d \
  409. -v $PWD/config/symbolicator/:/etc/symbolicator \
  410. --network host \
  411. --name symbolicator \
  412. us.gcr.io/sentryio/symbolicator:nightly \
  413. run -c /etc/symbolicator/config.yml
  414. docker ps -a
  415. - name: Run test
  416. run: |
  417. make test-symbolicator
  418. # Upload coverage data even if running the tests step fails since
  419. # it reduces large coverage fluctuations
  420. - name: Handle artifacts
  421. if: ${{ always() }}
  422. uses: ./.github/actions/artifacts
  423. with:
  424. token: ${{ secrets.CODECOV_TOKEN }}
  425. typing:
  426. if: needs.files-changed.outputs.backend == 'true'
  427. needs: files-changed
  428. name: backend typing
  429. runs-on: ubuntu-20.04
  430. timeout-minutes: 20
  431. steps:
  432. - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
  433. - uses: getsentry/action-setup-venv@9e3bbae3836b1b6f129955bf55a19e1d99a61c67 # v1.0.5
  434. with:
  435. python-version: 3.8.16
  436. cache-dependency-path: requirements-dev-frozen.txt
  437. install-cmd: pip install -r requirements-dev-frozen.txt
  438. - name: setup sentry (lite)
  439. run: |
  440. SENTRY_LIGHT_BUILD=1 pip install --no-deps -e .
  441. sentry init
  442. - run: make backend-typing
  443. id: run
  444. - uses: getsentry/action-github-app-token@97c9e23528286821f97fba885c1b1123284b29cc # v2.0.0
  445. id: token
  446. continue-on-error: true
  447. with:
  448. app_id: ${{ vars.SENTRY_INTERNAL_APP_ID }}
  449. private_key: ${{ secrets.SENTRY_INTERNAL_APP_PRIVATE_KEY }}
  450. # only if `backend-typing` succeeds should we try and trim the blocklist
  451. - run: |
  452. python3 -m tools.mypy_helpers.make_module_ignores
  453. git diff --exit-code
  454. - name: apply blocklist changes
  455. if: steps.token.outcome == 'success' && steps.run.outcome == 'success' && github.ref != 'refs/heads/master' && always()
  456. uses: getsentry/action-github-commit@748c31dd78cffe76f51bef49a0be856b6effeda7 # v1.1.0
  457. with:
  458. github-token: ${{ steps.token.outputs.token }}
  459. message: ':knife: regenerate mypy module blocklist'
  460. # This check runs once all dependant jobs have passed
  461. # It symbolizes that all required Backend checks have succesfully passed (Or skipped)
  462. # This check is the only required Github check
  463. backend-required-check:
  464. needs:
  465. [
  466. api-docs,
  467. backend-test,
  468. backend-migration-tests,
  469. cli,
  470. files-changed,
  471. lint,
  472. requirements,
  473. migration,
  474. plugins,
  475. relay,
  476. snuba,
  477. symbolicator,
  478. typing,
  479. ]
  480. name: Backend
  481. # This is necessary since a failed/skipped dependent job would cause this job to be skipped
  482. if: always()
  483. runs-on: ubuntu-20.04
  484. steps:
  485. # If any jobs we depend on fail, we will fail since this is a required check
  486. # NOTE: A timeout is considered a failure
  487. - name: Check for failures
  488. if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
  489. run: |
  490. echo "One of the dependent jobs have failed. You may need to re-run it." && exit 1