diff --git a/.github/actions/setup-maestro/action.yaml b/.github/actions/setup-maestro/action.yaml index 237100eda..bc6532956 100644 --- a/.github/actions/setup-maestro/action.yaml +++ b/.github/actions/setup-maestro/action.yaml @@ -1,21 +1,30 @@ name: "Setup Maestro" description: "Install and cache Maestro" +inputs: + maestro-version: + description: "Maestro CLI version" + required: false + default: "2.5.1" runs: using: "composite" steps: - name: "Cache Maestro" + id: cache-maestro uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 with: - path: $HOME/.local/bin/maestro - key: maestro-${{ runner.os }}-v1 - + path: ~/.local/bin/maestro + key: maestro-${{ runner.os }}-${{ inputs.maestro-version }} + - name: "Install Maestro" + if: steps.cache-maestro.outputs.cache-hit != 'true' shell: bash run: | - if [ ! -f "$HOME/.local/bin/maestro/bin/maestro" ]; then - mkdir -p $HOME/.local/bin - curl -L "https://github.com/mobile-dev-inc/maestro/releases/latest/download/maestro.zip" -o maestro.zip - unzip maestro.zip -d $HOME/.local/bin - chmod +x $HOME/.local/bin/maestro/bin/maestro - fi - echo "$HOME/.local/bin" >> $GITHUB_PATH \ No newline at end of file + mkdir -p "$HOME/.local/bin" + curl -fsSL "https://github.com/mobile-dev-inc/maestro/releases/download/cli-${{ inputs.maestro-version }}/maestro.zip" -o maestro.zip + unzip -q maestro.zip -d "$HOME/.local/bin" + chmod +x "$HOME/.local/bin/maestro/bin/maestro" + rm maestro.zip + + - name: "Add Maestro to PATH" + shell: bash + run: echo "$HOME/.local/bin/maestro/bin" >> "$GITHUB_PATH" \ No newline at end of file diff --git a/.github/actions/setup-tools/action.yaml b/.github/actions/setup-tools/action.yaml index 8ab61a4fd..714252484 100644 --- a/.github/actions/setup-tools/action.yaml +++ b/.github/actions/setup-tools/action.yaml @@ -11,12 +11,23 @@ outputs: runs: using: "composite" steps: - - name: "Setup Python and dependencies" - uses: ./.github/actions/setup-python + - name: "Setup Node" + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + with: + node-version-file: .nvmrc + package-manager-cache: false + + - name: "Setup Python for m2ee-tools" + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: "3.12" + cache: pip + cache-dependency-path: .github/scripts/m2ee-requirements.txt + + - name: "Install m2ee-tools Python dependencies" + shell: bash + run: pip install -r .github/scripts/m2ee-requirements.txt - - name: "Setup Node and dependencies" - uses: ./.github/actions/setup-node-with-cache - - name: "Setup Java 21" id: setup-java uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #v5.2.0 diff --git a/.github/scripts/m2ee-requirements.txt b/.github/scripts/m2ee-requirements.txt new file mode 100644 index 000000000..c32f2fd2a --- /dev/null +++ b/.github/scripts/m2ee-requirements.txt @@ -0,0 +1,2 @@ +PyYAML==6.0.3 +httplib2==0.31.2 diff --git a/.github/workflows/NativePipeline.yml b/.github/workflows/NativePipeline.yml index b7fc6e929..53f68fddd 100644 --- a/.github/workflows/NativePipeline.yml +++ b/.github/workflows/NativePipeline.yml @@ -475,7 +475,21 @@ jobs: run: pod install - name: "Build iOS app" working-directory: native-template/ios - run: xcodebuild -workspace NativeTemplate.xcworkspace -scheme nativeTemplate -configuration Debug -sdk iphonesimulator -derivedDataPath build ONLY_ACTIVE_ARCH=YES VALID_ARCHS="i386 x86_64" + run: | + set -o pipefail + xcodebuild \ + -workspace NativeTemplate.xcworkspace \ + -scheme nativeTemplate \ + -configuration Debug \ + -sdk iphonesimulator \ + -derivedDataPath build \ + -destination 'generic/platform=iOS Simulator' \ + -quiet \ + ONLY_ACTIVE_ARCH=YES \ + ARCHS=arm64 \ + EXCLUDED_ARCHS= \ + COMPILER_INDEX_STORE_ENABLE=NO \ + build - name: "Archive iOS app" uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7 with: @@ -537,6 +551,26 @@ jobs: echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm + - name: "AVD cache" + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-api35-google_apis-x86_64-pixel-v1 + - name: "Create AVD snapshot for cache" + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2.37.0 + with: + api-level: 35 + target: google_apis + arch: x86_64 + profile: pixel + force-avd-creation: false + emulator-options: "-no-window -gpu swiftshader_indirect -no-boot-anim -no-audio -memory 4096 -cores 4" + disable-animations: true + script: echo "Generated AVD snapshot for caching." - name: "Run android tests" uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2.37.0 with: @@ -544,14 +578,15 @@ jobs: target: google_apis arch: x86_64 profile: pixel - emulator-options: "-no-window -gpu swiftshader_indirect -no-boot-anim -no-snapshot -memory 4096 -cores 4" + force-avd-creation: false + emulator-options: "-no-window -gpu swiftshader_indirect -no-boot-anim -no-audio -no-snapshot-save -memory 4096 -cores 4" disable-animations: true script: | chmod +x maestro/helpers/prepare_android.sh chmod +x maestro/run_maestro_widget_tests.sh bash maestro/helpers/prepare_android.sh bash maestro/run_maestro_widget_tests.sh android "${{ matrix.widget }}" - + - name: Archive test results uses: ./.github/actions/archive-test-results with: @@ -703,6 +738,26 @@ jobs: echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm + - name: "AVD cache" + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-api35-google_apis-x86_64-pixel-v1 + - name: "Create AVD snapshot for cache" + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2.37.0 + with: + api-level: 35 + target: google_apis + arch: x86_64 + profile: pixel + force-avd-creation: false + emulator-options: "-no-window -gpu swiftshader_indirect -no-boot-anim -no-audio -memory 4096 -cores 4" + disable-animations: true + script: echo "Generated AVD snapshot for caching." - name: "Run android tests" uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2.37.0 with: @@ -710,7 +765,8 @@ jobs: target: google_apis arch: x86_64 profile: pixel - emulator-options: "-no-window -gpu swiftshader_indirect -no-boot-anim -no-snapshot -memory 4096 -cores 4" + force-avd-creation: false + emulator-options: "-no-window -gpu swiftshader_indirect -no-boot-anim -no-audio -no-snapshot-save -memory 4096 -cores 4" disable-animations: true script: | chmod +x maestro/helpers/prepare_android.sh diff --git a/configs/jsactions/rollup-plugin-collect-dependencies.mjs b/configs/jsactions/rollup-plugin-collect-dependencies.mjs index 1a6d4920d..b4f7c21b2 100644 --- a/configs/jsactions/rollup-plugin-collect-dependencies.mjs +++ b/configs/jsactions/rollup-plugin-collect-dependencies.mjs @@ -178,30 +178,40 @@ export async function copyJsModule(moduleSourcePath, to) { actualSourcePath = realpathSync(moduleSourcePath); } - cpSync(actualSourcePath, to, { - recursive: true, - dereference: true, // Follow symlinks and copy the actual files - filter: (src, dest) => { - const relativePath = src.replace(actualSourcePath, "").replace(/^[\\/]/, ""); - - // Skip certain directories - if (relativePath.match(/[\\/](android|ios|windows|mac|jest|github|gradle|__.*__|docs|example.*)[\\/]/)) { - return false; - } + try { + cpSync(actualSourcePath, to, { + recursive: true, + dereference: true, // Follow symlinks and copy the actual files + force: true, + errorOnExist: false, + filter: (src, dest) => { + const relativePath = src.replace(actualSourcePath, "").replace(/^[\\/]/, ""); + + // Skip certain directories + if (relativePath.match(/[\\/](android|ios|windows|mac|jest|github|gradle|__.*__|docs|example.*)[\\/]/)) { + return false; + } - // Skip certain file types - if (relativePath.match(/\.(config|setup)\.|\.podspec$|\.flow$/)) { - return false; - } + // Skip certain file types + if (relativePath.match(/\.(config|setup)\.|\.podspec$|\.flow$/)) { + return false; + } + + // Include LICENSE files + if (relativePath.match(/license/i)) { + return true; + } - // Include LICENSE files - if (relativePath.match(/license/i)) { return true; } - - return true; - } - }); + }); + } catch (err) { + // EEXIST can surface here when pnpm's symlinked node_modules layout causes cpSync's + // recursive walk to revisit the same realpath via different symlinks. Copies are + // idempotent (same source → same bytes), so treating this specific error as success + // is safe. Any other failure still propagates. + if (err?.code !== "EEXIST") throw err; + } } function getModuleName(modulePath) { diff --git a/package.json b/package.json index 96845820e..9acfea391 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "license": "Apache-2.0", "scripts": { - "prepare": "npx husky install && pnpm -r run prepare", + "prepare": "npx husky install", "postinstall": "pnpm -r run postinstall", "reinstall": "pnpm store prune && git clean -dfx && find . -type dir -name node_modules | xargs rm -rf && pnpm install && pnpm run postinstall", "prettier": "prettier --config \"./prettier.config.js\" --write \"**/*.{js,jsx,ts,tsx,scss,html,xml,yml,yaml}\"", diff --git a/packages/tools/piw-native-utils-internal/package.json b/packages/tools/piw-native-utils-internal/package.json index 90d677d1c..fa1a2bf46 100644 --- a/packages/tools/piw-native-utils-internal/package.json +++ b/packages/tools/piw-native-utils-internal/package.json @@ -17,7 +17,6 @@ "prebuild": "rimraf dist", "build": "tsc", "lint": "eslint --config ../../../.eslintrc.js --ext .jsx,.js,.ts,.tsx src/", - "prepare": "pnpm build", "postinstall": "pnpm build" }, "devDependencies": { diff --git a/packages/tools/piw-utils-internal/package.json b/packages/tools/piw-utils-internal/package.json index df868de37..7fdaa3997 100644 --- a/packages/tools/piw-utils-internal/package.json +++ b/packages/tools/piw-utils-internal/package.json @@ -17,7 +17,6 @@ "prebuild": "rimraf dist", "build": "tsc", "lint": "eslint --config ../../../.eslintrc.js --ext .jsx,.js,.ts,.tsx src/", - "prepare": "pnpm build", "test": "pluggable-widgets-tools test:unit:native", "postinstall": "pnpm build" },