123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- name: End-to-end tests
- on:
- push:
- branches: [main]
- paths-ignore:
- - '**.md'
- - '**.d.ts'
- - 'examples/**'
- - 'private/**'
- - 'website/**'
- - '.github/**'
- - '!.github/workflows/e2e.yml'
- pull_request_target:
- types: [opened, synchronize, reopened, labeled]
- paths-ignore:
- - '**.md'
- - '**.d.ts'
- - 'examples/**'
- - 'private/**'
- - 'website/**'
- - '.github/**'
- pull_request:
- types: [opened, synchronize, reopened]
- paths:
- - .github/workflows/e2e.yml
- concurrency:
- group:
- ${{ github.workflow }}--${{ github.event.pull_request.head.repo.full_name ||
- github.repository }} -- ${{ github.head_ref || github.ref }}
- cancel-in-progress:
- # For PRs coming from forks, we need the previous job to run until the end
- # to be sure it can remove the `safe to test` label before it affects the next run.
- ${{ github.event.pull_request.head.repo.full_name == github.repository }}
- permissions:
- pull-requests: write
- env:
- YARN_ENABLE_GLOBAL_CACHE: false
- jobs:
- compare_diff:
- runs-on: ubuntu-latest
- env:
- DIFF_BUILDER: true
- outputs:
- diff: ${{ steps.diff.outputs.OUTPUT_DIFF }}
- is_accurate_diff: ${{ steps.diff.outputs.IS_ACCURATE_DIFF }}
- steps:
- - name: Checkout sources
- uses: actions/checkout@v4
- with:
- fetch-depth: 2
- ref:
- ${{ github.event.pull_request && format('refs/pull/{0}/merge',
- github.event.pull_request.number) || github.sha }}
- - name: Check if there are "unsafe" changes
- id: build_chain_changes
- # If there are changes in JS script that generates the output, we cannot
- # test them here without human review to make sure they don't contain
- # someting "nasty".
- run: |
- EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
- echo "MIGHT_CONTAIN_OTHER_CHANGES<<$EOF" >> "$GITHUB_OUTPUT"
- git --no-pager diff HEAD^ --name-only bin package.json yarn.lock babel.config.js >> "$GITHUB_OUTPUT"
- echo "$EOF" >> "$GITHUB_OUTPUT"
- - run: git reset HEAD^ --hard
- - name: Get yarn cache directory path
- id: yarn-cache-dir-path
- run:
- echo "dir=$(corepack yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- - uses: actions/cache@v4
- id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
- with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
- - name: Install Node.js
- uses: actions/setup-node@v4
- with:
- node-version: lts/*
- - name: Install dependencies
- run:
- corepack yarn workspaces focus $(corepack yarn workspaces list --json
- | jq -r .name | awk '/^@uppy-example/{ next } { if ($0!="uppy.io")
- print $0 }')
- env:
- # https://docs.cypress.io/guides/references/advanced-installation#Skipping-installation
- CYPRESS_INSTALL_BINARY: 0
- - run: corepack yarn build:js:typeless
- - name: Store output file
- run: tar cf /tmp/previousVersion.tar packages/@uppy/*/lib
- - name: Fetch source from the PR
- if: steps.build_chain_changes.outputs.MIGHT_CONTAIN_OTHER_CHANGES == ''
- run: |
- git checkout FETCH_HEAD -- packages
- echo 'IS_ACCURATE_DIFF=true' >> "$GITHUB_ENV"
- - name: Fetch source from the PR
- if:
- steps.build_chain_changes.outputs.MIGHT_CONTAIN_OTHER_CHANGES != '' &&
- (!github.event.pull_request || (github.event.action == 'labeled' &&
- github.event.label.name == 'safe to test' &&
- github.event.pull_request.state == 'open') ||
- (github.event.pull_request.head.repo.full_name == github.repository &&
- github.event.event_name != 'labeled'))
- run: |
- git reset FETCH_HEAD --hard
- corepack yarn workspaces focus $(\
- corepack yarn workspaces list --json | \
- jq -r .name | \
- awk '/^@uppy-example/{ next } { if ($0!="uppy.io") print $0 }'\
- )
- echo 'IS_ACCURATE_DIFF=true' >> "$GITHUB_ENV"
- env:
- # https://docs.cypress.io/guides/references/advanced-installation#Skipping-installation
- CYPRESS_INSTALL_BINARY: 0
- - name: Fetch source from the PR
- if:
- steps.build_chain_changes.outputs.MIGHT_CONTAIN_OTHER_CHANGES != '' &&
- github.event.pull_request.head.repo.full_name != github.repository &&
- (github.event.action != 'labeled' || github.event.label.name != 'safe
- to test')
- run: |
- git checkout FETCH_HEAD -- packages
- - run: corepack yarn build:js:typeless
- - name: Store output file
- run: tar cf /tmp/newVersion.tar packages/@uppy/*/lib
- - name: Setup git
- run: |
- git config --global user.email "actions@github.com"
- git config --global user.name "GitHub Actions"
- git init /tmp/uppy
- echo '*.map' > /tmp/uppy/.gitignore
- - name: Install dformat
- run: |
- curl -fsSL https://dprint.dev/install.sh | sh
- cd /tmp/uppy && echo '{"plugins":[]}' > dprint.json && "$HOME/.dprint/bin/dprint" config add typescript
- - name: Extract previous version
- run: cd /tmp/uppy && tar xf /tmp/previousVersion.tar
- - name: Format previous output code
- run: cd /tmp/uppy && "$HOME/.dprint/bin/dprint" fmt **/*.js
- - name: Commit previous version
- run: cd /tmp/uppy && git add -A . && git commit -m 'previous version'
- - name: Extract new version
- run: cd /tmp/uppy && tar xf /tmp/newVersion.tar
- - name: Format new output code
- run: cd /tmp/uppy && "$HOME/.dprint/bin/dprint" fmt **/*.js
- - name: Build diff
- id: diff
- run: |
- EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
- echo "OUTPUT_DIFF<<$EOF" >> "$GITHUB_OUTPUT"
- cd /tmp/uppy && git --no-pager diff >> "$GITHUB_OUTPUT"
- echo "$EOF" >> "$GITHUB_OUTPUT"
- echo "IS_ACCURATE_DIFF=$IS_ACCURATE_DIFF" >> "$GITHUB_OUTPUT"
- - name: Add/update comment
- if: github.event.pull_request
- uses: marocchino/sticky-pull-request-comment@v2
- with:
- message: |
- <details><summary>Diff output files</summary>
- ```diff
- ${{ steps.diff.outputs.OUTPUT_DIFF || 'No diff' }}
- ```
- ${{ 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) || '' }}
- </details>
- - name: Remove 'safe to test' label if cancelled
- if:
- cancelled() && github.event.pull_request &&
- github.event.pull_request.head.repo.full_name != github.repository
- run: gh pr edit "$NUMBER" --remove-label 'safe to test'
- env:
- NUMBER: ${{ github.event.pull_request.number }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- toggle-pending-e2e-label:
- # Add the 'pending end-to-end tests' label for PRs that come from forks.
- # For those PRs, we want to review the code before running e2e tests.
- # See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
- needs: [compare_diff]
- if:
- github.event.pull_request.state == 'open' &&
- github.event.pull_request.head.repo.full_name != github.repository
- runs-on: ubuntu-latest
- steps:
- - name: Add label
- if:
- (needs.compare_diff.outputs.diff != '' ||
- !needs.compare_diff.outputs.is_accurate_diff) && (github.event.action
- != 'labeled' || github.event.label.name != 'safe to test')
- env:
- PR_URL: ${{ github.event.pull_request.html_url }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run:
- gh pr edit "$PR_URL" --repo ${{ github.repository }} --add-label
- 'pending end-to-end tests'
- - name: Remove label
- if:
- needs.compare_diff.outputs.diff == '' &&
- needs.compare_diff.outputs.is_accurate_diff && github.event.action ==
- 'labeled' && github.event.label.name == 'safe to test'
- env:
- PR_URL: ${{ github.event.pull_request.html_url }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run:
- gh pr edit "$PR_URL" --remove-label 'safe to test' --remove-label
- 'pending end-to-end tests'
- e2e:
- needs: [compare_diff]
- if:
- ${{ needs.compare_diff.outputs.diff != '' && (!github.event.pull_request
- || (github.event.action == 'labeled' && github.event.label.name == 'safe
- to test' && github.event.pull_request.state == 'open') ||
- (github.event.pull_request.head.repo.full_name == github.repository &&
- github.event.event_name != 'labeled')) }}
- name: Browser tests
- runs-on: ubuntu-latest
- steps:
- - name: Checkout sources
- uses: actions/checkout@v4
- with:
- ref: ${{ github.event.pull_request.head.sha || github.sha }}
- - name: Get yarn cache directory path
- id: yarn-cache-dir-path
- run:
- echo "dir=$(corepack yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- - uses: actions/cache@v4
- id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
- with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
- - name: Create cache folder for Cypress
- id: cypress-cache-dir-path
- run: echo "dir=$(mktemp -d)" >> $GITHUB_OUTPUT
- - uses: actions/cache@v4
- with:
- path: ${{ steps.cypress-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-cypress
- - name: Install Node.js
- uses: actions/setup-node@v4
- with:
- node-version: lts/*
- - name: Start Redis
- uses: supercharge/redis-github-action@ea9b21c6ecece47bd99595c532e481390ea0f044 # 1.8.0
- with:
- redis-version: 7
- - name: Install dependencies
- run: corepack yarn install --immutable
- env:
- # https://docs.cypress.io/guides/references/advanced-installation#Binary-cache
- CYPRESS_CACHE_FOLDER: ${{ steps.cypress-cache-dir-path.outputs.dir }}
- - name: Build Uppy packages
- run: corepack yarn build
- - name: Run end-to-end browser tests
- run: corepack yarn run e2e:ci
- env:
- COMPANION_DATADIR: ./output
- COMPANION_DOMAIN: localhost:3020
- COMPANION_PROTOCOL: http
- COMPANION_REDIS_URL: redis://localhost:6379
- COMPANION_UNSPLASH_KEY: ${{secrets.COMPANION_UNSPLASH_KEY}}
- COMPANION_UNSPLASH_SECRET: ${{secrets.COMPANION_UNSPLASH_SECRET}}
- COMPANION_AWS_KEY: ${{secrets.COMPANION_AWS_KEY}}
- COMPANION_AWS_SECRET: ${{secrets.COMPANION_AWS_SECRET}}
- COMPANION_AWS_BUCKET: ${{secrets.COMPANION_AWS_BUCKET}}
- COMPANION_AWS_REGION: ${{secrets.COMPANION_AWS_REGION}}
- VITE_COMPANION_URL: http://localhost:3020
- VITE_TRANSLOADIT_KEY: ${{secrets.TRANSLOADIT_KEY}}
- VITE_TRANSLOADIT_SECRET: ${{secrets.TRANSLOADIT_SECRET}}
- VITE_TRANSLOADIT_TEMPLATE: ${{secrets.TRANSLOADIT_TEMPLATE}}
- VITE_TRANSLOADIT_SERVICE_URL: ${{secrets.TRANSLOADIT_SERVICE_URL}}
- # https://docs.cypress.io/guides/references/advanced-installation#Binary-cache
- CYPRESS_CACHE_FOLDER: ${{ steps.cypress-cache-dir-path.outputs.dir }}
- - name: Upload videos in case of failure
- uses: actions/upload-artifact@v4
- if: failure()
- with:
- name: videos-and-screenshots
- path: |
- e2e/cypress/videos/
- e2e/cypress/screenshots/
- - name: Remove labels
- # Remove the 'pending end-to-end tests' label if tests ran successfully
- if:
- github.event.pull_request &&
- contains(github.event.pull_request.labels.*.name, 'pending end-to-end
- tests')
- run: gh pr edit "$NUMBER" --remove-label 'pending end-to-end tests'
- env:
- NUMBER: ${{ github.event.pull_request.number }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Remove 'safe to test' label
- if:
- always() && github.event.pull_request &&
- contains(github.event.pull_request.labels.*.name, 'safe to test')
- run: gh pr edit "$NUMBER" --remove-label 'safe to test'
- env:
- NUMBER: ${{ github.event.pull_request.number }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|