Compare commits
	
		
			7 Commits
		
	
	
		
			v0.0.36
			...
			33ce291b09
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 33ce291b09 | |||
| 4e07c10969 | |||
| bc63b57154 | |||
| fa083a1080 | |||
| c448e2dfb7 | |||
| d9061388dd | |||
| e764393706 | 
| @@ -25,8 +25,6 @@ jobs: | ||||
|         ls -la | ||||
|         # only install dev-packages | ||||
|         pipenv install --categories=dev-packages | ||||
|         pipenv run pip freeze         | ||||
|  | ||||
|       working-directory: backend | ||||
|  | ||||
|     - name: Run linter | ||||
|   | ||||
| @@ -25,7 +25,6 @@ jobs: | ||||
|         ls -la | ||||
|         # install all packages, including dev-packages | ||||
|         pipenv install --dev | ||||
|         pipenv run pip freeze         | ||||
|       working-directory: backend | ||||
|  | ||||
|     - name: Run Tests | ||||
|   | ||||
							
								
								
									
										14
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							| @@ -9,18 +9,16 @@ | ||||
|             "name": "Backend - debug", | ||||
|             "type": "debugpy", | ||||
|             "request": "launch", | ||||
|             "module": "uvicorn", | ||||
|             "env": { | ||||
|                 "DEBUG": "true" | ||||
|             }, | ||||
|             "args": [ | ||||
|                 // "--app-dir", | ||||
|                 // "src", | ||||
|                 "src.main:app", | ||||
|                 "--reload", | ||||
|             ], | ||||
|             "jinja": true, | ||||
|             "cwd": "${workspaceFolder}/backend" | ||||
|             "cwd": "${workspaceFolder}/backend", | ||||
|             "module": "fastapi", | ||||
|             "args": [ | ||||
|                 "dev", | ||||
|                 "src/main.py" | ||||
|             ] | ||||
|         }, | ||||
|         { | ||||
|             "name": "Backend - tester", | ||||
|   | ||||
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +0,0 @@ | ||||
| { | ||||
|     "cmake.ignoreCMakeListsMissing": true | ||||
| } | ||||
| @@ -14,5 +14,6 @@ EXPOSE 8000 | ||||
| ENV NUM_WORKERS=1 | ||||
| ENV OSM_CACHE_DIR=/cache | ||||
| ENV MEMCACHED_HOST_PATH=none | ||||
| ENV LOKI_URL=none | ||||
|  | ||||
| CMD fastapi run src/main.py --port 8000 --workers $NUM_WORKERS | ||||
| CMD ["fastapi", "run", "src/main.py", "--port", "8000", "--workers", "$NUM_WORKERS"] | ||||
|   | ||||
| @@ -25,3 +25,4 @@ pymemcache = "*" | ||||
| fastapi-cli = "*" | ||||
| scikit-learn = "*" | ||||
| pyqt6 = "*" | ||||
| loki-logger-handler = "*" | ||||
|   | ||||
							
								
								
									
										11
									
								
								backend/Pipfile.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								backend/Pipfile.lock
									
									
									
										generated
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|     "_meta": { | ||||
|         "hash": { | ||||
|             "sha256": "bb22b4e28c7aa199c94b688ad93d3ab0ccf1089a172131f4aec03b78e7bd7f1c" | ||||
|             "sha256": "6edd6644586e8814a0b4526adb3352dfc17828ca129de7a68c1d5929efe94daa" | ||||
|         }, | ||||
|         "pipfile-spec": 6, | ||||
|         "requires": {}, | ||||
| @@ -507,6 +507,15 @@ | ||||
|             "markers": "python_version >= '3.8'", | ||||
|             "version": "==1.4.7" | ||||
|         }, | ||||
|         "loki-logger-handler": { | ||||
|             "hashes": [ | ||||
|                 "sha256:aa1a9c933282c134a1e4271aba3cbaa2a3660eab6ea415bad7a072444ab98aa8", | ||||
|                 "sha256:f6114727a9e5e6f3f2058b9b5324d1cab6d1a04e802079f7b57a8aeb7bd0a112" | ||||
|             ], | ||||
|             "index": "pypi", | ||||
|             "markers": "python_version >= '2.7'", | ||||
|             "version": "==1.0.2" | ||||
|         }, | ||||
|         "lxml": { | ||||
|             "hashes": [ | ||||
|                 "sha256:01220dca0d066d1349bd6a1726856a78f7929f3878f7e2ee83c296c69495309e", | ||||
|   | ||||
 Submodule backend/deployment updated: 718df09e88...904f16bfc0
									
								
							
							
								
								
									
										1094
									
								
								backend/report.html
									
									
									
									
									
								
							
							
						
						
									
										1094
									
								
								backend/report.html
									
									
									
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,6 +1,5 @@ | ||||
| """Module allowing to access the parameters of route generation""" | ||||
| """Module setting global parameters for the application such as cache, route generation, etc.""" | ||||
|  | ||||
| import logging | ||||
| import os | ||||
| from pathlib import Path | ||||
|  | ||||
| @@ -16,21 +15,6 @@ cache_dir_string = os.getenv('OSM_CACHE_DIR', './cache') | ||||
| OSM_CACHE_DIR = Path(cache_dir_string) | ||||
|  | ||||
|  | ||||
| # if we are in a debug session, set verbose and rich logging | ||||
| if os.getenv('DEBUG', "false") == "true": | ||||
|     from rich.logging import RichHandler | ||||
|     logging.basicConfig( | ||||
|         level=logging.DEBUG, | ||||
|         format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', | ||||
|         handlers=[RichHandler()] | ||||
|     ) | ||||
| else: | ||||
|     logging.basicConfig( | ||||
|         level=logging.INFO, | ||||
|         format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', | ||||
|     ) | ||||
|  | ||||
|  | ||||
| MEMCACHED_HOST_PATH = os.getenv('MEMCACHED_HOST_PATH', None) | ||||
| if MEMCACHED_HOST_PATH == "none": | ||||
|     MEMCACHED_HOST_PATH = None | ||||
|   | ||||
							
								
								
									
										58
									
								
								backend/src/logging_config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								backend/src/logging_config.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| """Sets up global logging configuration for the application.""" | ||||
|  | ||||
| import logging | ||||
| import os | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| def configure_logging(): | ||||
|     """ | ||||
|     Called at startup of a FastAPI application instance to setup logging. Depending on the environment, it will log to stdout or to Loki. | ||||
|     """ | ||||
|  | ||||
|     is_debug = os.getenv('DEBUG', "false") == "true" | ||||
|     is_kubernetes = os.getenv('KUBERNETES_SERVICE_HOST') is not None | ||||
|  | ||||
|  | ||||
|     if is_kubernetes: | ||||
|         # in that case we want to log to stdout and also to loki | ||||
|         from loki_logger_handler.loki_logger_handler import LokiLoggerHandler | ||||
|         loki_url = os.getenv('LOKI_URL') | ||||
|         loki_url = "http://localhost:3100/loki/api/v1/push" | ||||
|         if loki_url is None: | ||||
|             raise ValueError("LOKI_URL environment variable is not set") | ||||
|          | ||||
|         loki_handler = LokiLoggerHandler( | ||||
|             url = loki_url, | ||||
|             labels = {'app': 'anyway', 'environment': 'staging' if is_debug else 'production'} | ||||
|         ) | ||||
|  | ||||
|         logger.info(f"Logging to Loki at {loki_url} with {loki_handler.labels} and {is_debug=}") | ||||
|         logging_handlers = [loki_handler, logging.StreamHandler()] | ||||
|         logging_level = logging.DEBUG if is_debug else logging.INFO | ||||
|         # silence the chatty logs loki generates itself | ||||
|         logging.getLogger('urllib3.connectionpool').setLevel(logging.WARNING) | ||||
|         # no need for time since it's added by loki or can be shown in kube logs | ||||
|         logging_format = '%(name)s - %(levelname)s - %(message)s' | ||||
|  | ||||
|     else: | ||||
|         # if we are in a debug (local) session, set verbose and rich logging | ||||
|         from rich.logging import RichHandler | ||||
|         logging_handlers = [RichHandler()] | ||||
|         logging_level = logging.DEBUG if is_debug else logging.INFO | ||||
|         logging_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' | ||||
|  | ||||
|  | ||||
|  | ||||
|     logging.basicConfig( | ||||
|         level = logging_level, | ||||
|         format = logging_format, | ||||
|         handlers = logging_handlers | ||||
|     ) | ||||
|  | ||||
|     # also overwrite the uvicorn loggers | ||||
|     logging.getLogger('uvicorn').handlers = logging_handlers | ||||
|     logging.getLogger('uvicorn.access').handlers = logging_handlers | ||||
|     logging.getLogger('uvicorn.error').handlers = logging_handlers | ||||
|  | ||||
| @@ -2,7 +2,9 @@ | ||||
|  | ||||
| import logging | ||||
| from fastapi import FastAPI, HTTPException, Query | ||||
| from contextlib import asynccontextmanager | ||||
|  | ||||
| from .logging_config import configure_logging | ||||
| from .structs.landmark import Landmark, Toilets | ||||
| from .structs.preferences import Preferences | ||||
| from .structs.linked_landmarks import LinkedLandmarks | ||||
| @@ -11,17 +13,28 @@ from .utils.landmarks_manager import LandmarkManager | ||||
| from .utils.toilets_manager import ToiletsManager | ||||
| from .utils.optimizer import Optimizer | ||||
| from .utils.refiner import Refiner | ||||
| from .persistence import client as cache_client | ||||
|  | ||||
| from .cache import client as cache_client | ||||
|  | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
| app = FastAPI() | ||||
| manager = LandmarkManager() | ||||
| optimizer = Optimizer() | ||||
| refiner = Refiner(optimizer=optimizer) | ||||
|  | ||||
|  | ||||
| @asynccontextmanager | ||||
| async def lifespan(app: FastAPI): | ||||
|     """Function to run at the start of the app""" | ||||
|     logger.info("Setting up logging") | ||||
|     configure_logging() | ||||
|     yield | ||||
|     logger.info("Shutting down logging") | ||||
|  | ||||
|  | ||||
| app = FastAPI(lifespan=lifespan) | ||||
|  | ||||
|  | ||||
|  | ||||
| @app.post("/trip/new") | ||||
| def new_trip(preferences: Preferences, | ||||
|              start: tuple[float, float], | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| """Definition of the Landmark class to handle visitable objects across the world.""" | ||||
|  | ||||
| from typing import Optional, Literal | ||||
| from uuid import uuid4 | ||||
| from uuid import uuid4, UUID | ||||
| from pydantic import BaseModel, Field | ||||
|  | ||||
|  | ||||
| @@ -29,12 +29,12 @@ class Landmark(BaseModel) : | ||||
|         description (Optional[str]): A text description of the landmark. | ||||
|         duration (Optional[int]): The estimated time to visit the landmark (in minutes). | ||||
|         name_en (Optional[str]): The English name of the landmark. | ||||
|         uuid (str): A unique identifier for the landmark, generated by default using uuid4. | ||||
|         uuid (UUID): A unique identifier for the landmark, generated by default using uuid4. | ||||
|         must_do (Optional[bool]): Whether the landmark is a "must-do" attraction. | ||||
|         must_avoid (Optional[bool]): Whether the landmark should be avoided. | ||||
|         is_secondary (Optional[bool]): Whether the landmark is secondary or less important. | ||||
|         time_to_reach_next (Optional[int]): Estimated time (in minutes) to reach the next landmark. | ||||
|         next_uuid (Optional[str]): UUID of the next landmark in sequence (if applicable). | ||||
|         next_uuid (Optional[UUID]): UUID of the next landmark in sequence (if applicable). | ||||
|     """ | ||||
|  | ||||
|     # Properties of the landmark | ||||
| @@ -52,7 +52,7 @@ class Landmark(BaseModel) : | ||||
|     name_en : Optional[str] = None | ||||
|  | ||||
|     # Unique ID of a given landmark | ||||
|     uuid: str = Field(default_factory=uuid4) | ||||
|     uuid: UUID = Field(default_factory=uuid4) | ||||
|  | ||||
|     # Additional properties depending on specific tour | ||||
|     must_do : Optional[bool] = False | ||||
| @@ -60,7 +60,7 @@ class Landmark(BaseModel) : | ||||
|     is_secondary : Optional[bool] = False | ||||
|  | ||||
|     time_to_reach_next : Optional[int] = 0 | ||||
|     next_uuid : Optional[str] = None | ||||
|     next_uuid : Optional[UUID] = None | ||||
|  | ||||
|     def __str__(self) -> str: | ||||
|         """ | ||||
| @@ -139,4 +139,4 @@ class Toilets(BaseModel) : | ||||
|      | ||||
|     class Config: | ||||
|         # This allows us to easily convert the model to and from dictionaries | ||||
|         orm_mode = True | ||||
|         from_attributes = True | ||||
| @@ -1,6 +1,6 @@ | ||||
| """Definition of the Trip class.""" | ||||
|  | ||||
| import uuid | ||||
| from uuid import uuid4, UUID | ||||
| from pydantic import BaseModel, Field | ||||
| from pymemcache.client.base import Client | ||||
|  | ||||
| @@ -19,9 +19,9 @@ class Trip(BaseModel): | ||||
|     Methods: | ||||
|         from_linked_landmarks: create a Trip from LinkedLandmarks object. | ||||
|     """ | ||||
|     uuid: str = Field(default_factory=uuid.uuid4) | ||||
|     uuid: UUID = Field(default_factory=uuid4) | ||||
|     total_time: int | ||||
|     first_landmark_uuid: str | ||||
|     first_landmark_uuid: UUID | ||||
|  | ||||
|  | ||||
|     @classmethod | ||||
| @@ -31,7 +31,7 @@ class Trip(BaseModel): | ||||
|         """ | ||||
|         trip = Trip( | ||||
|             total_time = landmarks.total_time, | ||||
|             first_landmark_uuid = str(landmarks[0].uuid) | ||||
|             first_landmark_uuid = landmarks[0].uuid | ||||
|         ) | ||||
|  | ||||
|         # Store the trip in the cache | ||||
|   | ||||
| @@ -4,7 +4,7 @@ from fastapi import HTTPException | ||||
| from pydantic import ValidationError | ||||
|  | ||||
| from ..structs.landmark import Landmark | ||||
| from ..persistence import client as cache_client | ||||
| from ..cache import client as cache_client | ||||
|  | ||||
|  | ||||
| def landmarks_to_osmid(landmarks: list[Landmark]) -> list[int] : | ||||
|   | ||||
							
								
								
									
										24
									
								
								frontend/.github/workflows/build_app_ios.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								frontend/.github/workflows/build_app_ios.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -6,14 +6,17 @@ on: | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: macos-latest | ||||
|     env: | ||||
|       # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps | ||||
|       BUNDLE_GEMFILE: ios/Gemfile | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Set up ruby env | ||||
|         uses: ruby/setup-ruby@v1 | ||||
|         with: | ||||
|           ruby-version: 3.2.1 | ||||
|           bundler-cache: true | ||||
|           ruby-version: 3.3 | ||||
|           bundler-cache: true # runs 'bundle install' and caches installed gems automatically | ||||
|  | ||||
|       - name: Install Flutter | ||||
|         uses: subosito/flutter-action@v2 | ||||
| @@ -31,16 +34,24 @@ jobs: | ||||
|           echo "BUILD_NAME=${REF_NAME//v}" >> $GITHUB_ENV | ||||
|  | ||||
|       - name: Setup SSH key for match git repo | ||||
|         run: echo "$MATCH_REPO_SSH_KEY" | base64 --decode > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa | ||||
|         # and mark the host as known | ||||
|         run: | | ||||
|           echo $MATCH_REPO_SSH_KEY | base64 --decode > ~/.ssh/id_rsa | ||||
|           chmod 600 ~/.ssh/id_rsa | ||||
|           ssh-keyscan -p 2222 git.kluster.moll.re > ~/.ssh/known_hosts | ||||
|         env: | ||||
|           MATCH_REPO_SSH_KEY: ${{ secrets.IOS_MATCH_REPO_SSH_KEY_BASE64 }} | ||||
|  | ||||
|       - name: Install fastlane | ||||
|         run: bundle install | ||||
|       - name: Install dependencies and clean up | ||||
|         run: | | ||||
|           flutter pub get | ||||
|           bundle exec pod install | ||||
|           flutter clean | ||||
|           bundle exec pod cache clean --all | ||||
|         working-directory: ios | ||||
|  | ||||
|       - name: Run fastlane lane | ||||
|         run: bundle exec fastlane deploy_release | ||||
|         run: bundle exec fastlane deploy_release --verbose | ||||
|         working-directory: ios | ||||
|         env: | ||||
|           BUILD_NUMBER: ${{ github.run_number }} | ||||
| @@ -50,3 +61,4 @@ jobs: | ||||
|           IOS_ASC_ISSUER_ID: ${{ secrets.IOS_ASC_ISSUER_ID }} | ||||
|           IOS_ASC_KEY: ${{ secrets.IOS_ASC_KEY }} | ||||
|           MATCH_PASSWORD: ${{ secrets.IOS_MATCH_PASSWORD }} | ||||
|           IOS_GOOGLE_MAPS_API_KEY: ${{ secrets.IOS_GOOGLE_MAPS_API_KEY }} | ||||
|   | ||||
| @@ -50,13 +50,12 @@ Secrets used by fastlane are stored on hashicorp vault and are fetched by the CI | ||||
|  | ||||
| ## Secrets | ||||
| These are mostly used by the CI/CD pipeline to deploy the application. The main usage for github actions is documented under [https://github.com/hashicorp/vault-action](https://github.com/hashicorp/vault-action). | ||||
| **Global secrets** are used for both versions of the app (android and ios).  | ||||
| - `GOOGLE_MAPS_API_KEY` is used to authenticate with the Google Maps API | ||||
|  | ||||
| **Platform-specific secrets** are used by the CI/CD pipeline to deploy to the respective app stores. | ||||
| - `GOOGLE_MAPS_API_KEY` is used to authenticate with the Google Maps API and is scoped to the android platform | ||||
| - `ANDROID_KEYSTORE` is used to sign the android apk | ||||
| - `ANDROID_GOOGLE_KEY` is used to authenticate with the Google Play Store api | ||||
| - `IOS_GOOGLE_...` | ||||
| - `IOS_GOOGLE_MAPS_API_KEY` is used to authenticate with the Google Maps API and is scoped to the ios platform | ||||
| - `IOS_GOOGLE_...` | ||||
| - `IOS_GOOGLE_...` | ||||
| - `IOS_GOOGLE_...` | ||||
| @@ -4,17 +4,15 @@ PODS: | ||||
|     - Flutter | ||||
|   - geolocator_apple (1.2.0): | ||||
|     - Flutter | ||||
|   - Google-Maps-iOS-Utils (6.0.0): | ||||
|   - Google-Maps-iOS-Utils (6.1.0): | ||||
|     - GoogleMaps (~> 9.0) | ||||
|   - google_maps_flutter_ios (0.0.1): | ||||
|     - Flutter | ||||
|     - Google-Maps-iOS-Utils (< 7.0, >= 5.0) | ||||
|     - GoogleMaps (< 10.0, >= 8.4) | ||||
|   - GoogleMaps (9.1.1): | ||||
|     - GoogleMaps/Maps (= 9.1.1) | ||||
|   - GoogleMaps/Base (9.1.1) | ||||
|   - GoogleMaps/Maps (9.1.1): | ||||
|     - GoogleMaps/Base | ||||
|   - GoogleMaps (9.2.0): | ||||
|     - GoogleMaps/Maps (= 9.2.0) | ||||
|   - GoogleMaps/Maps (9.2.0) | ||||
|   - map_launcher (0.0.1): | ||||
|     - Flutter | ||||
|   - path_provider_foundation (0.0.1): | ||||
| @@ -74,9 +72,9 @@ SPEC CHECKSUMS: | ||||
|   Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 | ||||
|   geocoding_ios: bcbdaa6bddd7d3129c9bcb8acddc5d8778689768 | ||||
|   geolocator_apple: d981750b9f47dbdb02427e1476d9a04397beb8d9 | ||||
|   Google-Maps-iOS-Utils: cfe6a0239c7ca634b7e001ad059a6707143dc8dc | ||||
|   Google-Maps-iOS-Utils: 0a484b05ed21d88c9f9ebbacb007956edd508a96 | ||||
|   google_maps_flutter_ios: 0291eb2aa252298a769b04d075e4a9d747ff7264 | ||||
|   GoogleMaps: 80ea184ed6bf44139f383a8b0e248ba3ec1cc8c9 | ||||
|   GoogleMaps: 634ec3ca99698b31ca2253d64f017217d70cfb38 | ||||
|   map_launcher: fe43bda6720bb73c12fcc1bdd86123ff49a4d4d6 | ||||
|   path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 | ||||
|   permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d | ||||
| @@ -84,6 +82,6 @@ SPEC CHECKSUMS: | ||||
|   sqflite: c35dad70033b8862124f8337cc994a809fcd9fa3 | ||||
|   url_launcher_ios: 694010445543906933d732453a59da0a173ae33d | ||||
|  | ||||
| PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 | ||||
| PODFILE CHECKSUM: bd1a78910c05ac1e3a220e80f392c61ab2cc8789 | ||||
|  | ||||
| COCOAPODS: 1.10.2 | ||||
|   | ||||
| @@ -8,9 +8,7 @@ import GoogleMaps | ||||
|     _ application: UIApplication, | ||||
|     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? | ||||
|   ) -> Bool { | ||||
|     // load the key from env | ||||
|     let key = ProcessInfo.processInfo.environment["GOOGLE_MAPS_API_KEY"]! | ||||
|     GMSServices.provideAPIKey(key) | ||||
|     GMSServices.provideAPIKey("IOS_GOOGLE_MAPS_API_KEY") | ||||
|     GeneratedPluginRegistrant.register(with: self) | ||||
|     return super.application(application, didFinishLaunchingWithOptions: launchOptions) | ||||
|   } | ||||
|   | ||||
| @@ -10,4 +10,4 @@ IOS_ASC_ISSUER_ID="sample" | ||||
| SIGNING_KEY_FILE_PATH="sample" | ||||
| SIGNING_KEY_PASSWORD="sample" | ||||
|  | ||||
| GOOGLE_MAPS_API_KEY="sample" | ||||
| IOS_GOOGLE_MAPS_API_KEY="sample" | ||||
|   | ||||
| @@ -33,7 +33,7 @@ platform :ios do | ||||
|       "flutter", | ||||
|       "build", | ||||
|       "ipa", | ||||
|       "--release", | ||||
|       "--debug", | ||||
|       "--build-name=#{build_name}", | ||||
|       "--build-number=#{build_number}", | ||||
|     ) | ||||
| @@ -44,7 +44,9 @@ platform :ios do | ||||
|       archive_path: "../build/ios/archive/Runner.xcarchive" | ||||
|     ) | ||||
|  | ||||
|     upload_to_testflight | ||||
|     upload_to_testflight( | ||||
|       skip_waiting_for_build_processing: true, | ||||
|     ) | ||||
|   end | ||||
|  | ||||
|  | ||||
| @@ -62,6 +64,16 @@ platform :ios do | ||||
|       readonly: true, | ||||
|     ) | ||||
|  | ||||
|     # replace secrets by real values, the stupid way | ||||
|     sh( | ||||
|       "sed", | ||||
|       "-i", | ||||
|       "", | ||||
|       "s/IOS_GOOGLE_MAPS_API_KEY/#{ENV["IOS_GOOGLE_MAPS_API_KEY"]}/g", | ||||
|       "../Runner/AppDelegate.swift" | ||||
|  | ||||
|     ) | ||||
|  | ||||
|     sh( | ||||
|       "flutter", | ||||
|       "build", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user