offline_first_core 0.5.0

High-performance LMDB-based local storage library optimized for FFI integration with Flutter and cross-platform applications
Documentation
name: Rust Build for Mobile and Desktop

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:

env:
  CARGO_TERM_COLOR: always

jobs:
  build-apple-android:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        run: |
          rustup update stable
          rustup target add aarch64-apple-ios aarch64-apple-darwin x86_64-apple-darwin
          # AƱadir targets necesarios para Android
          rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android

      - name: Install Android NDK
        run: |
          yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install "ndk;25.2.9519653" --sdk_root=$ANDROID_HOME

      - name: Install cargo-ndk
        run: cargo install cargo-ndk

      - name: Build for Android
        run: |
          export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/25.2.9519653
          # Usamos cargo-ndk para Android
          cargo ndk -t armeabi-v7a -t arm64-v8a -t x86 -t x86_64 -o ./android-libs build --release

      - name: Build for iOS
        run: |
          cargo build --target aarch64-apple-ios --release
          install_name_tool -id "@rpath/liboffline_first_core.dylib" "target/aarch64-apple-ios/release/liboffline_first_core.dylib"

      - name: Build for macOS
        run: |
          cargo build --target aarch64-apple-darwin --release
          cargo build --target x86_64-apple-darwin --release
          
          install_name_tool -id "@rpath/liboffline_first_core_arm64.dylib" "target/aarch64-apple-darwin/release/liboffline_first_core.dylib"
          install_name_tool -id "@rpath/liboffline_first_core_x86_64.dylib" "target/x86_64-apple-darwin/release/liboffline_first_core.dylib"
          
          mv "target/aarch64-apple-darwin/release/liboffline_first_core.dylib" "target/aarch64-apple-darwin/release/liboffline_first_core_arm64.dylib"
          mv "target/x86_64-apple-darwin/release/liboffline_first_core.dylib" "target/x86_64-apple-darwin/release/liboffline_first_core_x86_64.dylib"
          
          # Verificar archivos de macOS
          echo "Verificando archivos de macOS:"
          ls -la ./target/aarch64-apple-darwin/release/
          ls -la ./target/x86_64-apple-darwin/release/

      - name: Run tests
        run: cargo test --verbose

      - name: Upload Android libs
        uses: actions/upload-artifact@v4
        with:
          name: android-libs
          path: ./android-libs/**/*
          if-no-files-found: error

      - name: Upload iOS lib
        uses: actions/upload-artifact@v4
        with:
          name: ios-lib
          path: ./target/aarch64-apple-ios/release/liboffline_first_core.dylib
          if-no-files-found: error

      - name: Upload macOS libs
        uses: actions/upload-artifact@v4
        with:
          name: macos-libs
          path: |
            ./target/aarch64-apple-darwin/release/liboffline_first_core_arm64.dylib
            ./target/x86_64-apple-darwin/release/liboffline_first_core_x86_64.dylib
          if-no-files-found: warn

  build-linux:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        run: |
          rustup update stable
          rustup target add x86_64-unknown-linux-gnu

      - name: Install LMDB
        run: |
          sudo apt-get update
          sudo apt-get install -y liblmdb-dev

      - name: Build for Linux x86_64
        run: |
          cargo build --release --target x86_64-unknown-linux-gnu

      - name: Upload Linux libs
        uses: actions/upload-artifact@v4
        with:
          name: linux-libs
          path: |
            ./target/x86_64-unknown-linux-gnu/release/liboffline_first_core.so
            ./target/x86_64-unknown-linux-gnu/release/liboffline_first_core.a
          if-no-files-found: error

  build-windows:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        run: |
          rustup update stable
          rustup target add x86_64-pc-windows-msvc

      - name: Setup vcpkg
        uses: lukka/run-vcpkg@v11
        with:
          vcpkgDirectory: '${{ github.workspace }}/vcpkg'
          vcpkgGitCommitId: 'master'

      - name: Install LMDB
        run: |
          vcpkg install lmdb:x64-windows
        shell: cmd

      - name: Build for Windows x86_64
        run: |
          $env:VCPKG_ROOT = "${{ github.workspace }}/vcpkg"
          cargo build --release --target x86_64-pc-windows-msvc
        shell: powershell

      - name: Upload Windows libs
        uses: actions/upload-artifact@v4
        with:
          name: windows-libs
          path: |
            ./target/x86_64-pc-windows-msvc/release/offline_first_core.dll
            ./target/x86_64-pc-windows-msvc/release/offline_first_core.lib
          if-no-files-found: error

  publish:
    needs: [build-apple-android, build-linux, build-windows]
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
        with:
          repository: JhonaCodes/flutter_local_db
          token: ${{ secrets.FLUTTER_REPO_TOKEN }}

      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: ./tmp-artifacts

      - name: Move files to correct locations
        run: |
          # Crear directorios (los existentes y los nuevos)
          mkdir -p android/src/main/jniLibs/arm64-v8a
          mkdir -p android/src/main/jniLibs/armeabi-v7a
          mkdir -p android/src/main/jniLibs/x86
          mkdir -p android/src/main/jniLibs/x86_64
          mkdir -p ios/Frameworks
          mkdir -p macos/Frameworks
          mkdir -p linux/lib
          mkdir -p windows/lib
          
          # Crear archivos README para las nuevas carpetas si no existen
          if [ ! -f "linux/README.md" ]; then
            cat > linux/README.md << 'EOF'
          # Linux Libraries
          
          This directory contains the compiled native libraries for Linux x86_64.
          
          ## Files
          - `lib/liboffline_first_core.so` - Dynamic library
          - `lib/liboffline_first_core.a` - Static library
          
          ## Usage
          ```bash
          # Dynamic linking
          gcc -L./lib -loffline_first_core your_program.c
          
          # Static linking  
          gcc ./lib/liboffline_first_core.a your_program.c
          ```
          
          ## Dependencies
          - LMDB library: `sudo apt-get install liblmdb-dev`
          EOF
          fi
          
          if [ ! -f "windows/README.md" ]; then
            cat > windows/README.md << 'EOF'
          # Windows Libraries
          
          This directory contains the compiled native libraries for Windows x86_64.
          
          ## Files
          - `lib/offline_first_core.dll` - Dynamic library
          - `lib/offline_first_core.lib` - Static library
          
          ## Usage
          1. Add `offline_first_core.lib` to your project linker dependencies
          2. Ensure `offline_first_core.dll` is in your PATH or application directory
          
          ## Dependencies
          - LMDB library (install with vcpkg: `vcpkg install lmdb:x64-windows`)
          EOF
          fi
          
          # Verificar estructura de todos los directorios de artefactos
          echo "All artifact directories structure:"
          find ./tmp-artifacts -type f | sort
          
          # Mover archivos Android
          find ./tmp-artifacts/android-libs -name "*.so" -type f -exec bash -c 'cp "$0" "android/src/main/jniLibs/$(basename $(dirname "$0"))/liboffline_first_core.so"' {} \;
          
          # Mover archivo iOS
          if [ -f "./tmp-artifacts/ios-lib/liboffline_first_core.dylib" ]; then
            cp ./tmp-artifacts/ios-lib/liboffline_first_core.dylib ios/Frameworks/
          else
            echo "iOS library not found. Searching alternative paths..."
            find ./tmp-artifacts -name "*liboffline_first_core*.dylib" -not -path "*arm64.dylib" -not -path "*x86_64.dylib" -exec cp {} ios/Frameworks/liboffline_first_core.dylib \; || echo "No iOS library found"
          fi
          
          # Mover archivos macOS - con manejo de errores
          if [ -f "./tmp-artifacts/macos-libs/liboffline_first_core_arm64.dylib" ]; then
            cp ./tmp-artifacts/macos-libs/liboffline_first_core_arm64.dylib macos/Frameworks/
          else
            echo "macOS arm64 library not found. Searching alternative paths..."
            find ./tmp-artifacts -name "*liboffline_first_core*arm64*.dylib" -exec cp {} macos/Frameworks/liboffline_first_core_arm64.dylib \; || echo "No macOS arm64 library found"
          fi
          
          if [ -f "./tmp-artifacts/macos-libs/liboffline_first_core_x86_64.dylib" ]; then
            cp ./tmp-artifacts/macos-libs/liboffline_first_core_x86_64.dylib macos/Frameworks/
          else
            echo "macOS x86_64 library not found. Searching alternative paths..."
            find ./tmp-artifacts -name "*liboffline_first_core*x86_64*.dylib" -exec cp {} macos/Frameworks/liboffline_first_core_x86_64.dylib \; || echo "No macOS x86_64 library found"
          fi
          
          # Verificar archivos copiados
          echo "Files copied to Android:"
          find android/src/main/jniLibs -type f | sort
          
          echo "Files copied to iOS:"
          find ios/Frameworks -type f | sort
          
          echo "Files copied to macOS:"
          find macos/Frameworks -type f | sort
          
          # Mover archivos Linux
          if [ -f "./tmp-artifacts/linux-libs/liboffline_first_core.so" ]; then
            cp ./tmp-artifacts/linux-libs/liboffline_first_core.so linux/lib/
          else
            echo "Linux .so library not found. Searching alternative paths..."
            find ./tmp-artifacts -name "liboffline_first_core.so" -exec cp {} linux/lib/ \; || echo "No Linux .so library found"
          fi
          
          if [ -f "./tmp-artifacts/linux-libs/liboffline_first_core.a" ]; then
            cp ./tmp-artifacts/linux-libs/liboffline_first_core.a linux/lib/
          else
            echo "Linux .a library not found. Searching alternative paths..."
            find ./tmp-artifacts -name "liboffline_first_core.a" -exec cp {} linux/lib/ \; || echo "No Linux .a library found"
          fi
          
          # Mover archivos Windows
          if [ -f "./tmp-artifacts/windows-libs/offline_first_core.dll" ]; then
            cp ./tmp-artifacts/windows-libs/offline_first_core.dll windows/lib/
          else
            echo "Windows .dll library not found. Searching alternative paths..."
            find ./tmp-artifacts -name "offline_first_core.dll" -exec cp {} windows/lib/ \; || echo "No Windows .dll library found"
          fi
          
          if [ -f "./tmp-artifacts/windows-libs/offline_first_core.lib" ]; then
            cp ./tmp-artifacts/windows-libs/offline_first_core.lib windows/lib/
          else
            echo "Windows .lib library not found. Searching alternative paths..."
            find ./tmp-artifacts -name "offline_first_core.lib" -exec cp {} windows/lib/ \; || echo "No Windows .lib library found"
          fi
          
          echo "Files copied to Linux:"
          find linux/lib -type f | sort
          
          echo "Files copied to Windows:"
          find windows/lib -type f | sort

      - name: Commit and push changes
        run: |
          git config --global user.name "GitHub Actions"
          git config --global user.email "actions@github.com"
          
          # Solo incluir directorios que existen y tienen archivos
          if [ -n "$(find android/src/main/jniLibs -type f 2>/dev/null)" ]; then
            git add android/src/main/jniLibs
          fi
          
          if [ -n "$(find ios/Frameworks -type f 2>/dev/null)" ]; then
            git add ios/Frameworks
          fi
          
          if [ -n "$(find macos/Frameworks -type f 2>/dev/null)" ]; then
            git add macos/Frameworks
          fi
          
          if [ -n "$(find linux/lib -type f 2>/dev/null)" ]; then
            git add linux/lib
          fi
          
          if [ -n "$(find windows/lib -type f 2>/dev/null)" ]; then
            git add windows/lib
          fi
          
          # Agregar archivos README si fueron creados
          if [ -f "linux/README.md" ]; then
            git add linux/README.md
          fi
          
          if [ -f "windows/README.md" ]; then
            git add windows/README.md
          fi
          
          git commit -m "Update native libraries from Rust build [skip ci]" || echo "No changes to commit"
          git push