tests.yml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. name: Tests
  2. on:
  3. push:
  4. branches: ["develop", "release-*"]
  5. pull_request:
  6. concurrency:
  7. group: ${{ github.workflow }}-${{ github.ref }}
  8. cancel-in-progress: true
  9. jobs:
  10. # Job to detect what has changed so we don't run e.g. Rust checks on PRs that
  11. # don't modify Rust code.
  12. changes:
  13. runs-on: ubuntu-latest
  14. outputs:
  15. rust: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.rust }}
  16. steps:
  17. - uses: dorny/paths-filter@v2
  18. id: filter
  19. # We only check on PRs
  20. if: startsWith(github.ref, 'refs/pull/')
  21. with:
  22. filters: |
  23. rust:
  24. - 'rust/**'
  25. - 'Cargo.toml'
  26. check-sampleconfig:
  27. runs-on: ubuntu-latest
  28. steps:
  29. - uses: actions/checkout@v2
  30. - uses: actions/setup-python@v2
  31. - run: pip install .
  32. - run: scripts-dev/generate_sample_config.sh --check
  33. - run: scripts-dev/config-lint.sh
  34. check-schema-delta:
  35. runs-on: ubuntu-latest
  36. steps:
  37. - uses: actions/checkout@v2
  38. - uses: actions/setup-python@v2
  39. - run: "pip install 'click==8.1.1' 'GitPython>=3.1.20'"
  40. - run: scripts-dev/check_schema_delta.py --force-colors
  41. lint:
  42. uses: "matrix-org/backend-meta/.github/workflows/python-poetry-ci.yml@v1"
  43. with:
  44. typechecking-extras: "all"
  45. lint-crlf:
  46. runs-on: ubuntu-latest
  47. steps:
  48. - uses: actions/checkout@v2
  49. - name: Check line endings
  50. run: scripts-dev/check_line_terminators.sh
  51. lint-newsfile:
  52. if: ${{ github.base_ref == 'develop' || contains(github.base_ref, 'release-') }}
  53. runs-on: ubuntu-latest
  54. steps:
  55. - uses: actions/checkout@v2
  56. with:
  57. ref: ${{ github.event.pull_request.head.sha }}
  58. fetch-depth: 0
  59. - uses: actions/setup-python@v2
  60. - run: "pip install 'towncrier>=18.6.0rc1'"
  61. - run: scripts-dev/check-newsfragment.sh
  62. env:
  63. PULL_REQUEST_NUMBER: ${{ github.event.number }}
  64. lint-pydantic:
  65. runs-on: ubuntu-latest
  66. steps:
  67. - uses: actions/checkout@v2
  68. with:
  69. ref: ${{ github.event.pull_request.head.sha }}
  70. fetch-depth: 0
  71. - uses: matrix-org/setup-python-poetry@v1
  72. with:
  73. extras: "all"
  74. - run: poetry run scripts-dev/check_pydantic_models.py
  75. lint-clippy:
  76. runs-on: ubuntu-latest
  77. needs: changes
  78. if: ${{ needs.changes.outputs.rust == 'true' }}
  79. steps:
  80. - uses: actions/checkout@v2
  81. - name: Install Rust
  82. uses: actions-rs/toolchain@v1
  83. with:
  84. toolchain: 1.61.0
  85. override: true
  86. components: clippy
  87. - uses: Swatinem/rust-cache@v2
  88. - run: cargo clippy
  89. lint-rustfmt:
  90. runs-on: ubuntu-latest
  91. needs: changes
  92. if: ${{ needs.changes.outputs.rust == 'true' }}
  93. steps:
  94. - uses: actions/checkout@v2
  95. - name: Install Rust
  96. uses: actions-rs/toolchain@v1
  97. with:
  98. toolchain: 1.61.0
  99. override: true
  100. components: rustfmt
  101. - uses: Swatinem/rust-cache@v2
  102. - run: cargo fmt --check
  103. # Dummy step to gate other tests on without repeating the whole list
  104. linting-done:
  105. if: ${{ !cancelled() }} # Run this even if prior jobs were skipped
  106. needs:
  107. - lint
  108. - lint-crlf
  109. - lint-newsfile
  110. - lint-pydantic
  111. - check-sampleconfig
  112. - check-schema-delta
  113. - lint-clippy
  114. - lint-rustfmt
  115. runs-on: ubuntu-latest
  116. steps:
  117. - run: "true"
  118. calculate-test-jobs:
  119. if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
  120. needs: linting-done
  121. runs-on: ubuntu-latest
  122. steps:
  123. - uses: actions/checkout@v2
  124. - uses: actions/setup-python@v2
  125. - id: get-matrix
  126. run: .ci/scripts/calculate_jobs.py
  127. outputs:
  128. trial_test_matrix: ${{ steps.get-matrix.outputs.trial_test_matrix }}
  129. sytest_test_matrix: ${{ steps.get-matrix.outputs.sytest_test_matrix }}
  130. trial:
  131. if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
  132. needs: calculate-test-jobs
  133. runs-on: ubuntu-latest
  134. strategy:
  135. matrix:
  136. job: ${{ fromJson(needs.calculate-test-jobs.outputs.trial_test_matrix) }}
  137. steps:
  138. - uses: actions/checkout@v2
  139. - run: sudo apt-get -qq install xmlsec1
  140. - name: Set up PostgreSQL ${{ matrix.job.postgres-version }}
  141. if: ${{ matrix.job.postgres-version }}
  142. run: |
  143. docker run -d -p 5432:5432 \
  144. -e POSTGRES_PASSWORD=postgres \
  145. -e POSTGRES_INITDB_ARGS="--lc-collate C --lc-ctype C --encoding UTF8" \
  146. postgres:${{ matrix.job.postgres-version }}
  147. - uses: matrix-org/setup-python-poetry@v1
  148. with:
  149. python-version: ${{ matrix.job.python-version }}
  150. extras: ${{ matrix.job.extras }}
  151. - name: Await PostgreSQL
  152. if: ${{ matrix.job.postgres-version }}
  153. timeout-minutes: 2
  154. run: until pg_isready -h localhost; do sleep 1; done
  155. - run: poetry run trial --jobs=2 tests
  156. env:
  157. SYNAPSE_POSTGRES: ${{ matrix.job.database == 'postgres' || '' }}
  158. SYNAPSE_POSTGRES_HOST: localhost
  159. SYNAPSE_POSTGRES_USER: postgres
  160. SYNAPSE_POSTGRES_PASSWORD: postgres
  161. - name: Dump logs
  162. # Logs are most useful when the command fails, always include them.
  163. if: ${{ always() }}
  164. # Note: Dumps to workflow logs instead of using actions/upload-artifact
  165. # This keeps logs colocated with failing jobs
  166. # It also ignores find's exit code; this is a best effort affair
  167. run: >-
  168. find _trial_temp -name '*.log'
  169. -exec echo "::group::{}" \;
  170. -exec cat {} \;
  171. -exec echo "::endgroup::" \;
  172. || true
  173. trial-olddeps:
  174. # Note: sqlite only; no postgres
  175. if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
  176. needs: linting-done
  177. runs-on: ubuntu-20.04
  178. steps:
  179. - uses: actions/checkout@v2
  180. - name: Install Rust
  181. uses: actions-rs/toolchain@v1
  182. with:
  183. toolchain: 1.61.0
  184. override: true
  185. - uses: Swatinem/rust-cache@v2
  186. # There aren't wheels for some of the older deps, so we need to install
  187. # their build dependencies
  188. - run: |
  189. sudo apt-get -qq install build-essential libffi-dev python-dev \
  190. libxml2-dev libxslt-dev xmlsec1 zlib1g-dev libjpeg-dev libwebp-dev
  191. - uses: actions/setup-python@v4
  192. with:
  193. python-version: '3.7'
  194. # Calculating the old-deps actually takes a bunch of time, so we cache the
  195. # pyproject.toml / poetry.lock. We need to cache pyproject.toml as
  196. # otherwise the `poetry install` step will error due to the poetry.lock
  197. # file being outdated.
  198. #
  199. # This caches the output of `Prepare old deps`, which should generate the
  200. # same `pyproject.toml` and `poetry.lock` for a given `pyproject.toml` input.
  201. - uses: actions/cache@v3
  202. id: cache-poetry-old-deps
  203. name: Cache poetry.lock
  204. with:
  205. path: |
  206. poetry.lock
  207. pyproject.toml
  208. key: poetry-old-deps2-${{ hashFiles('pyproject.toml') }}
  209. - name: Prepare old deps
  210. if: steps.cache-poetry-old-deps.outputs.cache-hit != 'true'
  211. run: .ci/scripts/prepare_old_deps.sh
  212. # We only now install poetry so that `setup-python-poetry` caches the
  213. # right poetry.lock's dependencies.
  214. - uses: matrix-org/setup-python-poetry@v1
  215. with:
  216. python-version: '3.7'
  217. extras: "all test"
  218. - run: poetry run trial -j2 tests
  219. - name: Dump logs
  220. # Logs are most useful when the command fails, always include them.
  221. if: ${{ always() }}
  222. # Note: Dumps to workflow logs instead of using actions/upload-artifact
  223. # This keeps logs colocated with failing jobs
  224. # It also ignores find's exit code; this is a best effort affair
  225. run: >-
  226. find _trial_temp -name '*.log'
  227. -exec echo "::group::{}" \;
  228. -exec cat {} \;
  229. -exec echo "::endgroup::" \;
  230. || true
  231. trial-pypy:
  232. # Very slow; only run if the branch name includes 'pypy'
  233. # Note: sqlite only; no postgres. Completely untested since poetry move.
  234. if: ${{ contains(github.ref, 'pypy') && !failure() && !cancelled() }}
  235. needs: linting-done
  236. runs-on: ubuntu-latest
  237. strategy:
  238. matrix:
  239. python-version: ["pypy-3.7"]
  240. extras: ["all"]
  241. steps:
  242. - uses: actions/checkout@v2
  243. # Install libs necessary for PyPy to build binary wheels for dependencies
  244. - run: sudo apt-get -qq install xmlsec1 libxml2-dev libxslt-dev
  245. - uses: matrix-org/setup-python-poetry@v1
  246. with:
  247. python-version: ${{ matrix.python-version }}
  248. extras: ${{ matrix.extras }}
  249. - run: poetry run trial --jobs=2 tests
  250. - name: Dump logs
  251. # Logs are most useful when the command fails, always include them.
  252. if: ${{ always() }}
  253. # Note: Dumps to workflow logs instead of using actions/upload-artifact
  254. # This keeps logs colocated with failing jobs
  255. # It also ignores find's exit code; this is a best effort affair
  256. run: >-
  257. find _trial_temp -name '*.log'
  258. -exec echo "::group::{}" \;
  259. -exec cat {} \;
  260. -exec echo "::endgroup::" \;
  261. || true
  262. sytest:
  263. if: ${{ !failure() && !cancelled() }}
  264. needs: calculate-test-jobs
  265. runs-on: ubuntu-latest
  266. container:
  267. image: matrixdotorg/sytest-synapse:${{ matrix.job.sytest-tag }}
  268. volumes:
  269. - ${{ github.workspace }}:/src
  270. env:
  271. SYTEST_BRANCH: ${{ github.head_ref }}
  272. POSTGRES: ${{ matrix.job.postgres && 1}}
  273. MULTI_POSTGRES: ${{ (matrix.job.postgres == 'multi-postgres') && 1}}
  274. WORKERS: ${{ matrix.job.workers && 1 }}
  275. BLACKLIST: ${{ matrix.job.workers && 'synapse-blacklist-with-workers' }}
  276. TOP: ${{ github.workspace }}
  277. strategy:
  278. fail-fast: false
  279. matrix:
  280. job: ${{ fromJson(needs.calculate-test-jobs.outputs.sytest_test_matrix) }}
  281. steps:
  282. - uses: actions/checkout@v2
  283. - name: Prepare test blacklist
  284. run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers
  285. - name: Install Rust
  286. uses: actions-rs/toolchain@v1
  287. with:
  288. toolchain: 1.61.0
  289. override: true
  290. - uses: Swatinem/rust-cache@v2
  291. - name: Run SyTest
  292. run: /bootstrap.sh synapse
  293. working-directory: /src
  294. - name: Summarise results.tap
  295. if: ${{ always() }}
  296. run: /sytest/scripts/tap_to_gha.pl /logs/results.tap
  297. - name: Upload SyTest logs
  298. uses: actions/upload-artifact@v2
  299. if: ${{ always() }}
  300. with:
  301. name: Sytest Logs - ${{ job.status }} - (${{ join(matrix.job.*, ', ') }})
  302. path: |
  303. /logs/results.tap
  304. /logs/**/*.log*
  305. export-data:
  306. if: ${{ !failure() && !cancelled() }} # Allow previous steps to be skipped, but not fail
  307. needs: [linting-done, portdb]
  308. runs-on: ubuntu-latest
  309. env:
  310. TOP: ${{ github.workspace }}
  311. services:
  312. postgres:
  313. image: postgres
  314. ports:
  315. - 5432:5432
  316. env:
  317. POSTGRES_PASSWORD: "postgres"
  318. POSTGRES_INITDB_ARGS: "--lc-collate C --lc-ctype C --encoding UTF8"
  319. options: >-
  320. --health-cmd pg_isready
  321. --health-interval 10s
  322. --health-timeout 5s
  323. --health-retries 5
  324. steps:
  325. - uses: actions/checkout@v2
  326. - run: sudo apt-get -qq install xmlsec1
  327. - uses: matrix-org/setup-python-poetry@v1
  328. with:
  329. extras: "postgres"
  330. - run: .ci/scripts/test_export_data_command.sh
  331. portdb:
  332. if: ${{ !failure() && !cancelled() }} # Allow previous steps to be skipped, but not fail
  333. needs: linting-done
  334. runs-on: ubuntu-latest
  335. env:
  336. TOP: ${{ github.workspace }}
  337. strategy:
  338. matrix:
  339. include:
  340. - python-version: "3.7"
  341. postgres-version: "10"
  342. - python-version: "3.10"
  343. postgres-version: "14"
  344. services:
  345. postgres:
  346. image: postgres:${{ matrix.postgres-version }}
  347. ports:
  348. - 5432:5432
  349. env:
  350. POSTGRES_PASSWORD: "postgres"
  351. POSTGRES_INITDB_ARGS: "--lc-collate C --lc-ctype C --encoding UTF8"
  352. options: >-
  353. --health-cmd pg_isready
  354. --health-interval 10s
  355. --health-timeout 5s
  356. --health-retries 5
  357. steps:
  358. - uses: actions/checkout@v2
  359. - run: sudo apt-get -qq install xmlsec1
  360. - uses: matrix-org/setup-python-poetry@v1
  361. with:
  362. python-version: ${{ matrix.python-version }}
  363. extras: "postgres"
  364. - run: .ci/scripts/test_synapse_port_db.sh
  365. complement:
  366. if: "${{ !failure() && !cancelled() }}"
  367. needs: linting-done
  368. runs-on: ubuntu-latest
  369. strategy:
  370. fail-fast: false
  371. matrix:
  372. include:
  373. - arrangement: monolith
  374. database: SQLite
  375. - arrangement: monolith
  376. database: Postgres
  377. - arrangement: workers
  378. database: Postgres
  379. steps:
  380. - name: Run actions/checkout@v2 for synapse
  381. uses: actions/checkout@v2
  382. with:
  383. path: synapse
  384. - name: Install Rust
  385. uses: actions-rs/toolchain@v1
  386. with:
  387. toolchain: 1.61.0
  388. override: true
  389. - uses: Swatinem/rust-cache@v2
  390. - name: Prepare Complement's Prerequisites
  391. run: synapse/.ci/scripts/setup_complement_prerequisites.sh
  392. - run: |
  393. set -o pipefail
  394. POSTGRES=${{ (matrix.database == 'Postgres') && 1 || '' }} WORKERS=${{ (matrix.arrangement == 'workers') && 1 || '' }} COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -json 2>&1 | synapse/.ci/scripts/gotestfmt
  395. shell: bash
  396. name: Run Complement Tests
  397. cargo-test:
  398. if: ${{ needs.changes.outputs.rust == 'true' }}
  399. runs-on: ubuntu-latest
  400. needs:
  401. - linting-done
  402. - changes
  403. steps:
  404. - uses: actions/checkout@v2
  405. - name: Install Rust
  406. uses: actions-rs/toolchain@v1
  407. with:
  408. toolchain: 1.61.0
  409. override: true
  410. - uses: Swatinem/rust-cache@v2
  411. - run: cargo test
  412. # a job which marks all the other jobs as complete, thus allowing PRs to be merged.
  413. tests-done:
  414. if: ${{ always() }}
  415. needs:
  416. - check-sampleconfig
  417. - lint
  418. - lint-crlf
  419. - lint-newsfile
  420. - trial
  421. - trial-olddeps
  422. - sytest
  423. - export-data
  424. - portdb
  425. - complement
  426. - cargo-test
  427. runs-on: ubuntu-latest
  428. steps:
  429. - uses: matrix-org/done-action@v2
  430. with:
  431. needs: ${{ toJSON(needs) }}
  432. # The newsfile lint may be skipped on non PR builds
  433. skippable:
  434. lint-newsfile