fix(core): pass release publish commands as argv instead of shell strings #25041
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: | |
| - master | |
| - '[0-9]+.[0-9]+.x' | |
| pull_request: | |
| branches: | |
| - "**" | |
| env: | |
| NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} | |
| NX_CLOUD_ENABLE_METRICS_COLLECTION: 'true' | |
| PNPM_HOME: ~/.pnpm | |
| # See the root Cargo.toml: the release profile is incremental for local dev. | |
| # CI builds cold, so incremental only inflates the cargo cache. | |
| # Note this does NOT reach Nx Agents - see .nx/workflows/agents.yaml. | |
| CARGO_INCREMENTAL: '0' | |
| # Pin corepack to the pnpm version from packageManager. Without this, corepack | |
| # falls back to "latest" in directories that have no packageManager field | |
| # (e.g. e2e temp dirs) instead of the repo's pinned pnpm. | |
| COREPACK_DEFAULT_TO_LATEST: '0' | |
| jobs: | |
| main-linux: | |
| runs-on: ubuntu-latest | |
| env: | |
| NX_BATCH_MODE: 'true' | |
| NX_E2E_CI_CACHE_KEY: e2e-github-linux | |
| NX_DAEMON: 'true' | |
| NX_PERF_LOGGING: 'false' | |
| NX_VERBOSE_LOGGING: 'false' | |
| NX_NATIVE_LOGGING: 'false' | |
| NX_E2E_RUN_E2E: 'true' | |
| NX_CI_EXECUTION_ENV: 'linux' | |
| NX_CLOUD_NO_TIMEOUTS: 'true' | |
| NX_ALLOW_NON_CACHEABLE_DTE: 'true' | |
| NX_CLOUD_EXPERIMENTAL_POLLING: 'true' | |
| NX_CLOUD_CONTINUOUS_ASSIGNMENT: 'true' | |
| NX_CLOUD_VERBOSE_LOGGING: 'true' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| fetch-depth: 0 | |
| filter: tree:0 | |
| - name: Set verbose logging from debug mode | |
| if: runner.debug == '1' | |
| run: echo "NX_VERBOSE_LOGGING=true" >> "$GITHUB_ENV" | |
| - name: Fetch Master | |
| run: git fetch origin master:master | |
| if: ${{ github.event_name == 'pull_request' }} | |
| - name: Set SHAs | |
| uses: nrwl/nx-set-shas@310288c04d90696f9f1bc27c5e3caea6642b53d4 # v5.0.0 | |
| with: | |
| main-branch-name: 'master' | |
| - name: Start CI Run | |
| run: npx nx-cloud@next start-ci-run --distribute-on="./.nx/workflows/dynamic-changesets.yaml" --stop-agents-after="e2e" | |
| - name: Setup dev tools with mise | |
| uses: jdx/mise-action@146a28175021df8ca24f8ee1828cc2a60f980bd5 # v3 | |
| - name: Enable corepack and install pnpm | |
| run: | | |
| corepack enable | |
| corepack prepare --activate | |
| - name: Get pnpm store directory | |
| id: pnpm-cache | |
| run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT | |
| - name: Cache pnpm store | |
| uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 | |
| with: | |
| path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} | |
| key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pnpm-store- | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@48b5f213c81028ace310571dc5ec0fbbca0b2947 # v4.4.3 | |
| - name: Install project dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Restore .NET analyzer projects | |
| run: dotnet restore nx.sln | |
| - name: Nx Report | |
| run: | |
| pnpm nx report | |
| - name: Run Checks/Lint/Test/Build | |
| run: | | |
| pids=() | |
| pnpm nx record -- nx format:check & | |
| pids+=($!) | |
| pnpm nx record -- nx sync:check | |
| pids+=($!) | |
| pnpm nx build workspace-plugin && pnpm nx record -- pnpm nx-cloud conformance:check | |
| pids+=($!) | |
| pnpm nx run-many -t check-imports check-lock-files check-codeowners --parallel=1 --no-dte & | |
| pids+=($!) | |
| pnpm nx affected --targets=lint,oxlint,test,build,e2e,e2e-ci,format-native,lint-native,gradle:build-ci,vale,run,validate-example & | |
| pids+=($!) | |
| for pid in "${pids[@]}"; do | |
| wait "$pid" | |
| done | |
| timeout-minutes: 100 | |
| - name: Fix CI | |
| run: pnpm nx fix-ci | |
| if: failure() | |
| main-macos: | |
| runs-on: macos-latest | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }}${{ contains(github.event_name, 'push') && format('-{0}', github.sha) || '' }} | |
| cancel-in-progress: true | |
| env: | |
| NX_E2E_CI_CACHE_KEY: e2e-github-macos | |
| NX_PERF_LOGGING: 'false' | |
| NX_CI_EXECUTION_ENV: 'macos' | |
| SELECTED_PM: 'npm' | |
| steps: | |
| - name: Log concurrency info | |
| run: | | |
| echo "Concurrency group: ${{ github.workflow }}-${{ github.ref }}${{ contains(github.event_name, 'push') && format('-{0}', github.sha) || '' }}" | |
| echo "Concurrency cancel-in-progress: ${{ !contains(github.event_name, 'push') }}" | |
| echo "Concurrency cancel-event-name: ${{ github.event_name }}" | |
| if: always() | |
| - name: Checkout | |
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| fetch-depth: 0 | |
| filter: tree:0 | |
| - name: Set verbose logging from debug mode | |
| if: runner.debug == '1' | |
| run: echo "NX_VERBOSE_LOGGING=true" >> "$GITHUB_ENV" | |
| - name: Fetch Master | |
| run: git fetch origin master:master | |
| if: ${{ github.event_name == 'pull_request' }} | |
| - name: Setup dev tools with mise | |
| uses: jdx/mise-action@146a28175021df8ca24f8ee1828cc2a60f980bd5 # v3 | |
| - name: Enable corepack and install pnpm | |
| run: | | |
| corepack enable | |
| corepack prepare --activate | |
| - name: Set SHAs | |
| uses: nrwl/nx-set-shas@310288c04d90696f9f1bc27c5e3caea6642b53d4 # v5.0.0 | |
| with: | |
| main-branch-name: 'master' | |
| - name: Check for React Native changes | |
| id: check-changes | |
| run: | | |
| HAS_CHANGED=$(node ./scripts/check-react-native-changes.js $NX_BASE $NX_HEAD); | |
| if $HAS_CHANGED; then | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| echo "React Native projects are affected, will run macOS tests" | |
| else | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| echo "No React Native projects affected, skipping macOS tests" | |
| fi | |
| - name: Configure Detox Environment, Install applesimutils | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| run: | | |
| # Ensure Xcode command line tools are installed and configured | |
| xcode-select --print-path || sudo xcode-select --reset | |
| sudo xcode-select -s /Applications/Xcode.app | |
| # Install or update applesimutils with error handling | |
| if ! brew list applesimutils &>/dev/null; then | |
| echo "Installing applesimutils..." | |
| HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null | |
| # Homebrew now refuses to load formulae from third-party taps unless trusted | |
| brew trust wix/brew | |
| HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils >/dev/null || { | |
| echo "Failed to install applesimutils, retrying with update..." | |
| brew update | |
| brew trust wix/brew | |
| HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils | |
| } | |
| else | |
| echo "Updating applesimutils..." | |
| HOMEBREW_NO_AUTO_UPDATE=1 brew upgrade applesimutils || true | |
| fi | |
| # Verify applesimutils installation | |
| applesimutils --version || (echo "applesimutils installation failed" && exit 1) | |
| # Configure environment for M-series Mac | |
| echo "DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer" >> $GITHUB_ENV | |
| echo "PLATFORM_NAME=iOS Simulator" >> $GITHUB_ENV | |
| # Set additional environment variables for better debugging | |
| echo "DETOX_DISABLE_TELEMETRY=1" >> $GITHUB_ENV | |
| echo "DETOX_LOG_LEVEL=trace" >> $GITHUB_ENV | |
| # Verify Xcode installation | |
| xcodebuild -version | |
| # List available simulators | |
| xcrun simctl list devices available | |
| timeout-minutes: 10 | |
| continue-on-error: false | |
| - name: Reset iOS Simulators | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| id: reset-simulators | |
| run: | | |
| echo "Resetting iOS Simulators..." | |
| # Kill simulator processes | |
| sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService 2>/dev/null || true | |
| killall "Simulator" 2>/dev/null || true | |
| killall "iOS Simulator" 2>/dev/null || true | |
| # Wait for processes to terminate | |
| sleep 3 | |
| # Shutdown and erase all simulators (ignore failures) | |
| xcrun simctl shutdown all 2>/dev/null || true | |
| sleep 5 | |
| xcrun simctl erase all 2>/dev/null || true | |
| # If erase failed, try the nuclear option | |
| if xcrun simctl list devices | grep -q "Booted" 2>/dev/null; then | |
| echo "Standard reset failed, using nuclear option..." | |
| rm -rf ~/Library/Developer/CoreSimulator/Devices/* 2>/dev/null || true | |
| launchctl remove com.apple.CoreSimulator.CoreSimulatorService 2>/dev/null || true | |
| sleep 3 | |
| fi | |
| # Clean up additional directories | |
| rm -rf ~/Library/Developer/CoreSimulator/Caches/* 2>/dev/null || true | |
| rm -rf ~/Library/Logs/CoreSimulator/* 2>/dev/null || true | |
| rm -rf ~/Library/Developer/Xcode/DerivedData/* 2>/dev/null || true | |
| echo "Simulator reset completed" | |
| timeout-minutes: 5 | |
| continue-on-error: true | |
| - name: Verify Simulator Reset | |
| if: steps.check-changes.outputs.has_changes == 'true' && steps.reset-simulators.outcome == 'success' | |
| run: | | |
| # Verify CoreSimulator service restarted | |
| pgrep -fl "CoreSimulator" || (echo "CoreSimulator service not running" && exit 1) | |
| # Check simulator list is clean | |
| xcrun simctl list devices | |
| # Verify simulator runtime paths exist and are writable | |
| test -d ~/Library/Developer/CoreSimulator/Devices || (echo "Simulator devices directory missing" && exit 1) | |
| touch ~/Library/Developer/CoreSimulator/Devices/test || (echo "Simulator devices directory not writable" && exit 1) | |
| rm ~/Library/Developer/CoreSimulator/Devices/test | |
| timeout-minutes: 5 | |
| - name: Diagnose Simulator Reset Failure | |
| if: steps.check-changes.outputs.has_changes == 'true' && steps.reset-simulators.outcome == 'failure' | |
| run: | | |
| echo "Simulator reset failed. Collecting diagnostic information..." | |
| xcrun simctl list | |
| echo "Checking simulator logs..." | |
| ls -la ~/Library/Logs/CoreSimulator/ || echo "No simulator logs found" | |
| - name: Get pnpm store directory | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| id: pnpm-cache-macos | |
| run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT | |
| - name: Cache pnpm store | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 | |
| with: | |
| path: ${{ steps.pnpm-cache-macos.outputs.STORE_PATH }} | |
| key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pnpm-store- | |
| - name: Install project dependencies | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| run: | | |
| pnpm install --frozen-lockfile | |
| pnpm playwright install --with-deps | |
| - name: Restore .NET packages | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| run: dotnet restore nx.sln | |
| - name: Run E2E Tests for macOS | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| run: | | |
| pnpm nx affected -t e2e-macos-local --parallel=2 --base=$NX_BASE --head=$NX_HEAD |