spotube icon indicating copy to clipboard operation
spotube copied to clipboard

Create build-iPA.yml to build iPA for iOS

Open powenn opened this issue 1 year ago β€’ 9 comments

Hi , I saw some discussions about providing iPA files for iOS sideloading , so this pull request was made for solving it . Tested on TrollStore , video attach at bottom link to download iPA https://github.com/powenn/spotube/releases/tag/3.3.0 link to my build result https://github.com/powenn/spotube/actions/runs/7361863281 ζˆͺεœ– 2023-12-30 中午12 13 04

Description

This pull request introduces a continuous integration (CI) workflow using GitHub Actions for building and packaging the Flutter iOS app into an IPA file. The workflow runs on macOS-latest and performs the following steps:

  1. Checks out the repository.
  2. Initializes submodules.
  3. Sets up Flutter using the subosito/flutter-action GitHub Action.
  4. Builds the Flutter project, generating necessary files and artifacts.
  5. Creates an IPA file from the iOS build without code signing.
  6. Zips the resulting IPA file and uploads it as an artifact.

Changes Made

  • Added .github/workflows/build-ipa.yml for the GitHub Actions CI workflow.
  • Updated the Flutter version in the workflow.
  • Added steps to copy the environment file, run build_runner, and build the iOS app.
  • Zipped the resulting IPA file and uploaded it as an artifact.

Additional Notes

  • The workflow ~~is triggered on pushes, pull requests, and~~ manual runs using workflow_dispatch.
  • The IPA file is named spotube.ipa.
  • Set iOS app App Icon (same as the Android one)
  • Fix incorrect app name

https://github.com/KRTirtho/spotube/assets/72635554/1c231e45-71f9-40d3-808c-ea5d60ff5486

powenn avatar Dec 30 '23 04:12 powenn

Excellent work. First of all, thanks for submitting the PR ❀️

Some changes are requested:

  1. We use .github/workflow/spotube-release-binary.yml to release both nightly and stable binaries. So instead of a standalone build-ipa.yml, we should integrate with spotube-release-binary.yml so everything can be released at once, just like other platform executable formats.

  2. Currently, I guess ios only has nightly flavor. We should also add the dev and stable flavor for it as well. You can follow the official flutter flavors guide

KRTirtho avatar Dec 30 '23 13:12 KRTirtho

So there will be three flavors : nightly , dev , stable , right ?

powenn avatar Dec 30 '23 13:12 powenn

Yes, these are the 3 flavors.

  • nightly: For nightly builds in GitHub actions
  • stable: For stable releases in GitHub or other platforms
  • dev: For local development envrionment

KRTirtho avatar Dec 30 '23 14:12 KRTirtho

Okay , I will add flavors first

powenn avatar Dec 30 '23 14:12 powenn

update working status https://github.com/powenn/spotube/actions/runs/7364987962

now can build with flavors , each flavor has different bundle identifier follow this format oss.krtirtho.spotube.{flavor} for example oss.krtirtho.spotube.nightly

next step integrate with spotube-release-binary.yml after that , build-iPA.yml can be removed

ζˆͺεœ– 2023-12-31 ε‡Œζ™¨12 20 07 ζˆͺεœ– 2023-12-31 ε‡Œζ™¨12 44 27

IMG_7259

https://github.com/KRTirtho/spotube/assets/72635554/d6ba2e22-bf88-4664-884b-988937b50a0c

powenn avatar Dec 30 '23 16:12 powenn

needs help for test I can't do without GitHub secrets

name: Spotube Release Binary
on:
  workflow_dispatch:
    inputs:
      version:
        description: Version to release (x.x.x)
        default: 3.3.0
        required: true
      channel:
        type: choice
        description: Release Channel
        required: true
        options:
          - stable
          - nightly
        default: nightly
      debug:
        description: Debug on failed when channel is nightly
        required: true
        type: boolean
        default: false
      dry_run:
        description: Dry run
        required: true
        type: boolean
        default: true

env:
  FLUTTER_VERSION: '3.16.0'

jobs:
  windows:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/checkout@v4
        with:
          repository: KRTirtho/flutter_distributor
          path: flutter_distributor
          ref: fix-windows-build
      - uses: subosito/[email protected]
        with:
          cache: true
          flutter-version: ${{ env.FLUTTER_VERSION  }}

      - name: Replace pubspec version and BUILD_VERSION Env (nightly)
        if: ${{ inputs.channel == 'nightly' }}
        run: |
          choco install sed make yq -y
          yq -i '.version |= sub("\+\d+", "+${{ inputs.channel }}.")' pubspec.yaml
          yq -i '.version += strenv(GITHUB_RUN_NUMBER)' pubspec.yaml
          "BUILD_VERSION=${{ inputs.version }}+${{ inputs.channel }}.${{ github.run_number }}" >> $env:GITHUB_ENV

      - name: BUILD_VERSION Env (stable)
        if: ${{ inputs.channel == 'stable' }}
        run: |
          "BUILD_VERSION=${{ inputs.version }}" >> $env:GITHUB_ENV

      - name: Replace version in files
        run: |
          choco install sed make -y
          sed -i "s/%{{SPOTUBE_VERSION}}%/${{ env.BUILD_VERSION }}/" windows/runner/Runner.rc
          sed -i "s/%{{SPOTUBE_VERSION}}%/${{ env.BUILD_VERSION }}/" choco-struct/tools/VERIFICATION.txt
          sed -i "s/%{{SPOTUBE_VERSION}}%/${{ env.BUILD_VERSION }}/" choco-struct/spotube.nuspec

      - name: Create Stable .env
        if: ${{ inputs.channel == 'stable' }}
        run: echo '${{ secrets.DOTENV_RELEASE }}' > .env

      - name: Create Nightly .env
        if: ${{ inputs.channel == 'nightly' }}
        run: echo '${{ secrets.DOTENV_NIGHTLY }}' > .env

      - name: Generating Secrets
        run: |
          flutter config --enable-windows-desktop
          flutter pub get
          dart run build_runner build --delete-conflicting-outputs --enable-experiment=records,patterns

      - name: Build Windows Executable
        run: |
          dart pub global activate melos
          cd flutter_distributor && melos bs && cd ..
          make innoinstall
          dart run ./flutter_distributor/packages/flutter_distributor/bin/main.dart package --platform=windows --targets=exe --skip-clean
          mv dist/**/spotube-*-windows-setup.exe dist/Spotube-windows-x86_64-setup.exe

      - name: Create Chocolatey Package and set hash
        if: ${{ inputs.channel == 'stable' }}
        run: |
          Set-Variable -Name HASH -Value (Get-FileHash dist\Spotube-windows-x86_64-setup.exe).Hash
          sed -i "s/%{{WIN_SHA256}}%/$HASH/" choco-struct/tools/VERIFICATION.txt
          make choco
          mv dist/spotube.*.nupkg dist/Spotube-windows-x86_64.nupkg


      - name: Upload Artifact
        uses: actions/upload-artifact@v3
        with:
          if-no-files-found: error
          name: Spotube-Release-Binaries
          path: |
            dist/Spotube-windows-x86_64.nupkg
            dist/Spotube-windows-x86_64-setup.exe

      - name: Debug With SSH When fails
        if: ${{ failure() && inputs.debug && inputs.channel == 'nightly' }}
        uses: mxschmitt/action-tmate@v3
        with:
          limit-access-to-actor: true

  linux:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/[email protected]
        with:
          cache: true
          flutter-version: ${{ env.FLUTTER_VERSION  }}

      - name: Get current date
        id: date
        run: echo "::set-output name=date::$(date +'%Y-%m-%d')"

      - name: Install Dependencies
        run: |
          sudo apt-get update -y
          sudo apt-get install -y tar clang cmake ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse libunwind-dev locate patchelf gir1.2-appindicator3-0.1 libappindicator3-1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev mpv libmpv-dev

      - name: Install AppImage Tool
        run: |
          wget -O appimagetool "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
          chmod +x appimagetool
          mv appimagetool /usr/local/bin/

      - name: Replace pubspec version and BUILD_VERSION Env (nightly)
        if: ${{ inputs.channel == 'nightly' }}
        run: |
          curl -sS https://webi.sh/yq | sh
          yq -i '.version |= sub("\+\d+", "+${{ inputs.channel }}.")' pubspec.yaml
          yq -i '.version += strenv(GITHUB_RUN_NUMBER)' pubspec.yaml
          echo "BUILD_VERSION=${{ inputs.version }}+${{ inputs.channel  }}.${{ github.run_number }}" >> $GITHUB_ENV

      - name: BUILD_VERSION Env (stable)
        if: ${{ inputs.channel == 'stable' }}
        run: |
          echo "BUILD_VERSION=${{ inputs.version }}" >> $GITHUB_ENV

      - name: Create Stable .env
        if: ${{ inputs.channel == 'stable' }}
        run: echo '${{ secrets.DOTENV_RELEASE }}' > .env

      - name: Create Nightly .env
        if: ${{ inputs.channel == 'nightly' }}
        run: echo '${{ secrets.DOTENV_NIGHTLY }}' > .env

      - name: Replace Version in files
        run: |
          sed -i 's|%{{APPDATA_RELEASE}}%|<release version="${{ env.BUILD_VERSION }}" date="${{ steps.date.outputs.date }}" />|' linux/com.github.KRTirtho.Spotube.appdata.xml

      - name: Generate Secrets
        run: |
          flutter config --enable-linux-desktop
          flutter pub get
          dart run build_runner build --delete-conflicting-outputs --enable-experiment=records,patterns

      - name: Build Linux Packages
        run: |
          dart pub global activate flutter_distributor
          alias dpkg-deb="dpkg-deb --Zxz"
          flutter_distributor package --platform=linux --targets=deb
          flutter_distributor package --platform=linux --targets=appimage
          flutter_distributor package --platform=linux --targets=rpm

      - name: Create tar.xz (stable)
        if: ${{ inputs.channel == 'stable' }}
        run: make tar VERSION=${{ env.BUILD_VERSION }} ARCH=x64 PKG_ARCH=x86_64
      
      - name: Create tar.xz (nightly)
        if: ${{ inputs.channel == 'nightly' }}
        run: make tar VERSION=nightly ARCH=x64 PKG_ARCH=x86_64

      - name: Move Files to dist
        run: |
          mv build/spotube-linux-*-x86_64.tar.xz dist/
          mv dist/**/spotube-*-linux.deb dist/Spotube-linux-x86_64.deb
          mv dist/**/spotube-*-linux.rpm dist/Spotube-linux-x86_64.rpm
          mv dist/**/spotube-*-linux.AppImage dist/Spotube-linux-x86_64.AppImage


      - uses: actions/upload-artifact@v3
        with:
          if-no-files-found: error
          name: Spotube-Release-Binaries
          path: |
            dist/Spotube-linux-x86_64.AppImage
            dist/Spotube-linux-x86_64.deb
            dist/Spotube-linux-x86_64.rpm
            dist/spotube-linux-${{ env.BUILD_VERSION }}-x86_64.tar.xz

      - name: Debug With SSH When fails
        if: ${{ failure() && inputs.debug && inputs.channel == 'nightly' }}
        uses: mxschmitt/action-tmate@v3
        with:
          limit-access-to-actor: true


  android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/[email protected]
        with:
          cache: true
          flutter-version: ${{ env.FLUTTER_VERSION  }}

      - name: Install Dependencies
        run: |
          sudo apt-get update -y
          sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse xmlstarlet

      - name: Replace pubspec version and BUILD_VERSION Env (nightly)
        if: ${{ inputs.channel == 'nightly' }}
        run: |
          curl -sS https://webi.sh/yq | sh
          yq -i '.version |= sub("\+\d+", "+${{ inputs.channel }}.")' pubspec.yaml
          yq -i '.version += strenv(GITHUB_RUN_NUMBER)' pubspec.yaml
          echo "BUILD_VERSION=${{ inputs.version }}+${{ inputs.channel  }}.${{ github.run_number }}" >> $GITHUB_ENV

      - name: BUILD_VERSION Env (stable)
        if: ${{ inputs.channel == 'stable' }}
        run: |
          echo "BUILD_VERSION=${{ inputs.version }}" >> $GITHUB_ENV

      - name: Create Stable .env
        if: ${{ inputs.channel == 'stable' }}
        run: echo '${{ secrets.DOTENV_RELEASE }}' > .env

      - name: Create Nightly .env
        if: ${{ inputs.channel == 'nightly' }}
        run: echo '${{ secrets.DOTENV_NIGHTLY }}' > .env

      - name: Generate Secrets
        run: |
          flutter pub get
          dart run build_runner build --delete-conflicting-outputs --enable-experiment=records,patterns

      - name: Sign Apk
        run: |
          echo '${{ secrets.KEYSTORE }}' | base64 --decode > android/app/upload-keystore.jks
          echo '${{ secrets.KEY_PROPERTIES }}' > android/key.properties

      - name: Build Apk
        run: |
          flutter build apk --flavor ${{ inputs.channel }}          
          mv build/app/outputs/flutter-apk/app-${{ inputs.channel }}-release.apk build/Spotube-android-all-arch.apk

      - name: Build Playstore AppBundle
        run: |
          echo 'ENABLE_UPDATE_CHECK=0' >> .env
          dart run build_runner build --delete-conflicting-outputs --enable-experiment=records,patterns
          export MANIFEST=android/app/src/main/AndroidManifest.xml
          xmlstarlet ed -d '//meta-data[@android:name="com.google.android.gms.car.application"]' $MANIFEST > $MANIFEST.tmp
          mv $MANIFEST.tmp $MANIFEST
          flutter build appbundle --flavor ${{ inputs.channel }}
          mv build/app/outputs/bundle/${{ inputs.channel }}Release/app-${{ inputs.channel }}-release.aab build/Spotube-playstore-all-arch.aab


      - uses: actions/upload-artifact@v3
        with:
          if-no-files-found: error
          name: Spotube-Release-Binaries
          path: |
            build/Spotube-android-all-arch.apk
            build/Spotube-playstore-all-arch.aab

      - name: Debug With SSH When fails
        if: ${{ failure() && inputs.debug && inputs.channel == 'nightly' }}
        uses: mxschmitt/action-tmate@v3
        with:
          limit-access-to-actor: true

  macos:

    runs-on: macos-12
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/[email protected]
        with:
          cache: true
          flutter-version: ${{ env.FLUTTER_VERSION  }}

      - name: Replace pubspec version and BUILD_VERSION Env (nightly)
        if: ${{ inputs.channel == 'nightly' }}
        run: |
          brew install yq
          yq -i '.version |= sub("\+\d+", "+${{ inputs.channel }}.")' pubspec.yaml
          yq -i '.version += strenv(GITHUB_RUN_NUMBER)' pubspec.yaml
          echo "BUILD_VERSION=${{ inputs.version }}+${{ inputs.channel  }}.${{ github.run_number }}" >> $GITHUB_ENV

      - name: BUILD_VERSION Env (stable)
        if: ${{ inputs.channel == 'stable' }}
        run: |
          echo "BUILD_VERSION=${{ inputs.version }}" >> $GITHUB_ENV

      - name: Create Stable .env
        if: ${{ inputs.channel == 'stable' }}
        run: echo '${{ secrets.DOTENV_RELEASE }}' > .env

      - name: Create Nightly .env
        if: ${{ inputs.channel == 'nightly' }}
        run: echo '${{ secrets.DOTENV_NIGHTLY }}' > .env

      - name: Generate Secrets
        run: |
          flutter pub get
          flutter pub remove media_kit_native_event_loop
          dart run build_runner build --delete-conflicting-outputs --enable-experiment=records,patterns

      - name: Build Macos App
        run: |
          flutter config --enable-macos-desktop
          flutter build macos
          du -sh build/macos/Build/Products/Release/spotube.app

      - name: Package Macos App
        run: |
          python3 -m pip install setuptools
          npm install -g appdmg
          mkdir -p build/${{ env.BUILD_VERSION }}
          appdmg appdmg.json build/Spotube-macos-universal.dmg

  iOS:

    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4
      - uses: subosito/[email protected]
        with:
          cache: true
          flutter-version: ${{ env.FLUTTER_VERSION  }}

      - name: Replace pubspec version and BUILD_VERSION Env (nightly)
        if: ${{ inputs.channel == 'nightly' }}
        run: |
          brew install yq
          yq -i '.version |= sub("\+\d+", "+${{ inputs.channel }}.")' pubspec.yaml
          yq -i '.version += strenv(GITHUB_RUN_NUMBER)' pubspec.yaml
          echo "BUILD_VERSION=${{ inputs.version }}+${{ inputs.channel  }}.${{ github.run_number }}" >> $GITHUB_ENV

      - name: BUILD_VERSION Env (stable)
        if: ${{ inputs.channel == 'stable' }}
        run: |
          echo "BUILD_VERSION=${{ inputs.version }}" >> $GITHUB_ENV

      - name: Create Stable .env
        if: ${{ inputs.channel == 'stable' }}
        run: echo '${{ secrets.DOTENV_RELEASE }}' > .env

      - name: Create Nightly .env
        if: ${{ inputs.channel == 'nightly' }}
        run: echo '${{ secrets.DOTENV_NIGHTLY }}' > .env

      - name: Generate Secrets
        run: |
          flutter pub get
          dart run build_runner build --delete-conflicting-outputs --enable-experiment=records,patterns

      - name: Build iOS iPA
        run: |
          flutter build ios --release --no-codesign --flavor ${{ inputs.channel }}  
          ln -sf ./build/ios/iphoneos Payload
          zip -r9 spotube-${{ inputs.channel }}.ipa Payload/${{ inputs.channel }}.app

      - uses: actions/upload-artifact@v3
        with:
          if-no-files-found: error
          name: Spotube-Release-Binaries
          path: |
            spotube-${{ inputs.channel }}.ipa

      - name: Debug With SSH When fails
        if: ${{ failure() && inputs.debug && inputs.channel == 'nightly' }}
        uses: mxschmitt/action-tmate@v3
        with:
          limit-access-to-actor: true
          
  upload:
    runs-on: ubuntu-latest

    needs:
      - windows
      - linux
      - android
      - macos
      - iOS
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: Spotube-Release-Binaries
          path: ./Spotube-Release-Binaries

      - name: Install dependencies
        run: sudo apt-get install tree -y

      - name: Generate Checksums
        run: |
          tree .
          md5sum Spotube-Release-Binaries/* >> RELEASE.md5sum
          sha256sum Spotube-Release-Binaries/* >> RELEASE.sha256sum
          sed -i 's|Spotube-Release-Binaries/||' RELEASE.sha256sum RELEASE.md5sum

      - uses: actions/upload-artifact@v3
        with:
          if-no-files-found: error
          name: Spotube-Release-Binaries
          path: |
            RELEASE.md5sum
            RELEASE.sha256sum

      - name: Upload Release Binaries (stable)
        if: ${{ !inputs.dry_run && inputs.channel == 'stable' }}
        uses: ncipollo/release-action@v1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          tag: v${{ inputs.version }} # mind the "v" prefix
          omitBodyDuringUpdate: true
          omitNameDuringUpdate: true
          omitPrereleaseDuringUpdate: true
          allowUpdates: true
          artifacts: Spotube-Release-Binaries/*,RELEASE.sha256sum,RELEASE.md5sum

      - name: Upload Release Binaries (nightly)
        if: ${{ !inputs.dry_run && inputs.channel == 'nightly' }}
        uses: ncipollo/release-action@v1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          tag: nightly
          omitBodyDuringUpdate: true
          omitNameDuringUpdate: true
          omitPrereleaseDuringUpdate: true
          allowUpdates: true
          artifacts: Spotube-Release-Binaries/*,RELEASE.sha256sum,RELEASE.md5sum

powenn avatar Dec 30 '23 18:12 powenn

You'll need the following:

  • DOTENV_NIGHTLY (follow the .env.example)
  • DOTENV_RELEASE (same as nightly)
  • KEYSTORE (base64 encoded app signing keystore upload-keystore.jks. Follow flutter apk signing)
  • KEY_PROPERTIES - Learn here
  • GITHUB_TOKEN - Don't worry about it's supplied by default by Github

KRTirtho avatar Dec 30 '23 18:12 KRTirtho

I only set two DOTENV , but seems it works, I pass android part so it failed .

https://github.com/powenn/spotube/actions/workflows/spotube-release-binary.yml

image

powenn avatar Dec 30 '23 18:12 powenn

@KRTirtho I think it's ready for review

powenn avatar Dec 31 '23 02:12 powenn

@powenn Flavor support was added but the logo is still using the nightly version for every flavor.

You can run without specifying the nightly config files for flutter_native_splash and flutter_launcher_icons

$ dart run flutter_launcher_icons
$ dart run flutter_native_splash:create

KRTirtho avatar Jan 02 '24 16:01 KRTirtho

What is the correct asset for each flavor icon Like spotube-logo for stable spotube-nightly-logo for nightly

Then what's the asset for dev icon

powenn avatar Jan 02 '24 16:01 powenn

The dev and stable icons are the same. Only the name are different in home screen. One is "Spotube Dev" other is just "Spotube"

KRTirtho avatar Jan 02 '24 16:01 KRTirtho

Tried the command provided , but didn't generate appicon assets , do I have to update some yaml config ?

Solved in the latest commit , now dev and stable are using correct Appicon

powenn avatar Jan 02 '24 17:01 powenn

IMG_7273

powenn avatar Jan 02 '24 18:01 powenn

Awesome work! I guess it should work fine now. 😁

Thanks a lot for the contribution ❀️

KRTirtho avatar Jan 02 '24 18:01 KRTirtho

It install and works fine except if the screen get locked the music stop playing.

ZJPat avatar Jan 20 '24 18:01 ZJPat

Trying to install this ipa with AltStore and getting /Users/rileytestut/Developer/Projects/AltStore/Dependencies/AltSign/AltSign/ldid/../../Dependencies/ldid/ldid.cpp(1368): _assert(): end >= size - 0x10, any ideas?

sachit-menon avatar Jan 23 '24 05:01 sachit-menon