Skip to content

Commit 6fd54e2

Browse files
Build React Native Android E2E APK artifact
Assisted-By: devx/6c1e3ad5-96c8-4972-b087-da7ff7b195c3
1 parent 19ffe1b commit 6fd54e2

4 files changed

Lines changed: 109 additions & 6 deletions

File tree

e2e/BITRISE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,17 @@ The non-secret E2E defaults are defined in `e2e/bitrise.yml` under `app.envs`. D
5959
| `E2E_BROWSERSTACK_TIMEOUT_SECONDS` | `1800` | BrowserStack build timeout. |
6060
| `E2E_BROWSERSTACK_POLL_SECONDS` | `30` | BrowserStack status polling interval. |
6161
| `E2E_IOS_EXPORT_METHOD` | `development` | Export method for the React Native iOS IPA. |
62+
| `E2E_ANDROID_COMMAND_TIMEOUT_SECONDS` | `1800` | Per-command timeout for React Native Android artifact commands. |
6263
| `E2E_PACKAGE_COMMAND_TIMEOUT_SECONDS` | `300` | Per-command timeout for package-suite matrix and suite commands. |
6364
| `E2E_RUBY_INSTALL_TIMEOUT_SECONDS` | `1800` | Timeout for installing the exact repository Ruby version from `.ruby-version`. |
6465

6566
Secrets still need to be configured in Bitrise.io.
6667

68+
| Secret | Purpose |
69+
|---|---|
70+
| `STOREFRONT_DOMAIN` | Required by `scripts/setup_storefront_env` for sample app builds. |
71+
| `STOREFRONT_ACCESS_TOKEN` | Required by `scripts/setup_storefront_env` for sample app builds. |
72+
6773
## Future secrets
6874

6975
Do not add BrowserStack credentials until the BrowserStack integration phase.
@@ -85,6 +91,10 @@ React Native iOS IPA generation is added in a later phase and will require Bitri
8591

8692
## Caching
8793

94+
React Native Android E2E builds use the released native Maven artifact versions declared by the React Native sample and module configuration. Do not set local native SDK override flags for these builds.
95+
96+
React Native Android E2E builds run on `linux-docker-android-22.04` with `g2.linux.large`. Their cache keys are prefixed with `rn-android-linux-` so Linux caches cannot restore macOS-built dependencies.
97+
8898
The pipeline uses Bitrise cache steps for key-based pnpm/CocoaPods/Gradle cache paths.
8999

90100
Do not add `activate-build-cache-for-xcode` or `activate-build-cache-for-gradle`; the Bitrise Build Cache add-on is disabled for Shopify Bitrise apps.

e2e/bitrise.yml

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ app:
1515
- E2E_BROWSERSTACK_TIMEOUT_SECONDS: "1800"
1616
- E2E_BROWSERSTACK_POLL_SECONDS: "30"
1717
- E2E_IOS_EXPORT_METHOD: development
18+
- E2E_ANDROID_COMMAND_TIMEOUT_SECONDS: "1800"
1819
- E2E_PACKAGE_COMMAND_TIMEOUT_SECONDS: "300"
1920
- E2E_RUBY_INSTALL_TIMEOUT_SECONDS: "1800"
2021

@@ -100,28 +101,49 @@ workflows:
100101
platforms/react-native/sample/ios/Pods
101102
102103
e2e-build-react-native-android:
104+
meta:
105+
bitrise.io:
106+
stack: linux-docker-android-22.04
107+
machine_type_id: g2.linux.large
103108
steps:
104109
- git-clone@8: {}
105110
- restore-cache@3:
106111
inputs:
107112
- key: |-
108-
rn-android-{{ checksum "platforms/react-native/pnpm-lock.yaml" }}-{{ checksum "platforms/react-native/sample/android/**/*.gradle*" }}
113+
rn-android-linux-{{ checksum "platforms/react-native/pnpm-lock.yaml" }}-{{ checksum "platforms/react-native/sample/android/**/*.gradle*" }}
109114
- script@1:
110-
title: Create React Native Android artifact placeholder
115+
title: Build React Native Android APK artifact
111116
inputs:
112117
- content: |-
113118
set -euo pipefail
114-
mkdir -p "$BITRISE_DEPLOY_DIR/e2e"
115-
echo "Phase 2 placeholder for React Native Android APK" > "$BITRISE_DEPLOY_DIR/e2e/react-native-android.apk"
116-
envman add --key E2E_REACT_NATIVE_ANDROID_APP_PATH --value "$BITRISE_DEPLOY_DIR/e2e/react-native-android.apk"
119+
source e2e/scripts/bitrise_ci_helpers
120+
e2e_log "Enabling Corepack"
121+
corepack enable
122+
e2e_log "Checking storefront configuration secrets"
123+
: "${STOREFRONT_DOMAIN:?STOREFRONT_DOMAIN is required. Check https://app.bitrise.io/app/f51f9054-053e-40f1-81e9-ae727567ae76/workflow_editor#!/secrets and enable Expose for pull requests.}"
124+
: "${STOREFRONT_ACCESS_TOKEN:?STOREFRONT_ACCESS_TOKEN is required. Check https://app.bitrise.io/app/f51f9054-053e-40f1-81e9-ae727567ae76/workflow_editor#!/secrets and enable Expose for pull requests.}"
125+
e2e_log "Configuring storefront environment"
126+
./scripts/setup_storefront_env --skip-optional-prompts
127+
e2e_log "Installing React Native dependencies"
128+
cd platforms/react-native
129+
e2e_run_with_timeout "${E2E_ANDROID_COMMAND_TIMEOUT_SECONDS:-1800}" pnpm install --frozen-lockfile
130+
e2e_log "Building React Native module"
131+
e2e_run_with_timeout "${E2E_ANDROID_COMMAND_TIMEOUT_SECONDS:-1800}" pnpm module build
132+
e2e_log "Building Android E2E APK"
133+
cd sample/android
134+
e2e_run_with_timeout "${E2E_ANDROID_COMMAND_TIMEOUT_SECONDS:-1800}" ./gradlew assembleE2e --no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a
135+
android_apk="$PWD/app/build/outputs/apk/e2e/app-e2e.apk"
136+
test -f "$android_apk"
137+
e2e_log "Publishing Android APK path"
138+
envman add --key E2E_REACT_NATIVE_ANDROID_APP_PATH --value "$android_apk"
117139
- deploy-to-bitrise-io@2:
118140
inputs:
119141
- pipeline_intermediate_files: |-
120142
$E2E_REACT_NATIVE_ANDROID_APP_PATH:E2E_REACT_NATIVE_ANDROID_APP_PATH
121143
- save-cache@1:
122144
inputs:
123145
- key: |-
124-
rn-android-{{ checksum "platforms/react-native/pnpm-lock.yaml" }}-{{ checksum "platforms/react-native/sample/android/**/*.gradle*" }}
146+
rn-android-linux-{{ checksum "platforms/react-native/pnpm-lock.yaml" }}-{{ checksum "platforms/react-native/sample/android/**/*.gradle*" }}
125147
- paths: |-
126148
platforms/react-native/node_modules
127149
~/.gradle/caches

e2e/test/bitrise_pipeline_test.rb

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,62 @@ def test_dev_up_installs_bitrise_cli
138138
assert_includes packages, "bitrise"
139139
end
140140

141+
def test_react_native_android_workflow_uses_linux_resources
142+
workflow = load_bitrise_config.fetch("workflows").fetch("e2e-build-react-native-android")
143+
meta = workflow.fetch("meta").fetch("bitrise.io")
144+
cache_keys = workflow.fetch("steps").flat_map { |step| step.values.first.fetch("inputs", []) }.filter_map { |input| input["key"] }
145+
146+
assert_equal "linux-docker-android-22.04", meta.fetch("stack")
147+
assert_equal "g2.linux.large", meta.fetch("machine_type_id")
148+
assert cache_keys.all? { |key| key.start_with?("rn-android-linux-") }
149+
end
150+
151+
def test_react_native_android_sample_defines_metro_free_e2e_build_type
152+
gradle = File.read("platforms/react-native/sample/android/app/build.gradle")
153+
154+
assert_includes gradle, "e2e {"
155+
assert_includes gradle, "initWith release"
156+
assert_includes gradle, "matchingFallbacks = ['release']"
157+
assert_includes gradle, "signingConfig signingConfigs.debug"
158+
assert_includes gradle, "minifyEnabled false"
159+
end
160+
161+
def test_react_native_android_workflow_builds_real_apk_artifact
162+
script = workflow_script("e2e-build-react-native-android")
163+
164+
assert_equal "1800", app_env_values.fetch("E2E_ANDROID_COMMAND_TIMEOUT_SECONDS")
165+
assert_includes script, 'e2e_log "Checking storefront configuration secrets"'
166+
assert_includes script, 'STOREFRONT_DOMAIN is required'
167+
assert_includes script, 'STOREFRONT_ACCESS_TOKEN is required'
168+
assert_includes script, 'workflow_editor#!/secrets'
169+
assert_includes script, 'Expose for pull requests'
170+
assert_includes script, 'e2e_log "Configuring storefront environment"'
171+
assert_includes script, 'e2e_log "Installing React Native dependencies"'
172+
assert_includes script, 'e2e_log "Building React Native module"'
173+
assert_includes script, 'e2e_log "Building Android E2E APK"'
174+
assert_includes script, 'e2e_log "Publishing Android APK path"'
175+
assert_includes script, "corepack enable"
176+
assert_includes script, "cd platforms/react-native"
177+
assert_command_order script, "cd platforms/react-native", "pnpm install --frozen-lockfile"
178+
assert_includes script, "pnpm install --frozen-lockfile"
179+
assert_includes script, "./scripts/setup_storefront_env --skip-optional-prompts"
180+
assert_includes script, 'e2e_run_with_timeout "${E2E_ANDROID_COMMAND_TIMEOUT_SECONDS:-1800}" pnpm install --frozen-lockfile'
181+
assert_includes script, 'e2e_run_with_timeout "${E2E_ANDROID_COMMAND_TIMEOUT_SECONDS:-1800}" pnpm module build'
182+
assert_includes script, 'e2e_run_with_timeout "${E2E_ANDROID_COMMAND_TIMEOUT_SECONDS:-1800}" ./gradlew assembleE2e --no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a'
183+
assert_includes script, "app/build/outputs/apk/e2e/app-e2e.apk"
184+
refute_includes script, "assembleDebug"
185+
refute_includes script, "app-debug.apk"
186+
refute_includes script, "Phase 2 placeholder for React Native Android APK"
187+
end
188+
189+
def test_react_native_android_workflow_does_not_use_local_native_sdk_overrides
190+
script = workflow_script("e2e-build-react-native-android")
191+
192+
refute_includes script, "USE_LOCAL_SDK"
193+
refute_includes script, "publish_android_snapshot"
194+
refute_includes script, "--local"
195+
end
196+
141197
def test_bitrise_setup_docs_exist
142198
assert File.exist?("e2e/BITRISE.md")
143199
end
@@ -205,4 +261,13 @@ def assert_workflow_has_step(config, workflow, step_name)
205261
def cache_input(step, input_name)
206262
step.fetch("inputs", []).find { |input| input.key?(input_name) }&.fetch(input_name).to_s
207263
end
264+
265+
def assert_command_order(script, first_command, second_command)
266+
first_index = script.index(first_command)
267+
second_index = script.index(second_command)
268+
269+
assert first_index, "expected script to include #{first_command}"
270+
assert second_index, "expected script to include #{second_command}"
271+
assert_operator first_index, :<, second_index, "expected #{first_command} to run before #{second_command}"
272+
end
208273
end

platforms/react-native/sample/android/app/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ android {
136136
minifyEnabled true
137137
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
138138
}
139+
e2e {
140+
initWith release
141+
matchingFallbacks = ['release']
142+
signingConfig signingConfigs.debug
143+
minifyEnabled false
144+
}
139145
}
140146

141147
testOptions {

0 commit comments

Comments
 (0)