mirror of
https://github.com/chenasraf/pantry-flutter.git
synced 2026-05-17 17:28:03 +00:00
306 lines
11 KiB
Makefile
306 lines
11 KiB
Makefile
# Version from pubspec.yaml (without build number)
|
|
VERSION := $(shell grep '^version:' pubspec.yaml | sed 's/version: *//;s/+.*//')
|
|
|
|
# Default target
|
|
.PHONY: help
|
|
help:
|
|
@echo "Flutter project commands:"
|
|
@echo ""
|
|
@echo " Setup:"
|
|
@echo " get Install dependencies"
|
|
@echo " clean Clean build artifacts"
|
|
@echo " install-hooks Install git hooks via lefthook"
|
|
@echo " pods Update CocoaPods repo and install pods"
|
|
@echo ""
|
|
@echo " i18n:"
|
|
@echo " i18n Build i18n generated Dart code"
|
|
@echo " i18n-watch Watch and rebuild i18n on changes"
|
|
@echo ""
|
|
@echo " Development:"
|
|
@echo " run Run the app in debug mode"
|
|
@echo " format Format all Dart files"
|
|
@echo " analyze Analyze all Dart files"
|
|
@echo " check Check all files (format + analyze, no changes)"
|
|
@echo ""
|
|
@echo " Testing:"
|
|
@echo " test Run all tests"
|
|
@echo " test-coverage Run tests with coverage report"
|
|
@echo ""
|
|
@echo " API:"
|
|
@echo " fetch-openapi Fetch openapi.json from chenasraf/nextcloud-pantry"
|
|
@echo ""
|
|
@echo " Assets:"
|
|
@echo " icons Generate launcher icons, favicon & web logo from SVG"
|
|
@echo " splash Generate splash screen from SVG"
|
|
@echo ""
|
|
@echo " Building:"
|
|
@echo " android-install Build APK and install on connected device"
|
|
@echo " android-build-apk Build Android APK"
|
|
@echo " android-build-apk-split Build Android split-per-ABI APKs"
|
|
@echo " android-build-aab Build Android App Bundle"
|
|
@echo " android-push Build APK and push to device via adb"
|
|
@echo " ios-build Build iOS (no codesign)"
|
|
@echo " macos-build Build macOS app (.app bundle, no codesign)"
|
|
@echo " macos-build-pkg Build signed macOS .pkg for App Store"
|
|
@echo " build-all Build all platforms"
|
|
@echo ""
|
|
@echo " Release:"
|
|
@echo " android-release-apk Build APK and copy to build/release/"
|
|
@echo " android-release-aab Build AAB and copy to build/release/"
|
|
@echo " ios-release Build IPA and copy to build/release/"
|
|
@echo " macos-release Build PKG and copy to build/release/"
|
|
@echo " release-all Build and release all platforms"
|
|
@echo ""
|
|
@echo " Deploying:"
|
|
@echo " android-deploy Build AAB and upload to Google Play (TRACK=internal|beta|production, STATUS=draft|completed)"
|
|
@echo " android-promote Promote release between tracks (FROM=internal, TO=production, STATUS=draft|completed)"
|
|
@echo " ios-deploy Build IPA and upload (DEST=testflight|appstore, default: testflight)"
|
|
@echo " ios-submit Submit the existing App Store build for review (no upload)"
|
|
@echo " macos-deploy Build PKG and upload (DEST=testflight|appstore, default: testflight)"
|
|
@echo " macos-submit Submit the existing Mac App Store build for review (no upload)"
|
|
@echo " deploy-production Build and deploy to production (Google Play + App Store)"
|
|
@echo " deploy-beta Build and deploy to beta (Google Play beta + TestFlight)"
|
|
|
|
# Setup
|
|
.PHONY: get
|
|
get:
|
|
flutter pub get
|
|
|
|
.PHONY: clean
|
|
clean:
|
|
flutter clean
|
|
rm -rf coverage/
|
|
|
|
.PHONY: build-clean
|
|
build-clean:
|
|
rm -rf build/release/*
|
|
|
|
# i18n
|
|
.PHONY: i18n
|
|
i18n:
|
|
dart run tool/fix_i18n_escapes.dart
|
|
dart run build_runner build --delete-conflicting-outputs
|
|
|
|
.PHONY: i18n-watch
|
|
i18n-watch:
|
|
dart run build_runner watch --delete-conflicting-outputs
|
|
|
|
# Development
|
|
.PHONY: run
|
|
run:
|
|
flutter run
|
|
.PHONY: format
|
|
format:
|
|
dart format .
|
|
|
|
.PHONY: analyze
|
|
analyze:
|
|
flutter analyze --no-fatal-infos
|
|
|
|
.PHONY: check
|
|
check:
|
|
dart format --output=none --set-exit-if-changed .
|
|
flutter analyze --no-fatal-infos
|
|
|
|
# Testing
|
|
.PHONY: test
|
|
test:
|
|
ifdef FILES
|
|
flutter test $(FILES)
|
|
else
|
|
flutter test
|
|
endif
|
|
|
|
.PHONY: test-coverage
|
|
test-coverage:
|
|
flutter test --coverage
|
|
@echo "Coverage report generated at coverage/lcov.info"
|
|
|
|
# Building
|
|
.PHONY: android-build-apk
|
|
android-build-apk:
|
|
flutter build apk --release --obfuscate --split-debug-info=build/debug-info-apk
|
|
.PHONY: android-build-apk-split
|
|
android-build-apk-split:
|
|
flutter build apk --release --split-per-abi --obfuscate --split-debug-info=build/debug-info-apk
|
|
.PHONY: android-install
|
|
android-install: android-build-apk
|
|
flutter install
|
|
|
|
.PHONY: android-push
|
|
android-push: android-build-apk
|
|
adb push build/app/outputs/flutter-apk/app-release.apk /sdcard/Download/pantry-$(VERSION).apk
|
|
@echo "-> /sdcard/Download/pantry-$(VERSION).apk"
|
|
|
|
.PHONY: android-build-aab
|
|
android-build-aab:
|
|
flutter build appbundle --release --obfuscate --split-debug-info=build/debug-info-aab
|
|
.PHONY: ios-build
|
|
ios-build:
|
|
flutter build ios --release --no-codesign --obfuscate --split-debug-info=build/debug-info-ios
|
|
.PHONY: ios-build-ipa
|
|
ios-build-ipa:
|
|
flutter build ipa --release --obfuscate --split-debug-info=build/debug-info-ios --dart-define-from-file=.env --export-options-plist=ios/ExportOptions.plist
|
|
|
|
.PHONY: macos-build
|
|
macos-build:
|
|
flutter build macos --release --obfuscate --split-debug-info=build/debug-info-macos
|
|
|
|
.PHONY: macos-build-pkg
|
|
macos-build-pkg:
|
|
flutter build macos --config-only --obfuscate --split-debug-info=build/debug-info-macos
|
|
rm -rf build/macos/Runner.xcarchive build/macos/pkg
|
|
xcodebuild -workspace macos/Runner.xcworkspace \
|
|
-scheme Runner \
|
|
-configuration Release \
|
|
-archivePath build/macos/Runner.xcarchive \
|
|
-allowProvisioningUpdates \
|
|
archive
|
|
xcodebuild -exportArchive \
|
|
-archivePath build/macos/Runner.xcarchive \
|
|
-exportPath build/macos/pkg \
|
|
-exportOptionsPlist macos/ExportOptions.plist \
|
|
-allowProvisioningUpdates
|
|
|
|
.PHONY: build-all
|
|
build-all: android-build-apk android-build-aab
|
|
|
|
# Release (build + copy renamed artifacts to build/release/)
|
|
.PHONY: android-release-apk
|
|
android-release-apk: android-build-apk
|
|
mkdir -p build/release
|
|
cp build/app/outputs/flutter-apk/app-release.apk build/release/pantry-$(VERSION).apk
|
|
@echo "-> build/release/pantry-$(VERSION).apk"
|
|
|
|
.PHONY: android-release-aab
|
|
android-release-aab: android-build-aab
|
|
mkdir -p build/release
|
|
cp build/app/outputs/bundle/release/app-release.aab build/release/pantry-$(VERSION).aab
|
|
@echo "-> build/release/pantry-$(VERSION).aab"
|
|
|
|
.PHONY: ios-release
|
|
ios-release: ios-build-ipa
|
|
mkdir -p build/release
|
|
cp build/ios/ipa/*.ipa build/release/pantry-$(VERSION).ipa
|
|
@echo "-> build/release/pantry-$(VERSION).ipa"
|
|
|
|
.PHONY: macos-release
|
|
macos-release: macos-build-pkg
|
|
mkdir -p build/release
|
|
cp build/macos/pkg/*.pkg build/release/pantry-$(VERSION).pkg
|
|
@echo "-> build/release/pantry-$(VERSION).pkg"
|
|
|
|
.PHONY: android-upload
|
|
android-upload:
|
|
@echo "$(or $(TRACK),beta)" | grep -qE '^(internal|alpha|beta|production)$$' || (echo "Error: Invalid TRACK '$(TRACK)'. Must be: internal, alpha, beta, production"; exit 1)
|
|
@echo "$(or $(STATUS),draft)" | grep -qE '^(draft|completed|halted|inProgress)$$' || (echo "Error: Invalid STATUS '$(STATUS)'. Must be: draft, completed, halted, inProgress"; exit 1)
|
|
@echo "Track: $(or $(TRACK),internal) | Status: $(or $(STATUS),draft)"
|
|
bundle exec fastlane deploy track:$(or $(TRACK),internal) status:$(or $(STATUS),draft)
|
|
|
|
.PHONY: android-deploy
|
|
android-deploy: android-build-aab android-upload
|
|
|
|
.PHONY: android-promote
|
|
android-promote:
|
|
@echo "$(or $(FROM),internal)" | grep -qE '^(internal|alpha|beta|production)$$' || (echo "Error: Invalid FROM '$(FROM)'. Must be: internal, alpha, beta, production"; exit 1)
|
|
@echo "$(or $(TO),production)" | grep -qE '^(internal|alpha|beta|production)$$' || (echo "Error: Invalid TO '$(TO)'. Must be: internal, alpha, beta, production"; exit 1)
|
|
@echo "$(or $(STATUS),draft)" | grep -qE '^(draft|completed|halted|inProgress)$$' || (echo "Error: Invalid STATUS '$(STATUS)'. Must be: draft, completed, halted, inProgress"; exit 1)
|
|
@echo "Promote: $(or $(FROM),internal) -> $(or $(TO),production) | Status: $(or $(STATUS),draft)"
|
|
bundle exec fastlane promote from:$(or $(FROM),internal) to:$(or $(TO),production) status:$(or $(STATUS),draft)
|
|
|
|
.PHONY: ios-upload
|
|
ios-upload:
|
|
@echo "$(or $(DEST),testflight)" | grep -qE '^(testflight|appstore)$$' || (echo "Error: Invalid DEST '$(DEST)'. Must be: testflight, appstore"; exit 1)
|
|
@echo "Destination: $(or $(DEST),testflight)"
|
|
@if [ "$(or $(DEST),testflight)" = "appstore" ]; then \
|
|
bundle exec fastlane ios release; \
|
|
else \
|
|
bundle exec fastlane ios beta; \
|
|
fi
|
|
|
|
.PHONY: ios-deploy
|
|
ios-deploy: ios-build-ipa ios-upload
|
|
|
|
.PHONY: ios-submit
|
|
ios-submit:
|
|
bundle exec fastlane ios submit
|
|
|
|
.PHONY: macos-upload
|
|
macos-upload:
|
|
@echo "$(or $(DEST),testflight)" | grep -qE '^(testflight|appstore)$$' || (echo "Error: Invalid DEST '$(DEST)'. Must be: testflight, appstore"; exit 1)
|
|
@echo "Destination: $(or $(DEST),testflight)"
|
|
@if [ "$(or $(DEST),testflight)" = "appstore" ]; then \
|
|
bundle exec fastlane mac release; \
|
|
else \
|
|
bundle exec fastlane mac beta; \
|
|
fi
|
|
|
|
.PHONY: macos-deploy
|
|
macos-deploy: macos-build-pkg macos-upload
|
|
|
|
.PHONY: macos-submit
|
|
macos-submit:
|
|
bundle exec fastlane mac submit
|
|
|
|
.PHONY: release-all
|
|
release-all: android-release-apk android-release-aab
|
|
|
|
.PHONY: deploy-production
|
|
deploy-production:
|
|
$(MAKE) android-deploy TRACK=production STATUS=completed
|
|
$(MAKE) ios-deploy DEST=appstore
|
|
$(MAKE) macos-deploy DEST=appstore
|
|
|
|
.PHONY: deploy-beta
|
|
deploy-beta:
|
|
$(MAKE) android-deploy TRACK=beta STATUS=completed
|
|
$(MAKE) ios-deploy DEST=testflight
|
|
$(MAKE) macos-deploy DEST=testflight
|
|
|
|
# CocoaPods
|
|
.PHONY: pods
|
|
pods:
|
|
cd ios && pod install --repo-update
|
|
cd macos && pod install --repo-update
|
|
|
|
# Git hooks
|
|
.PHONY: install-hooks
|
|
install-hooks:
|
|
lefthook install
|
|
|
|
# API
|
|
.PHONY: fetch-openapi
|
|
fetch-openapi:
|
|
gh api repos/chenasraf/nextcloud-pantry/contents/openapi.json --jq '.content' | base64 -d > openapi.json
|
|
@echo "-> openapi.json updated"
|
|
|
|
# Assets
|
|
.PHONY: copy-graphics
|
|
copy-graphics:
|
|
ifndef GRAPHICS_DIR
|
|
$(error GRAPHICS_DIR is required. Usage: make copy-graphics GRAPHICS_DIR=~/path/to/graphics)
|
|
endif
|
|
@for pattern in icon logo; do \
|
|
for ext in svg png; do \
|
|
for f in $(GRAPHICS_DIR)/$$pattern*.$$ext; do \
|
|
[ -e "$$f" ] && cp "$$f" assets/icon/ && echo "Copied $$f" || true; \
|
|
done; \
|
|
done; \
|
|
done
|
|
|
|
.PHONY: icons
|
|
icons:
|
|
mkdir -p assets/icon
|
|
rsvg-convert -w 1024 -h 1024 assets/logo_icon_squircle.svg > assets/icon/icon.png
|
|
rsvg-convert -w 1024 -h 1024 assets/logo_icon_square.svg > assets/icon/icon_ios.png
|
|
rsvg-convert -w 1024 -h 1024 assets/logo_icon_foreground.svg > assets/icon/icon_foreground.png
|
|
rsvg-convert -w 1024 -h 1024 assets/logo_icon_macos.svg > assets/icon/icon_macos.png
|
|
dart run flutter_launcher_icons
|
|
rsvg-convert -w 512 -h 512 assets/logo_icon_squircle.svg > fastlane/metadata/android/en-US/images/icon.png
|
|
|
|
.PHONY: splash
|
|
splash:
|
|
mkdir -p assets/icon
|
|
rsvg-convert -h 1152 --page-width 1920 --page-height 1920 --top 384 --left 384 assets/logo_icon.svg > assets/icon/splash.png
|
|
dart run flutter_native_splash:create
|