From 3b664b39aa42be343898038ee4305a9d29465317 Mon Sep 17 00:00:00 2001 From: jigar-f <132374182+jigar-f@users.noreply.github.com> Date: Mon, 24 Jun 2024 02:36:42 +0530 Subject: [PATCH] IOS CI and Ability to distribute to single platform (#1095) * added IOS github action. * trigger workflow. * Update release.yml * fix branch issue. * fix syntex issue. * Update build-ios.yml * Added flutter pub get. * Added tunnel profile. * Update build-ios.yml * Hide tunnel profile. * uncomment tunnel profile. * Update build-ios.yml * Update build-ios.yml * Update build-ios.yml * Update build-ios.yml * Update build-ios.yml * Update build-ios.yml * Update tunnel vaules. * uncomment full steps. * Update project.pbxproj * Fix issue with variable. * Removes automatic signin * Trigger CI flow. * Added debug logs. * Change code sign. * Added verbose. * Update project.pbxproj * Update project.pbxproj * Update project.pbxproj * Added export_option.plist. * Update build-ios.yml * Update build-ios.yml * Update build-ios.yml * Update build-ios.yml * updated project path. * Update build-ios.yml * added scheme in action. * Added build framework as step. * update command. * updated config. * Update build-ios.yml * Added changes on FFI bindings step. * Fix syntax issue. * Removed unused code. * Added TestFlight action. * Change variable name. * Try to find workspace location. * Update build-ios.yml * Update build-ios.yml * Update build-ios.yml * Added debug step * Added more debug steps. * Update build-ios.yml * Remove debug steps. * Added lot of debug steps. * Added echo. * Update release.yml * use steps instead of needs. * Added logs. * Update release.yml * Use env. * Update release.yml * Try to use envs. * change tag for testing * Enable all jobs. * Added push to s3 step. * Comment push-binaries step. * Updated copy action. * Enable all workflow. * Upgrade multiple action packages due to d deprecated version. * Updated readme and updated more actions pacakges. * Do not push ios build to s3. * Build ios when tag to prod * merge latest --------- Co-authored-by: atavism --- .github/workflows/browerstack.yml | 2 +- .github/workflows/build-android.yml | 164 +++++++ .github/workflows/build-darwin.yml | 6 +- .github/workflows/build-ios.yml | 184 ++++++++ .github/workflows/build-linux.yml | 4 +- .github/workflows/build-windows.yml | 10 +- .github/workflows/go.yml | 2 +- .github/workflows/release.yml | 442 ++++++++---------- Makefile | 18 +- README.md | 29 +- ios/Runner.xcodeproj/project.pbxproj | 136 +++++- .../xcshareddata/xcschemes/prod.xcscheme | 4 +- .../xcshareddata/swiftpm/Package.resolved | 14 - 13 files changed, 687 insertions(+), 328 deletions(-) create mode 100644 .github/workflows/build-android.yml create mode 100644 .github/workflows/build-ios.yml delete mode 100644 ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/.github/workflows/browerstack.yml b/.github/workflows/browerstack.yml index 256948b29..bc9be0185 100644 --- a/.github/workflows/browerstack.yml +++ b/.github/workflows/browerstack.yml @@ -27,7 +27,7 @@ jobs: - run: flutter --version - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: "go.mod" diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml new file mode 100644 index 000000000..e8917a663 --- /dev/null +++ b/.github/workflows/build-android.yml @@ -0,0 +1,164 @@ +name: Build Android Installer +on: + workflow_call: + inputs: + version_file: + type: string + required: true + version: + type: string + required: true + prefix: + type: string + required: true + +env: + GOPRIVATE: github.com/getlantern + S3_BUCKET: lantern + +jobs: + build-android: + env: + version: ${{ inputs.version }} + version_file: ${{ inputs.version_file }} + prefix: ${{ inputs.prefix }} + runs-on: macos-latest-xlarge + steps: + - uses: actions/checkout@v4 + with: + lfs: true + + - name: Pull LFS objects + run: git lfs pull + + - name: Installing Flutter + uses: subosito/flutter-action@v2 + with: + channel: "stable" + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + + - name: Install latest protoc-gen-go + run: go install github.com/golang/protobuf/protoc-gen-go@latest + + - name: Granting private modules access + run: | + git config --global url."https://${{ secrets.CI_PRIVATE_REPOS_GH_TOKEN }}:x-oauth-basic@github.com/".insteadOf "https://github.com/" + + - name: Setup Sentry CLI + uses: mathieu-bour/setup-sentry-cli@v2 + with: + version: latest + token: ${{ SECRETS.SENTRY_TOKEN }} # from GitHub secrets + organization: getlantern + project: android + + - name: Setup JDK + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + + - name: Generate ffi bindings + run: | + make darwin + make ffigen + + - name: Setup protoc + uses: arduino/setup-protoc@v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Activate protoc-gen-dart plugin + run: | + echo "${HOME}/.pub-cache/bin" >> $GITHUB_PATH + dart pub global activate protoc_plugin + + - name: Set gradle properties + env: + GRADLE_PROPERTIES: ${{ secrets.GRADLE_PROPERTIES }} + run: | + mkdir -p ~/.gradle/ + echo "GRADLE_USER_HOME=${HOME}/.gradle" >> $GITHUB_ENV + echo "${GRADLE_PROPERTIES}" > ~/.gradle/gradle.properties + + - name: Decode Keystore + id: write_file + uses: timheuer/base64-to-file@v1.2 + with: + fileName: 'keystore.release.jks' + fileDir: './android/app' + encodedString: ${{ secrets.KEYSTORE }} + + - name: Generate app.env + env: + ANDROID_INTERSTITIAL_AD_ID: ${{ secrets.INTERSTITIAL_AD_UNIT_ID }} + IOS_INTERSTITIAL_AD_ID: ${{ secrets.INTERSTITIAL_AD_UNIT_ID_IOS }} + run: | + touch app.env + echo "Android_interstitialAd=$ANDROID_INTERSTITIAL_AD_ID" > app.env + echo "IOS_interstitialAd=$IOS_INTERSTITIAL_AD_ID" >> app.env + + - name: Build Android installers + run: make package-android + env: + INTERSTITIAL_AD_UNIT: "${{ secrets.INTERSTITIAL_AD_UNIT_ID }}" + SENTRY_AUTH_TOKEN: "${{ secrets.SENTRY_AUTH_TOKEN }}" + VERSION: "${{ env.version }}" + + - uses: actions/upload-artifact@v4 + with: + name: android-apk-build + retention-days: 2 + path: | + lantern-installer.apk + + - uses: actions/upload-artifact@v4 + with: + name: android-aab-build + retention-days: 2 + path: | + lantern-installer.aab + + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install s3cmd + run: pip install s3cmd + + - name: Set s3cmd permissions + run: | + echo "[default]" > "$HOME/.s3cfg" + echo "access_key = ${{ secrets.AWS_ACCESS_KEY }}" >> "$HOME/.s3cfg" + echo "secret_key = ${{ secrets.AWS_SECRET_KEY }}" >> "$HOME/.s3cfg" + + - name: Push binaries to s3 + env: + VERSION: "${{ env.version }}" + APK: "${{ env.prefix }}-${{ env.version }}.apk" + AAB: "${{ env.prefix }}-${{ env.version }}.aab" + update: "lantern_update_android_arm-${{inputs.version}}.bz2" + update_source: lantern_update_android_arm.bz2 + run: | + mv ${{ env.update_source }} ${{ env.update }} + mv lantern-installer.apk "$APK" + mv lantern-installer.aab "$AAB" + cp "$APK" ${{ env.prefix }}.apk + cp "$AAB" ${{ env.prefix }}.aab + echo ${{ env.version }} > ${{ env.version_file }} + shasum -a 256 "$APK" | cut -d " " -f 1 > "$APK".sha256 + shasum -a 256 "$AAB" | cut -d " " -f 1 > "$AAB".sha256 + shasum -a 256 ${{ env.update }} | cut -d " " -f 1 > ${{ env.update }}.sha256 + cp "$APK".sha256 ${{ env.prefix }}.apk.sha256 + cp "$AAB".sha256 ${{ env.prefix }}.aab.sha256 + s3cmd put --acl-public "$APK" "$APK".sha256 ${{ env.update }} ${{ env.update }}.sha256 ${{ env.version_file }} ${{ env.prefix }}.apk.sha256 ${{ env.prefix }}.apk "s3://$S3_BUCKET" + s3cmd put --acl-public "$AAB" "$AAB".sha256 ${{ env.prefix }}.aab.sha256 ${{ env.prefix }}.aab "s3://$S3_BUCKET" + s3cmd modify --add-header='content-type':'application/vnd.android.package-archive' "s3://$S3_BUCKET/$APK" + s3cmd modify --add-header='content-type':'application/vnd.android.package-archive' "s3://$S3_BUCKET/${{ env.prefix }}.apk" + s3cmd modify --add-header='content-type':'application/vnd.android.package-archive' "s3://$S3_BUCKET/$AAB" + s3cmd modify --add-header='content-type':'application/vnd.android.package-archive' "s3://$S3_BUCKET/${{ env.prefix }}.aab" + diff --git a/.github/workflows/build-darwin.yml b/.github/workflows/build-darwin.yml index d9843e578..2975c117a 100644 --- a/.github/workflows/build-darwin.yml +++ b/.github/workflows/build-darwin.yml @@ -34,7 +34,7 @@ jobs: AC_PASSWORD: ${{ secrets.AC_PASSWORD }} runs-on: ${{ inputs.macos_version }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: lfs: true @@ -42,7 +42,7 @@ jobs: run: git lfs pull - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: "go.mod" @@ -62,7 +62,7 @@ jobs: chmod 600 /tmp/cache/.netrc - name: Setup Sentry CLI - uses: mathieu-bour/setup-sentry-cli@v1 + uses: mathieu-bour/setup-sentry-cli@v2 with: version: latest token: ${{ SECRETS.SENTRY_TOKEN }} # from GitHub secrets diff --git a/.github/workflows/build-ios.yml b/.github/workflows/build-ios.yml new file mode 100644 index 000000000..3f114f029 --- /dev/null +++ b/.github/workflows/build-ios.yml @@ -0,0 +1,184 @@ +name: Build IOS +on: + workflow_call: + inputs: + version_file: + type: string + required: true + macos_version: + type: string + required: true + xcode_version: + type: string + required: true + version: + type: string + required: true + prefix: + type: string + required: true +env: + GOPRIVATE: github.com/getlantern +jobs: + build-ios: + runs-on: ${{ inputs.macos_version }} + permissions: + contents: "read" + id-token: "write" + env: + version: ${{ inputs.version }} + version_file: ${{ inputs.version_file }} + prefix: ${{ inputs.prefix }} + AC_USERNAME: accounts@getlantern.org + AC_PASSWORD: ${{ secrets.AC_PASSWORD }} + + steps: + - uses: actions/checkout@v4 + with: + lfs: true + - name: Pull LFS objects + run: git lfs pull + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + + - name: Setup Xcode + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: ${{ inputs.xcode_version }} + + - name: Repo access + run: | + mkdir /tmp/cache + echo "machine github.com login ${{ secrets.GH_TOKEN }} password x-oauth-basic" > /tmp/cache/.netrc + chmod 600 /tmp/cache/.netrc + + - name: Setup Sentry CLI + uses: mathieu-bour/setup-sentry-cli@v2 + with: + version: latest + token: ${{ SECRETS.SENTRY_TOKEN }} # from GitHub secrets + organization: getlantern + project: lantern-ios + + - name: Install Flutter + uses: subosito/flutter-action@v2 + with: + channel: "stable" + + - name: Install the Apple certificate and provisioning profile + env: + BUILD_CERTIFICATE_BASE64: ${{ secrets.IOS_CERTIFICATE_P12_BASE64 }} + P12_PASSWORD: ${{ secrets.IOS_CERTIFICATE_P12_PASS }} + BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.IOS_PROVISION_PROFILE_BASE6 }} + BUILD_TUNNEL_PROVISION_PROFILE_BASE64: ${{ secrets.IOS_TUNNEL_PROVISION_PROFILE_BASE64 }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + EXPORT_OPTIONS: ${{ secrets.EXPORT_OPTION_PLIST }} + run: | + set -x + # create variables + CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 + PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision + TPP_PATH=$RUNNER_TEMP/build_tpp.mobileprovision + KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db + EXPORT_OPTIONS_PATH=$GITHUB_WORKSPACE/ExportOptions.plist + + + # import certificate from secrets + echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH + + # create temporary keychain + security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + security set-keychain-settings -lut 21600 $KEYCHAIN_PATH + security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + + # import certificate to keychain + security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH + security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + security list-keychain -d user -s $KEYCHAIN_PATH + + PROVISIONING_PROFILES_DIR=~/Library/MobileDevice/Provisioning\ Profiles + mkdir -p "$PROVISIONING_PROFILES_DIR" + + # apply main provisioning profile + echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH + cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles + + # apply tunnel provisioning profile + echo -n "$BUILD_TUNNEL_PROVISION_PROFILE_BASE64" | base64 --decode -o $TPP_PATH + cp $TPP_PATH ~/Library/MobileDevice/Provisioning\ Profiles + + # Create ExportOptions.plist + echo "$EXPORT_OPTIONS" | base64 --decode > "$EXPORT_OPTIONS_PATH" + + - name: Generate FFI bindings + run: | + make darwin + make ffigen + + - name: Generate app.env + env: + ANDROID_INTERSTITIAL_AD_ID: ${{ secrets.INTERSTITIAL_AD_UNIT_ID }} + IOS_INTERSTITIAL_AD_ID: ${{ secrets.INTERSTITIAL_AD_UNIT_ID_IOS }} + run: | + touch app.env + echo "Android_interstitialAd=$ANDROID_INTERSTITIAL_AD_ID" > app.env + echo "IOS_interstitialAd=$IOS_INTERSTITIAL_AD_ID" >> app.env + + - name: Get dependencies & Pod install + run: | + flutter pub get + cd ios + pod install + cd .. + + - name: Build iOS app + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: getlantern + SENTRY_PROJECT_IOS: lantern-ios + run: make ios-release + + - name: Upload application + uses: actions/upload-artifact@v4 + with: + name: Lantern.ipa + path: ${{ github.workspace }}/build/ios/ipa/Lantern.ipa + retention-days: 2 +# +# - name: Compress artifacts using bzip2 +# run: | +# cd ${{ github.workspace }}/build/ios/ipa/ +# bzip2 -zk Lantern.ipa +# +# - name: Copy .ipa and .bz2 to root +# run: | +# cp ${{ github.workspace }}/build/ios/ipa/Lantern.ipa ${{ github.workspace }}/Lantern.ipa +# cp ${{ github.workspace }}/build/ios/ipa/Lantern.ipa.bz2 ${{ github.workspace }}/Lantern.ipa.bz2 +# +# - name: Install s3cmd +# run: pip install s3cmd +# +# - name: Set s3cmd permissions +# run: | +# echo "[default]" > "$HOME/.s3cfg" +# echo "access_key = ${{ secrets.AWS_ACCESS_KEY }}" >> "$HOME/.s3cfg" +# echo "secret_key = ${{ secrets.AWS_SECRET_KEY }}" >> "$HOME/.s3cfg" +# +# - name: Push binaries to s3 +# env: +# VERSION: "${{ env.version }}" +# IPA: "${{ env.prefix }}-${{ env.version }}.ipa" +# update: "lantern_update_ios-${{inputs.version}}.bz2" +# update_source: Lantern.ipa.bz2 +# run: | +# mv ${{ env.update_source }} ${{ env.update }} +# mv Lantern.ipa "$IPA" +# cp "$IPA" ${{ env.prefix }}.ipa +# echo ${{ env.version }} > ${{ env.version_file }} +# shasum -a 256 "$IPA" | cut -d " " -f 1 > "$IPA".sha256 +# shasum -a 256 ${{ env.update }} | cut -d " " -f 1 > ${{ env.update }}.sha256 +# cp "$IPA".sha256 ${{ env.prefix }}.ipa.sha256 +# s3cmd put --acl-public "$IPA" "$IPA".sha256 ${{ env.update }} ${{ env.update }}.sha256 ${{ env.version_file }} ${{ env.prefix }}.ipa.sha256 ${{ env.prefix }}.ipa "s3://lantern" diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index bc42c13f4..0b3977ceb 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -22,7 +22,7 @@ jobs: prefix: ${{ inputs.prefix }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Granting private modules access run: git config --global url."https://${{ secrets.GH_TOKEN }}:x-oauth-basic@github.com/".insteadOf "https://github.com/" - name: Repo access @@ -39,7 +39,7 @@ jobs: sudo apt-get install -y libgtk-3-0 libblkid1 liblzma5 sudo apt-get install -y libpcap-dev libgtk-3-dev libayatana-appindicator3-dev ruby ruby-dev && sudo gem install bundler -v 2.2.26 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: "go.mod" diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index dc5d197b4..304d63520 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -38,7 +38,7 @@ jobs: prefix: ${{ inputs.prefix }} runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: lfs: true @@ -46,7 +46,7 @@ jobs: run: git lfs pull - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: "go.mod" @@ -61,7 +61,7 @@ jobs: chmod 600 /tmp/cache/.netrc - name: Setup Sentry CLI - uses: mathieu-bour/setup-sentry-cli@v1 + uses: mathieu-bour/setup-sentry-cli@v2 with: version: latest token: ${{ SECRETS.SENTRY_TOKEN }} # from GitHub secrets @@ -126,7 +126,7 @@ jobs: prefix: ${{ inputs.prefix }} runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: lfs: true # Install Flutter @@ -211,7 +211,7 @@ jobs: run: | sudo apt-get install -y file build-essential pkg-config sudo apt-get install -y mingw-w64 nsis - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: name: windows${{inputs.build-suffix}}-build diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 2ce1f00d7..c25832e77 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -17,7 +17,7 @@ jobs: - name: Install libpcap run: sudo apt-get install libpcap-dev - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version-file: "go.mod" - name: Granting private modules access diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8adf6060d..9976561b9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,10 +1,9 @@ name: Publish releases -#on: -# push: -# branches: [ main ] -# tags: -# - '*' +on: + push: + branches: [ jigar/ios-ci ] + workflow_dispatch: permissions: contents: "read" @@ -14,13 +13,44 @@ env: GOPRIVATE: github.com/getlantern S3_BUCKET: lantern jobs: - set-version: - runs-on: ubuntu-latest - outputs: - version: ${{ steps.set-version.outputs.version }} - prefix: ${{ steps.set-version.outputs.prefix }} - version_file: ${{ steps.set-version.outputs.version_file }} - steps: + determine-platform: + runs-on: ubuntu-latest + outputs: + platform: ${{ steps.set-platform.outputs.platform }} + steps: + - name: Determine Platform + id: set-platform + run: | + echo "GITHUB_REF is: $GITHUB_REF" + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + TAG=${GITHUB_REF#refs/tags/} + echo "Tag is: $TAG" + if [[ $TAG == ios-* ]]; then + echo "Platform determined: ios" + echo "platform=ios" >> "$GITHUB_OUTPUT" + elif [[ $TAG == android-* ]]; then + echo "Platform determined: android" + echo "platform=android" >> "$GITHUB_OUTPUT" + elif [[ $TAG == desktop-* ]]; then + echo "Platform determined: macos" + echo "platform=desktop" >> "$GITHUB_OUTPUT" + else + echo "Platform determined: all (tag did not match specific platforms)" + echo "platform=all" >> "$GITHUB_OUTPUT" + fi + else + echo "Not a tag reference, defaulting to all platforms" + echo "platform=all" >> "$GITHUB_OUTPUT" + fi + + set-version: + needs: determine-platform + runs-on: ubuntu-latest + outputs: + version: ${{ steps.set-version.outputs.version }} + prefix: ${{ steps.set-version.outputs.prefix }} + version_file: ${{ steps.set-version.outputs.version_file }} + steps: - id: set-version shell: python run: | @@ -55,267 +85,165 @@ jobs: print(f'::set-output name=prefix::{li}') print(f'::set-output name=version_file::{vf}') - build-linux: - uses: ./.github/workflows/build-linux.yml - secrets: inherit - needs: set-version - with: - version: ${{ needs.set-version.outputs.version }} - prefix: ${{ needs.set-version.outputs.prefix }} - dist-suffix: x64 - -# build-windows-x32: -# uses: ./.github/workflows/build-windows.yml -# secrets: inherit -# needs: set-version -# with: -# version: ${{ needs.set-version.outputs.version }} -# prefix: ${{ needs.set-version.outputs.prefix }} -# dist-suffix: 32-bit -# installer-suffix: -x32 -# update-suffix: 386 -# arch: x32 - - build-windows-x64: - uses: ./.github/workflows/build-windows.yml - secrets: inherit - needs: set-version - with: - version: ${{ needs.set-version.outputs.version }} - prefix: ${{ needs.set-version.outputs.prefix }} - build-suffix: 64 - dist-suffix: 64-bit - update-suffix: x64 - installer-suffix: -x64 - arch: x64 - - build-darwin: - uses: ./.github/workflows/build-darwin.yml - secrets: inherit - needs: set-version - with: - macos_version: macos-14 - xcode_version: latest-stable - version: ${{ needs.set-version.outputs.version }} - version_file: ${{ needs.set-version.outputs.version_file }} - prefix: ${{ needs.set-version.outputs.prefix }} - - build-android: - needs: set-version - env: - version: ${{ needs.set-version.outputs.version }} - version_file: ${{ needs.set-version.outputs.version_file }} - prefix: ${{ needs.set-version.outputs.prefix }} - runs-on: macos-latest-xlarge - steps: - - uses: actions/checkout@v4 + build-linux: + uses: ./.github/workflows/build-linux.yml + secrets: inherit + needs: set-version + with: + version: ${{ needs.set-version.outputs.version }} + prefix: ${{ needs.set-version.outputs.prefix }} + dist-suffix: x64 + + # build-windows-x32: + # uses: ./.github/workflows/build-windows.yml + # secrets: inherit + # needs: set-version + # with: + # version: ${{ needs.set-version.outputs.version }} + # prefix: ${{ needs.set-version.outputs.prefix }} + # dist-suffix: 32-bit + # installer-suffix: -x32 + # update-suffix: 386 + # arch: x32 + + build-windows-x64: + uses: ./.github/workflows/build-windows.yml + secrets: inherit + needs: set-version + with: + version: ${{ needs.set-version.outputs.version }} + prefix: ${{ needs.set-version.outputs.prefix }} + build-suffix: 64 + dist-suffix: 64-bit + update-suffix: x64 + installer-suffix: -x64 + arch: x64 + + build-darwin: + uses: ./.github/workflows/build-darwin.yml + secrets: inherit + needs: set-version + with: + macos_version: macos-14 + xcode_version: latest-stable + version: ${{ needs.set-version.outputs.version }} + version_file: ${{ needs.set-version.outputs.version_file }} + prefix: ${{ needs.set-version.outputs.prefix }} + + build-ios: + uses: ./.github/workflows/build-ios.yml + secrets: inherit + needs: set-version + with: + macos_version: macos-14 + xcode_version: latest-stable + version: ${{ needs.set-version.outputs.version }} + version_file: ${{ needs.set-version.outputs.version_file }} + prefix: ${{ needs.set-version.outputs.prefix }} + + build-android: + uses: ./.github/workflows/build-android.yml + secrets: inherit + needs: set-version + with: + version: ${{ needs.set-version.outputs.version }} + version_file: ${{ needs.set-version.outputs.version_file }} + prefix: ${{ needs.set-version.outputs.prefix }} + + push-binaries: + runs-on: ubuntu-latest + needs: [ set-version, build-android, build-ios, build-darwin, build-linux, build-windows-x64 ] + env: + version: ${{ needs.set-version.outputs.version }} + prefix: ${{ needs.set-version.outputs.prefix }} + steps: + - name: Download the mac build output + uses: actions/download-artifact@v4 with: - lfs: true - - - name: Pull LFS objects - run: git lfs pull - - # Install Flutter - - uses: subosito/flutter-action@v2 + name: osx-build + - name: Download the linux build output + uses: actions/download-artifact@v4 with: - channel: "stable" - - - run: flutter --version + name: linux-build - - name: Setup Go - uses: actions/setup-go@v4 + - name: Download the windows64 build output + uses: actions/download-artifact@v4 with: - go-version-file: "go.mod" + name: windows64-installer-signed - - name: Install latest protoc-gen-go - run: go install github.com/golang/protobuf/protoc-gen-go@latest - - - name: Granting private modules access - run: | - git config --global url."https://${{ secrets.CI_PRIVATE_REPOS_GH_TOKEN }}:x-oauth-basic@github.com/".insteadOf "https://github.com/" - - - name: Setup Sentry CLI - uses: mathieu-bour/setup-sentry-cli@v1 + - name: Download the apk build output + uses: actions/download-artifact@v4 with: - version: latest - token: ${{ SECRETS.SENTRY_TOKEN }} # from GitHub secrets - organization: getlantern - project: android + name: android-apk-build - - name: Setup JDK - uses: actions/setup-java@v4 + - name: Download the aab build output + uses: actions/download-artifact@v4 with: - distribution: temurin - java-version: 17 - - - name: Generate ffi bindings - run: | - make darwin - make ffigen + name: android-aab-build - - name: Setup protoc - uses: arduino/setup-protoc@v2 + - name: Download the IPA + uses: actions/download-artifact@v4 with: - repo-token: ${{ secrets.GITHUB_TOKEN }} + name: Lantern.ipa - - name: Activate protoc-gen-dart plugin - run: | - echo "${HOME}/.pub-cache/bin" >> $GITHUB_PATH - dart pub global activate protoc_plugin - - - name: Set gradle properties - env: - GRADLE_PROPERTIES: ${{ secrets.GRADLE_PROPERTIES }} - run: | - mkdir -p ~/.gradle/ - echo "GRADLE_USER_HOME=${HOME}/.gradle" >> $GITHUB_ENV - echo "${GRADLE_PROPERTIES}" > ~/.gradle/gradle.properties - - - name: Decode Keystore - id: write_file - uses: timheuer/base64-to-file@v1.2 + - name: Upload Lantern to TestFlight + uses: apple-actions/upload-testflight-build@v1 + if: (needs.set-version.outputs.prefix == 'lantern-installer-preview'|| needs.set-version.outputs.prefix == 'lantern-installer') && (needs.determine-platform.outputs.platform == 'ios' || needs.determine-platform.outputs.platform == 'all') with: - fileName: 'keystore.release.jks' - fileDir: './android/app' - encodedString: ${{ secrets.KEYSTORE }} - - - name: Generate app.env - env: - ANDROID_INTERSTITIAL_AD_ID: ${{ secrets.INTERSTITIAL_AD_UNIT_ID }} - IOS_INTERSTITIAL_AD_ID: ${{ secrets.INTERSTITIAL_AD_UNIT_ID_IOS }} - run: | - touch app.env - echo "Android_interstitialAd=$ANDROID_INTERSTITIAL_AD_ID" > app.env - echo "IOS_interstitialAd=$IOS_INTERSTITIAL_AD_ID" >> app.env - - - name: Build Android installers - run: make package-android - env: - INTERSTITIAL_AD_UNIT: "${{ secrets.INTERSTITIAL_AD_UNIT_ID }}" - SENTRY_AUTH_TOKEN: "${{ secrets.SENTRY_AUTH_TOKEN }}" - VERSION: "${{ env.version }}" - - - uses: actions/upload-artifact@v3 + app-path: Lantern.ipa + issuer-id: ${{ secrets.APPSTORE_ISSUER_ID }} + api-key-id: ${{ secrets.APPSTORE_API_KEY_ID }} + api-private-key: ${{ secrets.APPSTORE_API_PRIVATE_KEY }} + + - name: Upload Android App bundle to Play Store (beta) + if: needs.set-version.outputs.prefix == 'lantern-installer-preview' && (needs.determine-platform.outputs.platform == 'android' || needs.determine-platform.outputs.platform == 'all') + uses: r0adkll/upload-google-play@v1 with: - name: android-apk-build - retention-days: 2 - path: | - lantern-installer.apk - - - uses: actions/upload-artifact@v3 + serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }} + packageName: org.getlantern.lantern + releaseFiles: lantern-installer.aab + track: beta + + - name: Upload Android App bundle to Play Store (production) + if: needs.set-version.outputs.prefix == 'lantern-installer' && (needs.determine-platform.outputs.platform == 'android' || needs.determine-platform.outputs.platform == 'all') + uses: r0adkll/upload-google-play@v1 with: - name: android-aab-build - retention-days: 2 - path: | - lantern-installer.aab + serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }} + packageName: org.getlantern.lantern + releaseFiles: lantern-installer.aab + track: production - - uses: actions/setup-python@v5 - with: - python-version: '3.12' + - name: Grant private modules access + run: git config --global url."https://${{ secrets.CI_PRIVATE_REPOS_GH_TOKEN }}:x-oauth-basic@github.com/".insteadOf "https://github.com/" - - name: Install s3cmd - run: pip install s3cmd + - name: Clone binaries repo + run: git clone --depth 1 https://github.com/getlantern/lantern-binaries - - name: Set s3cmd permissions + - name: Rename builds run: | - echo "[default]" > "$HOME/.s3cfg" - echo "access_key = ${{ secrets.AWS_ACCESS_KEY }}" >> "$HOME/.s3cfg" - echo "secret_key = ${{ secrets.AWS_SECRET_KEY }}" >> "$HOME/.s3cfg" - - - name: Push binaries to s3 - env: - VERSION: "${{ env.version }}" - APK: "${{ env.prefix }}-${{ env.version }}.apk" - AAB: "${{ env.prefix }}-${{ env.version }}.aab" - update: "lantern_update_android_arm-${{inputs.version}}.bz2" - update_source: lantern_update_android_arm.bz2 + diff lantern-installer.apk ${{ env.prefix }}.apk || mv -f lantern-installer.apk ${{ env.prefix }}.apk + diff lantern-installer.aab ${{ env.prefix }}.aab || mv -f lantern-installer.aab ${{ env.prefix }}.aab + mv "lantern_${{env.version}}_x64.deb" ${{ env.prefix }}-64-bit.deb + mv -f lantern-installer.dmg ${{ env.prefix }}.dmg + diff lantern-installer-x64.exe ${{ env.prefix }}-64-bit.exe || mv -f lantern-installer-x64.exe ${{ env.prefix }}-64-bit.exe + mv -f Lantern.ipa ${{ env.prefix }}.ipa + + - name: Prepare sha256 sums run: | - mv ${{ env.update_source }} ${{ env.update }} - mv lantern-installer.apk "$APK" - mv lantern-installer.aab "$AAB" - cp "$APK" ${{ env.prefix }}.apk - cp "$AAB" ${{ env.prefix }}.aab - echo ${{ env.version }} > ${{ env.version_file }} - shasum -a 256 "$APK" | cut -d " " -f 1 > "$APK".sha256 - shasum -a 256 "$AAB" | cut -d " " -f 1 > "$AAB".sha256 - shasum -a 256 ${{ env.update }} | cut -d " " -f 1 > ${{ env.update }}.sha256 - cp "$APK".sha256 ${{ env.prefix }}.apk.sha256 - cp "$AAB".sha256 ${{ env.prefix }}.aab.sha256 - s3cmd put --acl-public "$APK" "$APK".sha256 ${{ env.update }} ${{ env.update }}.sha256 ${{ env.version_file }} ${{ env.prefix }}.apk.sha256 ${{ env.prefix }}.apk "s3://$S3_BUCKET" - s3cmd put --acl-public "$AAB" "$AAB".sha256 ${{ env.prefix }}.aab.sha256 ${{ env.prefix }}.aab "s3://$S3_BUCKET" - s3cmd modify --add-header='content-type':'application/vnd.android.package-archive' "s3://$S3_BUCKET/$APK" - s3cmd modify --add-header='content-type':'application/vnd.android.package-archive' "s3://$S3_BUCKET/${{ env.prefix }}.apk" - s3cmd modify --add-header='content-type':'application/vnd.android.package-archive' "s3://$S3_BUCKET/$AAB" - s3cmd modify --add-header='content-type':'application/vnd.android.package-archive' "s3://$S3_BUCKET/${{ env.prefix }}.aab" - - push-binaries: - runs-on: ubuntu-latest - needs: [ set-version, build-android, build-darwin, build-linux, build-windows-x64 ] - env: - version: ${{ needs.set-version.outputs.version }} - prefix: ${{ needs.set-version.outputs.prefix }} - steps: - - name: Download the mac build output - uses: actions/download-artifact@v4 - with: - name: osx-build - - name: Download the linux build output - uses: actions/download-artifact@v4 - with: - name: linux-build - - name: Download the windows64 build output - uses: actions/download-artifact@v4 - with: - name: windows64-installer-signed - - name: Download the apk build output - uses: actions/download-artifact@v3 - with: - name: android-apk-build - - name: Download the aab build output - uses: actions/download-artifact@v3 - with: - name: android-aab-build - - name: Upload Android App bundle to Play Store (beta) - if: needs.set-version.outputs.prefix == 'lantern-installer-preview' - uses: r0adkll/upload-google-play@v1 - with: - serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }} - packageName: org.getlantern.lantern - releaseFiles: lantern-installer.aab - track: beta - - name: Upload Android App bundle to Play Store (production) - if: needs.set-version.outputs.prefix == 'lantern-installer' - uses: r0adkll/upload-google-play@v1 - with: - serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }} - packageName: org.getlantern.lantern - releaseFiles: lantern-installer.aab - track: production - - name: Grant private modules access - run: git config --global url."https://${{ secrets.CI_PRIVATE_REPOS_GH_TOKEN }}:x-oauth-basic@github.com/".insteadOf "https://github.com/" - - name: Clone binaries repo - run: git clone --depth 1 https://github.com/getlantern/lantern-binaries - - name: Rename builds - run: | - diff lantern-installer.apk ${{ env.prefix }}.apk || mv -f lantern-installer.apk ${{ env.prefix }}.apk - diff lantern-installer.aab ${{ env.prefix }}.aab || mv -f lantern-installer.aab ${{ env.prefix }}.aab - mv "lantern_${{env.version}}_x64.deb" ${{ env.prefix }}-64-bit.deb - mv -f lantern-installer.dmg ${{ env.prefix }}.dmg - diff lantern-installer-x64.exe ${{ env.prefix }}-64-bit.exe || mv -f lantern-installer-x64.exe ${{ env.prefix }}-64-bit.exe - - name: Prepare sha256 sums - run: | - shasum -a 256 ${{ env.prefix }}.apk | cut -d " " -f 1 > ${{ env.prefix }}.apk.sha256 - shasum -a 256 ${{ env.prefix }}.aab | cut -d " " -f 1 > ${{ env.prefix }}.aab.sha256 - shasum -a 256 ${{ env.prefix }}-mac.dmg | cut -d " " -f 1 > ${{ env.prefix }}-mac.dmg.sha256 - shasum -a 256 ${{ env.prefix }}-mac_arm.dmg | cut -d " " -f 1 > ${{ env.prefix }}-mac_arm.dmg.sha256 - shasum -a 256 ${{ env.prefix }}-x64.exe | cut -d " " -f 1 > ${{ env.prefix }}-x64.exe.sha256 - shasum -a 256 ${{ env.prefix }}-64-bit.deb | cut -d " " -f 1 > ${{ env.prefix }}-64-bit.deb.sha256 - - name: Commit - run: | - mv lantern-installer* ./lantern-binaries/ - cd lantern-binaries - git config user.email "admin@getlantern.org" - git config user.name "Lantern Bot" - git add . - git commit -m "Lantern binaries for version ${{ env.version }}" - git push origin main + shasum -a 256 ${{ env.prefix }}.apk | cut -d " " -f 1 > ${{ env.prefix }}.apk.sha256 + shasum -a 256 ${{ env.prefix }}.aab | cut -d " " -f 1 > ${{ env.prefix }}.aab.sha256 + shasum -a 256 ${{ env.prefix }}-mac.dmg | cut -d " " -f 1 > ${{ env.prefix }}-mac.dmg.sha256 + shasum -a 256 ${{ env.prefix }}-mac_arm.dmg | cut -d " " -f 1 > ${{ env.prefix }}-mac_arm.dmg.sha256 + shasum -a 256 ${{ env.prefix }}-x64.exe | cut -d " " -f 1 > ${{ env.prefix }}-x64.exe.sha256 + shasum -a 256 ${{ env.prefix }}-64-bit.deb | cut -d " " -f 1 > ${{ env.prefix }}-64-bit.deb.sha256 + shasum -a 256 ${{ env.prefix }}.ipa | cut -d " " -f 1 > ${{ env.prefix }}.ipa.sha256 + + - name: Commit + run: | + mv lantern-installer* ./lantern-binaries/ + cd lantern-binaries + git config user.email "admin@getlantern.org" + git config user.name "Lantern Bot" + git add . + git commit -m "Lantern binaries for version ${{ env.version }}" + git push origin main diff --git a/Makefile b/Makefile index ad8be6567..6d973cb53 100644 --- a/Makefile +++ b/Makefile @@ -117,23 +117,11 @@ GOMOBILE_EXTRA_BUILD_FLAGS := BETA_BASE_NAME ?= $(INSTALLER_NAME)-preview PROD_BASE_NAME ?= $(INSTALLER_NAME) -## secrets Keys -INTERSTITIAL_AD_UNIT=ca-app-pub-2685698271254859/9922829329 -## vault secrets -VAULT_ADS_SECRETS_PATH ?= secret/googleAds - -## vault keys -INTERSTITIAL_AD_UNIT_ID= INTERSTITIAL_AD_UNIT_ID S3_BUCKET ?= lantern FORCE_PLAY_VERSION ?= false DEBUG_VERSION ?= $(GIT_REVISION) -# Sentry properties -SENTRY_AUTH_TOKEN=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 -SENTRY_ORG=getlantern -SENTRY_PROJECT_IOS=lantern-ios - DWARF_DSYM_FOLDER_PATH=$(shell pwd)/build/ios/Release-prod-iphoneos/Runner.app.dSYM INFO_PLIST := ios/Runner/Info.plist @@ -278,7 +266,7 @@ define osxcodesign endef guard-%: - @ if [ -z '${${*}}' ]; then echo 'Environment variable $* not set' && exit 1; fi + @ if [ -z '${${*}}' ]; then echo 'Environment $* variable not set' && exit 1; fi .PHONY: require-app require-app: guard-APP @@ -473,9 +461,9 @@ set-version: /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $$NEXT_BUILD" $(INFO_PLIST) -ios-release:set-version build-framework +ios-release:set-version guard-SENTRY_AUTH_TOKEN guard-SENTRY_ORG guard-SENTRY_PROJECT_IOS build-framework @echo "Creating the Flutter iOS build..." - flutter build ipa --flavor prod --release + flutter build ipa --flavor prod --release --export-options-plist ./ExportOptions.plist @echo "Uploading debug symbols to Sentry..." export SENTRY_LOG_LEVEL=info sentry-cli --auth-token $(SENTRY_AUTH_TOKEN) upload-dif --include-sources --org $(SENTRY_ORG) --project $(SENTRY_PROJECT_IOS) $(DWARF_DSYM_FOLDER_PATH) diff --git a/README.md b/README.md index 745c5cc80..68170a2ae 100644 --- a/README.md +++ b/README.md @@ -228,9 +228,13 @@ Do this to make a release build: - Run `VERSION= make android-release ANDROID_ARCH=all` - Or, `DEVELOPMENT_MODE=true make android-release ANDROID_ARCH=all` to enable "Development Mode" which has extra dev features like taking screenshots and dev settings. -### Building release packages +### 📦 Building Release Packages and Distributing the App -Lantern Android release packages are built in CI. You can build installers for beta, for production, or for internal testing by varying the tag syntax. To build for production, you simply tag the current version on `main` with, for example: +Lantern-client release and beta packages are built using Continuous Integration (CI). You can create installers for beta, production, or internal testing by adjusting the tag syntax. + +#### Production Release for All Platforms 🌍 + +To release the production version for all platforms (including Android, iOS, and macOS), use the following command: `git tag -a "lantern-7.0.0" -f -m "Tagging production release"` @@ -242,9 +246,26 @@ Finally, to create an internal build, use "internal", as in: `git tag -a "lantern-7.0.0-internal" -f -m "Tagging internal release"` -For all of the above, don't forget to push the tags: -`git push --tags -f` +#### Platform-Specific Releases 📱💻 + +For releasing to specific platforms, use the appropriate prefix: + +* iOS: ios- +* Android: android- +* Desktop (Windows, macOS, Linux): desktop- + +Example command for releasing a beta version for Android: + +`git tag -a "android-lantern-7.0.0" -f -m "Tagging production release"` + +This command will build and release the beta version for Android. + +#### Pushing Tags to GitHub 🛠️ + +After creating a tag, push it to GitHub to trigger the CI/CD pipeline: + +`git push origin [TAG-NAME]`or `git push origin lantern-7.0.0` You can then find all built binaries in the [lantern-binaries repository](https://github.com/getlantern/lantern-binaries). diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 1f90cf6e9..00c8b3179 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -788,6 +788,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; CURRENT_SCHEME_NAME = appiumTest; DEBUG_INFORMATION_FORMAT = dwarf; @@ -823,8 +824,12 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 12; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -841,6 +846,8 @@ MARKETING_VERSION = 7.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Development"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -858,9 +865,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Tunnel/Tunnel.entitlements; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Tunnel/Info.plist; @@ -878,6 +887,8 @@ OTHER_LDFLAGS = "-lc++"; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern.Tunnel; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Tunnel Development"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -949,6 +960,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; CURRENT_SCHEME_NAME = appiumTest; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -980,8 +992,12 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 12; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -998,6 +1014,8 @@ MARKETING_VERSION = 7.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Development"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -1014,9 +1032,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Tunnel/Tunnel.entitlements; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Tunnel/Info.plist; @@ -1033,6 +1053,8 @@ OTHER_LDFLAGS = "-lc++"; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern.Tunnel; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Tunnel Development"; SKIP_INSTALL = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1103,6 +1125,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; CURRENT_SCHEME_NAME = appiumTest; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -1133,8 +1156,12 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 12; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1151,6 +1178,8 @@ MARKETING_VERSION = 7.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Development"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -1167,9 +1196,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Tunnel/Tunnel.entitlements; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Tunnel/Info.plist; @@ -1186,6 +1217,8 @@ OTHER_LDFLAGS = "-lc++"; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern.Tunnel; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Tunnel Development"; SKIP_INSTALL = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1256,6 +1289,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; CURRENT_SCHEME_NAME = appiumTest; DEBUG_INFORMATION_FORMAT = dwarf; @@ -1291,8 +1325,12 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 12; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1309,6 +1347,8 @@ MARKETING_VERSION = 7.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Development"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -1326,9 +1366,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Tunnel/Tunnel.entitlements; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Tunnel/Info.plist; @@ -1346,6 +1388,8 @@ OTHER_LDFLAGS = "-lc++"; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern.Tunnel; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Tunnel Development"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1398,9 +1442,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Tunnel/Tunnel.entitlements; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Tunnel/Info.plist; @@ -1418,6 +1464,8 @@ OTHER_LDFLAGS = "-lc++"; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern.Tunnel; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Tunnel Development"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1437,9 +1485,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Tunnel/Tunnel.entitlements; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Tunnel/Info.plist; @@ -1456,6 +1506,8 @@ OTHER_LDFLAGS = "-lc++"; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern.Tunnel; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Tunnel Distribution"; SKIP_INSTALL = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1475,9 +1527,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Tunnel/Tunnel.entitlements; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Tunnel/Info.plist; @@ -1494,6 +1548,8 @@ OTHER_LDFLAGS = "-lc++"; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern.Tunnel; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Tunnel Development"; SKIP_INSTALL = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_EMIT_LOC_STRINGS = YES; @@ -1532,6 +1588,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; CURRENT_SCHEME_NAME = prod; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -1562,8 +1619,12 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 12; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1580,6 +1641,8 @@ MARKETING_VERSION = 7.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Development"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -1615,6 +1678,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; CURRENT_SCHEME_NAME = prod; DEBUG_INFORMATION_FORMAT = dwarf; @@ -1671,6 +1735,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; CURRENT_SCHEME_NAME = prod; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -1702,8 +1767,12 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 12; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1720,6 +1789,8 @@ MARKETING_VERSION = 7.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Development"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -1735,8 +1806,12 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 12; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1753,6 +1828,8 @@ MARKETING_VERSION = 7.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS distribution"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -1788,6 +1865,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; CURRENT_SCHEME_NAME = prod; DEBUG_INFORMATION_FORMAT = dwarf; @@ -1823,8 +1901,12 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 12; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -1841,6 +1923,8 @@ MARKETING_VERSION = 7.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Development"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -1858,9 +1942,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = Tunnel/Tunnel.entitlements; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4FYC28AXA2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4FYC28AXA2; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Tunnel/Info.plist; @@ -1878,6 +1964,8 @@ OTHER_LDFLAGS = "-lc++"; PRODUCT_BUNDLE_IDENTIFIER = org.getlantern.lantern.Tunnel; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "IOS Tunnel Development"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme index fdd117926..4e44cd149 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/prod.xcscheme @@ -30,7 +30,7 @@ shouldAutocreateTestPlan = "YES"> diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index cb4b75775..000000000 --- a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,14 +0,0 @@ -{ - "pins" : [ - { - "identity" : "sqlite.swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/stephencelis/SQLite.swift.git", - "state" : { - "revision" : "7a2e3cd27de56f6d396e84f63beefd0267b55ccb", - "version" : "0.14.1" - } - } - ], - "version" : 2 -}