name: NodeShiftMusic iOS Build on: push: branches: [main, master] workflow_dispatch: jobs: build-ipa: name: Build Unsigned IPA runs-on: macos-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node 20 uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: Install dependencies run: | npm cache clean --force npm install --legacy-peer-deps - name: Patch react-native-track-player run: | node -e " const fs = require('fs'); const path = require('path'); const pkg = 'node_modules/react-native-track-player'; const srcDir = path.join(pkg, 'lib', 'src'); const target = path.join(srcDir, 'trackPlayer.js'); // List lib/src contents console.log('lib/src/ files:'); if (fs.existsSync(srcDir)) { fs.readdirSync(srcDir).forEach(f => console.log(' ', f)); } if (fs.existsSync(target)) { console.log('Already exists'); process.exit(0); } // Try web version const webVer = path.join(pkg, 'lib', 'web', 'trackPlayer.js'); if (fs.existsSync(webVer)) { fs.copyFileSync(webVer, target); console.log('Copied from lib/web/trackPlayer.js'); process.exit(0); } // Create re-export shim — forwards to NativeModules const shim = [ '\"use strict\";', 'Object.defineProperty(exports, \"__esModule\", { value: true });', 'const react_native_1 = require(\"react-native\");', 'const NTP = react_native_1.NativeModules.TrackPlayer || {};', 'const TrackPlayer = {', ' setupPlayer: (o) => NTP.setupPlayer(o),', ' add: (t, b) => NTP.add(t, b),', ' play: () => NTP.play(),', ' pause: () => NTP.pause(),', ' stop: () => NTP.stop(),', ' reset: () => NTP.reset(),', ' seekTo: (s) => NTP.seekTo(s),', ' skipToNext: () => NTP.skipToNext(),', ' skipToPrevious: () => NTP.skipToPrevious(),', ' getPlaybackState: () => NTP.getState ? NTP.getState() : Promise.resolve({ state: 0 }),', ' updateOptions: (o) => NTP.updateOptions ? NTP.updateOptions(o) : Promise.resolve(),', ' updateNowPlayingMetadata: (m) => NTP.updateNowPlayingMetadata ? NTP.updateNowPlayingMetadata(m) : Promise.resolve(),', '};', 'exports.default = TrackPlayer;', 'Object.assign(exports, TrackPlayer);', ].join('\n'); fs.mkdirSync(srcDir, { recursive: true }); fs.writeFileSync(target, shim); console.log('Created NativeModules shim trackPlayer.js'); " - name: Install CocoaPods run: sudo gem install cocoapods --no-document - name: Expo prebuild env: EXPO_NO_DOTENV: 1 run: npx expo prebuild --platform ios --clean - name: Install Pods working-directory: ios run: pod install --repo-update - name: Find workspace & scheme id: xcode run: | WS=$(find ios -name "*.xcworkspace" -maxdepth 2 | head -1) SCHEME=$(basename "$WS" .xcworkspace) echo "workspace=$WS" >> $GITHUB_OUTPUT echo "scheme=$SCHEME" >> $GITHUB_OUTPUT echo "Workspace: $WS | Scheme: $SCHEME" - name: Build unsigned archive run: | xcodebuild archive \ -workspace "${{ steps.xcode.outputs.workspace }}" \ -scheme "${{ steps.xcode.outputs.scheme }}" \ -configuration Release \ -sdk iphoneos \ -archivePath "$RUNNER_TEMP/NodeShiftMusic.xcarchive" \ CODE_SIGNING_REQUIRED=NO \ CODE_SIGN_IDENTITY="" \ CODE_SIGNING_ALLOWED=NO \ ENABLE_BITCODE=NO \ 2>&1 | xcpretty || true - name: Package IPA run: | APPS="$RUNNER_TEMP/NodeShiftMusic.xcarchive/Products/Applications" mkdir -p Payload cp -r "$APPS/"*.app Payload/ zip -qr NodeShiftMusic-unsigned.ipa Payload rm -rf Payload echo "IPA size: $(du -sh NodeShiftMusic-unsigned.ipa | cut -f1)" - name: Upload IPA uses: actions/upload-artifact@v4 with: name: NodeShiftMusic-unsigned path: NodeShiftMusic-unsigned.ipa retention-days: 90 - name: Summary run: | echo "## NodeShiftMusic Build" >> $GITHUB_STEP_SUMMARY echo "Branch: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY echo "Commit: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY if [ -f NodeShiftMusic-unsigned.ipa ]; then echo "IPA: $(du -sh NodeShiftMusic-unsigned.ipa | cut -f1)" >> $GITHUB_STEP_SUMMARY echo "Скачай из раздела Artifacts этого run'а" >> $GITHUB_STEP_SUMMARY fi