Skip to content
Open
Show file tree
Hide file tree
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
16 changes: 9 additions & 7 deletions e2e/BITRISE.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ Duplicate in-progress PR pipelines are cancelled by Bitrise native Rolling build

Nightly pipelines ship the sample apps to the stores from the same E2E test storefront the PR pipeline uses, so they need no storefront configuration of their own.

| Pipeline | App | Destination |
| ------------------------------ | ---------------------- | ----------- |
| `nightly-swift-ios-testflight` | `CheckoutKitSwiftDemo` | TestFlight |
| Pipeline | App | Destination |
| ------------------------------------- | ---------------------------- | ----------- |
| `nightly-swift-ios-testflight` | `CheckoutKitSwiftDemo` | TestFlight |
| `nightly-react-native-ios-testflight` | `CheckoutKitReactNativeDemo` | TestFlight |

These pipelines are deliberately absent from `trigger_map`, so nothing starts them on a pull request. Create a daily **scheduled build** under **Project settings > Scheduled builds**, targeting `main` and selecting the pipeline. The schedule is the one part of this design that Bitrise keeps outside the repository.

Expand All @@ -76,17 +77,18 @@ The gate asks whether HEAD was committed inside `NIGHTLY_COMMIT_WINDOW`, which d

The build number is `$BITRISE_BUILD_NUMBER`, injected as an `xcodebuild` build-setting override. No committed file changes value, so nothing has to be bumped by hand and no two uploads can collide.

This only works because the sample's XcodeGen spec binds `CFBundleVersion` to `$(CURRENT_PROJECT_VERSION)`. Without that binding XcodeGen writes the setting's current value into the plist as a literal, an override is silently discarded, and App Store Connect rejects every upload after the first. `e2e/scripts/build_swift_ios_testflight` re-reads the archived plist and fails the build if the number did not land.
This only works because each sample binds `CFBundleVersion` to `$(CURRENT_PROJECT_VERSION)` rather than to a literal. `CheckoutKitSwiftDemo` binds it in its XcodeGen spec, and `CheckoutKitReactNativeDemo` binds it in its committed `Info.plist`. Without that binding the literal wins, the override is silently discarded, and App Store Connect rejects every upload after the first. Both build scripts call `e2e_assert_archived_build_number`, which re-reads the archived plist and fails the build if the number did not land.

### Signing

The nightly iOS build passes its signing arguments explicitly and calls `e2e_reject_ios_signing_overrides` first, because each `E2E_IOS_*` variable in the Code signing table below wins over the matching argument. Do not expose any of them to a nightly workflow; a release build would silently fall back to development signing.

Each nightly iOS workflow names its profile in `NIGHTLY_IOS_PROVISIONING_PROFILE_SPECIFIER`, under that workflow's `envs` in `e2e/bitrise.yml`. The build script has no default and exits if the variable is missing, so a renamed profile fails the build immediately instead of signing with the wrong identity. The variable is workflow-scoped rather than an `app.envs` entry, because each app needs its own profile.

| App | Profile | Export method |
| ---------------------- | ---------------------------------------------- | ------------------- |
| `CheckoutKitSwiftDemo` | `PP-Bitrise-com.shopify.checkoutkit.swiftdemo` | `app-store-connect` |
| App | Profile | Export method |
| ---------------------------- | ---------------------------------------------------- | ------------------- |
| `CheckoutKitSwiftDemo` | `PP-Bitrise-com.shopify.checkoutkit.swiftdemo` | `app-store-connect` |
| `CheckoutKitReactNativeDemo` | `PP-Bitrise-com.shopify.checkoutkit.reactnativedemo` | `app-store-connect` |

Required Bitrise code signing assets, beyond the E2E development assets:

Expand Down
37 changes: 37 additions & 0 deletions e2e/bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ pipelines:
depends_on:
- nightly-decide-should-build

nightly-react-native-ios-testflight:
workflows:
nightly-decide-should-build: {}
nightly-release-react-native-ios:
run_if:
expression: '{{ enveq "NIGHTLY_SHOULD_BUILD" "true" }}'
depends_on:
- nightly-decide-should-build

step_bundles:
install-node-modules:
steps:
Expand Down Expand Up @@ -482,3 +491,31 @@ workflows:
- ipa_path: $NIGHTLY_SWIFT_IOS_IPA_PATH
- deploy-to-bitrise-io@2:
is_always_run: false

nightly-release-react-native-ios:
meta:
bitrise.io:
stack: *macos_stack
machine_type_id: g2.mac.4large
envs:
- NIGHTLY_IOS_PROVISIONING_PROFILE_SPECIFIER: PP-Bitrise-com.shopify.checkoutkit.reactnativedemo
steps:
- git-clone@8: {}
- certificate-and-profile-installer@1: {}
- bundle::install-node-modules: {}
- bundle::install-ruby-gems: {}
- bundle::install-cocoapods: {}
- script@1:
title: Build the React Native iOS App Store IPA
timeout: 5400
no_output_timeout: 1800
inputs:
- content: |-
set -euo pipefail
e2e/scripts/build_react_native_ios_testflight
- deploy-to-itunesconnect-application-loader@2:
inputs:
- connection: automatic
- ipa_path: $NIGHTLY_REACT_NATIVE_IOS_IPA_PATH
- deploy-to-bitrise-io@2:
is_always_run: false
39 changes: 39 additions & 0 deletions e2e/scripts/build_react_native_ios_testflight
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash

set -euo pipefail

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$script_dir/bitrise_ci_helpers"
source "$script_dir/ios_build_helpers"

: "${BITRISE_BUILD_NUMBER:?BITRISE_BUILD_NUMBER is required. App Store Connect rejects a build number it has already seen.}"
: "${NIGHTLY_IOS_PROVISIONING_PROFILE_SPECIFIER:?NIGHTLY_IOS_PROVISIONING_PROFILE_SPECIFIER is required. Set it to the name of the App Store provisioning profile installed on the Bitrise app.}"

e2e_reject_ios_signing_overrides

e2e_configure_storefront

app_name="CheckoutKitReactNativeDemo"
archive_path="$(e2e_deploy_dir)/${app_name}.xcarchive"

cd platforms/react-native/sample/ios

e2e_build_ios_device_ipa \
--workspace "${app_name}.xcworkspace" \
--scheme "$app_name" \
--app-name "$app_name" \
--bundle-id com.shopify.checkoutkit.reactnativedemo \
--code-sign-identity "Apple Distribution" \
--export-method app-store-connect \
--profile-specifier "$NIGHTLY_IOS_PROVISIONING_PROFILE_SPECIFIER" \
--archive-path "$archive_path" \
--build-setting "CURRENT_PROJECT_VERSION=$BITRISE_BUILD_NUMBER"

e2e_assert_archived_build_number \
"$archive_path" \
"$app_name" \
"$BITRISE_BUILD_NUMBER" \
"platforms/react-native/sample/ios/${app_name}/Info.plist"

e2e_log "Publishing React Native iOS IPA path"
envman add --key NIGHTLY_REACT_NATIVE_IOS_IPA_PATH --value "$E2E_IOS_PROVISIONED_IPA"
15 changes: 5 additions & 10 deletions e2e/scripts/build_swift_ios_testflight
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,11 @@ e2e_build_ios_device_ipa \
--archive-path "$archive_path" \
--build-setting "CURRENT_PROJECT_VERSION=$BITRISE_BUILD_NUMBER"

# A wrong build number is otherwise only reported by App Store Connect, long after
# this build has been marked green.
e2e_log "Verifying the archived build number"
archived_info_plist="$archive_path/Products/Applications/${app_name}.app/Info.plist"
archived_build_number="$(plutil -extract CFBundleVersion raw -o - "$archived_info_plist")"
if [ "$archived_build_number" != "$BITRISE_BUILD_NUMBER" ]; then
e2e_log "Archived CFBundleVersion is ${archived_build_number}, expected ${BITRISE_BUILD_NUMBER}"
echo "Check that CFBundleVersion in ${app_name}/project.yml still reads \$(CURRENT_PROJECT_VERSION)." >&2
exit 1
fi
e2e_assert_archived_build_number \
"$archive_path" \
"$app_name" \
"$BITRISE_BUILD_NUMBER" \
"platforms/swift/Samples/${app_name}/project.yml"

e2e_log "Publishing Swift iOS IPA path"
envman add --key NIGHTLY_SWIFT_IOS_IPA_PATH --value "$E2E_IOS_PROVISIONED_IPA"
19 changes: 19 additions & 0 deletions e2e/scripts/ios_build_helpers
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,22 @@ PLIST

E2E_IOS_PROVISIONED_IPA="$provisioned_ipa"
}

# A wrong build number is otherwise only reported by the store, long after this
# build has been marked green.
e2e_assert_archived_build_number() {
local archive_path="$1"
local app_name="$2"
local expected="$3"
local version_source="$4"

e2e_log "Verifying the archived build number"
local info_plist="$archive_path/Products/Applications/${app_name}.app/Info.plist"
local archived
archived="$(plutil -extract CFBundleVersion raw -o - "$info_plist")"
if [ "$archived" != "$expected" ]; then
e2e_log "Archived CFBundleVersion is ${archived}, expected ${expected}"
echo "Check that CFBundleVersion in ${version_source} still reads \$(CURRENT_PROJECT_VERSION)." >&2
return 1
fi
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
</array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>rn</string>
Expand Down
Loading