Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .cursor/rules/pr-creation-guidelines.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ Apply labels to enable automation and proper routing. Some labels can block merg
- **QA labels**:
- `needs-qa` (blocks merging until QA passes)
- `No QA Needed`
- `Run E2E Smoke`
- `Run Smoke E2E`
- `No E2E Smoke Needed`
- `Spot check on release build`
- **Blocking labels** (cannot merge while applied): `needs-qa`, `issues-found`, `blocked`, `DO-NOT-MERGE`
Expand Down
11 changes: 11 additions & 0 deletions .detoxrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ module.exports = {
device: 'ios.simulator',
app: 'ios.flask.release',
},
'ios.github_ci.main.release': {
device: 'ios.github_ci.simulator',
app: 'ios.debug',
},
'android.emu.debug': {
device: 'android.emulator',
app: 'android.debug',
Expand All @@ -74,6 +78,13 @@ module.exports = {
type: 'iPhone 15 Pro',
},
},
'ios.github_ci.simulator': {
type: 'ios.simulator',
device: {
type: 'iPhone 16 Pro',
os: 'iOS 18.6',
},
},
'android.bitrise.emulator': {
type: 'android.emulator',
device: {
Expand Down
3 changes: 3 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ self-hosted-runner:
- "gha-mmsdk-scale-set-ubuntu-22.04-amd64-large"
- "gha-mm-scale-set-ubuntu-22.04-amd64-large"
- "macos-15"
- "ghcr.io/cirruslabs/macos-runner:sequoia"
- "ghcr.io/cirruslabs/macos-runner:sequoia-xl"
- "low-priority"

# Configuration variables in array of strings defined in your repository or
# organization. `null` means disabling configuration variables check.
Expand Down
10 changes: 9 additions & 1 deletion .github/guidelines/LABELING_GUIDELINES.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,43 @@
# PR Labeling Guidelines

To maintain a consistent and efficient development workflow, we have set specific label guidelines for all pull requests (PRs). Please ensure you adhere to the following instructions:

### Mandatory team labels:

- **Internal Developers**: Every PR raised by an internal developer must include a label prefixed with `team-` (e.g., `team-mobile-ux`, `team-mobile-platform`, etc.). This indicates the respective internal team responsible for the PR.

- **External Contributors**: PRs submitted by contributors who are not part of the organization will be automatically labeled with `external-contributor`.

It's essential to ensure that PRs have the appropriate labels before they are considered for merging.

### Mandatory release version labels:

- **release-x.y.z**: This label is automatically added to a PR and its linked issues upon the PR's merge. The `x.y.z` in the label represents the version in which the changes from the PR will be included. This label is auto-generated by a [GitHub action](../workflows/add-release-label.yml), which determines the version by incrementing the minor version number from the most recent release. Manual intervention is only required in specific cases. For instance, if a merged PR is cherry-picked into a release branch, typically done to address Release Candidate (RC) bugs, the label would need to be manually updated to reflect the correct version.
- **regression-prod-x.y.z**: This label is automatically added to a bug report issue at the time of its creation. The `x.y.z` in the label represents the version in which the bug first appeared. This label is auto-generated by a [GitHub action](../workflows/check-template-and-add-labels.yml), which determines the `x.y.z` value based on the version information provided in the bug report issue form. Manual intervention is only necessary under certain circumstances. For example, if a user submits a bug report and specifies the version they are currently using, but the bug was actually introduced in a prior version, the label would need to be manually updated to accurately reflect the version where the bug originated.
- **regression-RC-x.y.z**: This label is manually added to a bug report issue by release engineers when a bug is found during release regerssion testing phase. The `x.y.z` in the label represents the release candidate (RC) version in which the bug's been discovered.

### Mandatory QA labels:

Every PR shall include one the QA labels below:

- **needs-qa**: If the PR includes a new features, complex testing steps, or large refactors, this label must be added to indicated PR requires a full manual QA prior being merged and added to a release.

- **Spot check on release build**: If PR does not require feature QA but needs non-automated verification, this label must be added. Furthermore, when that label is added, you must provide test scenarios in the description section, as well as add screenshots, and or recordings of what was tested.

To merge your PR one of the following QA labels are required:

- **QA Passed**: If the PR was labeled with `needs-qa`, this label must be added once QA has signed off
- **No QA Needed**: If the PR does not require any QA effort. This label should only be used in case you are updating a README or other files that does not impact the building or runtime of the application.
- **Run E2E Smoke**: This label will kick-off E2E testing and trigger a check to make sure the E2E tests pass.
- **Run Smoke E2E**: This label will kick-off E2E testing and trigger a check to make sure the E2E tests pass.
- **No E2E Smoke Needed**: This label will bypass the E2E smoke test gate and allow the PR to be merged.

### Optional labels:

- **regression-main**: This label can manually be added to a bug report issue at the time of its creation if the bug is present on the development branch, i.e., `main`, but is not yet released in production.
- **feature-branch-bug**: This label can manually be added to a bug report issue at the time of its creation if the bug is present on a feature branch, i.e., before merging to `main`.

### Labels prohibited when PR needs to be merged:

Any PR that includes one of the following labels can not be merged:

- **needs-qa**: The PR requires a full manual QA prior to being merged and added to a release.
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/build-android-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ jobs:
build-android-apks:
name: Build Android E2E APKs
runs-on: gha-mmsdk-scale-set-ubuntu-22.04-amd64-xl
env:
GRADLE_USER_HOME: /home/runner/_work/.gradle
outputs:
apk-uploaded: ${{ steps.upload-apk.outcome == 'success' }}
aab-uploaded: ${{ steps.upload-aab.outcome == 'success' }}
Expand All @@ -41,8 +43,8 @@ jobs:
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
/home/runner/_work/.gradle/caches
/home/runner/_work/.gradle/wrapper
android/.gradle
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
Expand Down
167 changes: 167 additions & 0 deletions .github/workflows/build-ios-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
name: Build iOS E2E Apps

on:
workflow_call:

permissions:
contents: read
id-token: write

jobs:
build-ios-apps:
name: Build iOS E2E Apps
runs-on: ghcr.io/cirruslabs/macos-runner:sequoia-xl
outputs:
artifacts-url: ${{ steps.set-artifacts-url.outputs.artifacts-url }}
app-uploaded: ${{ steps.upload-app.outcome == 'success' }}
sourcemap-uploaded: ${{ steps.upload-sourcemap.outcome == 'success' }}
env:
RCT_NO_LAUNCH_PACKAGER: 1
XCODE_BUILD_SETTINGS: "COMPILER_INDEX_STORE_ENABLE=NO"
GITHUB_CI: "true" # This ensures it's available during pod install
PLATFORM: ios
METAMASK_ENVIRONMENT: qa
METAMASK_BUILD_TYPE: main
IS_TEST: true
E2E: "true"
IGNORE_BOXLOGS_DEVELOPMENT: true
CI: "true"
NODE_OPTIONS: "--max-old-space-size=8192"
MM_UNIFIED_SWAPS_ENABLED: "true"
MM_BRIDGE_ENABLED: "true"
BRIDGE_USE_DEV_APIS: "true"
RAMP_INTERNAL_BUILD: "true"
SEEDLESS_ONBOARDING_ENABLED: "true"
MM_NOTIFICATIONS_UI_ENABLED: "true"
MM_SECURITY_ALERTS_API_ENABLED: "true"
FEATURES_ANNOUNCEMENTS_ACCESS_TOKEN: ${{ secrets.FEATURES_ANNOUNCEMENTS_ACCESS_TOKEN }}
FEATURES_ANNOUNCEMENTS_SPACE_ID: ${{ secrets.FEATURES_ANNOUNCEMENTS_SPACE_ID }}
SEGMENT_WRITE_KEY_QA: ${{ secrets.SEGMENT_WRITE_KEY_QA }}
SEGMENT_PROXY_URL_QA: ${{ secrets.SEGMENT_PROXY_URL_QA }}
SEGMENT_DELETE_API_SOURCE_ID_QA: ${{ secrets.SEGMENT_DELETE_API_SOURCE_ID_QA }}
SEGMENT_REGULATIONS_ENDPOINT_QA: ${{ secrets.SEGMENT_REGULATIONS_ENDPOINT_QA }}
MM_SENTRY_DSN_TEST: ${{ secrets.MM_SENTRY_DSN_TEST }}
MM_SENTRY_AUTH_TOKEN: ${{ secrets.MM_SENTRY_AUTH_TOKEN }}
MAIN_IOS_GOOGLE_CLIENT_ID_UAT: ${{ secrets.MAIN_IOS_GOOGLE_CLIENT_ID_UAT }}
MAIN_IOS_GOOGLE_REDIRECT_URI_UAT: ${{ secrets.MAIN_IOS_GOOGLE_REDIRECT_URI_UAT }}
MAIN_ANDROID_APPLE_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_APPLE_CLIENT_ID_UAT }}
MAIN_ANDROID_GOOGLE_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_GOOGLE_CLIENT_ID_UAT }}
MAIN_ANDROID_GOOGLE_SERVER_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_GOOGLE_SERVER_CLIENT_ID_UAT }}
GOOGLE_SERVICES_B64_IOS: ${{ secrets.GOOGLE_SERVICES_B64_IOS }}
GOOGLE_SERVICES_B64_ANDROID: ${{ secrets.GOOGLE_SERVICES_B64_ANDROID }}
MM_INFURA_PROJECT_ID: ${{ secrets.MM_INFURA_PROJECT_ID }}

steps:
# Get the source code from the repository
- name: Checkout repo
uses: actions/checkout@v4

- name: Cache Xcode derived data
uses: actions/cache@v4
with:
path: |
~/Library/Developer/Xcode/DerivedData
ios/build
key: ${{ runner.os }}-xcode-${{ hashFiles('ios/**/*.{h,m,mm,swift}', 'ios/**/Podfile.lock', 'yarn.lock') }}
restore-keys: |
${{ runner.os }}-xcode-

# Install Node.js, Xcode tools, and other iOS development dependencies
- name: Installing iOS Environment Setup
uses: MetaMask/github-tools/.github/actions/setup-e2e-env@self-hosted-runners-config
with:
platform: ios
setup-simulator: false

- name: Print iOS tool versions
run: |
echo "🔧 Node.js Version:"
node -v || echo "Node not found"
echo "🧶 Yarn Version:"
yarn -v || echo "Yarn not found"
echo "📦 CocoaPods Version:"
pod --version || echo "CocoaPods not found"
echo "🛠️ Xcode Path:"
xcode-select -p || echo "Xcode not found"
echo "📱 Booted iOS Simulators:"
xcrun simctl list | grep Booted || echo "No booted simulators found"
shell: bash

# Clean iOS plist files to prevent extended attribute issues
- name: Clean iOS plist files
run: find ios -name "*.plist" -exec xattr -c {} \;

# Run project setup and build the iOS E2E app for simulator
- name: Build iOS E2E App
run: |
echo "🚀 Setting up project..."
yarn setup:github-ci --build-ios --no-build-android
echo "🏗 Building iOS E2E App..."
export NODE_OPTIONS="--max-old-space-size=8192"
yarn build:ios:main:e2e
shell: bash
env:
PLATFORM: ios
METAMASK_ENVIRONMENT: main
METAMASK_BUILD_TYPE: main
IS_TEST: true
IS_SIM_BUILD: "true" # Ensures simulator build (.app) not device build (.ipa)
IGNORE_BOXLOGS_DEVELOPMENT: true
GITHUB_CI: "true"
CI: "true"

NODE_OPTIONS: "--max_old_space_size=4096" # Increase memory limit for build

SEGMENT_WRITE_KEY_QA: ${{ secrets.SEGMENT_WRITE_KEY_QA }}
SEGMENT_PROXY_URL_QA: ${{ secrets.SEGMENT_PROXY_URL_QA }}
SEGMENT_DELETE_API_SOURCE_ID_QA: ${{ secrets.SEGMENT_DELETE_API_SOURCE_ID_QA }}
SEGMENT_REGULATIONS_ENDPOINT_QA: ${{ secrets.SEGMENT_REGULATIONS_ENDPOINT_QA }}

MM_SENTRY_DSN_TEST: ${{ secrets.MM_SENTRY_DSN_TEST }}
MM_SENTRY_AUTH_TOKEN: ${{ secrets.MM_SENTRY_AUTH_TOKEN }}

MAIN_IOS_GOOGLE_CLIENT_ID_UAT: ${{ secrets.MAIN_IOS_GOOGLE_CLIENT_ID_UAT }}
MAIN_IOS_GOOGLE_REDIRECT_URI_UAT: ${{ secrets.MAIN_IOS_GOOGLE_REDIRECT_URI_UAT }}
MAIN_ANDROID_APPLE_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_APPLE_CLIENT_ID_UAT }}
MAIN_ANDROID_GOOGLE_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_GOOGLE_CLIENT_ID_UAT }}
MAIN_ANDROID_GOOGLE_SERVER_CLIENT_ID_UAT: ${{ secrets.MAIN_ANDROID_GOOGLE_SERVER_CLIENT_ID_UAT }}
GOOGLE_SERVICES_B64_IOS: ${{ secrets.GOOGLE_SERVICES_B64_IOS }}
GOOGLE_SERVICES_B64_ANDROID: ${{ secrets.GOOGLE_SERVICES_B64_ANDROID }}

# Upload the iOS .app file that works in simulators
- name: Upload iOS APP Artifact (Simulator)
id: upload-app
uses: actions/upload-artifact@v4
with:
name: MetaMask.app
path: ios/build/Build/Products/Release-iphonesimulator/MetaMask.app
retention-days: 7
if-no-files-found: error
continue-on-error: true

# Upload source map file for crash debugging and error tracking if exists
- name: Upload iOS Source Map
id: upload-sourcemap
uses: actions/upload-artifact@v4
with:
name: index.js.map
path: sourcemaps/ios/index.js.map
retention-days: 7
if-no-files-found: error
continue-on-error: true

# Generate artifact download URL and display upload status summary
- name: Set Artifacts URL and Status
id: set-artifacts-url
run: |
ARTIFACTS_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
echo "artifacts-url=${ARTIFACTS_URL}" >> "$GITHUB_OUTPUT"
echo "📦 Artifacts available at: ${ARTIFACTS_URL}"
echo ""
echo "Upload Status Summary:"
echo "- APP (Simulator): ${{ steps.upload-app.outcome }}"
echo "- Source Map: ${{ steps.upload-sourcemap.outcome }}"

env:
GITHUB_REPOSITORY: "${{ github.repository }}"
GITHUB_RUN_ID: "${{ github.run_id }}"
21 changes: 20 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: ci
on:
push:
branches: main
branches: [main]
pull_request:
merge_group:
types: [checks_requested]
Expand Down Expand Up @@ -175,6 +175,15 @@ jobs:
uses: ./.github/workflows/build-android-e2e.yml
secrets: inherit

build-ios-apps:
name: "Build iOS Apps"
if: ${{ github.event_name != 'merge_group' }}
permissions:
contents: read
id-token: write
uses: ./.github/workflows/build-ios-e2e.yml
secrets: inherit

e2e-smoke-tests-android:
name: "Android E2E Smoke Tests"
permissions:
Expand All @@ -184,6 +193,15 @@ jobs:
uses: ./.github/workflows/run-e2e-smoke-tests-android.yml
secrets: inherit

e2e-smoke-tests-ios:
name: "iOS E2E Smoke Tests"
permissions:
contents: read
id-token: write
needs: [build-ios-apps]
uses: ./.github/workflows/run-e2e-smoke-tests-ios.yml
secrets: inherit

js-bundle-size-check:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -348,6 +366,7 @@ jobs:
js-bundle-size-check,
sonar-cloud-quality-gate-status,
e2e-smoke-tests-android,
e2e-smoke-tests-ios,
]
outputs:
ALL_JOBS_PASSED: ${{ steps.jobs-passed-status.outputs.ALL_JOBS_PASSED }}
Expand Down
Loading
Loading