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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ app/core/Engine/controllers/remote-feature-flag-controller/ @MetaMask/mobile-pla
app/core/DeeplinkManager @MetaMask/mobile-platform
scripts/build.sh @MetaMask/mobile-platform
fingerprint.config.js @MetaMask/mobile-platform
.github/workflows/push-eas-update.yml @MetaMask/mobile-admins
scripts/update-expo-channel.js @MetaMask/mobile-admins
certs/certificate.pem @MetaMask/mobile-admins
ios/fastlane/ @MetaMask/mobile-admins
Expand Down
22 changes: 22 additions & 0 deletions .github/actions/restore-node-modules-permissions/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: 'Restore Node Modules Executable Permissions'
description: 'Restores executable permissions for node_modules binaries after artifact download'

inputs:
working-directory:
description: 'Working directory where node_modules is located'
required: false
default: '.'

runs:
using: 'composite'
steps:
- name: Restore executable permissions
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
echo "🔧 Restoring executable permissions..."
find node_modules/.bin -type f -exec chmod +x {} \; 2>/dev/null || true
find node_modules -type f -name "*.node" -exec chmod +x {} \; 2>/dev/null || true
find node_modules -path "*/bin/*" -type f -exec chmod +x {} \; 2>/dev/null || true
find node_modules -path "*/sdks/*" -type f -exec chmod +x {} \; 2>/dev/null || true
echo "✅ Permissions restored"
38 changes: 38 additions & 0 deletions .github/actions/validate-artifact-compatibility/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: 'Validate Artifact Compatibility'
description: 'Validates that the artifact was built with compatible Node version and OS'

inputs:
artifact-name:
description: 'The actual artifact name to validate'
required: true
artifact-prefix:
description: 'The expected artifact prefix (e.g., node-modules-eas-update-pr or node-modules-eas-update-base)'
required: true
validation-context:
description: 'Description of what is being validated (e.g., "PR commit", "base branch")'
required: false
default: 'artifact'

runs:
using: 'composite'
steps:
- name: Validate artifact compatibility
shell: bash
run: |
NODE_VERSION=$(node --version | sed 's/v//')
OS_NAME=$(echo "$RUNNER_OS" | tr '[:upper:]' '[:lower:]')
EXPECTED_ARTIFACT="${{ inputs.artifact-prefix }}-node${NODE_VERSION}-${OS_NAME}"

echo "🔍 Validating ${{ inputs.validation-context }} artifact compatibility..."
echo " Expected artifact: $EXPECTED_ARTIFACT"
echo " Actual artifact: ${{ inputs.artifact-name }}"

if [ "$EXPECTED_ARTIFACT" != "${{ inputs.artifact-name }}" ]; then
echo "::error title=Artifact Incompatibility::Node version or OS mismatch detected!"
echo "❌ The node_modules artifact was built with different Node version or OS"
echo " This could cause issues with native node modules"
echo " Expected: $EXPECTED_ARTIFACT"
echo " Actual: ${{ inputs.artifact-name }}"
exit 1
fi
echo "✅ ${{ inputs.validation-context }} artifact compatibility validated"
130 changes: 108 additions & 22 deletions .github/workflows/push-eas-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
required: true
type: string
base_branch:
description: 'Base branch ref to compare fingerprints against (e.g., main)'
description: 'Base ref to compare fingerprints against (branch name like "main" or tag name like "v7.61.6")'
required: true
type: string
message:
Expand Down Expand Up @@ -41,13 +41,43 @@ env:
TARGET_CHANNEL: ${{ inputs.channel }}

jobs:
setup-dependencies:
name: Setup Dependencies (PR)
needs:
- validate-pr
uses: ./.github/workflows/setup-node-modules.yml
with:
ref: ${{ inputs.commit_hash }}
fetch-depth: 0
upload-artifact: true
artifact-name: node-modules-eas-update-pr
artifact-retention-days: 1

setup-dependencies-base:
name: Setup Dependencies (Base)
needs:
- validate-pr
uses: ./.github/workflows/setup-node-modules.yml
with:
ref: ${{ inputs.base_branch }}
fetch-depth: 0
upload-artifact: true
artifact-name: node-modules-eas-update-base
artifact-retention-days: 1

fingerprint-comparison:
name: Compare Expo Fingerprints
needs:
- setup-dependencies
- setup-dependencies-base
runs-on: ubuntu-latest
outputs:
branch_fingerprint: ${{ steps.branch_fingerprint.outputs.fingerprint }}
main_fingerprint: ${{ steps.main_fingerprint.outputs.fingerprint }}
fingerprints_equal: ${{ steps.compare.outputs.equal }}
env:
PR_ARTIFACT_NAME: ${{ needs.setup-dependencies.outputs.artifact-name }}
BASE_ARTIFACT_NAME: ${{ needs.setup-dependencies-base.outputs.artifact-name }}
steps:
- name: Checkout target commit
uses: actions/checkout@v4
Expand All @@ -67,24 +97,59 @@ jobs:
with:
node-version: '20'

- name: Install dependencies (workflow branch)
- name: Validate artifact compatibility (PR commit)
Comment thread
sethkfman marked this conversation as resolved.
uses: ./.github/actions/validate-artifact-compatibility
with:
artifact-name: ${{ env.PR_ARTIFACT_NAME }}
artifact-prefix: node-modules-eas-update-pr
validation-context: PR commit

- name: Download node_modules artifact (PR commit)
uses: actions/download-artifact@v4
with:
name: ${{ env.PR_ARTIFACT_NAME }}

- name: Restore executable permissions
Comment thread
sethkfman marked this conversation as resolved.
uses: ./.github/actions/restore-node-modules-permissions

- name: Verify downloaded artifacts
run: |
echo "📦 Installing dependencies for current branch..."
yarn install --immutable
echo "✅ Verifying downloaded artifacts..."
if [ ! -d "node_modules" ]; then
echo "❌ node_modules directory not found"
exit 1
fi
if [ ! -f "app/core/InpageBridgeWeb3.js" ]; then
echo "❌ InpageBridgeWeb3.js not found in artifact"
exit 1
fi
echo "✅ Artifacts verified"

- name: Generate fingerprint (workflow branch)
- name: Generate fingerprint (target commit)
id: branch_fingerprint
run: |
echo "🧬 Generating fingerprint for current branch..."
FINGERPRINT=$(yarn fingerprint:generate)
echo "fingerprint=$FINGERPRINT" >> "$GITHUB_OUTPUT"
echo "Target PR fingerprint: $FINGERPRINT"

- name: Install dependencies (base branch)
working-directory: main
run: |
echo "📦 Installing dependencies for base branch snapshot (${BASE_BRANCH_REF})..."
yarn install --immutable
- name: Validate artifact compatibility (base branch)
Comment thread
sethkfman marked this conversation as resolved.
uses: ./.github/actions/validate-artifact-compatibility
with:
artifact-name: ${{ env.BASE_ARTIFACT_NAME }}
artifact-prefix: node-modules-eas-update-base
validation-context: base branch

- name: Download node_modules artifact (base branch)
uses: actions/download-artifact@v4
with:
name: ${{ env.BASE_ARTIFACT_NAME }}
path: main
Comment thread
cursor[bot] marked this conversation as resolved.

- name: Restore executable permissions (base branch)
Comment thread
sethkfman marked this conversation as resolved.
uses: ./.github/actions/restore-node-modules-permissions
with:
working-directory: main

- name: Generate fingerprint (base branch)
id: main_fingerprint
Expand Down Expand Up @@ -163,10 +228,10 @@ jobs:
if: ${{ needs.fingerprint-comparison.outputs.fingerprints_equal == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Await approval from mobile platform team
- name: Await approval from mobile release team
uses: op5dev/require-team-approval@dfd7b8b9a88bf82a955c103f7e19642b0411aecd
with:
team: mobile-platform
team: release-team
pr-number: ${{ needs.validate-pr.outputs.pr_number }}
token: ${{ secrets.METAMASK_MOBILE_ORG_READ_TOKEN }}

Expand All @@ -178,10 +243,12 @@ jobs:
- fingerprint-comparison
- approval
- validate-pr
- setup-dependencies
if: >
needs.fingerprint-comparison.outputs.fingerprints_equal == 'true' &&
needs.approval.result == 'success'
env:
ARTIFACT_NAME: ${{ needs.setup-dependencies.outputs.artifact-name }}
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
EXPO_PROJECT_ID: ${{ secrets.EXPO_PROJECT_ID }}
EXPO_CHANNEL: ${{ vars.EXPO_CHANNEL }}
Expand Down Expand Up @@ -240,6 +307,35 @@ jobs:
with:
node-version: '20'

- name: Validate artifact compatibility
Comment thread
sethkfman marked this conversation as resolved.
uses: ./.github/actions/validate-artifact-compatibility
with:
artifact-name: ${{ env.ARTIFACT_NAME }}
artifact-prefix: node-modules-eas-update-pr
validation-context: artifact

- name: Download node_modules artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.ARTIFACT_NAME }}

- name: Restore executable permissions
Comment thread
sethkfman marked this conversation as resolved.
uses: ./.github/actions/restore-node-modules-permissions

- name: Verify downloaded artifacts
run: |
echo "✅ Verifying downloaded artifacts..."
if [ ! -d "node_modules" ]; then
echo "❌ node_modules directory not found"
exit 1
fi
if [ ! -f "app/core/InpageBridgeWeb3.js" ]; then
echo "❌ InpageBridgeWeb3.js not found in artifact"
exit 1
fi
echo "📦 node_modules size: $(du -sh node_modules | cut -f1)"
echo "✅ Artifacts verified"

- name: Determine signing secret name
shell: bash
env:
Expand Down Expand Up @@ -286,16 +382,6 @@ jobs:
echo "✅ Set secret for key: $key"
done

- name: Install dependencies
run: |
echo "📦 Installing dependencies..."
yarn install --immutable

- name: Setup project
run: |
echo "🔧 Running setup for GitHub CI..."
yarn setup:github-ci

- name: Display configuration
run: |
TARGET_RUNTIME_VERSION=$(node -p "require('./package.json').version")
Expand Down
123 changes: 123 additions & 0 deletions .github/workflows/setup-node-modules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Reusable workflow for setting up node_modules
# This workflow installs dependencies and runs the project setup, then uploads
# the prepared node_modules as an artifact for consumption by other workflows.

name: Setup Node Modules

on:
workflow_call:
inputs:
ref:
description: 'Git ref to checkout (e.g., refs/pull/123/head or branch name)'
required: false
type: string
default: ''
fetch-depth:
description: 'Number of commits to fetch (0 for all history)'
required: false
type: number
default: 1
upload-artifact:
description: 'Whether to upload node_modules as an artifact'
required: false
type: boolean
default: true
artifact-name:
description: 'Name of the artifact to upload'
required: false
type: string
default: 'node-modules'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we can change the name of the node modules artifcact to include the node version and the OS name. We should pick those from the environment itself.

That way we can check it on the push-eas-update workflow if those are the same. That would prevent any undesired native (node native) behavior from happening

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is done below when we do name: Set artifact name with node version and OS

artifact-retention-days:
description: 'Number of days to retain the artifact'
required: false
type: number
default: 1
outputs:
artifact-name:
description: 'The actual artifact name used (includes node version and OS)'
value: ${{ jobs.setup.outputs.artifact-name }}

permissions:
contents: read

jobs:
setup:
name: Setup Node Modules
runs-on: ubuntu-latest
outputs:
artifact-name: ${{ steps.set-artifact-name.outputs.artifact-name }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
fetch-depth: ${{ inputs.fetch-depth }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Set artifact name with node version and OS
id: set-artifact-name
run: |
NODE_VERSION=$(node --version | sed 's/v//')
OS_NAME=$(echo "$RUNNER_OS" | tr '[:upper:]' '[:lower:]')
ARTIFACT_NAME="${{ inputs.artifact-name }}-node${NODE_VERSION}-${OS_NAME}"
echo "artifact-name=$ARTIFACT_NAME" >> "$GITHUB_OUTPUT"
echo "📦 Artifact name: $ARTIFACT_NAME"

- name: Install dependencies
run: |
echo "📦 Installing dependencies..."
yarn install --immutable

- name: Setup project
run: |
echo "🔧 Running setup for GitHub CI..."
yarn setup:github-ci

- name: Verify setup completed
run: |
echo "✅ Verifying setup artifacts..."
# Check that critical setup artifacts exist
if [ ! -d "node_modules" ]; then
echo "❌ node_modules directory not found"
exit 1
fi
if [ ! -f "app/util/termsOfUse/termsOfUseContent.ts" ]; then
echo "❌ Terms of Use content not generated"
exit 1
fi
if [ ! -f "app/core/InpageBridgeWeb3.js" ]; then
echo "❌ InpageBridgeWeb3.js not generated"
exit 1
fi
echo "🔍 Checking yarn setup..."
echo " Node version: $(node --version)"
echo " Yarn version: $(yarn --version)"
echo " Corepack version: $(corepack --version)"
echo "✅ Setup verification passed"

- name: Debug - List .yarn contents
run: |
echo "📂 Contents of .yarn directory:"
ls -la .yarn/ || echo "No .yarn directory"
echo "📊 .yarn size: $(du -sh .yarn 2>/dev/null || echo 'N/A')"
echo "📄 install-state.gz exists: $(test -f .yarn/install-state.gz && echo 'yes' || echo 'no')"
echo "📁 cache dir exists: $(test -d .yarn/cache && echo 'yes' || echo 'no')"

- name: Upload node_modules artifact
if: inputs.upload-artifact
uses: actions/upload-artifact@v4.5.0
with:
name: ${{ steps.set-artifact-name.outputs.artifact-name }}
path: |
node_modules
app/util/termsOfUse/termsOfUseContent.ts
app/core/InpageBridgeWeb3.js
scripts/inpage-bridge/dist
Comment thread
cursor[bot] marked this conversation as resolved.
retention-days: ${{ inputs.artifact-retention-days }}
compression-level: 1
if-no-files-found: warn
Comment thread
weitingsun marked this conversation as resolved.
include-hidden-files: true
Loading