Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create build-iPA.yml to build iPA for iOS #971

Merged
merged 11 commits into from
Jan 2, 2024
Merged

Conversation

powenn
Copy link
Contributor

@powenn powenn commented Dec 30, 2023

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
RPReplay_Final1703931424.MP4

@powenn powenn changed the title Create build-iPA.yml Create build-iPA.yml to build iPA for iOS Dec 30, 2023
- Set AppIcon(same as Android)
- Set to correct app name(Sptube -> Spotube)
-
@KRTirtho
Copy link
Owner

KRTirtho commented Dec 30, 2023

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

@powenn
Copy link
Contributor Author

powenn commented Dec 30, 2023

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

@KRTirtho
Copy link
Owner

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

@powenn
Copy link
Contributor Author

powenn commented Dec 30, 2023

Okay , I will add flavors first

@powenn
Copy link
Contributor Author

powenn commented Dec 30, 2023

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

RPReplay_Final1703953765.MP4

@powenn
Copy link
Contributor Author

powenn commented Dec 30, 2023

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

@KRTirtho
Copy link
Owner

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

@powenn
Copy link
Contributor Author

powenn commented Dec 30, 2023

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
Copy link
Contributor Author

powenn commented Dec 31, 2023

@KRTirtho I think it's ready for review

Copy link
Owner

@KRTirtho KRTirtho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we don't need build-iPA.yml anymore

@KRTirtho
Copy link
Owner

KRTirtho commented Jan 2, 2024

@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

@powenn
Copy link
Contributor Author

powenn commented Jan 2, 2024

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

@KRTirtho
Copy link
Owner

KRTirtho commented Jan 2, 2024

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

@powenn
Copy link
Contributor Author

powenn commented Jan 2, 2024

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
Copy link
Contributor Author

powenn commented Jan 2, 2024

IMG_7273

@KRTirtho
Copy link
Owner

KRTirtho commented Jan 2, 2024

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

Thanks a lot for the contribution ❤️

@KRTirtho KRTirtho merged commit b2ba6d9 into KRTirtho:master Jan 2, 2024
1 check failed
@ZJPat
Copy link

ZJPat commented Jan 20, 2024

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

@sachit-menon
Copy link

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants