spotube
spotube copied to clipboard
Create build-iPA.yml to build iPA for iOS
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
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:
- Checks out the repository.
- Initializes submodules.
- Sets up Flutter using the
subosito/flutter-action
GitHub Action. - Builds the Flutter project, generating necessary files and artifacts.
- Creates an IPA file from the iOS build without code signing.
- 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
Excellent work. First of all, thanks for submitting the PR β€οΈ
Some changes are requested:
-
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 withspotube-release-binary.yml
so everything can be released at once, just like other platform executable formats. -
Currently, I guess ios only has nightly flavor. We should also add the
dev
andstable
flavor for it as well. You can follow the official flutter flavors guide
So there will be three flavors : nightly , dev , stable , right ?
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
Okay , I will add flavors first
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
https://github.com/KRTirtho/spotube/assets/72635554/d6ba2e22-bf88-4664-884b-988937b50a0c
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
You'll need the following:
-
DOTENV_NIGHTLY
(follow the .env.example) -
DOTENV_RELEASE
(same as nightly) -
KEYSTORE
(base64 encoded app signing keystoreupload-keystore.jks
. Follow flutter apk signing) -
KEY_PROPERTIES
- Learn here -
GITHUB_TOKEN
- Don't worry about it's supplied by default by Github
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
@KRTirtho I think it's ready for review
@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
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
The dev and stable icons are the same. Only the name are different in home screen. One is "Spotube Dev" other is just "Spotube"
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
Awesome work! I guess it should work fine now. π
Thanks a lot for the contribution β€οΈ
It install and works fine except if the screen get locked the music stop playing.
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?