diff --git a/.env.example b/.env.example index 6c5d91e..f69c9a8 100644 --- a/.env.example +++ b/.env.example @@ -5,4 +5,5 @@ POSTGRES_DB_NAME=beerpong POSTGRES_URL=jdbc:postgresql://localhost:5432/${POSTGRES_DB_NAME} #backend API_BASE_URL=http://localhost:8080/ -EXPO_PUBLIC_API_BASE_URL=localhost:8080 +EXPO_PUBLIC_API_BASE_URL=http://localhost:8080 +EXPO_PUBLIC_API_WS_URL=ws://localhost:8080 diff --git a/.github/workflows/api-staging-cd.yml b/.github/workflows/api-staging-cd.yml index 8903ebb..f1411ee 100644 --- a/.github/workflows/api-staging-cd.yml +++ b/.github/workflows/api-staging-cd.yml @@ -80,7 +80,7 @@ jobs: service: 'api-springboot-staging' image: 'europe-west10-docker.pkg.dev/beer-pong-441815/api-beerpong/api-staging:${{ github.sha }}' region: europe-west10 - flags: '--port=8080 --add-cloudsql-instances=beer-pong-441815:europe-west10:beerpong-staging-db --no-cpu-throttling --min-instances 0 --max-instances 1' + flags: '--port=8080 --add-cloudsql-instances=beer-pong-441815:europe-west10:beerpong-staging-db --no-cpu-throttling --min-instances 0 --max-instances 1 --allow-unauthenticated' env_vars: | POSTGRES_USER=postgres POSTGRES_URL=jdbc:postgresql:///beerpong?cloudSqlInstance=beer-pong-441815:europe-west10:beerpong-staging-db&socketFactory=com.google.cloud.sql.postgres.SocketFactory diff --git a/.github/workflows/mobile-app-testflight.yml b/.github/workflows/mobile-app-testflight.yml new file mode 100644 index 0000000..e6b4d1f --- /dev/null +++ b/.github/workflows/mobile-app-testflight.yml @@ -0,0 +1,73 @@ +name: Mobile App To Testflight + +on: + workflow_dispatch: + # pull_request: + # branches: + # - staging + +defaults: + run: + working-directory: mobile-app + +jobs: + bump-version: + name: Bump the version of the app + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + build-testflight: + name: Build and push app to Apple Testflight + runs-on: macos-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + - name: Setup Expo + uses: expo/expo-github-action@v8 + with: + expo-version: latest + eas-version: latest + token: ${{ secrets.EXPO_TOKEN }} + + - name: Install dependencies + run: npm ci + + - name: Build app + run: npx eas-cli build -p ios --profile staging --local --non-interactive --output=./build.ipa + + - name: Submit to App Store + run: npx eas-cli submit -p ios --path=./build.ipa --non-interactive + + build-android-test: + name: Build and push app to Apple Testflight + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + - name: Setup Expo + uses: expo/expo-github-action@v8 + with: + expo-version: latest + eas-version: latest + token: ${{ secrets.EXPO_TOKEN }} + + - name: Install dependencies + run: npm ci + + - name: Build app + run: npx eas-cli build -p android --profile staging --local --non-interactive --output=./build.ipa + + - name: Submit to App Store + run: npx eas-cli submit -p android --path=./build.ipa + + diff --git a/.gitignore b/.gitignore index 17d50b0..1162648 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ node_modules .env socket-test/ build* + +.gen-builds/** +.DS_Store diff --git a/Makefile b/Makefile index d2250ab..9eb2b1e 100644 --- a/Makefile +++ b/Makefile @@ -40,4 +40,17 @@ docker-backend-down: .PHONY: docker-backend-rebuild docker-backend-rebuild: - make docker-backend-down; make docker-backend-up \ No newline at end of file + make docker-backend-down; make docker-backend-up + +.PHONY: app-build-development +app-build-development: + cd mobile-app && npx eas-cli build -p ios --profile development --local --output=../.gen-builds/build.tar.gz + +.PHONY: app-build-preview +app-build-preview: + cd mobile-app && npx eas-cli build -p ios --profile preview --local --output=../.gen-builds/build.tar.gz + +.PHONY: app-build-staging +app-build-staging: + cd mobile-app && npx eas-cli build -p ios --profile staging --local --output=../.gen-builds/build.ipa --non-interactive + diff --git a/mobile-app/api/env.ts b/mobile-app/api/env.ts index 50d14ba..ead8266 100644 --- a/mobile-app/api/env.ts +++ b/mobile-app/api/env.ts @@ -5,7 +5,8 @@ import packageJson from '../package.json'; /** the spaced format of group invite codes. `[3, 4, 3]` => `"xxx xxxx xxx"` */ const groupCodeFormat = [3, 3, 3]; -const host = process.env.EXPO_PUBLIC_API_BASE_URL; +const httpUrl = process.env.EXPO_PUBLIC_API_BASE_URL; +const wsUrl = process.env.EXPO_PUBLIC_API_WS_URL; const groupCodeSeperatorIndices = groupCodeFormat.slice(1).map((_, idx) => { return groupCodeFormat.slice(0, idx + 1).reduce((sum, i) => sum + i, 0) - 1; @@ -30,8 +31,8 @@ const getDayName = (date: Dayjs) => { }; export const env = { - apiBaseUrl: 'http://' + host, - realtimeBaseUrl: 'ws://' + host, + apiBaseUrl: httpUrl, + realtimeBaseUrl: wsUrl, groupCode: { format: groupCodeFormat, diff --git a/mobile-app/app.json b/mobile-app/app.json index 367face..ad423c3 100644 --- a/mobile-app/app.json +++ b/mobile-app/app.json @@ -1,8 +1,8 @@ { "expo": { "name": "beerpong-tournament", - "slug": "beerpong-tournament", - "version": "1.0.0", + "slug": "mobile-app", + "version": "1.0.1", "orientation": "portrait", "icon": "./assets/images/icon.png", "scheme": "myapp", @@ -23,7 +23,9 @@ "adaptiveIcon": { "foregroundImage": "./assets/images/adaptive-icon.png", "backgroundColor": "#ffffff" - } + }, + "permissions": ["android.permission.RECORD_AUDIO"], + "package": "com.linusbolls.mobileapp" }, "web": { "bundler": "metro", @@ -39,6 +41,13 @@ "project": "beerpong", "organization": "sackverein" } + ], + [ + "expo-image-picker", + { + "photosPermission": "The app accesses your photos to let you choose a picture", + "cameraPermission": "The app accesses your photos to let take a pic" + } ] ], "experiments": { diff --git a/mobile-app/eas.json b/mobile-app/eas.json index 2fb9fac..cb8e41d 100644 --- a/mobile-app/eas.json +++ b/mobile-app/eas.json @@ -5,13 +5,19 @@ }, "build": { "development": { + "env": { + "EXPO_PUBLIC_API_BASE_URL": "http://localhost:8080", + "SENTRY_DISABLE_AUTO_UPLOAD": "true", + "EXPO_PUBLIC_API_WS_URL": "ws://localhost:8080" + }, "developmentClient": true, "distribution": "internal" }, "preview": { "env": { - "EXPO_PUBLIC_API_BASE_URL": "localhost:8080", - "SENTRY_DISABLE_AUTO_UPLOAD": true + "EXPO_PUBLIC_API_BASE_URL": "http://localhost:8080", + "SENTRY_DISABLE_AUTO_UPLOAD": "true", + "EXPO_PUBLIC_API_WS_URL": "ws://localhost:8080" }, "ios": { "simulator": true @@ -19,13 +25,16 @@ }, "staging": { "env": { - "EXPO_PUBLIC_API_BASE_URL": "beerpong.lb.laurinnotemann.dev" - }, - "distribution": "internal" + "EXPO_PUBLIC_API_BASE_URL": "https://beerpong.lb.staging.laurinnotemann.dev", + "EXPO_PUBLIC_API_WS_URL": "wss://beerpong.lb.staging.laurinnotemann.dev", + "SENTRY_ALLOW_FAILURE": "true" + } }, "production": { "env": { - "EXPO_PUBLIC_API_BASE_URL": "beerpong.lb.laurinnotemann.dev" + "EXPO_PUBLIC_API_BASE_URL": "https://beerpong.lb.laurinnotemann.dev", + "EXPO_PUBLIC_API_WS_URL": "wss://beerpong.lb.laurinnotemann.dev", + "SENTRY_ALLOW_FAILURE": "true" }, "autoIncrement": true } diff --git a/mobile-app/package-lock.json b/mobile-app/package-lock.json index 139f6a1..2609de5 100644 --- a/mobile-app/package-lock.json +++ b/mobile-app/package-lock.json @@ -23,8 +23,9 @@ "expo": "~51.0.28", "expo-clipboard": "^6.0.3", "expo-constants": "~16.0.2", + "expo-dev-client": "~4.0.29", "expo-font": "~12.0.9", - "expo-image-picker": "^16.0.2", + "expo-image-picker": "~15.0.7", "expo-linking": "~6.3.1", "expo-router": "~3.5.23", "expo-splash-screen": "~0.27.5", @@ -12167,6 +12168,76 @@ "expo": "*" } }, + "node_modules/expo-dev-client": { + "version": "4.0.29", + "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-4.0.29.tgz", + "integrity": "sha512-aANlw9dC4PJEPaRNpe+X5xwyYI+aCIcbZklAAsFlkv2/05gLrsvAFgmQpRtowAzF+VggHWde1eKUOeUccAYIEg==", + "license": "MIT", + "dependencies": { + "expo-dev-launcher": "4.0.29", + "expo-dev-menu": "5.0.23", + "expo-dev-menu-interface": "1.8.4", + "expo-manifests": "~0.14.0", + "expo-updates-interface": "~0.16.2" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-dev-launcher": { + "version": "4.0.29", + "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-4.0.29.tgz", + "integrity": "sha512-0a0SL8mc4FrqPeGxJHe9kf0kG+Di+38Gd+HP5DEL9dcOa8m2qffKnk22UcyujCT6+Qk0OUK1s53nnfqFB26uVw==", + "license": "MIT", + "dependencies": { + "ajv": "8.11.0", + "expo-dev-menu": "5.0.23", + "expo-manifests": "~0.14.0", + "resolve-from": "^5.0.0", + "semver": "^7.6.0" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-dev-launcher/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/expo-dev-menu": { + "version": "5.0.23", + "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-5.0.23.tgz", + "integrity": "sha512-ztDvrSdFGkRbMoQlGLyKMS6CslMGylonVW4kQHUrBQApCL0c2NtRwLlr2bA1SXF0S7qYdPPg/ayLnj7DDR5X2w==", + "license": "MIT", + "dependencies": { + "expo-dev-menu-interface": "1.8.4", + "semver": "^7.5.4" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-dev-menu-interface": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-1.8.4.tgz", + "integrity": "sha512-FpYI57EUu9qTSOOi+FZJ58xkCGJK7QD0mTiXK/y1I8lRdZGjCmdBqVvC4dAx2GcbIT78EPxaVf4/90tK/KRK6A==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-file-system": { "version": "17.0.1", "license": "MIT", @@ -12185,24 +12256,32 @@ } }, "node_modules/expo-image-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-5.0.0.tgz", - "integrity": "sha512-Eg+5FHtyzv3Jjw9dHwu2pWy4xjf8fu3V0Asyy42kO+t/FbvW/vjUixpTjPtgKQLQh+2/9Nk4JjFDV6FwCnF2ZA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-4.7.0.tgz", + "integrity": "sha512-cx+MxxsAMGl9AiWnQUzrkJMJH4eNOGlu7XkLGnAXSJrRoIiciGaKqzeaD326IyCTV+Z1fXvIliSgNW+DscvD8g==", + "license": "MIT", "peerDependencies": { "expo": "*" } }, "node_modules/expo-image-picker": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-16.0.2.tgz", - "integrity": "sha512-wlJy2EjZQlbz6v3QAOfpHWhq8GXXER5z7TeSTo5rMdQ/gn9B4YDGxY4nQqI+LRFBuIxpEnOXizUGDUJsoDwo6A==", + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-15.0.7.tgz", + "integrity": "sha512-u8qiPZNfDb+ap6PJ8pq2iTO7JKX+ikAUQ0K0c7gXGliKLxoXgDdDmXxz9/6QdICTshJBJlBvI0MwY5NWu7A/uw==", + "license": "MIT", "dependencies": { - "expo-image-loader": "~5.0.0" + "expo-image-loader": "~4.7.0" }, "peerDependencies": { "expo": "*" } }, + "node_modules/expo-json-utils": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/expo-json-utils/-/expo-json-utils-0.13.1.tgz", + "integrity": "sha512-mlfaSArGVb+oJmUcR22jEONlgPp0wj4iNIHfQ2je9Q8WTOqMc0Ws9tUciz3JdJnhffdHqo/k8fpvf0IRmN5HPA==", + "license": "MIT" + }, "node_modules/expo-keep-awake": { "version": "13.0.2", "license": "MIT", @@ -12218,6 +12297,19 @@ "invariant": "^2.2.4" } }, + "node_modules/expo-manifests": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-0.14.3.tgz", + "integrity": "sha512-L3b5/qocBPiQjbW0cpOHfnqdKZbTJS7sA3mgeDJT+mWga/xYsdpma1EfNmsuvrOzjLGjStr1k1fceM9Bl49aqQ==", + "license": "MIT", + "dependencies": { + "@expo/config": "~9.0.0", + "expo-json-utils": "~0.13.0" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-modules-autolinking": { "version": "1.11.2", "license": "MIT", @@ -12363,6 +12455,15 @@ "expo": "*" } }, + "node_modules/expo-updates-interface": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/expo-updates-interface/-/expo-updates-interface-0.16.2.tgz", + "integrity": "sha512-929XBU70q5ELxkKADj1xL0UIm3HvhYhNAOZv5DSk7rrKvLo7QDdPyl+JVnwZm9LrkNbH4wuE2rLoKu1KMgZ+9A==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-web-browser": { "version": "13.0.3", "license": "MIT", diff --git a/mobile-app/package.json b/mobile-app/package.json index 3ed986a..09c96a8 100644 --- a/mobile-app/package.json +++ b/mobile-app/package.json @@ -6,8 +6,8 @@ "prestart": "cp ../.env.example .env", "start": "expo start", "reset-project": "node ./scripts/reset-project.js", - "android": "expo start --android", - "ios": "expo start --ios", + "android": "expo run:android", + "ios": "expo run:ios", "web": "expo start --web", "test": "vitest .", "lint": "expo lint", @@ -36,7 +36,7 @@ "expo-clipboard": "^6.0.3", "expo-constants": "~16.0.2", "expo-font": "~12.0.9", - "expo-image-picker": "^16.0.2", + "expo-image-picker": "~15.0.7", "expo-linking": "~6.3.1", "expo-router": "~3.5.23", "expo-splash-screen": "~0.27.5", @@ -65,7 +65,8 @@ "react-native-vector-icons": "^10.2.0", "react-native-web": "~0.19.10", "text-encoding": "^0.7.0", - "zustand": "^5.0.1" + "zustand": "^5.0.1", + "expo-dev-client": "~4.0.29" }, "devDependencies": { "@babel/core": "^7.20.0",