You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

591 lines
20 KiB

  1. name: Tests
  2. on:
  3. push:
  4. branches: ["develop", "release-*"]
  5. pull_request:
  6. workflow_dispatch:
  7. concurrency:
  8. group: ${{ github.workflow }}-${{ github.ref }}
  9. cancel-in-progress: true
  10. jobs:
  11. # Job to detect what has changed so we don't run e.g. Rust checks on PRs that
  12. # don't modify Rust code.
  13. changes:
  14. runs-on: ubuntu-latest
  15. outputs:
  16. rust: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.rust }}
  17. steps:
  18. - uses: dorny/paths-filter@v2
  19. id: filter
  20. # We only check on PRs
  21. if: startsWith(github.ref, 'refs/pull/')
  22. with:
  23. filters: |
  24. rust:
  25. - 'rust/**'
  26. - 'Cargo.toml'
  27. - 'Cargo.lock'
  28. check-sampleconfig:
  29. runs-on: ubuntu-latest
  30. steps:
  31. - uses: actions/checkout@v3
  32. - uses: matrix-org/setup-python-poetry@v1
  33. with:
  34. python-version: "3.x"
  35. poetry-version: "1.3.2"
  36. extras: "all"
  37. - run: poetry run scripts-dev/generate_sample_config.sh --check
  38. - run: poetry run scripts-dev/config-lint.sh
  39. check-schema-delta:
  40. runs-on: ubuntu-latest
  41. steps:
  42. - uses: actions/checkout@v3
  43. - uses: actions/setup-python@v4
  44. with:
  45. python-version: "3.x"
  46. - run: "pip install 'click==8.1.1' 'GitPython>=3.1.20'"
  47. - run: scripts-dev/check_schema_delta.py --force-colors
  48. check-lockfile:
  49. runs-on: ubuntu-latest
  50. steps:
  51. - uses: actions/checkout@v3
  52. - uses: actions/setup-python@v4
  53. with:
  54. python-version: "3.x"
  55. - run: .ci/scripts/check_lockfile.py
  56. lint:
  57. uses: "matrix-org/backend-meta/.github/workflows/python-poetry-ci.yml@v2"
  58. with:
  59. typechecking-extras: "all"
  60. lint-crlf:
  61. runs-on: ubuntu-latest
  62. steps:
  63. - uses: actions/checkout@v3
  64. - name: Check line endings
  65. run: scripts-dev/check_line_terminators.sh
  66. lint-newsfile:
  67. if: ${{ (github.base_ref == 'develop' || contains(github.base_ref, 'release-')) && github.actor != 'dependabot[bot]' }}
  68. runs-on: ubuntu-latest
  69. steps:
  70. - uses: actions/checkout@v3
  71. with:
  72. ref: ${{ github.event.pull_request.head.sha }}
  73. fetch-depth: 0
  74. - uses: actions/setup-python@v4
  75. with:
  76. python-version: "3.x"
  77. - run: "pip install 'towncrier>=18.6.0rc1'"
  78. - run: scripts-dev/check-newsfragment.sh
  79. env:
  80. PULL_REQUEST_NUMBER: ${{ github.event.number }}
  81. lint-pydantic:
  82. runs-on: ubuntu-latest
  83. steps:
  84. - uses: actions/checkout@v3
  85. with:
  86. ref: ${{ github.event.pull_request.head.sha }}
  87. - uses: matrix-org/setup-python-poetry@v1
  88. with:
  89. poetry-version: "1.3.2"
  90. extras: "all"
  91. - run: poetry run scripts-dev/check_pydantic_models.py
  92. lint-clippy:
  93. runs-on: ubuntu-latest
  94. needs: changes
  95. if: ${{ needs.changes.outputs.rust == 'true' }}
  96. steps:
  97. - uses: actions/checkout@v3
  98. - name: Install Rust
  99. # There don't seem to be versioned releases of this action per se: for each rust
  100. # version there is a branch which gets constantly rebased on top of master.
  101. # We pin to a specific commit for paranoia's sake.
  102. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  103. with:
  104. toolchain: 1.58.1
  105. components: clippy
  106. - uses: Swatinem/rust-cache@v2
  107. - run: cargo clippy -- -D warnings
  108. # We also lint against a nightly rustc so that we can lint the benchmark
  109. # suite, which requires a nightly compiler.
  110. lint-clippy-nightly:
  111. runs-on: ubuntu-latest
  112. needs: changes
  113. if: ${{ needs.changes.outputs.rust == 'true' }}
  114. steps:
  115. - uses: actions/checkout@v3
  116. - name: Install Rust
  117. # There don't seem to be versioned releases of this action per se: for each rust
  118. # version there is a branch which gets constantly rebased on top of master.
  119. # We pin to a specific commit for paranoia's sake.
  120. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  121. with:
  122. toolchain: nightly-2022-12-01
  123. components: clippy
  124. - uses: Swatinem/rust-cache@v2
  125. - run: cargo clippy --all-features -- -D warnings
  126. lint-rustfmt:
  127. runs-on: ubuntu-latest
  128. needs: changes
  129. if: ${{ needs.changes.outputs.rust == 'true' }}
  130. steps:
  131. - uses: actions/checkout@v3
  132. - name: Install Rust
  133. # There don't seem to be versioned releases of this action per se: for each rust
  134. # version there is a branch which gets constantly rebased on top of master.
  135. # We pin to a specific commit for paranoia's sake.
  136. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  137. with:
  138. toolchain: 1.58.1
  139. components: rustfmt
  140. - uses: Swatinem/rust-cache@v2
  141. - run: cargo fmt --check
  142. # Dummy step to gate other tests on without repeating the whole list
  143. linting-done:
  144. if: ${{ !cancelled() }} # Run this even if prior jobs were skipped
  145. needs:
  146. - lint
  147. - lint-crlf
  148. - lint-newsfile
  149. - lint-pydantic
  150. - check-sampleconfig
  151. - check-schema-delta
  152. - check-lockfile
  153. - lint-clippy
  154. - lint-rustfmt
  155. runs-on: ubuntu-latest
  156. steps:
  157. - run: "true"
  158. calculate-test-jobs:
  159. if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
  160. needs: linting-done
  161. runs-on: ubuntu-latest
  162. steps:
  163. - uses: actions/checkout@v3
  164. - uses: actions/setup-python@v4
  165. with:
  166. python-version: "3.x"
  167. - id: get-matrix
  168. run: .ci/scripts/calculate_jobs.py
  169. outputs:
  170. trial_test_matrix: ${{ steps.get-matrix.outputs.trial_test_matrix }}
  171. sytest_test_matrix: ${{ steps.get-matrix.outputs.sytest_test_matrix }}
  172. trial:
  173. if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
  174. needs: calculate-test-jobs
  175. runs-on: ubuntu-latest
  176. strategy:
  177. matrix:
  178. job: ${{ fromJson(needs.calculate-test-jobs.outputs.trial_test_matrix) }}
  179. steps:
  180. - uses: actions/checkout@v3
  181. - run: sudo apt-get -qq install xmlsec1
  182. - name: Set up PostgreSQL ${{ matrix.job.postgres-version }}
  183. if: ${{ matrix.job.postgres-version }}
  184. # 1. Mount postgres data files onto a tmpfs in-memory filesystem to reduce overhead of docker's overlayfs layer.
  185. # 2. Expose the unix socket for postgres. This removes latency of using docker-proxy for connections.
  186. run: |
  187. docker run -d -p 5432:5432 \
  188. --tmpfs /var/lib/postgres:rw,size=6144m \
  189. --mount 'type=bind,src=/var/run/postgresql,dst=/var/run/postgresql' \
  190. -e POSTGRES_PASSWORD=postgres \
  191. -e POSTGRES_INITDB_ARGS="--lc-collate C --lc-ctype C --encoding UTF8" \
  192. postgres:${{ matrix.job.postgres-version }}
  193. - name: Install Rust
  194. # There don't seem to be versioned releases of this action per se: for each rust
  195. # version there is a branch which gets constantly rebased on top of master.
  196. # We pin to a specific commit for paranoia's sake.
  197. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  198. with:
  199. toolchain: 1.58.1
  200. - uses: Swatinem/rust-cache@v2
  201. - uses: matrix-org/setup-python-poetry@v1
  202. with:
  203. python-version: ${{ matrix.job.python-version }}
  204. poetry-version: "1.3.2"
  205. extras: ${{ matrix.job.extras }}
  206. - name: Await PostgreSQL
  207. if: ${{ matrix.job.postgres-version }}
  208. timeout-minutes: 2
  209. run: until pg_isready -h localhost; do sleep 1; done
  210. - run: poetry run trial --jobs=6 tests
  211. env:
  212. SYNAPSE_POSTGRES: ${{ matrix.job.database == 'postgres' || '' }}
  213. SYNAPSE_POSTGRES_HOST: /var/run/postgresql
  214. SYNAPSE_POSTGRES_USER: postgres
  215. SYNAPSE_POSTGRES_PASSWORD: postgres
  216. - name: Dump logs
  217. # Logs are most useful when the command fails, always include them.
  218. if: ${{ always() }}
  219. # Note: Dumps to workflow logs instead of using actions/upload-artifact
  220. # This keeps logs colocated with failing jobs
  221. # It also ignores find's exit code; this is a best effort affair
  222. run: >-
  223. find _trial_temp -name '*.log'
  224. -exec echo "::group::{}" \;
  225. -exec cat {} \;
  226. -exec echo "::endgroup::" \;
  227. || true
  228. trial-olddeps:
  229. # Note: sqlite only; no postgres
  230. if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
  231. needs: linting-done
  232. runs-on: ubuntu-20.04
  233. steps:
  234. - uses: actions/checkout@v3
  235. - name: Install Rust
  236. # There don't seem to be versioned releases of this action per se: for each rust
  237. # version there is a branch which gets constantly rebased on top of master.
  238. # We pin to a specific commit for paranoia's sake.
  239. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  240. with:
  241. toolchain: 1.58.1
  242. - uses: Swatinem/rust-cache@v2
  243. # There aren't wheels for some of the older deps, so we need to install
  244. # their build dependencies
  245. - run: |
  246. sudo apt-get -qq install build-essential libffi-dev python-dev \
  247. libxml2-dev libxslt-dev xmlsec1 zlib1g-dev libjpeg-dev libwebp-dev
  248. - uses: actions/setup-python@v4
  249. with:
  250. python-version: '3.7'
  251. # Calculating the old-deps actually takes a bunch of time, so we cache the
  252. # pyproject.toml / poetry.lock. We need to cache pyproject.toml as
  253. # otherwise the `poetry install` step will error due to the poetry.lock
  254. # file being outdated.
  255. #
  256. # This caches the output of `Prepare old deps`, which should generate the
  257. # same `pyproject.toml` and `poetry.lock` for a given `pyproject.toml` input.
  258. - uses: actions/cache@v3
  259. id: cache-poetry-old-deps
  260. name: Cache poetry.lock
  261. with:
  262. path: |
  263. poetry.lock
  264. pyproject.toml
  265. key: poetry-old-deps2-${{ hashFiles('pyproject.toml') }}
  266. - name: Prepare old deps
  267. if: steps.cache-poetry-old-deps.outputs.cache-hit != 'true'
  268. run: .ci/scripts/prepare_old_deps.sh
  269. # We only now install poetry so that `setup-python-poetry` caches the
  270. # right poetry.lock's dependencies.
  271. - uses: matrix-org/setup-python-poetry@v1
  272. with:
  273. python-version: '3.7'
  274. poetry-version: "1.3.2"
  275. extras: "all test"
  276. - run: poetry run trial -j6 tests
  277. - name: Dump logs
  278. # Logs are most useful when the command fails, always include them.
  279. if: ${{ always() }}
  280. # Note: Dumps to workflow logs instead of using actions/upload-artifact
  281. # This keeps logs colocated with failing jobs
  282. # It also ignores find's exit code; this is a best effort affair
  283. run: >-
  284. find _trial_temp -name '*.log'
  285. -exec echo "::group::{}" \;
  286. -exec cat {} \;
  287. -exec echo "::endgroup::" \;
  288. || true
  289. trial-pypy:
  290. # Very slow; only run if the branch name includes 'pypy'
  291. # Note: sqlite only; no postgres. Completely untested since poetry move.
  292. if: ${{ contains(github.ref, 'pypy') && !failure() && !cancelled() }}
  293. needs: linting-done
  294. runs-on: ubuntu-latest
  295. strategy:
  296. matrix:
  297. python-version: ["pypy-3.7"]
  298. extras: ["all"]
  299. steps:
  300. - uses: actions/checkout@v3
  301. # Install libs necessary for PyPy to build binary wheels for dependencies
  302. - run: sudo apt-get -qq install xmlsec1 libxml2-dev libxslt-dev
  303. - uses: matrix-org/setup-python-poetry@v1
  304. with:
  305. python-version: ${{ matrix.python-version }}
  306. poetry-version: "1.3.2"
  307. extras: ${{ matrix.extras }}
  308. - run: poetry run trial --jobs=2 tests
  309. - name: Dump logs
  310. # Logs are most useful when the command fails, always include them.
  311. if: ${{ always() }}
  312. # Note: Dumps to workflow logs instead of using actions/upload-artifact
  313. # This keeps logs colocated with failing jobs
  314. # It also ignores find's exit code; this is a best effort affair
  315. run: >-
  316. find _trial_temp -name '*.log'
  317. -exec echo "::group::{}" \;
  318. -exec cat {} \;
  319. -exec echo "::endgroup::" \;
  320. || true
  321. sytest:
  322. if: ${{ !failure() && !cancelled() }}
  323. needs: calculate-test-jobs
  324. runs-on: ubuntu-latest
  325. container:
  326. image: matrixdotorg/sytest-synapse:${{ matrix.job.sytest-tag }}
  327. volumes:
  328. - ${{ github.workspace }}:/src
  329. env:
  330. SYTEST_BRANCH: ${{ github.head_ref }}
  331. POSTGRES: ${{ matrix.job.postgres && 1}}
  332. MULTI_POSTGRES: ${{ (matrix.job.postgres == 'multi-postgres') && 1}}
  333. WORKERS: ${{ matrix.job.workers && 1 }}
  334. BLACKLIST: ${{ matrix.job.workers && 'synapse-blacklist-with-workers' }}
  335. TOP: ${{ github.workspace }}
  336. strategy:
  337. fail-fast: false
  338. matrix:
  339. job: ${{ fromJson(needs.calculate-test-jobs.outputs.sytest_test_matrix) }}
  340. steps:
  341. - uses: actions/checkout@v3
  342. - name: Prepare test blacklist
  343. run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers
  344. - name: Install Rust
  345. # There don't seem to be versioned releases of this action per se: for each rust
  346. # version there is a branch which gets constantly rebased on top of master.
  347. # We pin to a specific commit for paranoia's sake.
  348. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  349. with:
  350. toolchain: 1.58.1
  351. - uses: Swatinem/rust-cache@v2
  352. - name: Run SyTest
  353. run: /bootstrap.sh synapse
  354. working-directory: /src
  355. - name: Summarise results.tap
  356. if: ${{ always() }}
  357. run: /sytest/scripts/tap_to_gha.pl /logs/results.tap
  358. - name: Upload SyTest logs
  359. uses: actions/upload-artifact@v3
  360. if: ${{ always() }}
  361. with:
  362. name: Sytest Logs - ${{ job.status }} - (${{ join(matrix.job.*, ', ') }})
  363. path: |
  364. /logs/results.tap
  365. /logs/**/*.log*
  366. export-data:
  367. if: ${{ !failure() && !cancelled() }} # Allow previous steps to be skipped, but not fail
  368. needs: [linting-done, portdb]
  369. runs-on: ubuntu-latest
  370. env:
  371. TOP: ${{ github.workspace }}
  372. services:
  373. postgres:
  374. image: postgres
  375. ports:
  376. - 5432:5432
  377. env:
  378. POSTGRES_PASSWORD: "postgres"
  379. POSTGRES_INITDB_ARGS: "--lc-collate C --lc-ctype C --encoding UTF8"
  380. options: >-
  381. --health-cmd pg_isready
  382. --health-interval 10s
  383. --health-timeout 5s
  384. --health-retries 5
  385. steps:
  386. - uses: actions/checkout@v3
  387. - run: sudo apt-get -qq install xmlsec1 postgresql-client
  388. - uses: matrix-org/setup-python-poetry@v1
  389. with:
  390. poetry-version: "1.3.2"
  391. extras: "postgres"
  392. - run: .ci/scripts/test_export_data_command.sh
  393. env:
  394. PGHOST: localhost
  395. PGUSER: postgres
  396. PGPASSWORD: postgres
  397. PGDATABASE: postgres
  398. portdb:
  399. if: ${{ !failure() && !cancelled() }} # Allow previous steps to be skipped, but not fail
  400. needs: linting-done
  401. runs-on: ubuntu-latest
  402. strategy:
  403. matrix:
  404. include:
  405. - python-version: "3.7"
  406. postgres-version: "11"
  407. - python-version: "3.11"
  408. postgres-version: "15"
  409. services:
  410. postgres:
  411. image: postgres:${{ matrix.postgres-version }}
  412. ports:
  413. - 5432:5432
  414. env:
  415. POSTGRES_PASSWORD: "postgres"
  416. POSTGRES_INITDB_ARGS: "--lc-collate C --lc-ctype C --encoding UTF8"
  417. options: >-
  418. --health-cmd pg_isready
  419. --health-interval 10s
  420. --health-timeout 5s
  421. --health-retries 5
  422. steps:
  423. - uses: actions/checkout@v3
  424. - name: Add PostgreSQL apt repository
  425. # We need a version of pg_dump that can handle the version of
  426. # PostgreSQL being tested against. The Ubuntu package repository lags
  427. # behind new releases, so we have to use the PostreSQL apt repository.
  428. # Steps taken from https://www.postgresql.org/download/linux/ubuntu/
  429. run: |
  430. sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
  431. wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
  432. sudo apt-get update
  433. - run: sudo apt-get -qq install xmlsec1 postgresql-client
  434. - uses: matrix-org/setup-python-poetry@v1
  435. with:
  436. python-version: ${{ matrix.python-version }}
  437. poetry-version: "1.3.2"
  438. extras: "postgres"
  439. - run: .ci/scripts/test_synapse_port_db.sh
  440. id: run_tester_script
  441. env:
  442. PGHOST: localhost
  443. PGUSER: postgres
  444. PGPASSWORD: postgres
  445. PGDATABASE: postgres
  446. - name: "Upload schema differences"
  447. uses: actions/upload-artifact@v3
  448. if: ${{ failure() && !cancelled() && steps.run_tester_script.outcome == 'failure' }}
  449. with:
  450. name: Schema dumps
  451. path: |
  452. unported.sql
  453. ported.sql
  454. schema_diff
  455. complement:
  456. if: "${{ !failure() && !cancelled() }}"
  457. needs: linting-done
  458. runs-on: ubuntu-latest
  459. strategy:
  460. fail-fast: false
  461. matrix:
  462. include:
  463. - arrangement: monolith
  464. database: SQLite
  465. - arrangement: monolith
  466. database: Postgres
  467. - arrangement: workers
  468. database: Postgres
  469. steps:
  470. - name: Run actions/checkout@v3 for synapse
  471. uses: actions/checkout@v3
  472. with:
  473. path: synapse
  474. - name: Install Rust
  475. # There don't seem to be versioned releases of this action per se: for each rust
  476. # version there is a branch which gets constantly rebased on top of master.
  477. # We pin to a specific commit for paranoia's sake.
  478. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  479. with:
  480. toolchain: 1.58.1
  481. - uses: Swatinem/rust-cache@v2
  482. - name: Prepare Complement's Prerequisites
  483. run: synapse/.ci/scripts/setup_complement_prerequisites.sh
  484. - run: |
  485. set -o pipefail
  486. 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
  487. shell: bash
  488. name: Run Complement Tests
  489. cargo-test:
  490. if: ${{ needs.changes.outputs.rust == 'true' }}
  491. runs-on: ubuntu-latest
  492. needs:
  493. - linting-done
  494. - changes
  495. steps:
  496. - uses: actions/checkout@v3
  497. - name: Install Rust
  498. # There don't seem to be versioned releases of this action per se: for each rust
  499. # version there is a branch which gets constantly rebased on top of master.
  500. # We pin to a specific commit for paranoia's sake.
  501. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  502. with:
  503. toolchain: 1.58.1
  504. - uses: Swatinem/rust-cache@v2
  505. - run: cargo test
  506. # a job which marks all the other jobs as complete, thus allowing PRs to be merged.
  507. tests-done:
  508. if: ${{ always() }}
  509. needs:
  510. - trial
  511. - trial-olddeps
  512. - sytest
  513. - export-data
  514. - portdb
  515. - complement
  516. - cargo-test
  517. runs-on: ubuntu-latest
  518. steps:
  519. - uses: matrix-org/done-action@v2
  520. with:
  521. needs: ${{ toJSON(needs) }}
  522. # The newsfile lint may be skipped on non PR builds
  523. # Cargo test is skipped if there is no changes on Rust code
  524. skippable: |
  525. lint-newsfile
  526. cargo-test