From da3ba573d89fd68ae3acbcdb2ffd67ee4f12126a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Fri, 20 Jun 2025 22:07:59 +0800 Subject: [PATCH] release: Add IPA build --- .github/workflows/build.yml | 75 ++++++++++++++++++++++++++----- Makefile | 20 +++++++++ cmd/internal/build_libbox/main.go | 15 +++++-- docs/clients/apple/index.md | 10 ++++- 4 files changed, 105 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 023f9db1..1e3c4b74 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -437,28 +437,24 @@ jobs: platform: ios scheme: SFI destination: 'generic/platform=iOS' - archive: build/SFI.xcarchive upload: SFI/Upload.plist - name: macOS if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'macOS' }} platform: macos scheme: SFM destination: 'generic/platform=macOS' - archive: build/SFM.xcarchive upload: SFI/Upload.plist - name: tvOS if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'tvOS' }} platform: tvos scheme: SFT destination: 'generic/platform=tvOS' - archive: build/SFT.xcarchive upload: SFI/Upload.plist - name: macOS-standalone if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone' }} platform: macos scheme: SFM.System destination: 'generic/platform=macOS' - archive: build/SFM.System.xcarchive export: SFM.System/Export.plist export_path: build/SFM.System steps: @@ -543,6 +539,12 @@ jobs: export PATH="$PATH:$(go env GOPATH)/bin" go run ./cmd/internal/build_libbox -target apple -platform ${{ matrix.platform }} mv Libbox.xcframework clients/apple + - name: Build library with tailscale + if: matrix.if && (matrix.name == 'iOS' || matrix.name == 'tvOS') + run: |- + export PATH="$PATH:$(go env GOPATH)/bin" + go run ./cmd/internal/build_libbox -target apple -platform ${{ matrix.platform }} -tailscale + mv Libbox.xcframework clients/apple/Libbox.WithTailscale.xcframework - name: Update macOS version if: matrix.if && matrix.name == 'macOS' && github.event_name == 'workflow_dispatch' run: |- @@ -561,18 +563,71 @@ jobs: -scheme "${{ matrix.scheme }}" \ -configuration Release \ -destination "${{ matrix.destination }}" \ - -archivePath "${{ matrix.archive }}" \ + -archivePath "build/${{ matrix.scheme }}.xcarchive" \ -allowProvisioningUpdates \ -authenticationKeyPath $ASC_KEY_PATH \ -authenticationKeyID $ASC_KEY_ID \ -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID + - name: Build with Tailscale + if: matrix.if && (matrix.name == 'iOS' || matrix.name == 'tvOS') + run: |- + cd clients/apple + mv Libbox.xcframework Libbox.WithoutTailscale.xcframework + mv Libbox.WithTailscale.xcframework Libbox.xcframework + xcodebuild archive \ + -scheme "${{ matrix.scheme }}" \ + -configuration Release \ + -destination "${{ matrix.destination }}" \ + -archivePath "build/${{ matrix.scheme }}.WithTailscale.xcarchive" \ + -allowProvisioningUpdates \ + -authenticationKeyPath $ASC_KEY_PATH \ + -authenticationKeyID $ASC_KEY_ID \ + -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID + - name: Export IPA + if: matrix.if && (matrix.name == 'iOS' || matrix.name == 'tvOS') && github.event_name == 'workflow_dispatch' + run: |- + pushd clients/apple + xcodebuild -exportArchive \ + -archivePath "build/${{ matrix.scheme }}.xcarchive" \ + -exportOptionsPlist SFI/Export.plist \ + -exportPath "build/${{ matrix.scheme }}" \ + -allowProvisioningUpdates \ + -authenticationKeyPath $ASC_KEY_PATH \ + -authenticationKeyID $ASC_KEY_ID \ + -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID + cp build/${{ matrix.scheme }}/sing-box.ipa . + popd + mkdir -p dist + cp clients/apple/sing-box.ipa "dist/${{ matrix.scheme }}-${{ needs.calculate_version.outputs.version }}.ipa" + - name: Export IPA with Tailscale + if: matrix.if && (matrix.name == 'iOS' || matrix.name == 'tvOS') && github.event_name == 'workflow_dispatch' + run: |- + pushd clients/apple + xcodebuild -exportArchive \ + -archivePath "build/${{ matrix.scheme }}.WithTailscale.xcarchive" \ + -exportOptionsPlist SFI/Export.plist \ + -exportPath "build/${{ matrix.scheme }}.WithTailscale" \ + -allowProvisioningUpdates \ + -authenticationKeyPath $ASC_KEY_PATH \ + -authenticationKeyID $ASC_KEY_ID \ + -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID + cp build/${{ matrix.scheme }}.WithTailscale/sing-box.ipa . + popd + mkdir -p dist + cp clients/apple/sing-box.ipa "dist/${{ matrix.scheme }}-${{ needs.calculate_version.outputs.version }}-WithTailscale.ipa" + - name: Upload IPA + if: matrix.if && (matrix.name == 'iOS' || matrix.name == 'tvOS') && github.event_name == 'workflow_dispatch' + uses: actions/upload-artifact@v4 + with: + name: binary-${{ matrix.name }}-ipa + path: 'dist' - name: Upload to App Store Connect if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch' run: |- go run -v ./cmd/internal/app_store_connect cancel_app_store ${{ matrix.platform }} cd clients/apple xcodebuild -exportArchive \ - -archivePath "${{ matrix.archive }}" \ + -archivePath "build/${{ matrix.scheme }}.xcarchive" \ -exportOptionsPlist ${{ matrix.upload }} \ -allowProvisioningUpdates \ -authenticationKeyPath $ASC_KEY_PATH \ @@ -587,7 +642,7 @@ jobs: run: |- pushd clients/apple xcodebuild -exportArchive \ - -archivePath "${{ matrix.archive }}" \ + -archivePath "build/${{ matrix.scheme }}.xcarchive" \ -exportOptionsPlist ${{ matrix.export }} \ -exportPath "${{ matrix.export_path }}" brew install create-dmg @@ -600,13 +655,13 @@ jobs: --skip-jenkins \ SFM.dmg "${{ matrix.export_path }}/SFM.app" xcrun notarytool submit "SFM.dmg" --wait --keychain-profile "notarytool-password" - cd "${{ matrix.archive }}" + cd "build/${{ matrix.scheme }}.xcarchive" zip -r SFM.dSYMs.zip dSYMs popd mkdir -p dist cp clients/apple/SFM.dmg "dist/SFM-${VERSION}-universal.dmg" - cp "clients/apple/${{ matrix.archive }}/SFM.dSYMs.zip" "dist/SFM-${VERSION}-universal.dSYMs.zip" + cp "clients/apple/build/${{ matrix.scheme }}.xcarchive/SFM.dSYMs.zip" "dist/SFM-${VERSION}-universal.dSYMs.zip" - name: Upload image if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch' uses: actions/upload-artifact@v4 @@ -615,7 +670,7 @@ jobs: path: 'dist' upload: name: Upload builds - if: always() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone') + if: "!failure() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone' || inputs.build == 'iOS' || inputs.build == 'tvOS')" runs-on: ubuntu-latest needs: - calculate_version diff --git a/Makefile b/Makefile index 1c102fdb..9299a6df 100644 --- a/Makefile +++ b/Makefile @@ -108,6 +108,16 @@ upload_ios_app_store: cd ../sing-box-for-apple && \ xcodebuild -exportArchive -archivePath build/SFI.xcarchive -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates +export_ios_ipa: + cd ../sing-box-for-apple && \ + xcodebuild -exportArchive -archivePath build/SFI.xcarchive -exportOptionsPlist SFI/Export.plist -allowProvisioningUpdates -exportPath build/SFI && \ + cp build/SFI/sing-box.ipa dist/SFI.ipa + +upload_ios_ipa: + cd dist && \ + cp SFI.ipa "SFI-${VERSION}.ipa" && \ + ghr --replace --draft --prerelease "v${VERSION}" "SFI-${VERSION}.ipa" + release_ios: build_ios upload_ios_app_store build_macos: @@ -175,6 +185,16 @@ upload_tvos_app_store: cd ../sing-box-for-apple && \ xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Upload.plist -allowProvisioningUpdates +export_tvos_ipa: + cd ../sing-box-for-apple && \ + xcodebuild -exportArchive -archivePath "build/SFT.xcarchive" -exportOptionsPlist SFI/Export.plist -allowProvisioningUpdates -exportPath build/SFT && \ + cp build/SFT/sing-box.ipa dist/SFT.ipa + +upload_tvos_ipa: + cd dist && \ + cp SFT.ipa "SFT-${VERSION}.ipa" && \ + ghr --replace --draft --prerelease "v${VERSION}" "SFT-${VERSION}.ipa" + release_tvos: build_tvos upload_tvos_app_store update_apple_version: diff --git a/cmd/internal/build_libbox/main.go b/cmd/internal/build_libbox/main.go index 7dcc9608..4fbb7d86 100644 --- a/cmd/internal/build_libbox/main.go +++ b/cmd/internal/build_libbox/main.go @@ -16,15 +16,17 @@ import ( ) var ( - debugEnabled bool - target string - platform string + debugEnabled bool + target string + platform string + withTailscale bool ) func init() { flag.BoolVar(&debugEnabled, "debug", false, "enable debug") flag.StringVar(&target, "target", "android", "target platform") flag.StringVar(&platform, "platform", "", "specify platform") + flag.BoolVar(&withTailscale, "with-tailscale", false, "build tailscale for iOS and tvOS") } func main() { @@ -151,7 +153,9 @@ func buildApple() { "-v", "-target", bindTarget, "-libname=box", - "-tags-macos=" + strings.Join(memcTags, ","), + } + if !withTailscale { + args = append(args, "-tags-macos="+strings.Join(memcTags, ",")) } if !debugEnabled { @@ -161,6 +165,9 @@ func buildApple() { } tags := append(sharedTags, iosTags...) + if withTailscale { + tags = append(tags, memcTags...) + } if debugEnabled { tags = append(tags, debugTags...) } diff --git a/docs/clients/apple/index.md b/docs/clients/apple/index.md index a872417a..ae897c0a 100644 --- a/docs/clients/apple/index.md +++ b/docs/clients/apple/index.md @@ -19,13 +19,21 @@ platform-specific function implementation, such as TUN transparent proxy impleme ## :material-download: Download * [App Store](https://apps.apple.com/app/sing-box-vt/id6673731168) -* TestFlight (Beta) +* TestFlight (Beta) **1** +* [GitHub Releases](https://github.com/SagerNet/sing-box/releases) **2** + +**1**: TestFlight quota is only available to [sponsors](https://github.com/sponsors/nekohasekai) (one-time sponsorships are accepted). Once you donate, you can get an invitation by join our Telegram group for sponsors from [@yet_another_sponsor_bot](https://t.me/yet_another_sponsor_bot) or sending us your Apple ID [via email](mailto:contact@sagernet.org). +**2**: + +You can now download compiled IPAs for iOS and tvOS directly from GitHub releases, +but you need to purchase the **Apple Developer Program** to install them through AltStore or SideStore. + ## :material-file-download: Download (macOS standalone version) * [Homebrew Cask](https://formulae.brew.sh/cask/sfm)