p2p-foundation 0.1.8

Complete P2P networking foundation with flexible contacts panel, collapsible system menu, sparkly interactive help, DHT inboxes with infinite TTL, embedded Flutter PWA with auto-scroll chat, native app support, three-word addresses, and built-in AI capabilities
Documentation
name: Deploy P2P Apps

on:
  push:
    tags:
      - 'v*'      # Deploy on version tags (e.g., v1.0.0)
    branches:
      - main      # Auto-deploy main branch to beta
  pull_request:
    branches:
      - main      # Test builds on PRs
  workflow_dispatch:  # Manual trigger
    inputs:
      app_name:
        description: 'Specific app to deploy (or "all")'
        required: true
        default: 'all'
        type: choice
        options:
          - all
          - ant-connect
      platform:
        description: 'Platform to deploy to'
        required: true
        default: 'both'
        type: choice
        options:
          - both
          - ios
          - android
      deployment_type:
        description: 'Deployment type'
        required: true
        default: 'beta'
        type: choice
        options:
          - beta
          - production
          - dev_build

env:
  FLUTTER_VERSION: '3.19.0'
  RUST_VERSION: 'stable'

jobs:
  changes:
    runs-on: ubuntu-latest
    outputs:
      rust: ${{ steps.changes.outputs.rust }}
      ant-connect: ${{ steps.changes.outputs.ant-connect }}
      fastlane: ${{ steps.changes.outputs.fastlane }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Needed for change detection
          
      - uses: dorny/paths-filter@v3
        id: changes
        with:
          filters: |
            rust:
              - 'src/**'
              - 'Cargo.toml'
              - 'Cargo.lock'
            ant-connect:
              - 'apps/ant-connect/**'
            fastlane:
              - 'fastlane/**'
              - '.github/workflows/deploy.yml'

  build-rust:
    runs-on: ubuntu-latest
    needs: changes
    if: needs.changes.outputs.rust == 'true' || github.event_name == 'workflow_dispatch' || github.ref_type == 'tag'
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: ${{ env.RUST_VERSION }}
          components: rustfmt, clippy
          
      - name: Cache Rust dependencies
        uses: Swatinem/rust-cache@v2
        with:
          key: rust-build-${{ runner.os }}
          workspaces: "."
          
      - name: Install cross-compilation tools
        run: |
          cargo install cargo-lipo cross --force
          
      - name: Add Rust targets
        run: |
          rustup target add aarch64-apple-ios x86_64-apple-ios
          rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
          
      - name: Build Rust backend
        run: |
          # Main release build
          cargo build --release
          
          # iOS targets (universal library)
          cargo lipo --release
          
          # Android targets
          cross build --target aarch64-linux-android --release || echo "Android aarch64 build failed"
          cross build --target armv7-linux-androideabi --release || echo "Android armv7 build failed"
          cross build --target i686-linux-android --release || echo "Android i686 build failed"
          cross build --target x86_64-linux-android --release || echo "Android x86_64 build failed"
          
      - name: Upload Rust artifacts
        uses: actions/upload-artifact@v4
        with:
          name: rust-libraries
          path: |
            target/release/
            target/universal/release/
            target/aarch64-linux-android/release/
            target/armv7-linux-androideabi/release/
            target/i686-linux-android/release/
            target/x86_64-linux-android/release/
          retention-days: 1

  test-flutter:
    runs-on: ubuntu-latest
    needs: changes
    if: needs.changes.outputs.ant-connect == 'true' || github.event_name == 'pull_request'
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ env.FLUTTER_VERSION }}
          cache: true
          
      - name: Test Flutter apps
        run: |
          for app_dir in apps/*/; do
            if [ -f "$app_dir/pubspec.yaml" ]; then
              echo "Testing $(basename "$app_dir")..."
              cd "$app_dir"
              flutter pub get
              flutter analyze
              flutter test || echo "Tests failed for $(basename "$app_dir")"
              cd ../..
            fi
          done

  deploy-ios:
    runs-on: macos-14  # Use latest macOS runner
    needs: [changes, build-rust]
    if: |
      (github.ref_type == 'tag' || github.event_name == 'workflow_dispatch' || 
       (github.ref == 'refs/heads/main' && needs.changes.outputs.ant-connect == 'true')) &&
      (github.event.inputs.platform == 'both' || github.event.inputs.platform == 'ios' || github.event.inputs.platform == '')
    
    strategy:
      matrix:
        app: [ant-connect]
        
    steps:
      - uses: actions/checkout@v4
      
      - name: Download Rust libraries
        uses: actions/download-artifact@v4
        with:
          name: rust-libraries
          path: target/
          
      - name: Setup Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ env.FLUTTER_VERSION }}
          cache: true
          
      - name: Setup Ruby and Fastlane
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.2'
          bundler-cache: true
          working-directory: fastlane
          
      - name: Install Fastlane
        run: gem install fastlane
        
      - name: Cache Fastlane
        uses: actions/cache@v4
        with:
          path: |
            ~/.fastlane
            ~/Library/Caches/com.github.ben-z.github-actions-cache-for-bazel
          key: ${{ runner.os }}-fastlane-${{ hashFiles('**/Gemfile.lock') }}
          
      - name: Setup iOS certificates and provisioning
        if: github.ref_type == 'tag' || github.event.inputs.deployment_type == 'production'
        env:
          MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
          MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
        run: |
          cd fastlane
          fastlane match appstore --readonly || echo "Certificate setup failed - continuing with development build"
          
      - name: Deploy iOS app
        env:
          FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
          FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }}
          FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }}
          APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
          APP_STORE_CONNECT_API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }}
          APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
        run: |
          cd fastlane
          
          # Determine deployment type
          if [[ "${{ github.ref_type }}" == "tag" ]] || [[ "${{ github.event.inputs.deployment_type }}" == "production" ]]; then
            echo "๐Ÿš€ Production deployment"
            fastlane deploy_app app:${{ matrix.app }} platform:ios
          elif [[ "${{ github.event.inputs.deployment_type }}" == "dev_build" ]]; then
            echo "๐Ÿ”จ Development build"
            fastlane build_dev app:${{ matrix.app }}
          else
            echo "๐Ÿงช Beta deployment"
            fastlane beta_all
          fi

  deploy-android:
    runs-on: ubuntu-latest
    needs: [changes, build-rust]
    if: |
      (github.ref_type == 'tag' || github.event_name == 'workflow_dispatch' || 
       (github.ref == 'refs/heads/main' && needs.changes.outputs.ant-connect == 'true')) &&
      (github.event.inputs.platform == 'both' || github.event.inputs.platform == 'android' || github.event.inputs.platform == '')
    
    strategy:
      matrix:
        app: [ant-connect]
        
    steps:
      - uses: actions/checkout@v4
      
      - name: Download Rust libraries
        uses: actions/download-artifact@v4
        with:
          name: rust-libraries
          path: target/
          
      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
          
      - name: Setup Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ env.FLUTTER_VERSION }}
          cache: true
          
      - name: Setup Ruby and Fastlane
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.2'
          bundler-cache: true
          
      - name: Install Fastlane
        run: gem install fastlane
        
      - name: Setup Android signing
        if: github.ref_type == 'tag' || github.event.inputs.deployment_type == 'production' || github.event.inputs.deployment_type == 'beta'
        run: |
          if [ -n "${{ secrets.ANDROID_KEYSTORE }}" ]; then
            echo "${{ secrets.ANDROID_KEYSTORE }}" | base64 --decode > android-keystore.jks
            
            # Create key.properties for each app
            for app_dir in apps/*/android; do
              if [ -d "$app_dir" ]; then
                cat > "$app_dir/key.properties" << EOF
          storeFile=../../../android-keystore.jks
          keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}
          storePassword=${{ secrets.ANDROID_STORE_PASSWORD }}
          keyPassword=${{ secrets.ANDROID_KEY_PASSWORD }}
          EOF
              fi
            done
          fi
          
      - name: Setup Google Play Service Account
        if: github.ref_type == 'tag' || github.event.inputs.deployment_type == 'production' || github.event.inputs.deployment_type == 'beta'
        run: |
          if [ -n "${{ secrets.GOOGLE_PLAY_JSON_KEY }}" ]; then
            echo "${{ secrets.GOOGLE_PLAY_JSON_KEY }}" > google-play-key.json
            echo "GOOGLE_PLAY_JSON_KEY_PATH=$(pwd)/google-play-key.json" >> $GITHUB_ENV
          fi
          
      - name: Deploy Android app
        env:
          GOOGLE_PLAY_JSON_KEY_PATH: ${{ env.GOOGLE_PLAY_JSON_KEY_PATH }}
        run: |
          cd fastlane
          
          # Determine deployment type
          if [[ "${{ github.ref_type }}" == "tag" ]] || [[ "${{ github.event.inputs.deployment_type }}" == "production" ]]; then
            echo "๐Ÿš€ Production deployment"
            fastlane deploy_app app:${{ matrix.app }} platform:android
          elif [[ "${{ github.event.inputs.deployment_type }}" == "dev_build" ]]; then
            echo "๐Ÿ”จ Development build"
            fastlane build_dev app:${{ matrix.app }}
          else
            echo "๐Ÿงช Beta deployment"
            fastlane beta_all
          fi

  cleanup:
    runs-on: ubuntu-latest
    needs: [deploy-ios, deploy-android]
    if: always()
    
    steps:
      - name: Cleanup artifacts
        if: always()
        run: |
          echo "Deployment completed"