name: Release build

on:
  push:
    branches:
      - master
      - ci
    tags-ignore:
      - "*-dev*"

jobs:
  version:
    runs-on: debian-release
    outputs:
      v: ${{ steps.version.outputs.v }}
      pre: ${{ steps.version.outputs.pre }}
      exists: ${{ steps.check.outputs.exists }}
      last_tag: ${{ steps.check_prev.outputs.last_tag }}
    steps:
      - uses: actions/checkout@v6
        with:
          submodules: recursive
      - name: Get version
        id: version
        run: |
          ver="$(grep -m 1 -Po 'version = "\K[^"]*' Cargo.toml)"
          [[ $ver == *"-dev"* ]] && ver=${ver} || ver=${ver}-dev
          [[ ${{ forgejo.ref_type }} == 'tag' ]] && app_ver=${{ forgejo.ref_name }} || app_ver=v${ver}
          echo "v=${app_ver}" >> "$FORGEJO_OUTPUT"
          echo $app_ver
          [[ ${{ forgejo.ref_type }} == 'tag' ]] && pre='false' || pre='true'
          echo "pre=${pre}" >> "$FORGEJO_OUTPUT"
          echo "pre-release: ${pre}"
      - name: Check existing release
        if: ${{ forgejo.ref_type == 'tag' }}
        id: check
        run: |
          git fetch --tags
          dev_sha=$(git rev-parse refs/tags/${{ forgejo.ref_name }}-dev) || :
          [[ "$(git show-ref)" == *"${dev_sha}"* ]] && exists='true' || exists='false'
          echo "exists=${exists}" >> "$FORGEJO_OUTPUT"
          echo ${exists}
          mkdir release
      - uses: actions/forgejo-release@v2.11.3
        if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }}
        with:
          direction: download
          token: ${{ secrets.RELEASE_TOKEN }}
          tag: "${{ forgejo.ref_name }}-dev"
          release-dir: ./release
      - name: Rename files
        if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }}
        working-directory: release
        run: for f in *; do mv "$f" "$(echo "$f" | sed s/-dev-/-/)"; done
      - name: Delete dev release
        if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }}
        uses: actions/delete-release@v1
        with:
          release_name: "${{ forgejo.ref_name }}-dev"
      - name: Check previous release
        id: check_prev
        run: |
          git fetch --tags
          [[ ${{ forgejo.ref_type }} == 'tag' ]] && skip=0 || skip=1
          last_tag=$(git describe --abbrev=0 --tags $(git rev-list --tags --skip=${skip} --max-count=1)) || true
          echo "last_tag=${last_tag}" >> "$FORGEJO_OUTPUT"
      - uses: actions/forgejo-release@v2.11.3
        if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }}
        with:
          direction: upload
          token: ${{ secrets.RELEASE_TOKEN }}
          tag: ${{ forgejo.ref_name }}
          override: false
          prerelease: false
          release-dir: ./release
          release-notes: "Full Changelog: [${{ steps.check_prev.outputs.last_tag }}...${{ steps.version.outputs.v }}](https://code.gri.mw/${{ forgejo.repository }}/compare/${{ steps.check_prev.outputs.last_tag }}...${{ steps.version.outputs.v }})"

  android_libs:
    if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
    runs-on: ubuntu
    needs: version
    steps:
      - uses: actions/checkout@v6
        with:
          submodules: recursive
      - name: Restore cargo cache
        id: cache-cargo-restore
        uses: actions/cache/restore@v5
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: grim-android-cargo-${{ hashFiles('**/Cargo.lock') }}
      - name: Setup registry
        run: |
          echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"' > ~/.cargo/config.toml
      - name: Build libs
        run: |
          chmod +x scripts/android.sh && ./scripts/android.sh lib ${{ needs.version.outputs.v }}
      - name: Save cargo cache
        uses: actions/cache/save@v5
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }}
      - name: Upload artifacts
        run: |
          cd android/app/src/main
          tar -czf jniLibs.tar.gz jniLibs
          curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file jniLibs.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/jniLibs.tar.gz

  android_release:
    if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
    runs-on: ubuntu-android
    needs: [version, android_libs]
    steps:
      - uses: actions/checkout@v6
        with:
          submodules: recursive
      - name: Restore gradle cache
        id: cache-gradle-restore
        uses: actions/cache/restore@v5
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: grim-android-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-
      - name: Download artifacts
        run: |
          cd android/app/src/main
          curl -o jniLibs.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/jniLibs.tar.gz
          tar -xzf jniLibs.tar.gz
          rm jniLibs.tar.gz
      - name: Setup build
        run: |
          chmod +x android/gradlew
          echo "${{ secrets.ANDROID_KEYSTORE }}" > release.keystore.txt
          base64 -d release.keystore.txt > android/keystore
          echo "${{ secrets.ANDROID_KEYSTORE_PROPS }}" > release.keystore.props.txt
          base64 -d release.keystore.props.txt > android/keystore.properties
          mkdir ~/.gradle && touch ~/.gradle/gradle.properties
          printf "mavenHost=${{ secrets.MAVEN_HOST }}\n" >> ~/.gradle/gradle.properties
          printf "mavenUser=${{ secrets.MAVEN_USER }}\n" >> ~/.gradle/gradle.properties
          printf "mavenPassword=${{ secrets.MAVEN_PASSWORD }}" >> ~/.gradle/gradle.properties
      - name: Release ARMv7+v8 APK
        working-directory: android
        run: |
          jni_path=app/src/main/jniLibs
          mv ${jni_path}/x86_64 x86_64
          ./gradlew assembleCiSignedRelease
          apk_path=app/build/outputs/apk/ci/signedRelease/app-ci-signedRelease.apk
          name=grim-${{ needs.version.outputs.v }}-android.apk
          mv ${apk_path} "${name}"
      - name: Checksum ARM APK
        working-directory: android
        run: |
          name=grim-${{ needs.version.outputs.v }}-android.apk
          checksum=grim-${{ needs.version.outputs.v }}-android-sha256sum.txt
          sha256sum "${name}" > "${checksum}"
      - name: Release x86_64 APK
        working-directory: android
        run: |
          ./gradlew clean
          jni_path=app/src/main/jniLibs
          rm -rf ${jni_path}/*
          mv x86_64 ${jni_path}
          ./gradlew assembleCiSignedRelease
          apk_path=app/build/outputs/apk/ci/signedRelease/app-ci-signedRelease.apk
          name=grim-${{ needs.version.outputs.v }}-android-x86_64.apk
          mv ${apk_path} "${name}"
      - name: Save gradle cache
        uses: actions/cache/save@v5
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ steps.cache-gradle-restore.outputs.cache-primary-key }}
      - name: Checksum x86_64 APK
        working-directory: android
        run: |
          name=grim-${{ needs.version.outputs.v }}-android.apk
          checksum=grim-${{ needs.version.outputs.v }}-android-x86_64-sha256sum.txt
          sha256sum "${name}" > "${checksum}"
      - name: Upload artifacts
        run: |
          mkdir release
          mv android/grim* release
          tar -czf android.tar.gz release
          curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file android.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/android.tar.gz

  linux_arm:
    if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
    runs-on: ubuntu
    needs: [version, android_libs]
    steps:
      - uses: actions/checkout@v6
        with:
          submodules: recursive
      - name: Restore cargo cache
        id: cache-cargo-restore
        uses: actions/cache/restore@v5
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: grim-linux-arm-cargo-${{ hashFiles('**/Cargo.lock') }}
      - name: Setup registry
        run: |
          echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"' > ~/.cargo/config.toml
      - name: Release Linux ARM
        run: cargo zigbuild --release --target aarch64-unknown-linux-gnu
      - name: Save cargo cache
        uses: actions/cache/save@v5
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }}
      - name: AppImage ARM
        run: |
          mkdir release
          cp target/aarch64-unknown-linux-gnu/release/grim linux/Grim.AppDir/AppRun
          appimagetool linux/Grim.AppDir grim-${{ needs.version.outputs.v }}-linux-arm.AppImage
          cp grim-${{ needs.version.outputs.v }}-linux-arm.AppImage release/
      - name: Checksum AppImage ARM
        working-directory: release
        run: sha256sum grim-${{ needs.version.outputs.v }}-linux-arm.AppImage > grim-${{ needs.version.outputs.v }}-linux-arm-appimage-sha256sum.txt
      - name: Upload artifacts
        run: |
          tar -czf linux-arm.tar.gz release
          curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file linux-arm.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/linux-arm.tar.gz

  linux_x86:
    if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
    runs-on: ubuntu-linux-x86
    needs: [version]
    steps:
      - uses: actions/checkout@v6
        with:
          submodules: recursive
      - name: Restore cargo cache
        id: cache-cargo-restore
        uses: actions/cache/restore@v5
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: grim-linux-x86-cargo-${{ hashFiles('**/Cargo.lock') }}
      - name: Setup registry
        run: |
          echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"' > ~/.cargo/config.toml
      - name: Release Linux x86
        run: cargo zigbuild --release --target x86_64-unknown-linux-gnu
      - name: Save cargo cache
        uses: actions/cache/save@v5
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }}
      - name: AppImage x86
        run: |
          mkdir release
          cp target/x86_64-unknown-linux-gnu/release/grim linux/Grim.AppDir/AppRun
          appimagetool linux/Grim.AppDir grim-${{ needs.version.outputs.v }}-linux-x86_64.AppImage
          cp grim-${{ needs.version.outputs.v }}-linux-x86_64.AppImage release/
      - name: Checksum AppImage x86
        working-directory: release
        run: sha256sum grim-${{ needs.version.outputs.v }}-linux-x86_64.AppImage > grim-${{ needs.version.outputs.v }}-linux-x86_64-appimage-sha256sum.txt
      - name: Upload artifacts
        run: |
          tar -czf linux-x86_64.tar.gz release
          curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file linux-x86_64.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/linux-x86_64.tar.gz      

  macos:
    if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
    runs-on: ubuntu
    needs: [version, android_libs, linux]
    steps:
      - uses: actions/checkout@v6
        with:
          submodules: recursive
      - run: mkdir release
      - name: Restore cargo cache
        id: cache-cargo-restore
        uses: actions/cache/restore@v5
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: grim-macos-cargo-${{ hashFiles('**/Cargo.lock') }}
      - name: Setup registry
        run: |
          echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"' > ~/.cargo/config.toml
      - name: Release MacOS Universal
        run: |
          cargo zigbuild --release --target universal2-apple-darwin
          cp target/universal2-apple-darwin/release/grim macos/Grim.app/Contents/MacOS
      - name: Save cargo cache
        uses: actions/cache/save@v5
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }}
      - name: Archive Universal
        working-directory: macos
        run: |
          zip -r grim-${{ needs.version.outputs.v }}-macos-universal.zip Grim.app
          mv grim-${{ needs.version.outputs.v }}-macos-universal.zip ../release
      - name: Checksum Release Universal
        working-directory: release
        run: sha256sum grim-${{ needs.version.outputs.v }}-macos-universal.zip > grim-${{ needs.version.outputs.v }}-macos-universal-sha256sum.txt
      - name: Upload artifacts
        run: |
          tar -czf macos.tar.gz release
          curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file macos.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/macos.tar.gz

  windows:
    if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
    runs-on: windows
    needs: [version]
    steps:
      - uses: actions/checkout@v6
        with:
          submodules: recursive
      - name: Update UpgradeCode
        shell: powershell
        run: |
          $guid = [guid]::NewGuid().ToString()
          $wix = [xml](Get-Content wix/main.wxs)
          $wix.Wix.Product.UpgradeCode = $guid
          $wix.Save("wix/main.wxs")
          Get-Content wix/main.wxs
      - run: mkdir release
      - name: Release Windows x86
        run: |
          cargo wix -p grim -o grim-${{ needs.version.outputs.v }}-win-x86_64.msi --nocapture
          mv grim-${{ needs.version.outputs.v }}-win-x86_64.msi release\
          Compress-Archive -Path target\release\grim.exe -DestinationPath grim-${{ needs.version.outputs.v }}-win-x86_64.zip
          mv grim-${{ needs.version.outputs.v }}-win-x86_64.zip release\
      - name: Checksum Archive x86
        working-directory: release
        run: |
          certutil -hashfile grim-${{ needs.version.outputs.v }}-win-x86_64.msi SHA256 > grim-${{ needs.version.outputs.v }}-win-x86_64-msi-sha256sum.txt
          certutil -hashfile grim-${{ needs.version.outputs.v }}-win-x86_64.zip SHA256 > grim-${{ needs.version.outputs.v }}-win-x86_64-sha256sum.txt
      - name: Upload artifacts
        run: |
          tar -czf windows.tar.gz release
          Remove-Item alias:curl
          curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file windows.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/windows.tar.gz

  release:
    if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
    runs-on: debian-release
    needs: [version, android_release, linux, linux_x86, macos, windows]
    steps:
      - name: Download All Artifacts
        run: |
          curl -o android.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/android.tar.gz
          tar -xzf android.tar.gz
          rm android.tar.gz
          curl -o linux-arm.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/linux-arm.tar.gz
          tar -xzf linux-arm.tar.gz
          rm linux-arm.tar.gz
          curl -o linux-x86_64.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/linux-x86_64.tar.gz
          tar -xzf linux-x86_64.tar.gz
          rm linux-x86_64.tar.gz
          curl -o macos.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/macos.tar.gz
          tar -xzf macos.tar.gz
          rm macos.tar.gz
          curl -o windows.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/windows.tar.gz
          tar -xzf windows.tar.gz
          rm windows.tar.gz
      - name: Upload release to Forgejo
        uses: actions/forgejo-release@v2.11.3
        with:
          direction: upload
          token: ${{ secrets.RELEASE_TOKEN }}
          tag: ${{ needs.version.outputs.v }}
          override: true
          prerelease: ${{ needs.version.outputs.pre == 'true' }}
          release-dir: release
          release-notes: "Full Changelog: [${{ needs.version.outputs.last_tag }}...${{ needs.version.outputs.v }}](https://code.gri.mw/${{ forgejo.repository }}/compare/${{ needs.version.outputs.last_tag }}...${{ needs.version.outputs.v }})"
      - name: Telegram Notify Channel
        if: always()
        uses: actions/telegram-notifier@main
        with:
          api_url: ${{ secrets.TELEGRAM_API_URL }}
          token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          chat_id: ${{ secrets.TELEGRAM_CHANNEL_ID }}
          status: ${{ job.status }}
          notify_fields: "actor,repository,workflow,branch,commit"
      - name: Telegram Notify Group
        if: always()
        uses: actions/telegram-notifier@main
        with:
          api_url: ${{ secrets.TELEGRAM_API_URL }}
          token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          chat_id: ${{ secrets.TELEGRAM_GROUP_ID }}
          status: ${{ job.status }}
          notify_fields: "actor,repository,workflow,branch,commit"

  release-telegram:
    runs-on: debian-release
    needs: [version, release]
    steps:
      - name: Download All Artifacts
        run: |
          mkdir release
          cd release
          wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/grim-${{ needs.version.outputs.v }}-android.apk
          wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/grim-${{ needs.version.outputs.v }}-android-x86_64.apk
          wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/grim-${{ needs.version.outputs.v }}-linux-arm.AppImage
          wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/grim-${{ needs.version.outputs.v }}-linux-x86_64.AppImage
          wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/grim-${{ needs.version.outputs.v }}-macos-universal.zip
          wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/grim-${{ needs.version.outputs.v }}-win-x86_64.msi
          wget ${{ secrets.REPO_HOST }}/${{ forgejo.repository }}/releases/download/${{ needs.version.outputs.v }}/grim-${{ needs.version.outputs.v }}-win-x86_64.zip
      - name: Upload files to Telegram
        uses: actions/telegram-send-file@main
        with:
          api_url: ${{ secrets.TELEGRAM_API_URL }}
          chat_ids: |
            ${{ secrets.TELEGRAM_CHANNEL_ID }}
            ${{ secrets.TELEGRAM_GROUP_ID }}
          body: '🎁 Release <a href="https://code.gri.mw/${{ forgejo.repository }}/releases">${{ needs.version.outputs.v }}</a> is ready!'
          token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          pin: true
          files: |
            release/grim-${{ needs.version.outputs.v }}-android.apk
            release/grim-${{ needs.version.outputs.v }}-android-x86_64.apk
            release/grim-${{ needs.version.outputs.v }}-linux-arm.AppImage
            release/grim-${{ needs.version.outputs.v }}-linux-x86_64.AppImage
            release/grim-${{ needs.version.outputs.v }}-macos-universal.zip
            release/grim-${{ needs.version.outputs.v }}-win-x86_64.msi
            release/grim-${{ needs.version.outputs.v }}-win-x86_64.zip