name: "Build & deploy for Android, Linux, Web and Windows"

on:
  push:
    tags: ['v*']

jobs:

  build_linux_x86_64:
    name: Build and release Linux app (x86_64)
    # Use the previous ubuntu version for compatibility (https://github.com/ferraridamiano/ConverterNOW/issues/370)
    runs-on: ubuntu-22.04
    timeout-minutes: 15
    steps:
    - name: Checkout
      uses: actions/checkout@v7

    - name: Install missing packages
      run: |
        sudo add-apt-repository universe
        sudo apt-get update
        sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev desktop-file-utils
    
    - name: Setup Flutter
      uses: subosito/flutter-action@v2
      with:
        channel: stable
        cache: true

    - name: Flutter version
      run: flutter --version

    - name: Bootstrap
      run: |
        flutter pub global activate melos
        melos bootstrap

    - name: Build for linux
      run: flutter build linux --release

    - name: Tar linux package
      run: |
        arch=$(ls build/linux)
        tar -C build/linux/$arch/release/bundle -czf converternow-linux-x86_64.tar.gz .

    - name: Build appimage
      run: |
        chmod +x .github/workflows/scripts/build_appimage.sh
        ./.github/workflows/scripts/build_appimage.sh

    - name: Release to GitHub
      uses: softprops/action-gh-release@v3
      with:
        files: |
          converternow-linux-x86_64.tar.gz
          converternow-x86_64.AppImage
        token: ${{ secrets.GH_TOKEN }}

    - name: Upload compiled icons
      uses: actions/upload-artifact@v7
      with:
        name: assets
        path: assets

  build_linux_aarch64:
    name: Build and release Linux app (aarch64)
    # Use the previous ubuntu version for compatibility (https://github.com/ferraridamiano/ConverterNOW/issues/370)
    runs-on: ubuntu-22.04-arm
    timeout-minutes: 15
    needs: build_linux_x86_64
    steps:

    - name: Checkout
      uses: actions/checkout@v7

    - name: Install missing packages
      run: |
        sudo add-apt-repository universe
        sudo apt-get update
        sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev desktop-file-utils

    # Use git because subosito/flutter-action does not support arm64 yet (https://github.com/subosito/flutter-action/issues/345)
    - name: Setup Flutter
      run: |
        git clone --branch stable https://github.com/flutter/flutter.git $RUNNER_TEMP/flutter
        cd $RUNNER_TEMP/flutter
        echo "$RUNNER_TEMP/flutter/bin" >> $GITHUB_PATH
        echo "$HOME/.pub-cache/bin" >> $GITHUB_PATH

    - name: Flutter version
      run: flutter --version

    # continue-on-error is set because we would receive an error on icon
    # compilation (but we import the compiled icons from previous step)
    - name: Bootstrap
      continue-on-error: true
      run: |
        flutter pub global activate melos
        melos bootstrap

    - name: Remove current assets
      run: rm -rf assets

    - name: Download compiled assets
      uses: actions/download-artifact@v8
      with:
        name: assets
        path: assets

    - name: Build for linux
      run: flutter build linux --release

    - name: Tar linux package
      run: |
        arch=$(ls build/linux)
        tar -C build/linux/$arch/release/bundle -czf converternow-linux-aarch64.tar.gz .

    - name: Build appimage
      run: |
        chmod +x .github/workflows/scripts/build_appimage.sh
        ./.github/workflows/scripts/build_appimage.sh

    - name: Release to GitHub
      uses: softprops/action-gh-release@v3
      with:
        files: |
          converternow-linux-aarch64.tar.gz
          converternow-aarch64.AppImage
        token: ${{ secrets.GH_TOKEN }}

  build_android:
    needs: build_linux_aarch64
    name: Build and release Android app
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
    - name: Checkout
      uses: actions/checkout@v7

    - name: Setup Java
      uses: actions/setup-java@v5
      with:
        distribution: 'temurin'
        java-version: '17'

    - name: Setup Flutter
      uses: subosito/flutter-action@v2
      with:
        channel: stable
        cache: true

    - name: Flutter version
      run: flutter --version

    - name: Bootstrap
      run: |
        dart pub global activate melos
        melos bootstrap

    - name: Download Android keystore
      id: android_keystore
      uses: timheuer/base64-to-file@v2
      with:
        fileName: key.jks
        encodedString: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
  
    - name: Create key.properties
      run: |
        echo "storeFile=${{ steps.android_keystore.outputs.filePath }}" > android/key.properties
        echo "storePassword=${{ secrets.ANDROID_KEYSTORE_PASSWORD }}" >> android/key.properties
        echo "keyPassword=${{ secrets.ANDROID_KEY_PASSWORD }}" >> android/key.properties
        echo "keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}" >> android/key.properties
  
    - name: Build Android App Bundle
      run: flutter build appbundle --dart-define=IS_PLAYSTORE=true --obfuscate --split-debug-info=/tmp

    - name: Build Android APK files
      run: flutter build apk --release --split-per-abi --obfuscate --split-debug-info=/tmp

    - name: Release to GitHub
      uses: softprops/action-gh-release@v3
      with:
        files: |
          build/app/outputs/flutter-apk/app-*-release.apk
          build/app/outputs/bundle/release/app-release.aab
        token: ${{ secrets.GH_TOKEN }}

  
  build_web:
    needs: build_android
    name: Build and release Web app
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
    - name: Checkout
      uses: actions/checkout@v7

    - name: Setup Flutter
      uses: subosito/flutter-action@v2
      with:
        channel: stable
        cache: true

    - name: Flutter version
      run: flutter --version

    - name: Bootstrap
      run: |
        dart pub global activate melos
        melos bootstrap

    - name: Build for Web
      run: flutter build web --release --wasm

    - name: Upload to Firebase Hosting
      uses: FirebaseExtended/action-hosting-deploy@v0
      with:
        repoToken: '${{ secrets.GITHUB_TOKEN }}'
        firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_CONVERTER_NOW }}'
        channelId: live
        projectId: converter-now

  build_windows:
    needs: build_web
    name: Build and release Windows app
    runs-on: windows-latest
    timeout-minutes: 20
    steps:
    - name: Checkout
      uses: actions/checkout@v7
    
    - name: Setup Flutter
      uses: subosito/flutter-action@v2
      with:
        channel: stable
        cache: true

    - name: Flutter version
      run: flutter --version

    - name: Bootstrap
      run: |
        dart pub global activate melos
        melos bootstrap

    - name: Build Windows
      run: flutter build windows --release

    - name: Build and create the .msix installer
      run: dart run msix:create --store

    - name: Create the .exe installer
      shell: pwsh
      run: |
        $version = (Select-String -Path pubspec.yaml -Pattern "^version:\s*(.+)").Matches[0].Groups[1].Value.Split("+")[0]
        iscc /DMyAppVersion=$version windows\innosetup.iss

    - name: Release to GitHub
      uses: softprops/action-gh-release@v3
      with:
        files: |
          build/windows/x64/runner/Release/converternow-windows.msix
          windows/converternow-windows-setup.exe
        token: ${{ secrets.GH_TOKEN }}

  build_docker:
    needs: build_windows
    name: Build and release Docker image
    runs-on: ubuntu-latest
    timeout-minutes: 10
    env:
      REGISTRY: ghcr.io
      IMAGE_NAME: ${{ github.repository }}
    permissions:
      contents: read
      packages: write
      attestations: write
      id-token: write
    steps:
      - name: Checkout code
        uses: actions/checkout@v7

      - name: Log in to the Container registry
        uses: docker/login-action@v4
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v6
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v4

      - name: Build and push Docker image
        id: push
        uses: docker/build-push-action@v7
        with:
          context: .
          push: true
          platforms: linux/amd64,linux/arm64
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Generate artifact attestation
        uses: actions/attest@v4
        with:
          subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
          subject-digest: ${{ steps.push.outputs.digest }}
          push-to-registry: true

  create_release:
    needs: build_docker
    name: Create GitHub Release
    runs-on: ubuntu-latest
    timeout-minutes: 5
    permissions:
      contents: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v7
        with:
          fetch-depth: 0

      - name: Generate Changelog using git-cliff
        uses: orhun/git-cliff-action@v4
        id: git-cliff
        with:
          args: --latest

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v3
        with:
          body: ${{ steps.git-cliff.outputs.content }}
