Skip to content

Commit 0511399

Browse files
committed
ci(e2e_mobile): address review feedback
1 parent a21a910 commit 0511399

File tree

2 files changed

+37
-126
lines changed

2 files changed

+37
-126
lines changed

ci/Jenkinsfile.test-e2e.android

Lines changed: 20 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,14 @@ pipeline {
1212
}
1313

1414
parameters {
15-
gitParameter(
15+
string(
1616
name: 'GIT_REF',
1717
description: 'Git branch to checkout.',
18-
branchFilter: 'origin/(.*)',
19-
branch: '',
20-
defaultValue: 'master',
21-
quickFilterEnabled: false,
22-
selectedValue: 'DEFAULT',
23-
sortMode: 'ASCENDING_SMART',
24-
tagFilter: '*',
25-
type: 'PT_BRANCH'
18+
defaultValue: 'master'
2619
)
2720
string(
2821
name: 'BUILD_SOURCE',
29-
description: 'URL to APK or Jenkins build (pkg/*.apk). Required when BROWSERSTACK_APP_ID is empty.',
22+
description: 'URL to APK OR path to Jenkins build.',
3023
defaultValue: ''
3124
)
3225
string(
@@ -88,48 +81,6 @@ pipeline {
8881
}
8982
}
9083

91-
stage('Use provided BrowserStack app') {
92-
when {
93-
expression { params.BROWSERSTACK_APP_ID?.trim() }
94-
}
95-
steps {
96-
script {
97-
env.BROWSERSTACK_APP_ID = params.BROWSERSTACK_APP_ID.trim()
98-
echo "Using provided BrowserStack app id: ${env.BROWSERSTACK_APP_ID}"
99-
}
100-
}
101-
}
102-
103-
stage('Download') {
104-
when {
105-
allOf {
106-
expression { !params.BROWSERSTACK_APP_ID?.trim() }
107-
expression { params.BUILD_SOURCE?.startsWith('http') }
108-
}
109-
}
110-
steps { timeout(5) { script { dir('test/e2e_appium') {
111-
if (!params.BUILD_SOURCE?.trim()) {
112-
error('Specify BUILD_SOURCE when BROWSERSTACK_APP_ID is empty.')
113-
}
114-
sh 'mkdir -p ./pkg/'
115-
fileOperations([
116-
fileDownloadOperation(
117-
url: params.BUILD_SOURCE,
118-
targetFileName: 'downloaded.apk',
119-
targetLocation: './pkg/',
120-
userName: '',
121-
password: '',
122-
)
123-
])
124-
def apkPath = utils.findFile('test/e2e_appium/pkg/*.apk')
125-
if (!apkPath) {
126-
error("Unable to locate APK under pkg/. Ensure BUILD_SOURCE produces pkg/*.apk artifacts.")
127-
}
128-
env.APK_PATH = apkPath
129-
echo "APK ready at ${env.APK_PATH}"
130-
} } } }
131-
}
132-
13384
stage('Copy') {
13485
when {
13586
allOf {
@@ -138,30 +89,23 @@ pipeline {
13889
}
13990
}
14091
steps { timeout(5) { script { dir('test/e2e_appium') {
141-
if (!params.BUILD_SOURCE?.trim()) {
142-
error('Specify BUILD_SOURCE when BROWSERSTACK_APP_ID is empty.')
143-
}
14492
copyArtifacts(
14593
projectName: params.BUILD_SOURCE,
14694
filter: 'pkg/*.apk',
14795
selector: lastWithArtifacts(),
148-
target: './'
96+
target: './pkg/'
14997
)
150-
def apkPath = utils.findFile('test/e2e_appium/pkg/*.apk')
151-
if (!apkPath) {
152-
error("Unable to locate APK under pkg/. Ensure BUILD_SOURCE produces pkg/*.apk artifacts.")
153-
}
154-
env.APK_PATH = apkPath
155-
echo "APK ready at ${env.APK_PATH}"
15698
} } } }
15799
}
158100

159101
stage('Upload APK to BrowserStack') {
160102
when {
161-
expression { !env.BROWSERSTACK_APP_ID }
103+
expression { !params.BROWSERSTACK_APP_ID?.trim() }
162104
}
163105
steps {
164106
script {
107+
def autSource = params.BUILD_SOURCE?.startsWith('http') ?
108+
params.BUILD_SOURCE : utils.findFile('test/e2e_appium/pkg/*.apk')
165109
withCredentials([
166110
usernamePassword(
167111
credentialsId: 'browserstack-status-desktop',
@@ -170,18 +114,16 @@ pipeline {
170114
)
171115
]) {
172116
def response = sh(
173-
script: "./scripts/upload_browserstack_apk.sh",
117+
script: "./scripts/upload_browserstack_apk.sh '${autSource}'",
174118
returnStdout: true
175119
).trim()
176120
def result = readJSON text: response
177-
def appUrl = result?.app_url
178-
if (!appUrl) {
121+
if (!result?.app_url) {
179122
error("BrowserStack upload failed: ${response}")
180123
}
181-
env.BROWSERSTACK_APP_ID = appUrl
182-
env.BROWSERSTACK_BUILD_NAME = result?.custom_id
124+
env.BROWSERSTACK_APP_ID = result.app_url
125+
env.BROWSERSTACK_BUILD_NAME = result.custom_id
183126
env.BROWSERSTACK_BUILD_IDENTIFIER = env.BUILD_NUMBER
184-
echo "BrowserStack app uploaded: ${env.BROWSERSTACK_APP_ID}"
185127
}
186128
}
187129
}
@@ -190,9 +132,11 @@ pipeline {
190132
stage('Run pytest suite') {
191133
steps {
192134
script {
135+
if (params.BROWSERSTACK_APP_ID?.trim()) {
136+
env.BROWSERSTACK_APP_ID = params.BROWSERSTACK_APP_ID.trim()
137+
}
138+
env.E2E_RUN_ID = env.BUILD_TAG
193139
dir('test/e2e_appium') {
194-
println("Using TEST_DEVICE_ID: ${env.TEST_DEVICE_ID}")
195-
196140
withCredentials([
197141
usernamePassword(
198142
credentialsId: 'browserstack-status-desktop',
@@ -209,30 +153,18 @@ pipeline {
209153

210154
stage('Publish test results') {
211155
steps {
212-
script {
213-
def runId = env.E2E_RUN_ID?.trim()
214-
def reportsPattern = runId ? "test/e2e_appium/reports/${runId}/**/*.xml" : "test/e2e_appium/reports/**/*.xml"
215-
junit allowEmptyResults: true, testResults: reportsPattern
216-
def archivePattern = runId ? "test/e2e_appium/reports/${runId}/**/*" : "test/e2e_appium/reports/**/*"
217-
archiveArtifacts artifacts: archivePattern, allowEmptyArchive: true
218-
}
156+
junit allowEmptyResults: true, testResults: "test/e2e_appium/reports/${env.BUILD_TAG}/pytest_results_*.xml"
157+
archiveArtifacts artifacts: "test/e2e_appium/reports/${env.BUILD_TAG}/**/*", allowEmptyArchive: true
219158
}
220159
}
221160
}
222161

223162
post {
224-
success {
225-
script {
226-
github.notifyPR(true)
227-
}
228-
}
229-
failure {
230-
script {
231-
github.notifyPR(false)
232-
}
233-
}
163+
success { script { github.notifyPR(true) } }
164+
failure { script { github.notifyPR(false) } }
234165
cleanup {
235166
cleanWs(disableDeferredWipeout: true)
167+
dir(env.WORKSPACE_TMP) { deleteDir() }
236168
}
237169
}
238170
}
@@ -243,7 +175,6 @@ def setNewBuildName() {
243175
currentBuild.displayName = parent.getFullDisplayName().minus('status-desktop » ')
244176
}
245177
}
246-
247178
def updateGitHubStatus() {
248179
if (params.BUILD_SOURCE ==~ /.*\/PR-[0-9]+\/?$/) {
249180
github.statusUpdate(
@@ -253,4 +184,3 @@ def updateGitHubStatus() {
253184
)
254185
}
255186
}
256-

scripts/upload_browserstack_apk.sh

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,25 @@
22
set -euo pipefail
33

44
# Upload APK to BrowserStack and output JSON response to stdout
5-
# Requires environment variables:
6-
# APK_PATH - Path to the APK file
7-
# BROWSERSTACK_USERNAME - BrowserStack username
8-
# BROWSERSTACK_ACCESS_KEY - BrowserStack access key
9-
# BUILD_NUMBER - Build number (optional, defaults to current timestamp)
5+
# Usage: ./upload_browserstack_apk.sh <apk_path_or_url>
6+
# URLs must be publicly accessible (BrowserStack fetches directly)
107

11-
if [[ -z "${APK_PATH:-}" ]]; then
12-
echo "Error: APK_PATH environment variable is required" >&2
13-
exit 1
14-
fi
15-
16-
if [[ ! -f "${APK_PATH}" ]]; then
17-
echo "Error: APK_PATH does not exist or is not a file: ${APK_PATH}" >&2
18-
exit 1
19-
fi
20-
21-
if [[ ! -r "${APK_PATH}" ]]; then
22-
echo "Error: APK_PATH is not readable: ${APK_PATH}" >&2
23-
exit 1
24-
fi
8+
APK_SOURCE="${1:?Usage: $0 <apk_path_or_url>}"
9+
: "${BROWSERSTACK_USERNAME:?required}"
10+
: "${BROWSERSTACK_ACCESS_KEY:?required}"
2511

26-
if [[ -z "${BROWSERSTACK_USERNAME:-}" ]]; then
27-
echo "Error: BROWSERSTACK_USERNAME environment variable is required" >&2
28-
exit 1
29-
fi
12+
APK_NAME=$(basename "${APK_SOURCE%%\?*}")
13+
CUSTOM_ID=$(printf '%s' "${APK_NAME}" | tr -cs '[:alnum:]._-' '-' | cut -c1-100)
3014

31-
if [[ -z "${BROWSERSTACK_ACCESS_KEY:-}" ]]; then
32-
echo "Error: BROWSERSTACK_ACCESS_KEY environment variable is required" >&2
33-
exit 1
15+
if [[ "${APK_SOURCE}" == http* ]]; then
16+
FORM_KEY="url="
17+
else
18+
[[ -f "${APK_SOURCE}" ]] || { echo "Error: File not found: ${APK_SOURCE}" >&2; exit 1; }
19+
FORM_KEY="file=@"
3420
fi
3521

36-
APK_NAME=$(basename "${APK_PATH}")
37-
SANITIZED_NAME=$(printf '%s' "${APK_NAME}" | tr -cs '[:alnum:]._-' '-' | cut -c1-80)
38-
BUILD_ID="${BUILD_NUMBER:-$(date +%s)}"
39-
CUSTOM_ID="${SANITIZED_NAME}-${BUILD_ID}"
40-
41-
curl -s -u "${BROWSERSTACK_USERNAME}:${BROWSERSTACK_ACCESS_KEY}" \
42-
-X POST "https://api-cloud.browserstack.com/app-automate/upload" \
43-
-F "file=@${APK_PATH}" \
44-
-F "custom_id=${CUSTOM_ID}"
45-
22+
curl --request POST "https://api-cloud.browserstack.com/app-automate/upload" \
23+
--silent --show-error --fail-with-body \
24+
--user "${BROWSERSTACK_USERNAME}:${BROWSERSTACK_ACCESS_KEY}" \
25+
--form "${FORM_KEY}${APK_SOURCE}" \
26+
--form "custom_id=${CUSTOM_ID}"

0 commit comments

Comments
 (0)