From 02088701ac1a7f63a5da80ebeef2e164e1c9b76b Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 15 Sep 2026 14:32:01 +0200 Subject: [PATCH 1/2] ci: make local e2e the merge gate Keep e2e-status as the required local check, move staging off PRs, and run migration on release-* with the same Slack summary as staging. --- .github/workflows/e2e-staging.yml | 4 +- .github/workflows/e2e-tests.yml | 231 +--------------------------- .github/workflows/e2e_migration.yml | 45 +++++- 3 files changed, 45 insertions(+), 235 deletions(-) diff --git a/.github/workflows/e2e-staging.yml b/.github/workflows/e2e-staging.yml index ce7fd428b..91f16f477 100644 --- a/.github/workflows/e2e-staging.yml +++ b/.github/workflows/e2e-staging.yml @@ -128,7 +128,7 @@ jobs: shard: - { name: multi_address_2, grep: "@multi_address_2" } - { name: pubky, grep: "@pubky" } - - { name: transfer_max, grep: "@transfer_max" } + - { name: transfer, grep: "@transfer_1|@transfer_max" } name: e2e-tests-staging - ${{ matrix.shard.name }} @@ -266,7 +266,7 @@ jobs: uses: actions/checkout@v7 with: repository: synonymdev/bitkit-e2e-tests - ref: ${{ needs.e2e-branch.outputs.branch }} + ref: main - name: Post Slack summary env: diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 4108d43b8..ebc2390f9 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -131,95 +131,6 @@ jobs: name: bitkit-e2e-ios_${{ github.run_number }} path: e2e-app/ - build-staging: - needs: detect-changes - if: github.event.pull_request.draft == false && needs.detect-changes.outputs.code == 'true' - runs-on: macos-latest - - steps: - - name: Checkout - uses: actions/checkout@v7 - - - name: Set up Xcode - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: "26.2" - - - name: System Information - run: | - echo "=== System Information ===" - echo "macOS Version:" - sw_vers - echo "" - echo "Xcode Version:" - xcodebuild -version - - - name: Install xcbeautify - run: | - brew install xcbeautify - - - name: Cache Swift Package Manager - uses: actions/cache@v6 - with: - path: | - ~/Library/Caches/org.swift.swiftpm - ~/Library/org.swift.swiftpm - Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm - key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }} - - - name: Install dependencies - run: | - echo "⏱️ Starting dependency resolution at $(date)" - xcodebuild -resolvePackageDependencies -onlyUsePackageVersionsFromResolvedFile | xcbeautify - echo "✅ Dependencies resolved at $(date)" - - - name: Pre-start simulator - run: | - echo "⏱️ Starting simulator at $(date)" - xcrun simctl boot "iPhone 17" || true - echo "✅ Simulator started at $(date)" - - - name: Build iOS app (regtest) - env: - GITHUB_ACTOR: ${{ github.actor }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SIMULATOR_NAME: "iPhone 17" - OS_VERSION: "26.2" - GEO: false - E2E_BACKEND: network - E2E_NETWORK: regtest - run: | - echo "=== Building iOS app (regtest) ===" - echo "Using simulator: $SIMULATOR_NAME (iOS $OS_VERSION)" - - if xcodebuild -showsdks | grep -q "iOS Simulator"; then - echo "✅ iOS Simulator platform already installed" - else - echo "⚙️ iOS Simulator platform not found — downloading..." - xcodebuild -downloadPlatform iOS - fi - - xcodebuild -workspace Bitkit.xcodeproj/project.xcworkspace \ - -scheme Bitkit \ - -configuration Debug \ - -destination "platform=iOS Simulator,name=$SIMULATOR_NAME,OS=$OS_VERSION" \ - -derivedDataPath DerivedData \ - SWIFT_ACTIVE_COMPILATION_CONDITIONS='DEBUG E2E_BUILD' \ - -allowProvisioningUpdates \ - build - - - name: Prepare app for E2E tests (regtest) - run: | - # Copy the .app bundle to the expected location and name - mkdir -p e2e-app - cp -r DerivedData/Build/Products/Debug-iphonesimulator/Bitkit.app e2e-app/bitkit.app - - - name: Upload iOS app (regtest) - uses: actions/upload-artifact@v7 - with: - name: bitkit-e2e-ios-regtest_${{ github.run_number }} - path: e2e-app/ - e2e-branch: needs: detect-changes if: github.event.pull_request.draft == false && needs.detect-changes.outputs.code == 'true' @@ -241,7 +152,7 @@ jobs: # - { name: onchain_boost_receive_widgets, grep: "@onchain|@boost|@receive|@widgets" } # - { name: settings, grep: "@settings" } # - { name: security, grep: "@security" } - - { name: e2e, grep: '@transfer|@send|@lnurl|@lightning|@backup|@onboarding|@onchain_1|@onchain_2|@numberpad|@widgets|@boost|@receive|@settings|@security|@multi_address_1|@multi_address_3|@multi_address_4|@hardware_wallet' } + - { name: e2e, grep: '@transfer_2|@send|@lnurl|@lightning|@backup|@onboarding|@onchain_1|@onchain_2|@numberpad|@widgets|@boost|@receive|@settings|@security|@multi_address_1|@multi_address_3|@multi_address_4|@hardware_wallet' } name: e2e-tests-local - ${{ matrix.shard.name }} @@ -370,147 +281,11 @@ jobs: run: | cd docker && docker compose down -v || true - e2e-tests-staging: - if: github.event.pull_request.draft == false && needs.detect-changes.outputs.code == 'true' - runs-on: macos-latest - timeout-minutes: 90 - needs: [detect-changes, build-staging, e2e-branch] - - strategy: - fail-fast: false - matrix: - shard: - - { name: multi_address_2_regtest, grep: "@multi_address_2" } - - { name: pubky_paykit, grep: "@pubky" } - - name: e2e-tests-staging - ${{ matrix.shard.name }} - - steps: - - name: Show selected E2E branch - env: - E2E_BRANCH: ${{ needs.e2e-branch.outputs.branch }} - run: echo $E2E_BRANCH - - - name: Clone E2E tests - uses: actions/checkout@v7 - with: - repository: synonymdev/bitkit-e2e-tests - path: bitkit-e2e-tests - ref: ${{ needs.e2e-branch.outputs.branch }} - - - name: Download iOS app (regtest) - uses: actions/download-artifact@v8 - with: - name: bitkit-e2e-ios-regtest_${{ github.run_number }} - path: bitkit-e2e-tests/aut - - - name: List iOS app directory contents - run: ls -l bitkit-e2e-tests/aut - - - name: Setup Node.js - uses: actions/setup-node@v7 - with: - node-version: 22 - - - name: Cache npm cache - uses: actions/cache@v6 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - - - name: Install dependencies - working-directory: bitkit-e2e-tests - run: npm ci - - - name: Install ffmpeg - run: | - echo "Installing ffmpeg with Homebrew..." - brew install ffmpeg - echo "ffmpeg version: $(ffmpeg -version | head -1)" - - - name: Boot Simulator - run: | - echo "Erasing simulator..." - xcrun simctl erase "iPhone 17" || true - - echo "Booting simulator..." - xcrun simctl boot "iPhone 17" || true - - echo "Waiting for boot status..." - xcrun simctl bootstatus "iPhone 17" -b - - echo "Opening Simulator app to ensure UI is ready..." - open -a Simulator - - echo "Waiting for simulator to fully initialize..." - sleep 30 - - echo "Verifying simulator state..." - xcrun simctl list devices booted - - - name: Run E2E Tests 1 (${{ matrix.shard.name }}) - continue-on-error: true - id: test1 - working-directory: bitkit-e2e-tests - run: ./ci_run_ios.sh --mochaOpts.grep '${{ matrix.shard.grep }}' - env: - BACKEND: regtest - SIMULATOR_NAME: "iPhone 17" - SIMULATOR_OS_VERSION: "26.2" - RECORD_VIDEO: true - ATTEMPT: 1 - - - name: Run E2E Tests 2 (${{ matrix.shard.name }}) - continue-on-error: true - if: steps.test1.outcome != 'success' - id: test2 - working-directory: bitkit-e2e-tests - run: ./ci_run_ios.sh --mochaOpts.grep "${{ matrix.shard.grep }}" - env: - BACKEND: regtest - SIMULATOR_NAME: "iPhone 17" - SIMULATOR_OS_VERSION: "26.2" - RECORD_VIDEO: true - ATTEMPT: 2 - - - name: Reset iOS Simulator before attempt 3 - if: steps.test1.outcome != 'success' && steps.test2.outcome != 'success' - run: | - echo "🔁 Resetting iOS simulator before attempt 3..." - xcrun simctl shutdown all || true - xcrun simctl erase "iPhone 17" || true - xcrun simctl boot "iPhone 17" || true - xcrun simctl bootstatus "iPhone 17" -b - open -a Simulator - sleep 15 - xcrun simctl list devices booted - - - name: Run E2E Tests 3 (${{ matrix.shard.name }}) - if: steps.test1.outcome != 'success' && steps.test2.outcome != 'success' - id: test3 - working-directory: bitkit-e2e-tests - run: ./ci_run_ios.sh --mochaOpts.grep "${{ matrix.shard.grep }}" - env: - BACKEND: regtest - SIMULATOR_NAME: "iPhone 17" - SIMULATOR_OS_VERSION: "26.2" - RECORD_VIDEO: true - ATTEMPT: 3 - - - name: Upload E2E Artifacts (${{ matrix.shard.name }}) - if: failure() - uses: actions/upload-artifact@v7 - with: - name: e2e-artifacts-regtest_${{ matrix.shard.name }}_${{ github.run_number }} - path: bitkit-e2e-tests/artifacts/ - e2e-status: if: always() && github.event.pull_request.draft == false name: e2e-status runs-on: ubuntu-latest - needs: [detect-changes, e2e-tests-local, e2e-tests-staging] + needs: [detect-changes, e2e-tests-local] steps: - name: E2E skipped - no code changes if: needs.detect-changes.outputs.code != 'true' @@ -519,7 +294,7 @@ jobs: - name: Verify all E2E shards succeeded if: needs.detect-changes.outputs.code == 'true' run: | - if [ "${{ needs.e2e-tests-local.result }}" != "success" ] || [ "${{ needs.e2e-tests-staging.result }}" != "success" ]; then + if [ "${{ needs.e2e-tests-local.result }}" != "success" ]; then echo "❌ Some E2E shards failed." exit 1 fi diff --git a/.github/workflows/e2e_migration.yml b/.github/workflows/e2e_migration.yml index 22292319d..cfa04f6a8 100644 --- a/.github/workflows/e2e_migration.yml +++ b/.github/workflows/e2e_migration.yml @@ -7,8 +7,15 @@ on: description: "Branch of synonymdev/bitkit-e2e-tests to use (main | default-feature-branch | custom branch name)" required: false default: "default-feature-branch" + post_to_slack: + description: "Post E2E migration summary to Slack (#bitkit-staging-nightly)" + type: boolean + default: false + required: false schedule: - cron: "0 3 * * *" + pull_request: + types: [opened, synchronize, reopened, ready_for_review] env: TERM: xterm-256color @@ -18,12 +25,12 @@ env: IOS_VERSION: "26.2" concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} cancel-in-progress: true jobs: build: - if: github.event.pull_request.draft == false + if: github.event_name != 'pull_request' || (github.event.pull_request.draft == false && (startsWith(github.head_ref, 'release-') || startsWith(github.base_ref, 'release-'))) runs-on: macos-latest steps: @@ -110,14 +117,14 @@ jobs: path: e2e-app/ e2e-branch: - if: github.event.pull_request.draft == false + if: github.event_name != 'pull_request' || (github.event.pull_request.draft == false && (startsWith(github.head_ref, 'release-') || startsWith(github.base_ref, 'release-'))) uses: synonymdev/bitkit-e2e-tests/.github/workflows/determine-e2e-branch.yml@main with: app_branch: ${{ github.head_ref || github.ref_name }} e2e_branch_input: ${{ github.event.inputs.e2e_branch || 'default-feature-branch' }} prepare-wallets: - if: github.event.pull_request.draft == false + if: github.event_name != 'pull_request' || (github.event.pull_request.draft == false && (startsWith(github.head_ref, 'release-') || startsWith(github.base_ref, 'release-'))) uses: synonymdev/bitkit-e2e-tests/.github/workflows/migration-wallet-setup.yml@main needs: [e2e-branch] strategy: @@ -137,7 +144,7 @@ jobs: scenario_name: ${{ matrix.scenario.name }} e2e-tests: - if: github.event.pull_request.draft == false + if: github.event_name != 'pull_request' || (github.event.pull_request.draft == false && (startsWith(github.head_ref, 'release-') || startsWith(github.base_ref, 'release-'))) runs-on: macos-latest needs: [build, e2e-branch, prepare-wallets] @@ -320,3 +327,31 @@ jobs: with: name: e2e-artifacts_${{ matrix.scenario.name }}_${{ matrix.rn_version }}_${{ github.run_number }} path: bitkit-e2e-tests/artifacts/ + + slack-report: + if: >- + always() && + (github.event_name == 'schedule' || + (github.event_name == 'workflow_dispatch' && inputs.post_to_slack == true)) + runs-on: ubuntu-latest + needs: [build, e2e-branch, prepare-wallets, e2e-tests] + steps: + - name: Checkout E2E tests + uses: actions/checkout@v7 + with: + repository: synonymdev/bitkit-e2e-tests + ref: main + + - name: Post Slack summary + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_STAGING }} + PLATFORM: ios + MIGRATION_RESULT: ${{ needs.build.result == 'success' && needs.e2e-branch.result == 'success' && needs.prepare-wallets.result == 'success' && needs.e2e-tests.result == 'success' && 'success' || 'failure' }} + BUILD_RESULT: ${{ needs.build.result }} + E2E_BRANCH_RESULT: ${{ needs.e2e-branch.result }} + PREPARE_WALLETS_RESULT: ${{ needs.prepare-wallets.result }} + E2E_TESTS_RESULT: ${{ needs.e2e-tests.result }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + RUN_ATTEMPT: ${{ github.run_attempt }} + E2E_TESTS_REF: ${{ needs.e2e-branch.outputs.branch }} + run: python3 scripts/slack_summary.py e2e-migration From 502d8430a34d1b40b5f87c1a2d7bad2b48ff7704 Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 15 Sep 2026 14:49:39 +0200 Subject: [PATCH 2/2] ci: checkout slack script from resolved e2e branch Pinning to main blocked testing slack_summary.py on a matching e2e-tests branch. Leave transfer_1 off staging until it is stable. --- .github/workflows/e2e-staging.yml | 4 ++-- .github/workflows/e2e_migration.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e-staging.yml b/.github/workflows/e2e-staging.yml index 91f16f477..ce7fd428b 100644 --- a/.github/workflows/e2e-staging.yml +++ b/.github/workflows/e2e-staging.yml @@ -128,7 +128,7 @@ jobs: shard: - { name: multi_address_2, grep: "@multi_address_2" } - { name: pubky, grep: "@pubky" } - - { name: transfer, grep: "@transfer_1|@transfer_max" } + - { name: transfer_max, grep: "@transfer_max" } name: e2e-tests-staging - ${{ matrix.shard.name }} @@ -266,7 +266,7 @@ jobs: uses: actions/checkout@v7 with: repository: synonymdev/bitkit-e2e-tests - ref: main + ref: ${{ needs.e2e-branch.outputs.branch }} - name: Post Slack summary env: diff --git a/.github/workflows/e2e_migration.yml b/.github/workflows/e2e_migration.yml index cfa04f6a8..efc8505d0 100644 --- a/.github/workflows/e2e_migration.yml +++ b/.github/workflows/e2e_migration.yml @@ -340,7 +340,7 @@ jobs: uses: actions/checkout@v7 with: repository: synonymdev/bitkit-e2e-tests - ref: main + ref: ${{ needs.e2e-branch.outputs.branch }} - name: Post Slack summary env: