name: Nightly SideStore build
on:
  push:
    branches:
      - develop

jobs:
  build:
    name: Build and upload SideStore Nightly releases
    concurrency:
      group: ${{ github.ref }}
      cancel-in-progress: true
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: 'macos-14'
            version: '16.1'

    runs-on: ${{ matrix.os }}
    steps:

      - name: Set current build as BETA
        run: echo "IS_BETA=1" >> $GITHUB_ENV
        
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Install dependencies
        run: brew install ldid

      - name: Install xcbeautify
        run: brew install xcbeautify

      - name: Cache .nightly-build-num
        uses: actions/cache@v4
        with:
          path: .nightly-build-num
          key: nightly-build-num

      - name: Get version
        id: version-marketing
        run: echo "VERSION_IPA=$(grep MARKETING_VERSION Build.xcconfig | sed -e "s/MARKETING_VERSION = //g")" >> $GITHUB_ENV

      - name: Increase nightly build number and set as version
        run: bash .github/workflows/increase-nightly-build-num.sh

      - name: Get version
        id: version
        run: echo "version=$(grep MARKETING_VERSION Build.xcconfig | sed -e "s/MARKETING_VERSION = //g")" >> $GITHUB_OUTPUT

      - name: Echo version
        run: echo "${{ steps.version.outputs.version }}"

      - name: Setup Xcode
        uses: maxim-lobanov/setup-xcode@v1.6.0
        with:
          xcode-version: ${{ matrix.version }}

      - name: Cache Build
        uses: irgaly/xcode-cache@v1
        with:
          key: xcode-cache-deriveddata-${{ github.sha }}
          restore-keys: xcode-cache-deriveddata-
          swiftpm-cache-key: xcode-cache-sourcedata-${{ github.sha }}
          swiftpm-cache-restore-keys: |
            xcode-cache-sourcedata-


      - name: Restore Pods from Cache (Exact match)
        id: pods-restore
        uses: actions/cache/restore@v3
        with:
          path: |
            ./Podfile.lock
            ./Pods/
            ./AltStore.xcworkspace/
          key: pods-cache-${{ hashFiles('Podfile') }}
          # restore-keys: |         # commented out to strictly check cache for this particular podfile
          #   pods-cache-
          
      - name: Restore Pods from Cache (Last Available)
        if: ${{ steps.pods-restore.outputs.cache-hit != 'true' }} 
        id: pods-restore-recent
        uses: actions/cache/restore@v3
        with:
          path: |
            ./Podfile.lock
            ./Pods/
            ./AltStore.xcworkspace/
          key: pods-cache-

      - name: Install CocoaPods
        # if: ${{ steps.pods-restore.outputs.cache-hit != 'true'}}
        id: pods-install
        run: |
          pod install

      - name: Save Pods to Cache
        id: save-pods
        if: ${{ steps.pods-restore.outputs.cache-hit != 'true' }}
        uses: actions/cache/save@v3
        with:
          path: |
            ./Podfile.lock
            ./Pods/
            ./AltStore.xcworkspace/
          key: pods-cache-${{ hashFiles('Podfile') }}
    
      - name: List Files and derived data
        run: |
          echo ">>>>>>>>> Workdir <<<<<<<<<<"
          ls -la .
          echo ""
          
          echo ">>>>>>>>> Pods <<<<<<<<<<"
          find Pods -maxdepth 2 -exec ls -ld {} + || true  # List contents if directory exists    
          echo ""
          
          echo ">>>>>>>>> SideStore <<<<<<<<<<"
          find SideStore -maxdepth 2 -exec ls -ld {} +  || true  # List contents if directory exists    
          echo ""
          
          echo ">>>>>>>>> Dependencies <<<<<<<<<<"
          find Dependencies -maxdepth 2 -exec ls -ld {} +  || true  # List contents if directory exists    
          echo ""
          
          echo ">>>>>>>>> Xcode-Derived-Data <<<<<<<<<<"
          ls -la ~/Library/Developer/Xcode/DerivedData || true  # List contents if directory exists    
          echo ""

        
      - name: Build SideStore
        run: NSUnbufferedIO=YES make build 2>&1 | xcbeautify --renderer github-actions && exit ${PIPESTATUS[0]}

      - name: Fakesign app
        run: make fakesign

      - name: Convert to IPA
        run: make ipa

      - name: Get current date
        id: date
        run: echo "date=$(date -u +'%c')" >> $GITHUB_OUTPUT

      - name: Get current date in AltStore date form
        id: date_altstore
        run: echo "date=$(date -u +'%Y-%m-%d')" >> $GITHUB_OUTPUT

      - name: Create dSYMs zip
        run: zip -r -9 ./SideStore.dSYMs.zip ./SideStore.xcarchive/dSYMs/*
      
      - name: Upload to nightly release
        uses: IsaacShelton/update-existing-release@v1.3.1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          release: "Nightly"
          tag: "nightly"
          prerelease: true
          files: SideStore.ipa SideStore.dSYMs.zip
          body: |
              This is an ⚠️ **EXPERIMENTAL** ⚠️ nightly build for commit [${{ github.sha }}](https://github.com/${{ github.repository }}/commit/${{ github.sha }}).
              
              Nightly builds are **extremely experimental builds only meant to be used by developers and beta testers. They often contain bugs and experimental features. Use at your own risk!**
              
              If you want to try out new features early but want a lower chance of bugs, you can look at [SideStore Stable](https://github.com/${{ github.repository }}/releases?q=stable).
              
              ## Build Info
              
              Built at (UTC): `${{ steps.date.outputs.date }}`
              Built at (UTC date): `${{ steps.date_altstore.outputs.date }}`
              Commit SHA: `${{ github.sha }}`
              Version: `${{ steps.version.outputs.version }}`

      - name: Add version to IPA file name
        run: mv SideStore.ipa SideStore-${{ steps.version.outputs.version }}.ipa

      - name: Upload SideStore.ipa Artifact
        uses: actions/upload-artifact@v4
        with:
          name: SideStore-${{ steps.version.outputs.version }}.ipa
          path: SideStore-${{ steps.version.outputs.version }}.ipa

      - name: Upload *.dSYM Artifact
        uses: actions/upload-artifact@v4
        with:
          name: SideStore-${{ steps.version.outputs.version }}-dSYM
          path: ./SideStore.xcarchive/dSYMs/*

      # Check if PUBLISH_BETA_UPDATES secret is set to non-zero
      - name: Check if PUBLISH_BETA_UPDATES is set
        id: check_publish
        run: |
          if [[ "${{ secrets.PUBLISH_BETA_UPDATES }}" != "__YES__" ]]; then
            echo "PUBLISH_BETA_UPDATES is not set. Skipping deployment."
            exit 1  # Exit with 1 to indicate no deployment
          else
            echo "PUBLISH_BETA_UPDATES is set. Proceeding with deployment."
            exit 0  # Exit with 0 to indicate deployment should proceed
          fi
        continue-on-error: true  # Continue even if exit code is 1

      - name: Get short commit hash
        if: ${{ steps.check_publish.outcome == 'success' }}
        run: |
          # SHORT_COMMIT="${{ github.sha }}"
          SHORT_COMMIT=${GITHUB_SHA:0:7}
          echo "Short commit hash: $SHORT_COMMIT"
          echo "SHORT_COMMIT=$SHORT_COMMIT" >> $GITHUB_ENV          

      - name: Get formatted date
        if: ${{ steps.check_publish.outcome == 'success' }}
        run: |
          FORMATTED_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
          echo "Formatted date: $FORMATTED_DATE"
          echo "FORMATTED_DATE=$FORMATTED_DATE" >> $GITHUB_ENV          
      
      - name: Get size of IPA in bytes (macOS/Linux)
        if: ${{ steps.check_publish.outcome == 'success' }}
        run: |
          if [[ "$(uname)" == "Darwin" ]]; then
            # macOS
            IPA_SIZE=$(stat -f %z SideStore-${{ steps.version.outputs.version }}.ipa)
          else
            # Linux
            IPA_SIZE=$(stat -c %s SideStore-${{ steps.version.outputs.version }}.ipa)
          fi
          echo "IPA size in bytes: $IPA_SIZE"
          echo "IPA_SIZE=$IPA_SIZE" >> $GITHUB_ENV

      - name: Compute SHA-256 of IPA
        if: ${{ steps.check_publish.outcome == 'success' }}
        run: |
          SHA256_HASH=$(shasum -a 256 SideStore-${{ steps.version.outputs.version }}.ipa | awk '{ print $1 }')
          echo "SHA-256 Hash: $SHA256_HASH"
          echo "SHA256_HASH=$SHA256_HASH" >> $GITHUB_ENV

      - name: Set environment variables dynamically
        if: ${{ steps.check_publish.outcome == 'success' }}
        run: |
          echo "VERSION_IPA=$VERSION_IPA" >> $GITHUB_ENV
          echo "VERSION_DATE=$FORMATTED_DATE" >> $GITHUB_ENV
          echo "BETA=true" >> $GITHUB_ENV
          echo "COMMIT_ID=$SHORT_COMMIT" >> $GITHUB_ENV
          echo "SIZE=$IPA_SIZE" >> $GITHUB_ENV
          echo "SHA256=$SHA256_HASH" >> $GITHUB_ENV
          echo "LOCALIZED_DESCRIPTION=This is nightly release for revision: ${{ github.sha }}" >> $GITHUB_ENV
          echo "DOWNLOAD_URL=https://github.com/SideStore/SideStore/releases/download/nightly/SideStore.ipa" >> $GITHUB_ENV

      # - name: Checkout SideStore/apps-v2.json
      #   if: ${{ steps.check_publish.outcome == 'success' }}
      #   uses: actions/checkout@v4
      #   with:
      #       # Repository name with owner. For example, actions/checkout
      #       # Default: ${{ github.repository }}
      #       repository: 'SideStore/apps-v2.json'
      #       # ref: 'main' # TODO: use branches for alpha and beta tracks? so as to avoid push collision?
      #       ref: 'nightly' # TODO: use branches for alpha and beta tracks? so as to avoid push collision?
      #       # token: ${{ github.token }}
      #       token: ${{ secrets.APPS_DEPLOY_KEY }}
      #       path: 'SideStore/apps-v2.json'
      
      # - name: Publish to SideStore/apps-v2.json
      #   if: ${{ steps.check_publish.outcome == 'success' }}
      #   run: |
      #     # Copy and execute the update script
      #     pushd SideStore/apps-v2.json/
  
      #     # Configure Git user (committer details)
      #     git config user.name "GitHub Actions"
      #     git config user.email "github-actions@github.com"
          
      #     # Make the update script executable and run it
      #     python3 ../../update_apps.py "./_includes/source.json"
          
      #     # Commit changes and push using SSH
      #     git add ./_includes/source.json
      #     git commit -m " - updated for $SHORT_COMMIT deployment" || echo "No changes to commit"

      #     git status
      #     # git push origin HEAD:main
      #     git push origin HEAD:nightly
      #     popd
