Build IPA #21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build IPA | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| ipa_url: | |
| description: "URL to the decrypted IPA file" | |
| default: "" | |
| required: true | |
| type: string | |
| display_name: | |
| description: "App Name (Optional)" | |
| default: "Swiftgram" | |
| required: true | |
| type: choice | |
| options: | |
| - Telegram | |
| - Nicegram | |
| - Swiftgram | |
| - Turrit | |
| - Vartagram | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| name: Build IPA | |
| runs-on: macos-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@v6.0.2 | |
| - name: Resolve Bundle ID | |
| id: resolve | |
| run: | | |
| case "${{ inputs.display_name }}" in | |
| "Telegram") BUNDLE_ID="ph.telegra.Telegraph" ;; | |
| "Nicegram") BUNDLE_ID="app.nicegram" ;; | |
| "Swiftgram") BUNDLE_ID="app.swiftgram.ios" ;; | |
| "Turrit") BUNDLE_ID="com.seastar.turrit" ;; | |
| "Vartagram") BUNDLE_ID="org.cpartisans.vartagram" ;; | |
| esac | |
| echo "bundle_id=$BUNDLE_ID" >> $GITHUB_OUTPUT | |
| - name: Hide Sensitive Inputs | |
| uses: levibostian/action-hide-sensitive-inputs@1.2.0 | |
| with: | |
| exclude_inputs: display_name | |
| - name: Download and Validate IPA | |
| run: | | |
| wget "${{ inputs.ipa_url }}" --quiet --no-verbose -O telegram.ipa | |
| file_type=$(file --mime-type -b telegram.ipa) | |
| if [[ "$file_type" != "application/x-ios-app" && "$file_type" != "application/zip" ]]; then | |
| echo "::error::Validation failed: The downloaded file is not a valid IPA. Detected type: $file_type." | |
| exit 1 | |
| fi | |
| - name: Get App Version | |
| run: | | |
| unzip -q telegram.ipa -d tgextracted | |
| APP_PAYLOAD=$(find tgextracted/Payload/ -maxdepth 1 -mindepth 1 -type d | head -n 1) | |
| if [[ -z "$APP_PAYLOAD" ]]; then | |
| echo "::error::Could not find app bundle in Payload/" | |
| exit 1 | |
| fi | |
| VERSION=$(plutil -extract CFBundleShortVersionString raw -o - "$APP_PAYLOAD/Info.plist") | |
| echo "APP_VERSION=$VERSION" >> $GITHUB_ENV | |
| rm -rf tgextracted | |
| - name: Get Lead Version | |
| run: | | |
| DEB_FILE=$(ls resources/com.w3ltyyy.lead_*.deb) | |
| echo "LEAD_VERSION=$(echo $DEB_FILE | sed 's/.*lead_\([^_]*\).*/\1/')" >> $GITHUB_ENV | |
| - name: Install Dependencies | |
| run: brew install make ldid | |
| - name: Set PATH Environment Variables | |
| run: | | |
| echo "$(brew --prefix make)/libexec/gnubin" >> $GITHUB_PATH | |
| echo "THEOS=${{ github.workspace }}/theos" >> $GITHUB_ENV | |
| - name: Cache Theos | |
| id: theos_cache | |
| uses: actions/cache@v5.0.5 | |
| with: | |
| path: ${{ github.workspace }}/theos | |
| key: theos-${{ runner.os }} | |
| - name: Install Theos | |
| if: steps.theos_cache.outputs.cache-hit != 'true' | |
| run: | | |
| git clone --quiet --recursive https://github.com/theos/theos.git $THEOS | |
| - name: Download iOS SDK | |
| if: steps.theos_cache.outputs.cache-hit != 'true' | |
| run: | | |
| git clone --quiet --depth=1 -n --filter=tree:0 https://github.com/Tonwalter888/iOS-SDKs.git | |
| cd iOS-SDKs | |
| git sparse-checkout set --no-cone iPhoneOS18.6.sdk | |
| git checkout | |
| mv *.sdk $THEOS/sdks | |
| - name: Install cyan | |
| run: | | |
| if ! command -v cyan &> /dev/null; then | |
| pipx install --force https://github.com/asdfzxcvbn/pyzule-rw/archive/main.zip | |
| fi | |
| - name: Clone and Build zxPluginsInject | |
| run: | | |
| git clone --quiet --depth=1 --recurse-submodules https://github.com/royerlraph79/zxPluginsInject.git | |
| cd zxPluginsInject && make FINALPACKAGE=1 THEOS_PACKAGE_SCHEME=rootless TARGET=iphone:clang:18.6:15.0 | |
| mv .theos/obj/*.dylib ${{ github.workspace }}/zxPluginsInject.dylib | |
| - name: Inject Into IPA | |
| run: | | |
| shopt -s nullglob | |
| tweaks=("zxPluginsInject.dylib") | |
| for file in resources/*.{deb,dylib}; do | |
| if [[ "$file" != "resources/SwiftgramCrack.dylib" ]]; then | |
| tweaks+=("$file") | |
| fi | |
| done | |
| if [ "${{ steps.resolve.outputs.bundle_id }}" = "app.swiftgram.ios" ]; then | |
| tweaks+=("resources/SwiftgramCrack.dylib") | |
| fi | |
| for t in "${tweaks[@]}"; do | |
| if [[ ! -f "$t" ]]; then | |
| echo "::error::Tweak file $t not found!" | |
| exit 1 | |
| fi | |
| done | |
| cyan -i telegram.ipa \ | |
| -o "${{ inputs.display_name }}_${{ env.APP_VERSION }}_${{ env.LEAD_VERSION }}.ipa" \ | |
| -f "${tweaks[@]}" \ | |
| -n "${{ inputs.display_name }}" \ | |
| -b "${{ steps.resolve.outputs.bundle_id }}" | |
| - name: Create a Draft Release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| i=1 | |
| while gh release view "tg-ipa${i}" --repo "$GITHUB_REPOSITORY" &>/dev/null; do | |
| i=$(( i + 1 )) | |
| done | |
| gh release create "tg-ipa${i}" \ | |
| --repo "$GITHUB_REPOSITORY" \ | |
| --title "${{ inputs.display_name }}_${{ env.APP_VERSION }}_${{ env.LEAD_VERSION }}" \ | |
| --draft \ | |
| ${{ inputs.display_name }}_${{ env.APP_VERSION }}_${{ env.LEAD_VERSION }}.ipa | |
| - name: Job Summary - Build Complete | |
| run: echo -e '### 🛠️ Build IPA Complete!' >> $GITHUB_STEP_SUMMARY | |
| - name: Job Summary - Output the Draft Release Link | |
| run: | | |
| echo -e "### 🚀 Draft Release\n\nDraft release has been created successfully! You can view your release here: https://github.com/${{ github.repository }}/releases" >> $GITHUB_STEP_SUMMARY |