1
0

integration-test.yml 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. name: Integration Test
  2. on:
  3. push:
  4. branches:
  5. - main
  6. - dev
  7. pull_request:
  8. branches:
  9. - main
  10. - dev
  11. jobs:
  12. cypress-run:
  13. name: Run Cypress Integration Tests
  14. runs-on: ubuntu-latest
  15. steps:
  16. - name: Checkout Repository
  17. uses: actions/checkout@v4
  18. - name: Build and run Compose Stack
  19. run: |
  20. docker compose \
  21. --file docker-compose.yaml \
  22. --file docker-compose.api.yaml \
  23. --file docker-compose.a1111-test.yaml \
  24. up --detach --build
  25. - name: Wait for Ollama to be up
  26. timeout-minutes: 5
  27. run: |
  28. until curl --output /dev/null --silent --fail http://localhost:11434; do
  29. printf '.'
  30. sleep 1
  31. done
  32. echo "Service is up!"
  33. - name: Delete Docker build cache
  34. run: |
  35. docker builder prune --all --force
  36. - name: Preload Ollama model
  37. run: |
  38. docker exec ollama ollama pull qwen:0.5b-chat-v1.5-q2_K
  39. - name: Cypress run
  40. uses: cypress-io/github-action@v6
  41. with:
  42. browser: chrome
  43. wait-on: 'http://localhost:3000'
  44. config: baseUrl=http://localhost:3000
  45. - uses: actions/upload-artifact@v4
  46. if: always()
  47. name: Upload Cypress videos
  48. with:
  49. name: cypress-videos
  50. path: cypress/videos
  51. if-no-files-found: ignore
  52. - name: Extract Compose logs
  53. if: always()
  54. run: |
  55. docker compose logs > compose-logs.txt
  56. - uses: actions/upload-artifact@v4
  57. if: always()
  58. name: Upload Compose logs
  59. with:
  60. name: compose-logs
  61. path: compose-logs.txt
  62. if-no-files-found: ignore
  63. # pytest:
  64. # name: Run Backend Tests
  65. # runs-on: ubuntu-latest
  66. # steps:
  67. # - uses: actions/checkout@v4
  68. # - name: Set up Python
  69. # uses: actions/setup-python@v4
  70. # with:
  71. # python-version: ${{ matrix.python-version }}
  72. # - name: Install dependencies
  73. # run: |
  74. # python -m pip install --upgrade pip
  75. # pip install -r backend/requirements.txt
  76. # - name: pytest run
  77. # run: |
  78. # ls -al
  79. # cd backend
  80. # PYTHONPATH=. pytest . -o log_cli=true -o log_cli_level=INFO
  81. migration_test:
  82. name: Run Migration Tests
  83. runs-on: ubuntu-latest
  84. services:
  85. postgres:
  86. image: postgres
  87. env:
  88. POSTGRES_PASSWORD: postgres
  89. options: >-
  90. --health-cmd pg_isready
  91. --health-interval 10s
  92. --health-timeout 5s
  93. --health-retries 5
  94. ports:
  95. - 5432:5432
  96. # mysql:
  97. # image: mysql
  98. # env:
  99. # MYSQL_ROOT_PASSWORD: mysql
  100. # MYSQL_DATABASE: mysql
  101. # options: >-
  102. # --health-cmd "mysqladmin ping -h localhost"
  103. # --health-interval 10s
  104. # --health-timeout 5s
  105. # --health-retries 5
  106. # ports:
  107. # - 3306:3306
  108. steps:
  109. - name: Checkout Repository
  110. uses: actions/checkout@v4
  111. - name: Set up Python
  112. uses: actions/setup-python@v5
  113. with:
  114. python-version: ${{ matrix.python-version }}
  115. - name: Set up uv
  116. uses: yezz123/setup-uv@v4
  117. with:
  118. uv-venv: venv
  119. - name: Activate virtualenv
  120. run: |
  121. . venv/bin/activate
  122. echo PATH=$PATH >> $GITHUB_ENV
  123. - name: Install dependencies
  124. run: |
  125. uv pip install -r backend/requirements.txt
  126. - name: Test backend with SQLite
  127. id: sqlite
  128. env:
  129. WEBUI_SECRET_KEY: secret-key
  130. GLOBAL_LOG_LEVEL: debug
  131. run: |
  132. cd backend
  133. uvicorn main:app --port "8080" --forwarded-allow-ips '*' &
  134. UVICORN_PID=$!
  135. # Wait up to 40 seconds for the server to start
  136. for i in {1..40}; do
  137. curl -s http://localhost:8080/api/config > /dev/null && break
  138. sleep 1
  139. if [ $i -eq 40 ]; then
  140. echo "Server failed to start"
  141. kill -9 $UVICORN_PID
  142. exit 1
  143. fi
  144. done
  145. # Check that the server is still running after 5 seconds
  146. sleep 5
  147. if ! kill -0 $UVICORN_PID; then
  148. echo "Server has stopped"
  149. exit 1
  150. fi
  151. - name: Test backend with Postgres
  152. if: success() || steps.sqlite.conclusion == 'failure'
  153. env:
  154. WEBUI_SECRET_KEY: secret-key
  155. GLOBAL_LOG_LEVEL: debug
  156. DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres
  157. run: |
  158. cd backend
  159. uvicorn main:app --port "8081" --forwarded-allow-ips '*' &
  160. UVICORN_PID=$!
  161. # Wait up to 20 seconds for the server to start
  162. for i in {1..20}; do
  163. curl -s http://localhost:8081/api/config > /dev/null && break
  164. sleep 1
  165. if [ $i -eq 20 ]; then
  166. echo "Server failed to start"
  167. kill -9 $UVICORN_PID
  168. exit 1
  169. fi
  170. done
  171. # Check that the server is still running after 5 seconds
  172. sleep 5
  173. if ! kill -0 $UVICORN_PID; then
  174. echo "Server has stopped"
  175. exit 1
  176. fi
  177. # Check that service will reconnect to postgres when connection will be closed
  178. status_code=$(curl --write-out %{http_code} -s --output /dev/null http://localhost:8081/health/db)
  179. if [[ "$status_code" -ne 200 ]] ; then
  180. echo "Server has failed before postgres reconnect check"
  181. exit 1
  182. fi
  183. echo "Terminating all connections to postgres..."
  184. python -c "import os, psycopg2 as pg2; \
  185. conn = pg2.connect(dsn=os.environ['DATABASE_URL'].replace('+pool', '')); \
  186. cur = conn.cursor(); \
  187. cur.execute('SELECT pg_terminate_backend(psa.pid) FROM pg_stat_activity psa WHERE datname = current_database() AND pid <> pg_backend_pid();')"
  188. status_code=$(curl --write-out %{http_code} -s --output /dev/null http://localhost:8081/health/db)
  189. if [[ "$status_code" -ne 200 ]] ; then
  190. echo "Server has not reconnected to postgres after connection was closed: returned status $status_code"
  191. exit 1
  192. fi
  193. # - name: Test backend with MySQL
  194. # if: success() || steps.sqlite.conclusion == 'failure' || steps.postgres.conclusion == 'failure'
  195. # env:
  196. # WEBUI_SECRET_KEY: secret-key
  197. # GLOBAL_LOG_LEVEL: debug
  198. # DATABASE_URL: mysql://root:mysql@localhost:3306/mysql
  199. # run: |
  200. # cd backend
  201. # uvicorn main:app --port "8083" --forwarded-allow-ips '*' &
  202. # UVICORN_PID=$!
  203. # # Wait up to 20 seconds for the server to start
  204. # for i in {1..20}; do
  205. # curl -s http://localhost:8083/api/config > /dev/null && break
  206. # sleep 1
  207. # if [ $i -eq 20 ]; then
  208. # echo "Server failed to start"
  209. # kill -9 $UVICORN_PID
  210. # exit 1
  211. # fi
  212. # done
  213. # # Check that the server is still running after 5 seconds
  214. # sleep 5
  215. # if ! kill -0 $UVICORN_PID; then
  216. # echo "Server has stopped"
  217. # exit 1
  218. # fi