-
Notifications
You must be signed in to change notification settings - Fork 91
ci: add Jenkinsfile and config for e2e mobile tests #19163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
0865107
675de6e
86c43eb
c6b5fad
a21a910
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,256 @@ | ||||||||||||||||||||||||||
| #!/usr/bin/env groovy | ||||||||||||||||||||||||||
| library '[email protected]' | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| pipeline { | ||||||||||||||||||||||||||
| agent { | ||||||||||||||||||||||||||
| dockerfile { | ||||||||||||||||||||||||||
| label 'linuxcontainer' | ||||||||||||||||||||||||||
| filename 'tests.Dockerfile' | ||||||||||||||||||||||||||
| dir 'ci' | ||||||||||||||||||||||||||
| args '--user jenkins' | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| parameters { | ||||||||||||||||||||||||||
| gitParameter( | ||||||||||||||||||||||||||
| name: 'GIT_REF', | ||||||||||||||||||||||||||
| description: 'Git branch to checkout.', | ||||||||||||||||||||||||||
| branchFilter: 'origin/(.*)', | ||||||||||||||||||||||||||
| branch: '', | ||||||||||||||||||||||||||
| defaultValue: 'master', | ||||||||||||||||||||||||||
| quickFilterEnabled: false, | ||||||||||||||||||||||||||
| selectedValue: 'DEFAULT', | ||||||||||||||||||||||||||
| sortMode: 'ASCENDING_SMART', | ||||||||||||||||||||||||||
| tagFilter: '*', | ||||||||||||||||||||||||||
| type: 'PT_BRANCH' | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| string( | ||||||||||||||||||||||||||
| name: 'BUILD_SOURCE', | ||||||||||||||||||||||||||
| description: 'URL to APK or Jenkins build (pkg/*.apk). Required when BROWSERSTACK_APP_ID is empty.', | ||||||||||||||||||||||||||
| defaultValue: '' | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| string( | ||||||||||||||||||||||||||
| name: 'BROWSERSTACK_APP_ID', | ||||||||||||||||||||||||||
| description: 'Existing BrowserStack app identifier (bs://...). Leave empty to upload from BUILD_SOURCE.', | ||||||||||||||||||||||||||
| defaultValue: '' | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| choice( | ||||||||||||||||||||||||||
| name: 'TEST_DEVICE_ID', | ||||||||||||||||||||||||||
| description: 'BrowserStack device id to run on (leave empty to use the environment default).', | ||||||||||||||||||||||||||
| choices: ['', 'galaxy_tab_s10p_android_15', 'pixel_8_android_14', 'pixel_7_android_13', 'samsung_s23_android_13'] | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| string( | ||||||||||||||||||||||||||
| name: 'PYTEST_ARGS', | ||||||||||||||||||||||||||
| description: 'Pytest flags (e.g. "-m smoke" or "-m critical") and other args.', | ||||||||||||||||||||||||||
| defaultValue: '-n=5 -m smoke tests' | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| options { | ||||||||||||||||||||||||||
| timestamps() | ||||||||||||||||||||||||||
| timeout(time: 120, unit: 'MINUTES') | ||||||||||||||||||||||||||
| buildDiscarder(logRotator( | ||||||||||||||||||||||||||
| daysToKeepStr: '30', | ||||||||||||||||||||||||||
| numToKeepStr: '30', | ||||||||||||||||||||||||||
| artifactNumToKeepStr: '30', | ||||||||||||||||||||||||||
| )) | ||||||||||||||||||||||||||
| disableRestartFromStage() | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| environment { | ||||||||||||||||||||||||||
| VIRTUAL_ENV = "${env.WORKSPACE_TMP}/venv-appium" | ||||||||||||||||||||||||||
| PYTHONUNBUFFERED = "1" | ||||||||||||||||||||||||||
| TEST_DEVICE_ID = "${params.TEST_DEVICE_ID}" | ||||||||||||||||||||||||||
| BROWSERSTACK_PROJECT_NAME = "Mobile E2E ${utils.getBuildType()}" | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| stages { | ||||||||||||||||||||||||||
| stage('Prep') { | ||||||||||||||||||||||||||
| steps { | ||||||||||||||||||||||||||
| script { | ||||||||||||||||||||||||||
| setNewBuildName() | ||||||||||||||||||||||||||
| updateGitHubStatus() | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| stage('Setup Python environment') { | ||||||||||||||||||||||||||
| steps { | ||||||||||||||||||||||||||
| dir('test/e2e_appium') { | ||||||||||||||||||||||||||
| sh """ | ||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||
| python3 -m venv ${VIRTUAL_ENV} | ||||||||||||||||||||||||||
| source ${VIRTUAL_ENV}/bin/activate | ||||||||||||||||||||||||||
| pip install --upgrade pip | ||||||||||||||||||||||||||
| pip install -r requirements.txt | ||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| stage('Use provided BrowserStack app') { | ||||||||||||||||||||||||||
| when { | ||||||||||||||||||||||||||
| expression { params.BROWSERSTACK_APP_ID?.trim() } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| steps { | ||||||||||||||||||||||||||
| script { | ||||||||||||||||||||||||||
| env.BROWSERSTACK_APP_ID = params.BROWSERSTACK_APP_ID.trim() | ||||||||||||||||||||||||||
| echo "Using provided BrowserStack app id: ${env.BROWSERSTACK_APP_ID}" | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+91
to
+101
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pointless stage that achieves nothing. |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| stage('Download') { | ||||||||||||||||||||||||||
| when { | ||||||||||||||||||||||||||
| allOf { | ||||||||||||||||||||||||||
| expression { !params.BROWSERSTACK_APP_ID?.trim() } | ||||||||||||||||||||||||||
| expression { params.BUILD_SOURCE?.startsWith('http') } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| steps { timeout(5) { script { dir('test/e2e_appium') { | ||||||||||||||||||||||||||
| if (!params.BUILD_SOURCE?.trim()) { | ||||||||||||||||||||||||||
| error('Specify BUILD_SOURCE when BROWSERSTACK_APP_ID is empty.') | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+111
to
+113
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Has no chance of happening. |
||||||||||||||||||||||||||
| sh 'mkdir -p ./pkg/' | ||||||||||||||||||||||||||
| fileOperations([ | ||||||||||||||||||||||||||
| fileDownloadOperation( | ||||||||||||||||||||||||||
| url: params.BUILD_SOURCE, | ||||||||||||||||||||||||||
| targetFileName: 'downloaded.apk', | ||||||||||||||||||||||||||
| targetLocation: './pkg/', | ||||||||||||||||||||||||||
| userName: '', | ||||||||||||||||||||||||||
| password: '', | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| ]) | ||||||||||||||||||||||||||
| def apkPath = utils.findFile('test/e2e_appium/pkg/*.apk') | ||||||||||||||||||||||||||
| if (!apkPath) { | ||||||||||||||||||||||||||
| error("Unable to locate APK under pkg/. Ensure BUILD_SOURCE produces pkg/*.apk artifacts.") | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| env.APK_PATH = apkPath | ||||||||||||||||||||||||||
| echo "APK ready at ${env.APK_PATH}" | ||||||||||||||||||||||||||
|
Comment on lines
+124
to
+129
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Entirely pointless. |
||||||||||||||||||||||||||
| } } } } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| stage('Copy') { | ||||||||||||||||||||||||||
| when { | ||||||||||||||||||||||||||
| allOf { | ||||||||||||||||||||||||||
| expression { !params.BROWSERSTACK_APP_ID?.trim() } | ||||||||||||||||||||||||||
| expression { !params.BUILD_SOURCE?.startsWith('http') } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| steps { timeout(5) { script { dir('test/e2e_appium') { | ||||||||||||||||||||||||||
| if (!params.BUILD_SOURCE?.trim()) { | ||||||||||||||||||||||||||
| error('Specify BUILD_SOURCE when BROWSERSTACK_APP_ID is empty.') | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+141
to
+143
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pointless. |
||||||||||||||||||||||||||
| copyArtifacts( | ||||||||||||||||||||||||||
| projectName: params.BUILD_SOURCE, | ||||||||||||||||||||||||||
| filter: 'pkg/*.apk', | ||||||||||||||||||||||||||
| selector: lastWithArtifacts(), | ||||||||||||||||||||||||||
| target: './' | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| def apkPath = utils.findFile('test/e2e_appium/pkg/*.apk') | ||||||||||||||||||||||||||
| if (!apkPath) { | ||||||||||||||||||||||||||
| error("Unable to locate APK under pkg/. Ensure BUILD_SOURCE produces pkg/*.apk artifacts.") | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| env.APK_PATH = apkPath | ||||||||||||||||||||||||||
| echo "APK ready at ${env.APK_PATH}" | ||||||||||||||||||||||||||
|
Comment on lines
+150
to
+155
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pointless. |
||||||||||||||||||||||||||
| } } } } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| stage('Upload APK to BrowserStack') { | ||||||||||||||||||||||||||
| when { | ||||||||||||||||||||||||||
| expression { !env.BROWSERSTACK_APP_ID } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| steps { | ||||||||||||||||||||||||||
| script { | ||||||||||||||||||||||||||
| withCredentials([ | ||||||||||||||||||||||||||
| usernamePassword( | ||||||||||||||||||||||||||
| credentialsId: 'browserstack-status-desktop', | ||||||||||||||||||||||||||
| usernameVariable: 'BROWSERSTACK_USERNAME', | ||||||||||||||||||||||||||
| passwordVariable: 'BROWSERSTACK_ACCESS_KEY' | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| ]) { | ||||||||||||||||||||||||||
| def response = sh( | ||||||||||||||||||||||||||
| script: "./scripts/upload_browserstack_apk.sh", | ||||||||||||||||||||||||||
| returnStdout: true | ||||||||||||||||||||||||||
| ).trim() | ||||||||||||||||||||||||||
| def result = readJSON text: response | ||||||||||||||||||||||||||
| def appUrl = result?.app_url | ||||||||||||||||||||||||||
| if (!appUrl) { | ||||||||||||||||||||||||||
| error("BrowserStack upload failed: ${response}") | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| env.BROWSERSTACK_APP_ID = appUrl | ||||||||||||||||||||||||||
| env.BROWSERSTACK_BUILD_NAME = result?.custom_id | ||||||||||||||||||||||||||
| env.BROWSERSTACK_BUILD_IDENTIFIER = env.BUILD_NUMBER | ||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is |
||||||||||||||||||||||||||
| echo "BrowserStack app uploaded: ${env.BROWSERSTACK_APP_ID}" | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| stage('Run pytest suite') { | ||||||||||||||||||||||||||
| steps { | ||||||||||||||||||||||||||
| script { | ||||||||||||||||||||||||||
| dir('test/e2e_appium') { | ||||||||||||||||||||||||||
| println("Using TEST_DEVICE_ID: ${env.TEST_DEVICE_ID}") | ||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what the point of this is since user can just look up job parameters. |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| withCredentials([ | ||||||||||||||||||||||||||
| usernamePassword( | ||||||||||||||||||||||||||
| credentialsId: 'browserstack-status-desktop', | ||||||||||||||||||||||||||
| usernameVariable: 'BROWSERSTACK_USERNAME', | ||||||||||||||||||||||||||
| passwordVariable: 'BROWSERSTACK_ACCESS_KEY' | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| ]) { | ||||||||||||||||||||||||||
| sh "${VIRTUAL_ENV}/bin/python -m pytest --env browserstack ${params.PYTEST_ARGS?.trim() ?: ''}" | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| stage('Publish test results') { | ||||||||||||||||||||||||||
| steps { | ||||||||||||||||||||||||||
| script { | ||||||||||||||||||||||||||
| def runId = env.E2E_RUN_ID?.trim() | ||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is this supposed to come from? |
||||||||||||||||||||||||||
| def reportsPattern = runId ? "test/e2e_appium/reports/${runId}/**/*.xml" : "test/e2e_appium/reports/**/*.xml" | ||||||||||||||||||||||||||
| junit allowEmptyResults: true, testResults: reportsPattern | ||||||||||||||||||||||||||
| def archivePattern = runId ? "test/e2e_appium/reports/${runId}/**/*" : "test/e2e_appium/reports/**/*" | ||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this pattern wider than the one above? How are those artifacts useful? |
||||||||||||||||||||||||||
| archiveArtifacts artifacts: archivePattern, allowEmptyArchive: true | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| post { | ||||||||||||||||||||||||||
| success { | ||||||||||||||||||||||||||
| script { | ||||||||||||||||||||||||||
| github.notifyPR(true) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| failure { | ||||||||||||||||||||||||||
| script { | ||||||||||||||||||||||||||
| github.notifyPR(false) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+224
to
+233
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||
| cleanup { | ||||||||||||||||||||||||||
| cleanWs(disableDeferredWipeout: true) | ||||||||||||||||||||||||||
glitchminer marked this conversation as resolved.
Show resolved
Hide resolved
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| def setNewBuildName() { | ||||||||||||||||||||||||||
| if (currentBuild.upstreamBuilds) { | ||||||||||||||||||||||||||
| def parent = utils.parentOrCurrentBuild() | ||||||||||||||||||||||||||
| currentBuild.displayName = parent.getFullDisplayName().minus('status-desktop » ') | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| def updateGitHubStatus() { | ||||||||||||||||||||||||||
| if (params.BUILD_SOURCE ==~ /.*\/PR-[0-9]+\/?$/) { | ||||||||||||||||||||||||||
| github.statusUpdate( | ||||||||||||||||||||||||||
| context: 'jenkins/prs/tests/e2e-android', | ||||||||||||||||||||||||||
| commit: jenkins.getJobCommitByPath(params.BUILD_SOURCE), | ||||||||||||||||||||||||||
| repo_url: 'https://github.com/status-im/status-desktop' | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,45 @@ | ||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||
| set -euo pipefail | ||||||||||||||
|
|
||||||||||||||
| # Upload APK to BrowserStack and output JSON response to stdout | ||||||||||||||
| # Requires environment variables: | ||||||||||||||
| # APK_PATH - Path to the APK file | ||||||||||||||
| # BROWSERSTACK_USERNAME - BrowserStack username | ||||||||||||||
| # BROWSERSTACK_ACCESS_KEY - BrowserStack access key | ||||||||||||||
| # BUILD_NUMBER - Build number (optional, defaults to current timestamp) | ||||||||||||||
|
|
||||||||||||||
| if [[ -z "${APK_PATH:-}" ]]; then | ||||||||||||||
| echo "Error: APK_PATH environment variable is required" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
Comment on lines
+11
to
+14
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this an env variables rather than a positional argument? |
||||||||||||||
|
|
||||||||||||||
| if [[ ! -f "${APK_PATH}" ]]; then | ||||||||||||||
| echo "Error: APK_PATH does not exist or is not a file: ${APK_PATH}" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| if [[ ! -r "${APK_PATH}" ]]; then | ||||||||||||||
| echo "Error: APK_PATH is not readable: ${APK_PATH}" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
Comment on lines
+16
to
+24
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pointless double test, the |
||||||||||||||
|
|
||||||||||||||
| if [[ -z "${BROWSERSTACK_USERNAME:-}" ]]; then | ||||||||||||||
| echo "Error: BROWSERSTACK_USERNAME environment variable is required" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| if [[ -z "${BROWSERSTACK_ACCESS_KEY:-}" ]]; then | ||||||||||||||
| echo "Error: BROWSERSTACK_ACCESS_KEY environment variable is required" >&2 | ||||||||||||||
| exit 1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| APK_NAME=$(basename "${APK_PATH}") | ||||||||||||||
| SANITIZED_NAME=$(printf '%s' "${APK_NAME}" | tr -cs '[:alnum:]._-' '-' | cut -c1-80) | ||||||||||||||
| BUILD_ID="${BUILD_NUMBER:-$(date +%s)}" | ||||||||||||||
| CUSTOM_ID="${SANITIZED_NAME}-${BUILD_ID}" | ||||||||||||||
|
|
||||||||||||||
| curl -s -u "${BROWSERSTACK_USERNAME}:${BROWSERSTACK_ACCESS_KEY}" \ | ||||||||||||||
| -X POST "https://api-cloud.browserstack.com/app-automate/upload" \ | ||||||||||||||
| -F "file=@${APK_PATH}" \ | ||||||||||||||
| -F "custom_id=${CUSTOM_ID}" | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use
Suggested change
And use full flag names instead of cryptic one letter flags. Those are for CLI use, not for scripts. |
||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,7 @@ report/ | |
| reports/ | ||
| screenshots/ | ||
| logs/ | ||
| log/ | ||
| *.log | ||
| result.xml | ||
| junit.xml | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using
gitParameter, see this PR for problem description: