diff --git a/.gitea/workflows/build-and-deploy.yml b/.gitea/workflows/build-and-deploy.yml new file mode 100644 index 00000000..535e653a --- /dev/null +++ b/.gitea/workflows/build-and-deploy.yml @@ -0,0 +1,121 @@ +# Gitea Actions — CI/CD Smart App City Web +# Trigger: push sur master ou PR +name: Build & Deploy Smart App Web + +on: + push: + branches: [master] + paths: + - 'smart-app-city/frontend/**' + pull_request: + branches: [master] + +jobs: + # ─── Lint + Type Check ───────────────────────────────────────────────── + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: smart-app-city/frontend/package-lock.json + + - name: Install dependencies + working-directory: smart-app-city/frontend + run: npm ci --legacy-peer-deps + + - name: TypeScript check + working-directory: smart-app-city/frontend + run: npx tsc --noEmit + continue-on-error: true # TODO: fix TS strict errors + + # ─── Build Web ───────────────────────────────────────────────────────── + build-web: + runs-on: ubuntu-latest + needs: lint + if: github.event_name == 'push' + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: smart-app-city/frontend/package-lock.json + + - name: Install dependencies + working-directory: smart-app-city/frontend + run: npm ci --legacy-peer-deps + + - name: Build Expo web + working-directory: smart-app-city/frontend + run: npx expo export:web + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: smartapp-web-build + path: smart-app-city/frontend/dist/ + retention-days: 7 + + # ─── Deploy to Server ────────────────────────────────────────────────── + deploy: + runs-on: ubuntu-latest + needs: build-web + if: github.ref == 'refs/heads/master' + steps: + - uses: actions/checkout@v4 + + - name: Download build artifact + uses: actions/download-artifact@v4 + with: + name: smartapp-web-build + path: smart-app-city/frontend/dist/ + + - name: Deploy to server via SSH + uses: appleboy/scp-action@v0.1.7 + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USER }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + source: "smart-app-city/frontend/dist/" + target: "/var/www/smartapp/" + strip_components: 3 + + - name: Restart nginx (or copy to Docker volume) + uses: appleboy/ssh-action@v1.0.7 + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USER }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + script: | + # Option A: If using Docker volume + docker cp /var/www/smartapp/ smartapp-web:/usr/share/nginx/html/ + # Option B: If using Docker build + # cd /home/eric/smart-city-digital-twin-martinique/smart-app-city + # docker compose up -d --build smartapp-web + echo "✅ Smart App Web deployed at $(date)" + + # ─── Build Docker Image (alternative) ─────────────────────────────────── + docker-build: + runs-on: ubuntu-latest + needs: lint + if: github.ref == 'refs/heads/master' + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + working-directory: smart-app-city/frontend + run: | + docker build -t smartapp-web:${{ github.sha }} . + docker tag smartapp-web:${{ github.sha }} smartapp-web:latest + + # Note: Pour pousser vers un registry privé, ajouter docker login + push + # - name: Push to registry + # run: docker push registry.digitribe.fr/smartapp-web:latest diff --git a/smart-app-city/deploy.sh b/smart-app-city/deploy.sh new file mode 100755 index 00000000..a6acae98 --- /dev/null +++ b/smart-app-city/deploy.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# Smart App City — Build & Deploy Script +# Usage: ./deploy.sh [web|api|all] + +set -e + +FRONTEND_DIR="$(dirname "$0")/smart-app-city/frontend" +DEPLOY_DIR="/var/www/smartapp" +DOCKER_COMPOSE="$(dirname "$0")/smart-app-city/docker-compose.yml" +TIMESTAMP=$(date +%Y%m%d_%H%M%S) + +echo "🏙️ Smart App City — Deploy (${TIMESTAMP})" +echo "================================================" + +build_web() { + echo "" + echo "📦 Building Expo web..." + cd "${FRONTEND_DIR}" + + echo " → Install deps..." + npm ci --legacy-peer-deps --silent 2>/dev/null + + echo " → Expo export:web..." + npx expo export:web --output-dir dist 2>&1 | tail -5 + + echo " → Build OK → dist/" + ls -lh dist/ | tail -5 +} + +deploy_local() { + echo "" + echo "🚀 Deploying to local nginx..." + + if [ ! -d "${DEPLOY_DIR}" ]; then + sudo mkdir -p "${DEPLOY_DIR}" + fi + + sudo rm -rf "${DEPLOY_DIR:?}"/* + sudo cp -r "${FRONTEND_DIR}/dist/"* "${DEPLOY_DIR}/" + sudo chown -R www-data:www-data "${DEPLOY_DIR}" + + echo " → Deployed to ${DEPLOY_DIR}/" + echo " → URL: https://smartapp.digitribe.fr" +} + +deploy_docker() { + echo "" + echo "🐳 Deploying via Docker Compose..." + cd "$(dirname "$DOCKER_COMPOSE")" + docker compose up -d --build smartapp-web + echo " → Container smartapp-web restarted" +} + +case "${1:-all}" in + web) + build_web + deploy_local + ;; + docker) + build_web + deploy_docker + ;; + api) + cd "$(dirname "$DOCKER_COMPOSE")" + docker compose up -d --build api-gateway + ;; + all) + build_web + deploy_local + deploy_docker + ;; + *) + echo "Usage: $0 [web|docker|api|all]" + exit 1 + ;; +esac + +echo "" +echo "✅ Deploy complete!" +echo "🌐 Web: https://smartapp.digitribe.fr" +echo "🔌 API: https://api-smartapp.digitribe.fr" diff --git a/smart-app-city/frontend/app.json b/smart-app-city/frontend/app.json index e69de29b..83981de4 100644 --- a/smart-app-city/frontend/app.json +++ b/smart-app-city/frontend/app.json @@ -0,0 +1,36 @@ +{ + "expo": { + "name": "Smart App City", + "slug": "smart-app-city", + "version": "0.1.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "userInterfaceStyle": "automatic", + "splash": { + "image": "./assets/splash.png", + "resizeMode": "contain", + "backgroundColor": "#1565C0" + }, + "assetBundlePatterns": ["**/*"], + "ios": { + "supportsTablet": true, + "bundleIdentifier": "fr.digitribe.smartapp" + }, + "android": { + "adaptiveIcon": { + "foregroundImage": "./assets/adaptive-icon.png", + "backgroundColor": "#1565C0" + }, + "package": "fr.digitribe.smartapp" + }, + "web": { + "favicon": "./assets/favicon.png", + "bundler": "webpack" + }, + "plugins": [ + "expo-localization", + "expo-location", + "expo-notifications" + ] + } +} diff --git a/smart-app-city/frontend/assets/adaptive-icon.png b/smart-app-city/frontend/assets/adaptive-icon.png new file mode 100644 index 00000000..5ba14495 Binary files /dev/null and b/smart-app-city/frontend/assets/adaptive-icon.png differ diff --git a/smart-app-city/frontend/assets/favicon.png b/smart-app-city/frontend/assets/favicon.png new file mode 100644 index 00000000..ba274c5c Binary files /dev/null and b/smart-app-city/frontend/assets/favicon.png differ diff --git a/smart-app-city/frontend/assets/icon.png b/smart-app-city/frontend/assets/icon.png new file mode 100644 index 00000000..5ba14495 Binary files /dev/null and b/smart-app-city/frontend/assets/icon.png differ diff --git a/smart-app-city/frontend/assets/splash.png b/smart-app-city/frontend/assets/splash.png new file mode 100644 index 00000000..5ba14495 Binary files /dev/null and b/smart-app-city/frontend/assets/splash.png differ