e2e.yml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  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 ||
  98. (contains(github.event.pull_request.labels.*.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. !contains(github.event.pull_request.labels.*.name, 'safe to test')
  118. run: |
  119. git checkout FETCH_HEAD -- packages
  120. - run: corepack yarn build:lib
  121. - name: Store output file
  122. run: tar cf /tmp/newVersion.tar packages/@uppy/*/lib
  123. - name: Setup git
  124. run: |
  125. git config --global user.email "actions@github.com"
  126. git config --global user.name "GitHub Actions"
  127. git init /tmp/uppy
  128. echo '*.map' > /tmp/uppy/.gitignore
  129. - name: Install dformat
  130. run: |
  131. curl -fsSL https://dprint.dev/install.sh | sh
  132. cd /tmp/uppy && echo '{"plugins":[]}' > dprint.json && "$HOME/.dprint/bin/dprint" config add typescript
  133. - name: Extract previous version
  134. run: cd /tmp/uppy && tar xf /tmp/previousVersion.tar
  135. - name: Format previous output code
  136. run: cd /tmp/uppy && "$HOME/.dprint/bin/dprint" fmt **/*.js
  137. - name: Commit previous version
  138. run: cd /tmp/uppy && git add -A . && git commit -m 'previous version'
  139. - name: Extract new version
  140. run: cd /tmp/uppy && tar xf /tmp/newVersion.tar
  141. - name: Format new output code
  142. run: cd /tmp/uppy && "$HOME/.dprint/bin/dprint" fmt **/*.js
  143. - name: Build diff
  144. id: diff
  145. run: |
  146. EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
  147. echo "OUTPUT_DIFF<<$EOF" >> "$GITHUB_OUTPUT"
  148. cd /tmp/uppy && git --no-pager diff >> "$GITHUB_OUTPUT"
  149. echo "$EOF" >> "$GITHUB_OUTPUT"
  150. echo "IS_ACCURATE_DIFF=$IS_ACCURATE_DIFF" >> "$GITHUB_OUTPUT"
  151. - name: Add/update comment
  152. uses: marocchino/sticky-pull-request-comment@v2
  153. with:
  154. message: |
  155. <details><summary>Diff output files</summary>
  156. ```diff
  157. ${{ steps.diff.outputs.OUTPUT_DIFF || 'No diff' }}
  158. ```
  159. ${{ 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) || '' }}
  160. </details>
  161. - name: Remove 'safe to test' label if cancelled
  162. if:
  163. cancelled() && github.event.pull_request.head.repo.full_name !=
  164. github.repository
  165. run: gh pr edit "$NUMBER" --remove-label 'safe to test'
  166. env:
  167. NUMBER: ${{ github.event.pull_request.number }}
  168. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  169. toggle-pending-e2e-label:
  170. # Add the 'pending end-to-end tests' label for PRs that come from forks.
  171. # For those PRs, we want to review the code before running e2e tests.
  172. # See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
  173. needs: [compare_diff]
  174. if:
  175. github.event.pull_request.state == 'open' &&
  176. github.event.pull_request.head.repo.full_name != github.repository
  177. runs-on: ubuntu-latest
  178. steps:
  179. - name: Add label
  180. if:
  181. (needs.compare_diff.outputs.diff != '' ||
  182. !needs.compare_diff.outputs.is_accurate_diff) &&
  183. (!contains(github.event.pull_request.labels.*.name, 'safe to test') &&
  184. !contains(github.event.pull_request.labels.*.name, 'pending end-to-end
  185. tests'))
  186. env:
  187. PR_URL: ${{ github.event.pull_request.html_url }}
  188. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  189. run:
  190. gh pr edit "$PR_URL" --repo ${{ github.repository }} --add-label
  191. 'pending end-to-end tests'
  192. - name: Remove label
  193. if:
  194. needs.compare_diff.outputs.diff == '' &&
  195. needs.compare_diff.outputs.is_accurate_diff &&
  196. (contains(github.event.pull_request.labels.*.name, 'safe to test') ||
  197. contains(github.event.pull_request.labels.*.name, 'pending end-to-end
  198. tests'))
  199. env:
  200. PR_URL: ${{ github.event.pull_request.html_url }}
  201. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  202. run:
  203. gh pr edit "$PR_URL" --remove-label 'safe to test' --remove-label
  204. 'pending end-to-end tests'
  205. e2e:
  206. needs: [compare_diff]
  207. if:
  208. ${{ needs.compare_diff.outputs.diff != '' && (!github.event.pull_request
  209. || (contains(github.event.pull_request.labels.*.name, 'safe to test') &&
  210. github.event.pull_request.state == 'open') ||
  211. (github.event.pull_request.head.repo.full_name == github.repository &&
  212. github.event.event_name != 'labeled')) }}
  213. name: Browser tests
  214. runs-on: ubuntu-latest
  215. steps:
  216. - name: Checkout sources
  217. uses: actions/checkout@v3
  218. with:
  219. ref: ${{ github.event.pull_request.head.sha || github.sha }}
  220. - name: Get yarn cache directory path
  221. id: yarn-cache-dir-path
  222. run:
  223. echo "dir=$(corepack yarn config get cacheFolder)" >> $GITHUB_OUTPUT
  224. - uses: actions/cache@v3
  225. id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
  226. with:
  227. path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
  228. key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
  229. restore-keys: |
  230. ${{ runner.os }}-yarn-
  231. - name: Create cache folder for Cypress
  232. id: cypress-cache-dir-path
  233. run: echo "dir=$(mktemp -d)" >> $GITHUB_OUTPUT
  234. - uses: actions/cache@v3
  235. with:
  236. path: ${{ steps.cypress-cache-dir-path.outputs.dir }}
  237. key: ${{ runner.os }}-cypress
  238. - name: Install Node.js
  239. uses: actions/setup-node@v3
  240. with:
  241. node-version: lts/*
  242. - name: Start Redis
  243. uses: supercharge/redis-github-action@1.4.0
  244. with:
  245. redis-version: 7
  246. - name: Install dependencies
  247. run: corepack yarn install --immutable
  248. env:
  249. # https://docs.cypress.io/guides/references/advanced-installation#Binary-cache
  250. CYPRESS_CACHE_FOLDER: ${{ steps.cypress-cache-dir-path.outputs.dir }}
  251. - name: Build Uppy packages
  252. run: corepack yarn build
  253. - name: Run end-to-end browser tests
  254. run: corepack yarn run e2e:ci
  255. env:
  256. COMPANION_DATADIR: ./output
  257. COMPANION_DOMAIN: localhost:3020
  258. COMPANION_PROTOCOL: http
  259. COMPANION_REDIS_URL: redis://localhost:6379
  260. COMPANION_UNSPLASH_KEY: ${{secrets.COMPANION_UNSPLASH_KEY}}
  261. COMPANION_UNSPLASH_SECRET: ${{secrets.COMPANION_UNSPLASH_SECRET}}
  262. COMPANION_AWS_KEY: ${{secrets.COMPANION_AWS_KEY}}
  263. COMPANION_AWS_SECRET: ${{secrets.COMPANION_AWS_SECRET}}
  264. COMPANION_AWS_BUCKET: ${{secrets.COMPANION_AWS_BUCKET}}
  265. COMPANION_AWS_REGION: ${{secrets.COMPANION_AWS_REGION}}
  266. VITE_COMPANION_URL: http://localhost:3020
  267. VITE_TRANSLOADIT_KEY: ${{secrets.TRANSLOADIT_KEY}}
  268. VITE_TRANSLOADIT_SECRET: ${{secrets.TRANSLOADIT_SECRET}}
  269. VITE_TRANSLOADIT_TEMPLATE: ${{secrets.TRANSLOADIT_TEMPLATE}}
  270. VITE_TRANSLOADIT_SERVICE_URL: ${{secrets.TRANSLOADIT_SERVICE_URL}}
  271. # https://docs.cypress.io/guides/references/advanced-installation#Binary-cache
  272. CYPRESS_CACHE_FOLDER: ${{ steps.cypress-cache-dir-path.outputs.dir }}
  273. - name: Upload videos in case of failure
  274. uses: actions/upload-artifact@v3
  275. if: failure()
  276. with:
  277. name: videos-and-screenshots
  278. path: |
  279. e2e/cypress/videos/
  280. e2e/cypress/screenshots/
  281. - name: Remove labels
  282. # Remove the 'pending end-to-end tests' label if tests ran successfully
  283. if:
  284. github.event.pull_request &&
  285. contains(github.event.pull_request.labels.*.name, 'pending end-to-end
  286. tests')
  287. run: gh pr edit "$NUMBER" --remove-label 'pending end-to-end tests'
  288. env:
  289. NUMBER: ${{ github.event.pull_request.number }}
  290. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  291. - name: Remove 'safe to test' label
  292. if:
  293. always() && github.event.pull_request &&
  294. contains(github.event.pull_request.labels.*.name, 'safe to test')
  295. run: gh pr edit "$NUMBER" --remove-label 'safe to test'
  296. env:
  297. NUMBER: ${{ github.event.pull_request.number }}
  298. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}