Files

178 lines
4.4 KiB
Bash
Raw Permalink Normal View History

#!/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 <ip-or-domain> [--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 "lib/main.dart"
popd >/dev/null
SOURCE_APK="$OUTPUT_APK"
if [[ ! -f "$SOURCE_APK" ]]; then
printf 'Expected APK not found: %s\n' "$SOURCE_APK" >&2
exit 1
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"