e2e.yml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. name: End-to-end tests
  2. on:
  3. push:
  4. branches: [main]
  5. paths-ignore:
  6. - '**.md'
  7. - '**.d.ts'
  8. - 'examples/**'
  9. - 'private/**'
  10. - 'website/**'
  11. - '.github/**'
  12. - '!.github/workflows/e2e.yml'
  13. pull_request_target:
  14. types: [opened, synchronize, reopened, labeled]
  15. paths-ignore:
  16. - '**.md'
  17. - '**.d.ts'
  18. - 'examples/**'
  19. - 'private/**'
  20. - 'website/**'
  21. - '.github/**'
  22. pull_request:
  23. types: [opened, synchronize, reopened]
  24. paths:
  25. - .github/workflows/e2e.yml
  26. concurrency:
  27. group:
  28. ${{ github.workflow }}--${{ github.event.pull_request.head.repo.full_name ||
  29. github.repository }} -- ${{ github.head_ref || github.ref }}
  30. cancel-in-progress:
  31. # For PRs coming from forks, we need the previous job to run until the end
  32. # to be sure it can remove the `safe to test` label before it affects the next run.
  33. ${{ github.event.pull_request.head.repo.full_name == github.repository }}
  34. permissions:
  35. pull-requests: write
  36. env:
  37. YARN_ENABLE_GLOBAL_CACHE: false
  38. jobs:
  39. compare_diff:
  40. runs-on: ubuntu-latest
  41. env:
  42. DIFF_BUILDER: true
  43. outputs:
  44. diff: ${{ steps.diff.outputs.OUTPUT_DIFF }}
  45. is_accurate_diff: ${{ steps.diff.outputs.IS_ACCURATE_DIFF }}
  46. steps:
  47. - name: Checkout sources
  48. uses: actions/checkout@v3
  49. with:
  50. fetch-depth: 2
  51. ref: refs/pull/${{ github.event.pull_request.number }}/merge
  52. - name: Check if there are "unsafe" changes
  53. id: build_chain_changes
  54. # If there are changes in JS script that generates the output, we cannot
  55. # test them here without human review to make sure they don't contain
  56. # someting "nasty".
  57. run: |
  58. EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
  59. echo "MIGHT_CONTAIN_OTHER_CHANGES<<$EOF" >> "$GITHUB_OUTPUT"
  60. git --no-pager diff HEAD^ --name-only bin package.json yarn.lock babel.config.js >> "$GITHUB_OUTPUT"
  61. echo "$EOF" >> "$GITHUB_OUTPUT"
  62. - run: git reset HEAD^ --hard
  63. - name: Get yarn cache directory path
  64. id: yarn-cache-dir-path
  65. run:
  66. echo "dir=$(corepack yarn config get cacheFolder)" >> $GITHUB_OUTPUT
  67. - uses: actions/cache@v3
  68. id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
  69. with:
  70. path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
  71. key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
  72. restore-keys: |
  73. ${{ runner.os }}-yarn-
  74. - name: Install Node.js
  75. uses: actions/setup-node@v3
  76. with:
  77. node-version: lts/*
  78. - name: Install dependencies
  79. run:
  80. corepack yarn workspaces focus $(corepack yarn workspaces list --json
  81. | jq -r .name | awk '/^@uppy-example/{ next } { if ($0!="uppy.io")
  82. print $0 }')
  83. env:
  84. # https://docs.cypress.io/guides/references/advanced-installation#Skipping-installation
  85. CYPRESS_INSTALL_BINARY: 0
  86. - run: corepack yarn build:lib
  87. - name: Store output file
  88. run: tar cf /tmp/previousVersion.tar packages/@uppy/*/lib
  89. - name: Fetch source from the PR
  90. if: steps.build_chain_changes.outputs.MIGHT_CONTAIN_OTHER_CHANGES == ''
  91. run: |
  92. git checkout FETCH_HEAD -- packages
  93. echo 'IS_ACCURATE_DIFF=true' >> "$GITHUB_ENV"
  94. - name: Fetch source from the PR
  95. if:
  96. steps.build_chain_changes.outputs.MIGHT_CONTAIN_OTHER_CHANGES != '' &&
  97. (!github.event.pull_request || (github.event.action == 'labeled' &&
  98. github.event.label.name == 'safe to test' &&
  99. github.event.pull_request.state == 'open') ||
  100. (github.event.pull_request.head.repo.full_name == github.repository &&
  101. github.event.event_name != 'labeled'))
  102. run: |
  103. git reset FETCH_HEAD --hard
  104. corepack yarn workspaces focus $(\
  105. corepack yarn workspaces list --json | \
  106. jq -r .name | \
  107. awk '/^@uppy-example/{ next } { if ($0!="uppy.io") print $0 }'\
  108. )
  109. echo 'IS_ACCURATE_DIFF=true' >> "$GITHUB_ENV"
  110. env:
  111. # https://docs.cypress.io/guides/references/advanced-installation#Skipping-installation
  112. CYPRESS_INSTALL_BINARY: 0
  113. - name: Fetch source from the PR
  114. if:
  115. steps.build_chain_changes.outputs.MIGHT_CONTAIN_OTHER_CHANGES != '' &&
  116. github.event.pull_request.head.repo.full_name != github.repository &&
  117. (github.event.action != 'labeled' || github.event.label.name != 'safe
  118. to test')
  119. run: |
  120. git checkout FETCH_HEAD -- packages
  121. - run: corepack yarn build:lib
  122. - name: Store output file
  123. run: tar cf /tmp/newVersion.tar packages/@uppy/*/lib
  124. - name: Setup git
  125. run: |
  126. git config --global user.email "actions@github.com"
  127. git config --global user.name "GitHub Actions"
  128. git init /tmp/uppy
  129. echo '*.map' > /tmp/uppy/.gitignore
  130. - name: Install dformat
  131. run: |
  132. curl -fsSL https://dprint.dev/install.sh | sh
  133. cd /tmp/uppy && echo '{"plugins":[]}' > dprint.json && "$HOME/.dprint/bin/dprint" config add typescript
  134. - name: Extract previous version
  135. run: cd /tmp/uppy && tar xf /tmp/previousVersion.tar
  136. - name: Format previous output code
  137. run: cd /tmp/uppy && "$HOME/.dprint/bin/dprint" fmt **/*.js
  138. - name: Commit previous version
  139. run: cd /tmp/uppy && git add -A . && git commit -m 'previous version'
  140. - name: Extract new version
  141. run: cd /tmp/uppy && tar xf /tmp/newVersion.tar
  142. - name: Format new output code
  143. run: cd /tmp/uppy && "$HOME/.dprint/bin/dprint" fmt **/*.js
  144. - name: Build diff
  145. id: diff
  146. run: |
  147. EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
  148. echo "OUTPUT_DIFF<<$EOF" >> "$GITHUB_OUTPUT"
  149. cd /tmp/uppy && git --no-pager diff >> "$GITHUB_OUTPUT"
  150. echo "$EOF" >> "$GITHUB_OUTPUT"
  151. echo "IS_ACCURATE_DIFF=$IS_ACCURATE_DIFF" >> "$GITHUB_OUTPUT"
  152. - name: Add/update comment
  153. uses: marocchino/sticky-pull-request-comment@v2
  154. with:
  155. message: |
  156. <details><summary>Diff output files</summary>
  157. ```diff
  158. ${{ steps.diff.outputs.OUTPUT_DIFF || 'No diff' }}
  159. ```
  160. ${{ env.IS_ACCURATE_DIFF != 'true' && format(fromJson('"The following build files have been modified and might affect the actual diff:\n\n```\n{0}\n```"'), steps.build_chain_changes.outputs.MIGHT_CONTAIN_OTHER_CHANGES) || '' }}
  161. </details>
  162. - name: Remove 'safe to test' label if cancelled
  163. if:
  164. cancelled() && github.event.pull_request.head.repo.full_name !=
  165. github.repository
  166. run: gh pr edit "$NUMBER" --remove-label 'safe to test'
  167. env:
  168. NUMBER: ${{ github.event.pull_request.number }}
  169. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  170. toggle-pending-e2e-label:
  171. # Add the 'pending end-to-end tests' label for PRs that come from forks.
  172. # For those PRs, we want to review the code before running e2e tests.
  173. # See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
  174. needs: [compare_diff]
  175. if:
  176. github.event.pull_request.state == 'open' &&
  177. github.event.pull_request.head.repo.full_name != github.repository &&
  178. github.event.action != 'labeled'
  179. runs-on: ubuntu-latest
  180. steps:
  181. - name: Add label
  182. if:
  183. (needs.compare_diff.outputs.diff != '' ||
  184. !needs.compare_diff.outputs.is_accurate_diff) &&
  185. (!contains(github.event.pull_request.labels.*.name, 'safe to test') &&
  186. !contains(github.event.pull_request.labels.*.name, 'pending end-to-end
  187. tests'))
  188. env:
  189. PR_URL: ${{ github.event.pull_request.html_url }}
  190. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  191. run:
  192. gh pr edit "$PR_URL" --repo ${{ github.repository }} --add-label
  193. 'pending end-to-end tests'
  194. - name: Remove label
  195. if:
  196. needs.compare_diff.outputs.diff == '' &&
  197. needs.compare_diff.outputs.is_accurate_diff &&
  198. (contains(github.event.pull_request.labels.*.name, 'safe to test') ||
  199. contains(github.event.pull_request.labels.*.name, 'pending end-to-end
  200. tests'))
  201. env:
  202. PR_URL: ${{ github.event.pull_request.html_url }}
  203. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  204. run:
  205. gh pr edit "$PR_URL" --remove-label 'safe to test' --remove-label
  206. 'pending end-to-end tests'
  207. e2e:
  208. needs: [compare_diff]
  209. if:
  210. ${{ needs.compare_diff.outputs.diff != '' && (!github.event.pull_request
  211. || (github.event.action == 'labeled' && github.event.label.name == 'safe
  212. to test' && github.event.pull_request.state == 'open') ||
  213. (github.event.pull_request.head.repo.full_name == github.repository &&
  214. github.event.event_name != 'labeled')) }}
  215. name: Browser tests
  216. runs-on: ubuntu-latest
  217. steps:
  218. - name: Checkout sources
  219. uses: actions/checkout@v3
  220. with:
  221. ref: ${{ github.event.pull_request.head.sha || github.sha }}
  222. - name: Get yarn cache directory path
  223. id: yarn-cache-dir-path
  224. run:
  225. echo "dir=$(corepack yarn config get cacheFolder)" >> $GITHUB_OUTPUT
  226. - uses: actions/cache@v3
  227. id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
  228. with:
  229. path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
  230. key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
  231. restore-keys: |
  232. ${{ runner.os }}-yarn-
  233. - name: Create cache folder for Cypress
  234. id: cypress-cache-dir-path
  235. run: echo "dir=$(mktemp -d)" >> $GITHUB_OUTPUT
  236. - uses: actions/cache@v3
  237. with:
  238. path: ${{ steps.cypress-cache-dir-path.outputs.dir }}
  239. key: ${{ runner.os }}-cypress
  240. - name: Install Node.js
  241. uses: actions/setup-node@v3
  242. with:
  243. node-version: lts/*
  244. - name: Start Redis
  245. uses: supercharge/redis-github-action@1.4.0
  246. with:
  247. redis-version: 7
  248. - name: Install dependencies
  249. run: corepack yarn install --immutable
  250. env:
  251. # https://docs.cypress.io/guides/references/advanced-installation#Binary-cache
  252. CYPRESS_CACHE_FOLDER: ${{ steps.cypress-cache-dir-path.outputs.dir }}
  253. - name: Build Uppy packages
  254. run: corepack yarn build
  255. - name: Run end-to-end browser tests
  256. run: corepack yarn run e2e:ci
  257. env:
  258. COMPANION_DATADIR: ./output
  259. COMPANION_DOMAIN: localhost:3020
  260. COMPANION_PROTOCOL: http
  261. COMPANION_REDIS_URL: redis://localhost:6379
  262. COMPANION_UNSPLASH_KEY: ${{secrets.COMPANION_UNSPLASH_KEY}}
  263. COMPANION_UNSPLASH_SECRET: ${{secrets.COMPANION_UNSPLASH_SECRET}}
  264. COMPANION_AWS_KEY: ${{secrets.COMPANION_AWS_KEY}}
  265. COMPANION_AWS_SECRET: ${{secrets.COMPANION_AWS_SECRET}}
  266. COMPANION_AWS_BUCKET: ${{secrets.COMPANION_AWS_BUCKET}}
  267. COMPANION_AWS_REGION: ${{secrets.COMPANION_AWS_REGION}}
  268. VITE_COMPANION_URL: http://localhost:3020
  269. VITE_TRANSLOADIT_KEY: ${{secrets.TRANSLOADIT_KEY}}
  270. VITE_TRANSLOADIT_SECRET: ${{secrets.TRANSLOADIT_SECRET}}
  271. VITE_TRANSLOADIT_TEMPLATE: ${{secrets.TRANSLOADIT_TEMPLATE}}
  272. VITE_TRANSLOADIT_SERVICE_URL: ${{secrets.TRANSLOADIT_SERVICE_URL}}
  273. # https://docs.cypress.io/guides/references/advanced-installation#Binary-cache
  274. CYPRESS_CACHE_FOLDER: ${{ steps.cypress-cache-dir-path.outputs.dir }}
  275. - name: Upload videos in case of failure
  276. uses: actions/upload-artifact@v3
  277. if: failure()
  278. with:
  279. name: videos-and-screenshots
  280. path: |
  281. e2e/cypress/videos/
  282. e2e/cypress/screenshots/
  283. - name: Remove labels
  284. # Remove the 'pending end-to-end tests' label if tests ran successfully
  285. if:
  286. github.event.pull_request &&
  287. contains(github.event.pull_request.labels.*.name, 'pending end-to-end
  288. tests')
  289. run: gh pr edit "$NUMBER" --remove-label 'pending end-to-end tests'
  290. env:
  291. NUMBER: ${{ github.event.pull_request.number }}
  292. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  293. - name: Remove 'safe to test' label
  294. if:
  295. always() && github.event.pull_request &&
  296. contains(github.event.pull_request.labels.*.name, 'safe to test')
  297. run: gh pr edit "$NUMBER" --remove-label 'safe to test'
  298. env:
  299. NUMBER: ${{ github.event.pull_request.number }}
  300. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}