name: Flutter CICD on: push: tags: - "v*" jobs: build: runs-on: ubuntu-latest env: KEY_JKS: ${{ secrets.KEY_JKS }} KEY_PATH: ${{ github.workspace }}/apps/weblibre/key.jks KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} KEY_ALIAS: ${{ secrets.KEY_ALIAS }} permissions: contents: write steps: - name: Free Disk Space uses: jlumbroso/free-disk-space@main with: tool-cache: false android: false dotnet: true haskell: true large-packages: false docker-images: false swap-storage: false - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '17' - uses: actions/setup-go@v5 with: go-version: '1.25.x' - name: Install Android NDK run: | set -euo pipefail ANDROID_NDK_VERSION="$( sed -n 's/^weblibre\.ndkVersion[[:space:]]*=[[:space:]]*//p' \ apps/weblibre/android/gradle.properties )" if [[ -z "$ANDROID_NDK_VERSION" ]]; then echo "Missing weblibre.ndkVersion in apps/weblibre/android/gradle.properties" >&2 exit 1 fi set +e yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --install "ndk;$ANDROID_NDK_VERSION" sdkmanager_status=${PIPESTATUS[1]} set -e if [[ $sdkmanager_status -ne 0 ]]; then exit "$sdkmanager_status" fi test -f "$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION/source.properties" { echo "ANDROID_NDK_VERSION=$ANDROID_NDK_VERSION" echo "ANDROID_NDK_HOME=$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION" echo "ANDROID_NDK_ROOT=$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION" echo "NDK_HOME=$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION" } >> "$GITHUB_ENV" - name: Determine build type id: build-type run: | if [[ "${{ github.ref_name }}" =~ (pre|alpha) ]]; then echo "is_prerelease=true" >> $GITHUB_OUTPUT echo "Build type: Prerelease (APK only)" else echo "is_prerelease=false" >> $GITHUB_OUTPUT echo "Build type: Full release (APK + Bundle + Play Console)" fi - uses: ruby/setup-ruby@v1 if: steps.build-type.outputs.is_prerelease == 'false' with: ruby-version: '3.3' bundler-cache: true working-directory: apps/weblibre - uses: actions/setup-node@v4 with: node-version: 20 - name: Cache Go build dependencies uses: actions/cache@v4 with: path: | ~/.cache/go-build ~/go/pkg/mod ~/go/bin/gomobile ~/go/bin/gobind key: ${{ runner.os }}-go-runtime-${{ hashFiles('native/go_mobile_runtime/pins.env') }} restore-keys: | ${{ runner.os }}-go-runtime- - name: Download bundle dependencies if: steps.build-type.outputs.is_prerelease == 'false' run: | gem install bundler bundle config path vendor/bundle bundle install - name: Create key file working-directory: apps/weblibre run: | echo $KEY_JKS | base64 -di > key.jks chmod 600 key.jks - uses: subosito/flutter-action@v2 with: channel: stable flutter-version: 3.44.5 cache: true - name: Setup Flutter dependencies run: | dart pub global activate melos 7.8.1 melos bootstrap - name: Update external assets run: melos run update-assets --no-select - name: Build components run: melos run build-components --no-select - name: Checkout native runtime sources run: | set -euo pipefail source native/go_mobile_runtime/pins.env git clone https://github.com/SagerNet/sing-box.git "$RUNNER_TEMP/sing-box" git -C "$RUNNER_TEMP/sing-box" checkout "$SING_BOX_TAG" test "$(git -C "$RUNNER_TEMP/sing-box" rev-parse HEAD)" = "$SING_BOX_COMMIT" git clone https://github.com/tladesignz/IPtProxy.git "$RUNNER_TEMP/IPtProxy" git -C "$RUNNER_TEMP/IPtProxy" checkout "$IPTPROXY_TAG" test "$(git -C "$RUNNER_TEMP/IPtProxy" rev-parse HEAD)" = "$IPTPROXY_COMMIT" git -C "$RUNNER_TEMP/IPtProxy" submodule update --init dnstt - name: Build native gomobile runtime env: SING_BOX_SOURCE: ${{ runner.temp }}/sing-box IPTPROXY_SOURCE: ${{ runner.temp }}/IPtProxy run: melos run build-go-runtime --no-select - name: Build APK (Alpha) if: steps.build-type.outputs.is_prerelease == 'true' run: melos run build-browser-alpha --no-select - name: Build APK (Alpha, Legacy renderer) if: steps.build-type.outputs.is_prerelease == 'true' run: melos run build-browser-alpha-legacy --no-select - name: Build APK (Stable) if: steps.build-type.outputs.is_prerelease == 'false' run: melos run build-browser --no-select - name: Build App Bundle if: steps.build-type.outputs.is_prerelease == 'false' working-directory: apps/weblibre run: flutter build appbundle --flavor stable --target-platform android-arm,android-arm64 --no-tree-shake-icons - name: Create github artifact release (Prerelease) if: steps.build-type.outputs.is_prerelease == 'true' uses: ncipollo/release-action@v1.17.0 with: artifacts: "apps/weblibre/build/app/outputs/apk/alpha/release/*.apk,apps/weblibre/build/app/outputs/apk/alphaLegacy/release/*.apk" prerelease: true - name: Create github artifact release (Full) if: steps.build-type.outputs.is_prerelease == 'false' uses: ncipollo/release-action@v1.17.0 with: artifacts: "apps/weblibre/build/app/outputs/apk/stable/release/*.apk,apps/weblibre/build/app/outputs/bundle/stableRelease/app-stable-release.aab" - name: Upload app bundle artifact if: steps.build-type.outputs.is_prerelease == 'false' uses: actions/upload-artifact@v4 with: name: appbundle path: apps/weblibre/build/app/outputs/bundle/stableRelease/app-stable-release.aab - name: Release to Google Play (internal) if: steps.build-type.outputs.is_prerelease == 'false' working-directory: apps/weblibre env: SUPPLY_PACKAGE_NAME: ${{ secrets.ANDROID_PACKAGE_NAME }} SUPPLY_JSON_KEY_DATA: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_KEY }} run: | bundle exec fastlane supply \ --aab build/app/outputs/bundle/stableRelease/app-stable-release.aab \ --track internal - name: Cleanup if: always() working-directory: apps/weblibre run: rm -f key.jks