Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 69 additions & 16 deletions .github/workflows/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,19 @@

name: Cypress

on: pull_request
on:
pull_request:
types:
- opened
- synchronize
- reopened
- ready_for_review
- labeled
- unlabeled
pull_request_review:
types:
- submitted
- dismissed

concurrency:
group: cypress-${{ github.head_ref || github.run_id }}
Expand All @@ -22,15 +34,55 @@ env:
# Usually it's the base branch of the PR, but for pushes it's the branch itself.
# e.g. 'main', 'stable27' or 'feature/my-feature'
# n.b. server will use head_ref, as we want to test the PR branch.
BRANCH: ${{ github.base_ref || github.ref_name }}

BRANCH: ${{ github.event.pull_request.base.ref || github.base_ref || github.ref_name }}

permissions:
contents: read
pull-requests: read

jobs:
gate:
runs-on: ubuntu-latest
outputs:
should_run: ${{ steps.evaluate.outputs.should_run }}
reason: ${{ steps.evaluate.outputs.reason }}
steps:
- name: Evaluate cypress execution conditions
id: evaluate
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v8.0.0
with:
script: |
const pr = context.payload.pull_request
if (!pr) {
core.setOutput('should_run', 'false')
core.setOutput('reason', 'not a pull request event')
return
}

const hasLabel = pr.labels.some((label) => label.name === 'test:e2e')

const files = await github.paginate(github.rest.pulls.listFiles, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
per_page: 100,
})
const cypressTouched = files.some((file) => file.filename.startsWith('cypress/'))

const reviews = await github.paginate(github.rest.pulls.listReviews, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
per_page: 100,
})
const hasTwoApprovals = reviews.filter((review) => review.state === 'APPROVED').length >= 2

core.setOutput('should_run', String(hasLabel || hasTwoApprovals || cypressTouched))

init:
runs-on: ubuntu-latest
needs: gate
if: needs.gate.outputs.should_run == 'true'
outputs:
nodeVersion: ${{ steps.versions.outputs.nodeVersion }}
npmVersion: ${{ steps.versions.outputs.npmVersion }}
Expand All @@ -52,7 +104,7 @@ jobs:
id: check_composer
uses: andstor/file-existence-action@558493d6c74bf472d87c84eab196434afc2fa029 # v3.1.0
with:
files: 'composer.json'
files: "composer.json"

- name: Install composer dependencies
if: steps.check_composer.outputs.files_exists == 'true'
Expand All @@ -62,8 +114,8 @@ jobs:
uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
id: versions
with:
fallbackNode: '^24'
fallbackNpm: '^11.3'
fallbackNode: "^24"
fallbackNpm: "^11.3"

- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
Expand Down Expand Up @@ -98,14 +150,15 @@ jobs:

cypress:
runs-on: ubuntu-latest
needs: init
needs: [gate, init]
if: needs.gate.outputs.should_run == 'true'

strategy:
fail-fast: false
matrix:
# Run multiple copies of the current job in parallel
# Please increase the number or runners as your tests suite grows (0 based index for e2e tests)
containers: ['setup', '0', '1', '2', '3', '4', '5', '6', '7']
containers: ["setup", "0", "1", "2", "3", "4", "5", "6", "7"]
# Hack as strategy.job-total includes the "setup" and GitHub does not allow math expressions
# Always align this number with the total of e2e runners (max. index + 1)
total-containers: [8]
Expand All @@ -115,7 +168,7 @@ jobs:
# Only start mysql if we are running the setup tests
image: ${{matrix.containers == 'setup' && 'ghcr.io/nextcloud/continuous-integration-mysql-8.4:latest' || ''}} # zizmor: ignore[unpinned-images]
ports:
- '3306/tcp'
- "3306/tcp"
env:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_USER: oc_autotest
Expand All @@ -127,7 +180,7 @@ jobs:
# Only start mariadb if we are running the setup tests
image: ${{matrix.containers == 'setup' && 'mariadb:11.4' || ''}} # zizmor: ignore[unpinned-images]
ports:
- '3306/tcp'
- "3306/tcp"
env:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_USER: oc_autotest
Expand All @@ -139,7 +192,7 @@ jobs:
# Only start postgres if we are running the setup tests
image: ${{matrix.containers == 'setup' && 'ghcr.io/nextcloud/continuous-integration-postgres-17:latest' || ''}} # zizmor: ignore[unpinned-images]
ports:
- '5432/tcp'
- "5432/tcp"
env:
POSTGRES_USER: root
POSTGRES_PASSWORD: rootpassword
Expand All @@ -150,10 +203,10 @@ jobs:
# Only start oracle if we are running the setup tests
image: ${{matrix.containers == 'setup' && 'ghcr.io/gvenzl/oracle-free:23' || ''}} # zizmor: ignore[unpinned-images]
ports:
- '1521'
- "1521"
env:
ORACLE_PASSWORD: oracle
options: --health-cmd healthcheck.sh --health-interval 20s --health-timeout 10s --health-retries 10
options: --health-cmd healthcheck.sh --health-interval 20s --health-timeout 10s --health-retries 10

name: runner ${{ matrix.containers }}

Expand All @@ -178,7 +231,7 @@ jobs:
if: steps.cache.outputs.cache-hit != 'true'
uses: andstor/file-existence-action@558493d6c74bf472d87c84eab196434afc2fa029 # v3.1.0
with:
files: 'composer.json'
files: "composer.json"

- name: Install composer dependencies
if: steps.check_composer.outputs.files_exists == 'true' && steps.cache.outputs.cache-hit != 'true'
Expand Down Expand Up @@ -252,9 +305,9 @@ jobs:

summary:
runs-on: ubuntu-latest-low
needs: [init, cypress]
needs: [gate, init, cypress]

if: always()
if: always() && needs.gate.outputs.should_run == 'true'

name: cypress-summary

Expand Down
Loading