Skip to content

Commit

Permalink
chore: [DHIS2-17377] enhance CI with conditional e2e tests recording …
Browse files Browse the repository at this point in the history
…in Cypress Cloud (#2984)

Implements DHIS2-17377

Conditional Recording Triggers:
Implemented conditional recording triggers via commit messages
and GitHub labels to ensure that Cypress tests are only recorded when necessary.

Parallel Execution Strategies: Refined parallel execution strategies to improve efficiency and
resolve test redundancies in GitHub Actions.
Debugging Enhancements: Added detailed debugging outputs to help track the dynamic values of
the test environment variables and ensure correct parameter passing in the workflow.

Manual Grouping of Tests:
In GitHub Actions, without specified test groups, all tests would run
in every parallel container, leading to unnecessary repetition. By organizing tests into
predefined groups, each group runs only once. This prevents redundancy and expedites the testing
process.

Why Not Rely on Cypress's Automatic Balancing? While Cypress automatically assigns tests to
machines to balance workload (more on Cypress load balancing), GitHub Actions requires explicit
distribution of tasks. This manual grouping ensures efficient resource usage and prevents multiple
executions of the same tests across different runners.

Benefits:
This approach allows precise control over test distribution, enhancing predictability
and efficiency. It reduces total execution time and operational costs by ensuring each test is run
precisely once across the available infrastructure.

This method optimises our use of GitHub Actions, ensuring a faster, cost-effective,
and efficient testing process.

Update Documentation:
Updated the documentation to reflect the changes and ensure clarity
on the new CI/CD processes.

Expected Outcomes:
Reduced Cypress Cloud Credit Usage: By optimising the conditions under which tests are recorded
and uploaded to Cypress Cloud, we anticipate a significant reduction in credit usage.

Increased CI Efficiency: With better management of parallel execution and conditional testing, the
CI process should be more efficient, leading to quicker test cycles.

---------

Co-authored-by: @dhis2-bot <[email protected]>
Co-authored-by: Jen Jones Arnesen <[email protected]>
  • Loading branch information
3 people authored Jun 4, 2024
1 parent 1c2d1b2 commit 74c9b19
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 7 deletions.
48 changes: 41 additions & 7 deletions .github/workflows/dhis2-verify-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: 'dhis2: verify (app)'

on:
pull_request:
types: ['opened', 'edited', 'reopened', 'synchronize']
types: ['opened', 'labeled', 'reopened', 'synchronize']
push:
branches:
- 'master'
Expand All @@ -19,6 +19,18 @@ env:
CI: true

jobs:
setup-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.specs }}
steps:
- uses: actions/checkout@v3
- name: Generate test matrix
id: set-matrix
run: |
node cypress/support/generateTestMatrix.js > matrix.json
echo "::set-output name=specs::$(cat matrix.json)"
build:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -77,12 +89,16 @@ jobs:

e2e-prod:
runs-on: ubuntu-latest
needs: test
needs: [test, setup-matrix]
if: "!contains(github.event.head_commit.message, '[skip ci]')"

strategy:
fail-fast: false
matrix:
containers: [1, 2, 3, 4]
spec-group: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}

env:
SHOULD_RECORD: ${{ contains(github.event.head_commit.message, '[e2e record]') || contains(join(github.event.pull_request.labels.*.name), 'e2e record') }}

steps:
- uses: actions/checkout@v3
Expand All @@ -96,17 +112,35 @@ jobs:
path: '**/node_modules'
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('patches/*.patch') }}

- name: Set Cypress Record Environment Variables
if: env.SHOULD_RECORD == 'true'
run: |
echo "CYPRESS_GROUP=e2e-${{ matrix.spec-group.id }}" >> $GITHUB_ENV
echo "CYPRESS_TAG=${{ github.event_name }}" >> $GITHUB_ENV
echo "CYPRESS_CI_BUILD_ID=${{ github.run_id }}" >> $GITHUB_ENV
- name: Debug Environment Variables
run: |
echo "SHOULD_RECORD=${{ env.SHOULD_RECORD }}"
echo "CI Build ID=${{ github.run_id }}"
echo "Computed Group=${{ env.SHOULD_RECORD == 'true' && env.CYPRESS_GROUP || '' }}"
echo "Computed Tag=${{ env.SHOULD_RECORD == 'true' && env.CYPRESS_TAG || '' }}"
echo "Computed CI Build ID=${{ env.SHOULD_RECORD == 'true' && env.CYPRESS_CI_BUILD_ID || '' }}"
echo "Spec=${{ join(matrix.spec-group.tests, ',') }}"
- name: End-to-End tests
uses: cypress-io/github-action@v2
with:
record: true
parallel: true
start: ${{ env.SERVER_START_CMD }}
wait-on: ${{ env.SERVER_URL }}
wait-on-timeout: 300
cache-key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('patches/*.patch') }}
group: 'e2e'
tag: ${{ github.event_name }}
record: ${{ env.SHOULD_RECORD }}
parallel: ${{ env.SHOULD_RECORD }}
group: ${{ env.SHOULD_RECORD == 'true' && env.CYPRESS_GROUP || '' }}
tag: ${{ env.SHOULD_RECORD == 'true' && env.CYPRESS_TAG || '' }}
ci-build-id: ${{ env.SHOULD_RECORD == 'true' && env.CYPRESS_CI_BUILD_ID || '' }}
spec: ${{ join(matrix.spec-group.tests, ',') }}
env:
CI: true
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ Builds the app for production to the `build` folder.<br />. This command is run

See the [building](https://platform.dhis2.nu/#/scripts/build) section for more information.

## Conditional E2E Test Recording

To record e2e tests in Cypress Cloud, you can use one of the following methods based on your needs:

- **Commit Message**: Include `[e2e record]` in your commit messages to activate recording.
- **GitHub Labels**: Apply the `e2e record` label to your pull request to trigger recording.

This setup helps in managing Cypress Cloud credits more efficiently, ensuring recordings are only made when explicitly required.

## Learn More

You can learn more about the platform in the [DHIS2 Application Platform Documentation](https://platform.dhis2.nu/).
Expand Down
35 changes: 35 additions & 0 deletions cypress/support/generateTestMatrix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const fs = require('fs')
const path = require('path')

const getAllFiles = (dirPath, arrayOfFiles = []) => {
const files = fs.readdirSync(dirPath)

files.forEach((file) => {
if (fs.statSync(path.join(dirPath, file)).isDirectory()) {
arrayOfFiles = getAllFiles(path.join(dirPath, file), arrayOfFiles)
} else if (path.extname(file) === '.feature') {
arrayOfFiles.push(path.join(dirPath, file))
}
})

return arrayOfFiles
}

const createGroups = (files, numberOfGroups = 8) => {
const groups = []
for (let i = 0; i < numberOfGroups; i++) {
groups.push([])
}

files.forEach((file, index) => {
groups[index % numberOfGroups].push(file)
})

return groups.map((group, index) => ({ id: index + 1, tests: group }))
}

const cypressSpecsPath = './cypress/integration'
const specs = getAllFiles(cypressSpecsPath)
const groupedSpecs = createGroups(specs)

console.log(JSON.stringify(groupedSpecs))

0 comments on commit 74c9b19

Please sign in to comment.