#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(git rev-parse --show-toplevel)" APPS_DIR="$ROOT_DIR/apps" OUTPUT_APK="$APPS_DIR/build/app/outputs/flutter-apk/app-release.apk" RELEASES_DIR="$ROOT_DIR/deploy/static/releases" MANIFEST_FILE="$RELEASES_DIR/manifest.json" BACKEND_HOST="" CHANNEL="release" RELEASE_NOTES="" while [[ $# -gt 0 ]]; do case "$1" in --backend-host) BACKEND_HOST="$2" shift 2 ;; --channel) CHANNEL="$2" shift 2 ;; --release-notes) RELEASE_NOTES="$2" shift 2 ;; *) printf 'Unknown arg: %s\n' "$1" >&2 exit 1 ;; esac done if [[ -z "$BACKEND_HOST" ]]; then printf 'Usage: %s --backend-host [--channel release] [--release-notes "..."]\n' "$0" >&2 exit 1 fi if [[ "$BACKEND_HOST" == *":"* ]]; then printf 'Invalid backend host: do not include port (%s)\n' "$BACKEND_HOST" >&2 exit 1 fi if ! [[ "$CHANNEL" =~ ^[a-z0-9_-]+$ ]]; then printf 'Invalid channel: %s\n' "$CHANNEL" >&2 exit 1 fi BACKEND_URL="http://$BACKEND_HOST" readarray -t VERSION_INFO < <( python - <<'PY' import re from pathlib import Path text = Path("apps/pubspec.yaml").read_text(encoding="utf-8") match = re.search(r"^version:\s*([0-9]+\.[0-9]+\.[0-9]+)\+([0-9]+)\s*$", text, re.MULTILINE) if not match: raise SystemExit("pubspec.yaml version format invalid") print(match.group(1)) print(match.group(2)) PY ) VERSION_NAME="${VERSION_INFO[0]}" CURRENT_VERSION_CODE="${VERSION_INFO[1]}" NEXT_VERSION_CODE="$((CURRENT_VERSION_CODE + 1))" FILE_NAME="social-app-android-v${VERSION_NAME}+${NEXT_VERSION_CODE}-${CHANNEL}.apk" TARGET_APK="$RELEASES_DIR/$FILE_NAME" mkdir -p "$RELEASES_DIR" pushd "$APPS_DIR" >/dev/null flutter build apk --release \ --build-name="$VERSION_NAME" \ --build-number="$NEXT_VERSION_CODE" \ --dart-define="BACKEND_URL=$BACKEND_URL" \ --target-platform=android-arm64 \ --split-per-abi \ --target "lib/main.dart" popd >/dev/null SOURCE_APK="$APPS_DIR/build/app/outputs/flutter-apk/app-arm64-v8a-release.apk" if [[ ! -f "$SOURCE_APK" ]]; then SOURCE_APK="$OUTPUT_APK" fi cp "$SOURCE_APK" "$TARGET_APK" FILE_SIZE="$(stat -c%s "$TARGET_APK")" SHA256="$(sha256sum "$TARGET_APK" | cut -d' ' -f1)" python - <<'PY' "$ROOT_DIR/apps/pubspec.yaml" "$VERSION_NAME" "$NEXT_VERSION_CODE" import re import sys from pathlib import Path pubspec_path = Path(sys.argv[1]) version_name = sys.argv[2] version_code = sys.argv[3] content = pubspec_path.read_text(encoding="utf-8") updated, count = re.subn( r"^version:\s*[0-9]+\.[0-9]+\.[0-9]+\+[0-9]+\s*$", f"version: {version_name}+{version_code}", content, count=1, flags=re.MULTILINE, ) if count != 1: raise SystemExit("failed to update version in pubspec.yaml") pubspec_path.write_text(updated, encoding="utf-8") PY RELEASE_NOTES="$RELEASE_NOTES" python - <<'PY' "$MANIFEST_FILE" "$FILE_NAME" "$VERSION_NAME" "$NEXT_VERSION_CODE" "$CHANNEL" "$FILE_SIZE" "$SHA256" import json import os import sys from pathlib import Path manifest_path = Path(sys.argv[1]) file_name = sys.argv[2] version_name = sys.argv[3] version_code = int(sys.argv[4]) channel = sys.argv[5] file_size = int(sys.argv[6]) sha256 = sys.argv[7] release_notes = os.environ.get("RELEASE_NOTES", "") if manifest_path.is_file(): data = json.loads(manifest_path.read_text(encoding="utf-8")) else: data = {"releases": []} releases = data.get("releases") or [] releases = [ item for item in releases if not ( item.get("platform") == "android" and item.get("channel") == channel and item.get("version_code") == version_code ) ] releases.append( { "platform": "android", "channel": channel, "version_name": version_name, "version_code": version_code, "min_supported_version_code": version_code, "file_name": file_name, "release_notes": release_notes or None, "file_size": file_size, "sha256": sha256, } ) releases.sort( key=lambda item: ( item.get("platform", ""), item.get("channel", ""), item.get("version_code", 0), ) ) manifest_path.write_text( json.dumps({"releases": releases}, indent=2, ensure_ascii=True) + "\n", encoding="utf-8", ) PY printf 'Build completed\n' printf 'Version: %s+%s\n' "$VERSION_NAME" "$NEXT_VERSION_CODE" printf 'Previous buildNumber: %s\n' "$CURRENT_VERSION_CODE" printf 'Backend URL: %s\n' "$BACKEND_URL" printf 'Package: %s\n' "$TARGET_APK" printf 'SHA256: %s\n' "$SHA256"