mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-03-31 17:10:29 +02:00
577 lines
20 KiB
YAML
577 lines
20 KiB
YAML
name: Release
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "v*"
|
|
workflow_dispatch:
|
|
inputs:
|
|
version:
|
|
description: "Version tag (e.g., v1.0.0)"
|
|
required: true
|
|
default: "v1.0.0"
|
|
|
|
jobs:
|
|
# Get version first (quick job)
|
|
get-version:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
version: ${{ steps.version.outputs.version }}
|
|
is_prerelease: ${{ steps.version.outputs.is_prerelease }}
|
|
steps:
|
|
- name: Get version
|
|
id: version
|
|
run: |
|
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
VERSION="${{ github.event.inputs.version }}"
|
|
else
|
|
VERSION="${GITHUB_REF#refs/tags/}"
|
|
fi
|
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
|
|
# Check if version contains -preview, -beta, -rc, or -alpha (NOT -hotfix)
|
|
VERSION_LOWER=$(echo "$VERSION" | tr '[:upper:]' '[:lower:]')
|
|
if [[ "$VERSION_LOWER" == *"-preview"* ]] || [[ "$VERSION_LOWER" == *"-beta"* ]] || [[ "$VERSION_LOWER" == *"-rc"* ]] || [[ "$VERSION_LOWER" == *"-alpha"* ]]; then
|
|
echo "is_prerelease=true" >> $GITHUB_OUTPUT
|
|
echo "Detected pre-release version: $VERSION"
|
|
else
|
|
echo "is_prerelease=false" >> $GITHUB_OUTPUT
|
|
echo "Detected stable version: $VERSION"
|
|
fi
|
|
|
|
# Android and iOS build in PARALLEL
|
|
build-android:
|
|
runs-on: ubuntu-latest
|
|
needs: get-version
|
|
|
|
steps:
|
|
- name: Free disk space
|
|
run: |
|
|
# Remove large unused tools (~15GB total)
|
|
sudo rm -rf /usr/share/dotnet
|
|
sudo rm -rf /opt/ghc
|
|
sudo rm -rf /opt/hostedtoolcache/CodeQL
|
|
sudo rm -rf /usr/local/share/boost
|
|
sudo rm -rf /usr/share/swift
|
|
sudo rm -rf /usr/local/.ghcup
|
|
# Clean docker images
|
|
sudo docker image prune --all --force
|
|
# Show available space
|
|
df -h
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Setup Java
|
|
uses: actions/setup-java@v5
|
|
with:
|
|
distribution: "temurin"
|
|
java-version: "17"
|
|
|
|
- name: Setup Go
|
|
uses: actions/setup-go@v6
|
|
with:
|
|
go-version: "1.25.7"
|
|
cache-dependency-path: go_backend/go.sum
|
|
|
|
# Cache Gradle for faster builds
|
|
- name: Cache Gradle
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: |
|
|
~/.gradle/caches
|
|
~/.gradle/wrapper
|
|
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
|
restore-keys: gradle-${{ runner.os }}-
|
|
|
|
- name: Install Android SDK & NDK
|
|
run: |
|
|
# Use pre-installed Android SDK on GitHub runners
|
|
echo "ANDROID_HOME=$ANDROID_HOME"
|
|
echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT"
|
|
|
|
# Accept licenses
|
|
yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses || true
|
|
|
|
# Install NDK r27d LTS (required for 16KB page size support on Android 15+)
|
|
# Platform android-36 and build-tools 36.0.0 for targetSdk 36 (Android 16)
|
|
$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager "ndk;27.3.13750724" "platforms;android-36" "build-tools;36.0.0"
|
|
|
|
# Set NDK path
|
|
echo "ANDROID_NDK_HOME=$ANDROID_HOME/ndk/27.3.13750724" >> $GITHUB_ENV
|
|
|
|
- name: Install gomobile
|
|
run: |
|
|
go install golang.org/x/mobile/cmd/gomobile@latest
|
|
gomobile init
|
|
|
|
- name: Build Go backend for Android
|
|
working-directory: go_backend
|
|
run: |
|
|
mkdir -p ../android/app/libs
|
|
gomobile bind -target=android -androidapi 24 -o ../android/app/libs/gobackend.aar .
|
|
env:
|
|
CGO_ENABLED: 1
|
|
|
|
- name: Setup Flutter
|
|
uses: subosito/flutter-action@v2
|
|
with:
|
|
channel: "stable"
|
|
cache: true
|
|
|
|
- name: Get Flutter dependencies
|
|
run: flutter pub get
|
|
|
|
- name: Generate app icons
|
|
run: dart run flutter_launcher_icons
|
|
|
|
- name: Build APK (Release - unsigned)
|
|
run: |
|
|
flutter build apk --release --split-per-abi || true
|
|
# Verify APKs were created
|
|
ls -la build/app/outputs/flutter-apk/
|
|
if [ ! -f "build/app/outputs/flutter-apk/app-arm64-v8a-release.apk" ]; then
|
|
echo "ERROR: APK not found!"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Sign APKs
|
|
uses: r0adkll/sign-android-release@v1
|
|
id: sign_arm64
|
|
with:
|
|
releaseDirectory: build/app/outputs/flutter-apk
|
|
signingKeyBase64: ${{ secrets.KEYSTORE_BASE64 }}
|
|
alias: ${{ secrets.KEY_ALIAS }}
|
|
keyStorePassword: ${{ secrets.KEYSTORE_PASSWORD }}
|
|
keyPassword: ${{ secrets.KEY_PASSWORD }}
|
|
env:
|
|
BUILD_TOOLS_VERSION: "36.0.0"
|
|
|
|
- name: Rename APKs
|
|
run: |
|
|
VERSION=${{ needs.get-version.outputs.version }}
|
|
cd build/app/outputs/flutter-apk
|
|
# Signed files have -signed suffix
|
|
mv app-arm64-v8a-release-signed.apk SpotiFLAC-${VERSION}-arm64.apk || mv app-arm64-v8a-release.apk SpotiFLAC-${VERSION}-arm64.apk || true
|
|
mv app-armeabi-v7a-release-signed.apk SpotiFLAC-${VERSION}-arm32.apk || mv app-armeabi-v7a-release.apk SpotiFLAC-${VERSION}-arm32.apk || true
|
|
mv app-release-signed.apk SpotiFLAC-${VERSION}-universal.apk || mv app-release.apk SpotiFLAC-${VERSION}-universal.apk || true
|
|
ls -la
|
|
|
|
- name: Upload APK artifact
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: android-apk
|
|
path: build/app/outputs/flutter-apk/SpotiFLAC-*.apk
|
|
|
|
build-ios:
|
|
runs-on: macos-latest
|
|
needs: get-version # Only depends on version, NOT android build!
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Setup Go
|
|
uses: actions/setup-go@v6
|
|
with:
|
|
go-version: "1.25.7"
|
|
cache-dependency-path: go_backend/go.sum
|
|
|
|
# Cache CocoaPods
|
|
- name: Cache CocoaPods
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: ios/Pods
|
|
key: pods-${{ runner.os }}-${{ hashFiles('ios/Podfile.lock') }}
|
|
restore-keys: pods-${{ runner.os }}-
|
|
|
|
- name: Install gomobile
|
|
run: |
|
|
go install golang.org/x/mobile/cmd/gomobile@latest
|
|
gomobile init
|
|
|
|
- name: Build Go backend for iOS
|
|
working-directory: go_backend
|
|
run: |
|
|
mkdir -p ../ios/Frameworks
|
|
gomobile bind -target=ios -tags ios -o ../ios/Frameworks/Gobackend.xcframework .
|
|
env:
|
|
CGO_ENABLED: 1
|
|
|
|
- name: Verify XCFramework created
|
|
run: |
|
|
ls -la ios/Frameworks/
|
|
ls -la ios/Frameworks/Gobackend.xcframework/ || (echo "ERROR: XCFramework not found!" && exit 1)
|
|
|
|
- name: Add XCFramework to Xcode project
|
|
run: |
|
|
# Install xcodeproj gem for modifying Xcode project
|
|
sudo gem install xcodeproj
|
|
|
|
# Create Ruby script to add framework
|
|
cat > add_framework.rb << 'EOF'
|
|
require 'xcodeproj'
|
|
|
|
project_path = 'ios/Runner.xcodeproj'
|
|
project = Xcodeproj::Project.open(project_path)
|
|
|
|
# Get the main target
|
|
target = project.targets.find { |t| t.name == 'Runner' }
|
|
|
|
# Get or create Frameworks group
|
|
frameworks_group = project.main_group.find_subpath('Frameworks', true)
|
|
frameworks_group ||= project.main_group.new_group('Frameworks')
|
|
|
|
# Add XCFramework reference
|
|
framework_path = 'Frameworks/Gobackend.xcframework'
|
|
framework_ref = frameworks_group.new_file(framework_path, :project)
|
|
|
|
# Add to frameworks build phase
|
|
frameworks_build_phase = target.frameworks_build_phase
|
|
frameworks_build_phase.add_file_reference(framework_ref)
|
|
|
|
# Add to embed frameworks build phase
|
|
embed_phase = target.build_phases.find { |p| p.is_a?(Xcodeproj::Project::Object::PBXCopyFilesBuildPhase) && p.name == 'Embed Frameworks' }
|
|
if embed_phase
|
|
build_file = embed_phase.add_file_reference(framework_ref)
|
|
build_file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy', 'RemoveHeadersOnCopy'] }
|
|
end
|
|
|
|
project.save
|
|
puts "Successfully added Gobackend.xcframework to Xcode project"
|
|
EOF
|
|
|
|
ruby add_framework.rb
|
|
|
|
- name: Setup Flutter
|
|
uses: subosito/flutter-action@v2
|
|
with:
|
|
channel: "stable"
|
|
cache: true
|
|
|
|
- name: Get Flutter dependencies
|
|
run: flutter pub get
|
|
|
|
- name: Generate app icons
|
|
run: dart run flutter_launcher_icons
|
|
|
|
- name: Build iOS (unsigned)
|
|
run: |
|
|
# Build Flutter iOS without codesigning
|
|
flutter build ios --release --no-codesign --config-only
|
|
|
|
# Use xcodebuild with code signing disabled
|
|
cd ios
|
|
xcodebuild -workspace Runner.xcworkspace \
|
|
-scheme Runner \
|
|
-configuration Release \
|
|
-sdk iphoneos \
|
|
-destination 'generic/platform=iOS' \
|
|
-archivePath build/Runner.xcarchive \
|
|
archive \
|
|
CODE_SIGNING_ALLOWED=NO \
|
|
CODE_SIGNING_REQUIRED=NO \
|
|
CODE_SIGN_IDENTITY="" \
|
|
DEVELOPMENT_TEAM=""
|
|
|
|
- name: Create IPA
|
|
run: |
|
|
VERSION=${{ needs.get-version.outputs.version }}
|
|
mkdir -p build/ios/ipa
|
|
cd ios/build/Runner.xcarchive/Products/Applications
|
|
mkdir Payload
|
|
cp -r Runner.app Payload/
|
|
# Use absolute path to avoid relative path issues
|
|
zip -r $GITHUB_WORKSPACE/build/ios/ipa/SpotiFLAC-${VERSION}-ios-unsigned.ipa Payload
|
|
rm -rf Payload
|
|
|
|
- name: Verify IPA created
|
|
run: |
|
|
ls -la build/ios/ipa/
|
|
VERSION=${{ needs.get-version.outputs.version }}
|
|
if [ ! -f "build/ios/ipa/SpotiFLAC-${VERSION}-ios-unsigned.ipa" ]; then
|
|
echo "ERROR: IPA not created!"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Upload IPA artifact
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: ios-ipa
|
|
path: build/ios/ipa/SpotiFLAC-*.ipa
|
|
|
|
create-release:
|
|
runs-on: ubuntu-latest
|
|
needs: [get-version, build-android, build-ios]
|
|
permissions:
|
|
contents: write
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0 # Full history needed for git-cliff
|
|
|
|
- name: Generate changelog with git-cliff
|
|
id: changelog
|
|
uses: orhun/git-cliff-action@v4
|
|
with:
|
|
config: cliff.toml
|
|
args: --latest --strip header
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
OUTPUT: /tmp/changelog.txt
|
|
|
|
- name: Show generated changelog
|
|
run: |
|
|
echo "Generated changelog:"
|
|
cat /tmp/changelog.txt
|
|
|
|
- name: Download Android APK
|
|
uses: actions/download-artifact@v7
|
|
with:
|
|
name: android-apk
|
|
path: ./release
|
|
|
|
- name: Download iOS IPA
|
|
uses: actions/download-artifact@v7
|
|
with:
|
|
name: ios-ipa
|
|
path: ./release
|
|
|
|
- name: Prepare release body
|
|
run: |
|
|
VERSION=${{ needs.get-version.outputs.version }}
|
|
REPO_OWNER="${{ github.repository_owner }}"
|
|
REPO_NAME="${{ github.event.repository.name }}"
|
|
CURRENT_REF=$(git rev-list -n 1 "$VERSION" 2>/dev/null || git rev-parse HEAD)
|
|
PREVIOUS_TAG=$(git describe --tags --abbrev=0 "${CURRENT_REF}^" 2>/dev/null || true)
|
|
|
|
# Start with git-cliff changelog, but replace its compare footer with a
|
|
# deterministic previous-tag lookup from git.
|
|
sed '/^## [0-9][0-9.[:alpha:]-]*$/d; /^\*\*Full Changelog\*\*/d' /tmp/changelog.txt > /tmp/release_body.txt
|
|
|
|
if [ -n "$PREVIOUS_TAG" ]; then
|
|
printf '\n**Full Changelog**: [%s...%s](https://github.com/%s/%s/compare/%s...%s)\n' \
|
|
"$PREVIOUS_TAG" "$VERSION" "$REPO_OWNER" "$REPO_NAME" "$PREVIOUS_TAG" "$VERSION" \
|
|
>> /tmp/release_body.txt
|
|
fi
|
|
|
|
# Append download section
|
|
cat >> /tmp/release_body.txt << FOOTER
|
|
|
|
---
|
|
|
|
### Downloads
|
|
|
|
#### Android
|
|
- **arm64**: \`SpotiFLAC-${VERSION}-arm64.apk\` (recommended for modern devices)
|
|
- **arm32**: \`SpotiFLAC-${VERSION}-arm32.apk\` (older devices)
|
|
|
|
#### iOS
|
|
- **iOS**: \`SpotiFLAC-${VERSION}-ios-unsigned.ipa\` (sideload required)
|
|
|
|
### Installation
|
|
**Android**: Enable "Install from unknown sources" and install the APK
|
|
**iOS**: Use AltStore, Sideloadly, or similar tools to sideload the IPA
|
|
|
|
  
|
|
FOOTER
|
|
|
|
echo "Release body:"
|
|
cat /tmp/release_body.txt
|
|
|
|
- name: Create Release
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
tag_name: ${{ needs.get-version.outputs.version }}
|
|
name: SpotiFLAC ${{ needs.get-version.outputs.version }}
|
|
body_path: /tmp/release_body.txt
|
|
files: ./release/*
|
|
draft: false
|
|
prerelease: ${{ needs.get-version.outputs.is_prerelease == 'true' }}
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
update-altstore:
|
|
runs-on: ubuntu-latest
|
|
needs: [get-version, build-ios, create-release]
|
|
if: ${{ needs.get-version.outputs.is_prerelease != 'true' }}
|
|
permissions:
|
|
contents: write
|
|
|
|
steps:
|
|
- name: Checkout main branch
|
|
uses: actions/checkout@v6
|
|
with:
|
|
ref: main
|
|
|
|
- name: Download iOS IPA
|
|
uses: actions/download-artifact@v7
|
|
with:
|
|
name: ios-ipa
|
|
path: ./release
|
|
|
|
- name: Update apps.json
|
|
run: |
|
|
VERSION="${{ needs.get-version.outputs.version }}"
|
|
VERSION_NUM="${VERSION#v}"
|
|
DATE=$(date -u +%Y-%m-%d)
|
|
IPA_FILE=$(find ./release -name "*ios*.ipa" | head -1)
|
|
|
|
if [ -z "$IPA_FILE" ]; then
|
|
echo "WARNING: IPA file not found, skipping apps.json update"
|
|
exit 0
|
|
fi
|
|
|
|
IPA_SIZE=$(stat -c%s "$IPA_FILE" 2>/dev/null || stat -f%z "$IPA_FILE")
|
|
|
|
if [ ! -f apps.json ]; then
|
|
echo "WARNING: apps.json not found on main, skipping"
|
|
exit 0
|
|
fi
|
|
|
|
jq --arg ver "$VERSION_NUM" \
|
|
--arg date "$DATE" \
|
|
--arg url "https://github.com/zarzet/SpotiFLAC-Mobile/releases/download/${VERSION}/SpotiFLAC-${VERSION}-ios-unsigned.ipa" \
|
|
--argjson size "$IPA_SIZE" \
|
|
'.apps[0].version = $ver | .apps[0].versionDate = $date | .apps[0].downloadURL = $url | .apps[0].size = $size' \
|
|
apps.json > apps.json.tmp && mv apps.json.tmp apps.json
|
|
|
|
echo "Updated apps.json:"
|
|
cat apps.json
|
|
|
|
- name: Commit and push
|
|
run: |
|
|
VERSION="${{ needs.get-version.outputs.version }}"
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add apps.json
|
|
git diff --cached --quiet && echo "No changes to commit" || \
|
|
(git commit -m "chore: update AltStore source to ${VERSION}" && git push)
|
|
|
|
notify-telegram:
|
|
runs-on: ubuntu-latest
|
|
needs: [get-version, create-release]
|
|
if: ${{ needs.get-version.outputs.is_prerelease != 'true' }}
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Download Android APK
|
|
uses: actions/download-artifact@v7
|
|
with:
|
|
name: android-apk
|
|
path: ./release
|
|
|
|
- name: Download iOS IPA
|
|
uses: actions/download-artifact@v7
|
|
with:
|
|
name: ios-ipa
|
|
path: ./release
|
|
|
|
- name: Generate changelog with git-cliff for Telegram
|
|
uses: orhun/git-cliff-action@v4
|
|
with:
|
|
config: cliff.toml
|
|
args: --latest --strip all
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
OUTPUT: /tmp/cliff_tg.txt
|
|
|
|
- name: Convert changelog for Telegram
|
|
id: changelog
|
|
run: |
|
|
if [ ! -s /tmp/cliff_tg.txt ]; then
|
|
echo "See release notes on GitHub for details." > /tmp/changelog.txt
|
|
else
|
|
# Convert Markdown to Telegram HTML
|
|
CHANGELOG=$(cat /tmp/cliff_tg.txt | \
|
|
sed '/^## [0-9][0-9.[:alpha:]-]*$/d' | \
|
|
sed '/^\*\*Full Changelog\*\*/d' | \
|
|
sed 's/ by \[@[^]]*\](https:\/\/github\.com\/[^)]*)//g' | \
|
|
sed 's/ by @[A-Za-z0-9_-]\+//g' | \
|
|
sed 's/\[#\([0-9]*\)\]([^)]*)/#\1/g' | \
|
|
sed 's/\[@\([^]]*\)\]([^)]*)/@\1/g' | \
|
|
sed 's/&/\&/g' | \
|
|
sed 's/</\</g' | \
|
|
sed 's/>/\>/g' | \
|
|
sed 's/\*\*\([^*]*\)\*\*/<b>\1<\/b>/g' | \
|
|
sed 's/^### \(.*\)$/<b>\1<\/b>/g' | \
|
|
sed 's/^## \(.*\)$/<b>\1<\/b>/g' | \
|
|
sed 's/^- /• /g')
|
|
|
|
# Truncate for Telegram 4096 char limit
|
|
CHANGELOG=$(echo "$CHANGELOG" | head -c 2500 | sed '$d')
|
|
echo "$CHANGELOG" > /tmp/changelog.txt
|
|
fi
|
|
|
|
echo "Telegram changelog:"
|
|
cat /tmp/changelog.txt
|
|
|
|
- name: Send to Telegram Channel
|
|
env:
|
|
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
|
TELEGRAM_CHANNEL_ID: ${{ secrets.TELEGRAM_CHANNEL_ID }}
|
|
run: |
|
|
VERSION=${{ needs.get-version.outputs.version }}
|
|
CHANGELOG=$(cat /tmp/changelog.txt)
|
|
|
|
# Find APK files
|
|
ARM64_APK=$(find ./release -name "*arm64*.apk" | head -1)
|
|
ARM32_APK=$(find ./release -name "*arm32*.apk" | head -1)
|
|
|
|
# Prepare message with changelog (HTML format)
|
|
printf '%s\n' \
|
|
"<b>SpotiFLAC Mobile ${VERSION} Released!</b>" \
|
|
"" \
|
|
"<b>What's New:</b>" \
|
|
"${CHANGELOG}" \
|
|
"" \
|
|
"<a href=\"https://github.com/${{ github.repository }}/releases/tag/${VERSION}\">View Release Notes</a>" \
|
|
> /tmp/telegram_message.txt
|
|
|
|
MESSAGE=$(cat /tmp/telegram_message.txt)
|
|
|
|
# Send message first (using HTML parse mode)
|
|
# Use --data-urlencode for proper encoding of special chars (+, &, etc.)
|
|
# Use || true to ensure file uploads continue even if message fails
|
|
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
|
|
--data-urlencode "chat_id=${TELEGRAM_CHANNEL_ID}" \
|
|
--data-urlencode "text=${MESSAGE}" \
|
|
--data-urlencode "parse_mode=HTML" \
|
|
--data-urlencode "disable_web_page_preview=true" || true
|
|
|
|
# Upload arm64 APK to channel
|
|
if [ -f "$ARM64_APK" ]; then
|
|
echo "Uploading arm64 APK to Telegram..."
|
|
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendDocument" \
|
|
-F chat_id="${TELEGRAM_CHANNEL_ID}" \
|
|
-F document=@"${ARM64_APK}" \
|
|
-F caption="SpotiFLAC ${VERSION} - arm64 (recommended)"
|
|
fi
|
|
|
|
# Upload arm32 APK to channel
|
|
if [ -f "$ARM32_APK" ]; then
|
|
echo "Uploading arm32 APK to Telegram..."
|
|
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendDocument" \
|
|
-F chat_id="${TELEGRAM_CHANNEL_ID}" \
|
|
-F document=@"${ARM32_APK}" \
|
|
-F caption="SpotiFLAC ${VERSION} - arm32"
|
|
fi
|
|
|
|
# Upload iOS IPA to channel
|
|
IOS_IPA=$(find ./release -name "*ios*.ipa" | head -1)
|
|
if [ -f "$IOS_IPA" ]; then
|
|
echo "Uploading iOS IPA to Telegram..."
|
|
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendDocument" \
|
|
-F chat_id="${TELEGRAM_CHANNEL_ID}" \
|
|
-F document=@"${IOS_IPA}" \
|
|
-F caption="SpotiFLAC ${VERSION} - iOS (unsigned, sideload required)"
|
|
fi
|
|
|
|
echo "Telegram notification sent!"
|