adding frontend to cicd
Some checks failed
Build and Deploy Backend / Run Linters and Tests (Backend) (push) Successful in 19s
Build and Deploy Backend / Build (Backend) (push) Has been cancelled
Build and Deploy Backend / Build Native Android App (EAS) (push) Has been cancelled
Build and Deploy Backend / Deploy to Host (push) Has been cancelled
Build and Deploy Backend / Build (Frontend Web) (push) Has been cancelled
@@ -7,8 +7,9 @@ on:
|
||||
# Triggers the workflow on push events but only for the main branch
|
||||
push:
|
||||
branches: [ main ]
|
||||
paths: # Only run if backend code or Docker config changes
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- 'interfaces/nativeapp/**'
|
||||
- '.gitea/workflows/deploy.yml'
|
||||
- 'backend/docker-compose.deploy.yml'
|
||||
|
||||
@@ -22,10 +23,10 @@ on:
|
||||
|
||||
jobs:
|
||||
# ========================================================================
|
||||
# Job to run unit tests.
|
||||
# Job to run backend unit tests.
|
||||
# ========================================================================
|
||||
test:
|
||||
name: Run Linters and Tests
|
||||
test-backend:
|
||||
name: Run Linters and Tests (Backend)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Checks out the repo under $GITHUB_WORKSPACE
|
||||
@@ -70,12 +71,12 @@ jobs:
|
||||
pytest
|
||||
|
||||
# ========================================================================
|
||||
# Job to build and deploy the Docker image to mara.
|
||||
# Job to build the backend Docker image.
|
||||
# ========================================================================
|
||||
build-and-deploy:
|
||||
name: Build and Deploy
|
||||
build-backend:
|
||||
name: Build (Backend)
|
||||
runs-on: ubuntu-latest
|
||||
needs: test # Ensure tests pass before deploying
|
||||
needs: test-backend # Ensure tests pass before deploying
|
||||
|
||||
# Only run this job if triggered by a push to main or manual dispatch/schedule
|
||||
if: gitea.event_name == 'push' || gitea.event_name == 'workflow_dispatch' || gitea.event_name == 'schedule'
|
||||
@@ -116,9 +117,102 @@ jobs:
|
||||
# Pull latest base image updates when building (good for scheduled runs)
|
||||
pull: true
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Deploy to mara
|
||||
# ------------------------------------------------------------------
|
||||
# ========================================================================
|
||||
# Job to build the frontend Nginx image.
|
||||
# ========================================================================
|
||||
build-frontend-web:
|
||||
name: Build (Frontend Web)
|
||||
runs-on: ubuntu-latest
|
||||
# needs: test-frontend
|
||||
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: interfaces/nativeapp/package-lock.json
|
||||
|
||||
- name: Install frontend dependencies
|
||||
working-directory: ./interfaces/nativeapp
|
||||
run: npm ci
|
||||
|
||||
- name: Build Expo web assets
|
||||
working-directory: ./interfaces/nativeapp
|
||||
run: npx expo export --platform web --output-dir dist
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build and push frontend nginx image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
# Context is the frontend dir where Dockerfile.nginx, nginx.conf and dist/ are
|
||||
context: ./interfaces/nativeapp
|
||||
file: ./interfaces/nativeapp/Dockerfile.nginx # Path to the Nginx Dockerfile
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia-frontend:${{ gitea.sha }}
|
||||
ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia-frontend:latest
|
||||
pull: true # Pull base nginx image updates
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# Build Native Android App (Trigger EAS Build)
|
||||
# ========================================================================
|
||||
build-native-android:
|
||||
name: Build Native Android App (EAS)
|
||||
runs-on: ubuntu-latest
|
||||
# needs: test-frontend # Depends on frontend tests passing
|
||||
# Only run for deploy triggers
|
||||
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: interfaces/nativeapp/package-lock.json
|
||||
- name: Install frontend dependencies
|
||||
working-directory: ./interfaces/nativeapp
|
||||
run: npm ci
|
||||
- name: Install EAS CLI
|
||||
run: npm install -g eas-cli
|
||||
- name: Log in to Expo account
|
||||
env:
|
||||
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
|
||||
run: eas login --token $EXPO_TOKEN
|
||||
- name: Trigger EAS Build for Android
|
||||
working-directory: ./interfaces/nativeapp
|
||||
run: |
|
||||
eas build --platform android --profile production --non-interactive --no-wait
|
||||
|
||||
# ========================================================================
|
||||
# Deploy Backend and Frontend Web to Host
|
||||
# ========================================================================
|
||||
deploy:
|
||||
name: Deploy to Host
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build-backend # Wait for backend image build
|
||||
- build-frontend-web # Wait for frontend image build
|
||||
if: gitea.event_name == 'push' || gitea.event_name == 'workflow_dispatch' || gitea.event_name == 'schedule'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Deploy Locally
|
||||
env:
|
||||
DB_HOST: ${{ vars.DB_HOST }}
|
||||
@@ -132,55 +226,50 @@ jobs:
|
||||
run: |
|
||||
#!/bin/bash -ex
|
||||
|
||||
# Define path to compose file WITHIN the checked-out workspace
|
||||
COMPOSE_FILE="${{ gitea.workspace }}/backend/docker-compose.deploy.yml"
|
||||
PROJECT_NAME="maia"
|
||||
# Define paths and names
|
||||
WORKSPACE_DIR="${{ gitea.workspace }}/backend" # Dir where deploy compose file lives
|
||||
COMPOSE_FILE="${WORKSPACE_DIR}/docker-compose.deploy.yml"
|
||||
PROJECT_NAME="maia" # Project name used by docker compose
|
||||
BACKEND_IMAGE_TAG="${GITEA_SHA}"
|
||||
FRONTEND_IMAGE_TAG="${GITEA_SHA}" # same tag for simplicity
|
||||
|
||||
echo "--- Start Deploy Locally (using compose file from repo) ---"
|
||||
echo "Workspace root: ${{ gitea.workspace }}"
|
||||
echo "--- Start Deployment ---"
|
||||
echo "Using compose file: ${COMPOSE_FILE}"
|
||||
|
||||
# --- START Verify Environment Variables ---
|
||||
echo "Verifying environment variables available to the script:"
|
||||
echo "DB_HOST: ${DB_HOST}"
|
||||
echo "DB_USER: ${DB_USER}"
|
||||
echo "DB_NAME: ${DB_NAME}"
|
||||
echo "DB_PASSWORD length: ${#DB_PASSWORD}" # Check length, not value
|
||||
echo "REDIS_URL: ${REDIS_URL}"
|
||||
echo "PEPPER length: ${#PEPPER}"
|
||||
echo "JWT_SECRET_KEY length: ${#JWT_SECRET_KEY}"
|
||||
echo "GOOGLE_API_KEY length: ${#GOOGLE_API_KEY}"
|
||||
# --- END Verify Environment Variables ---
|
||||
|
||||
# Verify compose file exists
|
||||
# --- Verify compose file exists ---
|
||||
if [ ! -f "${COMPOSE_FILE}" ]; then
|
||||
echo "ERROR: Compose file not found at ${COMPOSE_FILE}"
|
||||
ls -la "${{ gitea.workspace }}/backend/" # List contents for debugging
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Pull the specific image version built in this workflow
|
||||
echo "Pulling image ${{ gitea.sha }}..."
|
||||
docker pull ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia:${{ gitea.sha }}
|
||||
echo "Pull complete."
|
||||
# --- Pull specific backend image version ---
|
||||
echo "Pulling backend image ${BACKEND_IMAGE_TAG}..."
|
||||
docker pull ghcr.io/${DOCKER_REGISTRY_USERNAME}/maia:${BACKEND_IMAGE_TAG}
|
||||
echo "Backend pull complete."
|
||||
|
||||
# Pull other images defined in compose using the specific file
|
||||
# Ensures base images like redis/db are up-to-date if specified in compose
|
||||
echo "Pulling other compose services..."
|
||||
docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE}" pull redis db
|
||||
# --- Pull specific frontend image version ---
|
||||
echo "Pulling frontend image ${FRONTEND_IMAGE_TAG}..."
|
||||
docker pull ghcr.io/${DOCKER_REGISTRY_USERNAME}/maia-frontend:${FRONTEND_IMAGE_TAG}
|
||||
echo "Frontend pull complete."
|
||||
|
||||
# --- Pull other images defined in compose ---
|
||||
echo "Pulling other compose services for project ${PROJECT_NAME}..."
|
||||
cd "${WORKSPACE_DIR}" || exit 1
|
||||
docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE##*/}" pull redis db
|
||||
echo "Other service pull complete."
|
||||
|
||||
# Update the image tag IN THE CHECKED-OUT COMPOSE FILE
|
||||
# This change only exists within the job's workspace, it doesn't modify the repo source
|
||||
echo "Running sed on ${COMPOSE_FILE}..."
|
||||
sed -i 's|image: ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia:.*|image: ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia:${{ gitea.sha }}|g' "${COMPOSE_FILE}"
|
||||
echo "sed complete. Showing updated line:"
|
||||
grep "image: ghcr.io/${{ secrets.DOCKER_REGISTRY_USERNAME }}/maia" "${COMPOSE_FILE}" || echo "Image line not found after sed!"
|
||||
# --- Update Backend image tag in compose file ---
|
||||
echo "Updating Backend image tag in ${COMPOSE_FILE##*/}..."
|
||||
sed -i "s|image: ghcr.io/${DOCKER_REGISTRY_USERNAME}/maia:.*|image: ghcr.io/${DOCKER_REGISTRY_USERNAME}/maia:${BACKEND_IMAGE_TAG}|g" "${COMPOSE_FILE##*/}"
|
||||
grep "image: ghcr.io/${DOCKER_REGISTRY_USERNAME}/maia:" "${COMPOSE_FILE##*/}" || echo "Backend image line not found!"
|
||||
|
||||
# Restart the services using the updated compose file from the workspace
|
||||
# Docker compose interacts with the HOST daemon via the mounted socket
|
||||
echo "Bringing compose stack down and up with new image..."
|
||||
docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE}" up -d --force-recreate --remove-orphans
|
||||
# --- Update Frontend image tag in compose file ---
|
||||
echo "Updating Frontend image tag in ${COMPOSE_FILE##*/}..."
|
||||
sed -i "s|image: ghcr.io/${DOCKER_REGISTRY_USERNAME}/maia-frontend:.*|image: ghcr.io/${DOCKER_REGISTRY_USERNAME}/maia-frontend:${FRONTEND_IMAGE_TAG}|g" "${COMPOSE_FILE##*/}"
|
||||
grep "image: ghcr.io/${DOCKER_REGISTRY_USERNAME}/maia-frontend:" "${COMPOSE_FILE##*/}" || echo "Frontend image line not found!"
|
||||
|
||||
# --- Restart services using updated compose file ---
|
||||
echo "Bringing compose stack down and up for project ${PROJECT_NAME}..."
|
||||
docker compose -p "${PROJECT_NAME}" -f "${COMPOSE_FILE##*/}" up -d --force-recreate --remove-orphans
|
||||
echo "Docker compose up command finished."
|
||||
echo "--- Local deployment complete! ---"
|
||||
|
||||
echo "--- Deployment complete! ---"
|
||||
1
.gitignore
vendored
@@ -8,7 +8,6 @@ backend/redis_data
|
||||
# frontend
|
||||
interfaces/nativeapp/node_modules
|
||||
interfaces/nativeapp/.expo/
|
||||
interfaces/nativeapp/dist/
|
||||
interfaces/nativeapp/web-build/
|
||||
interfaces/nativeapp/expo-env.d.ts
|
||||
interfaces/nativeapp/*.orig.*
|
||||
|
||||
@@ -77,12 +77,9 @@ services:
|
||||
|
||||
# ----- Frontend (nginx) ------
|
||||
frontend:
|
||||
image: nginx:1.25-alpine
|
||||
image: ghcr.io/c-d-p/maia-frontend:latest
|
||||
container_name: MAIA_FRONTEND
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /srv/docker/container/MAIA/frontend/dist:/usr/share/nginx/html:ro # read only
|
||||
- /srv/docker/container/MAIA/frontend/conf/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
networks:
|
||||
- default
|
||||
expose:
|
||||
|
||||
16
interfaces/nativeapp/Dockerfile.nginx
Normal file
@@ -0,0 +1,16 @@
|
||||
# ./frontend/Dockerfile.nginx
|
||||
|
||||
FROM nginx:1.28-alpine
|
||||
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Remove default Nginx welcome page
|
||||
RUN rm /usr/share/nginx/html/*
|
||||
|
||||
# Copy the pre-built Expo web output
|
||||
COPY dist/ /usr/share/nginx/html
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
# Start Nginx in the foreground
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
1331
interfaces/nativeapp/dist/_expo/static/js/web/index-0ef639b7ebb0f592fe73fd94db0b4205.js
vendored
Normal file
|
After Width: | Height: | Size: 653 B |
BIN
interfaces/nativeapp/dist/assets/node_modules/@react-navigation/elements/lib/module/assets/back-icon.35ba0eaec5a4f5ed12ca16fabeae451d.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 207 B |
BIN
interfaces/nativeapp/dist/assets/node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 220 B |
|
After Width: | Height: | Size: 334 B |
|
After Width: | Height: | Size: 502 B |
|
After Width: | Height: | Size: 645 B |
BIN
interfaces/nativeapp/dist/assets/node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 141 B |
|
After Width: | Height: | Size: 201 B |
|
After Width: | Height: | Size: 266 B |
|
After Width: | Height: | Size: 332 B |
BIN
interfaces/nativeapp/dist/assets/node_modules/@react-navigation/elements/lib/module/assets/search-icon.286d67d3f74808a60a78d3ebf1a5fb57.png
generated
vendored
Normal file
|
After Width: | Height: | Size: 928 B |
BIN
interfaces/nativeapp/dist/assets/src/assets/MAIA_ICON.55dab8d84a31f13e7cdf223a69c97d91.png
vendored
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
interfaces/nativeapp/dist/assets/src/assets/fonts/Inter-Bold.8b04b3bd9435341377d7f4b4d68b6ecc.ttf
vendored
Normal file
BIN
interfaces/nativeapp/dist/assets/src/assets/fonts/Inter-Light.65ec965bd90e1a297cdb3be407420abc.ttf
vendored
Normal file
BIN
interfaces/nativeapp/dist/assets/src/assets/fonts/Inter-Medium.4591e900425d177e6ba268d165bf12e8.ttf
vendored
Normal file
BIN
interfaces/nativeapp/dist/assets/src/assets/fonts/Inter-Regular.e48c1217adab2a0e44f8df400d33c325.ttf
vendored
Normal file
BIN
interfaces/nativeapp/dist/assets/src/assets/fonts/Inter-Thin.1e9e30c74648950a240427636b6c1992.ttf
vendored
Normal file
BIN
interfaces/nativeapp/dist/favicon.ico
vendored
Normal file
|
After Width: | Height: | Size: 14 KiB |
37
interfaces/nativeapp/dist/index.html
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
<title>MAIA</title>
|
||||
<!-- The `react-native-web` recommended style reset: https://necolas.github.io/react-native-web/docs/setup/#root-element -->
|
||||
<style id="expo-reset">
|
||||
/* These styles make the body full-height */
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
/* These styles disable body scrolling if you are using <ScrollView> */
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
/* These styles make the root element full-height */
|
||||
#root {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
<link rel="shortcut icon" href="/favicon.ico" /></head>
|
||||
|
||||
<body>
|
||||
<!-- Use static rendering with Expo Router to support running without JavaScript. -->
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<!-- The root element for your Expo app. -->
|
||||
<div id="root"></div>
|
||||
<script src="/_expo/static/js/web/index-0ef639b7ebb0f592fe73fd94db0b4205.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
1
interfaces/nativeapp/dist/metadata.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":0,"bundler":"metro","fileMetadata":{}}
|
||||
36
interfaces/nativeapp/nginx.conf
Normal file
@@ -0,0 +1,36 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name app.maia.depaoli.id.au;
|
||||
|
||||
# Set the root directory for static files
|
||||
root /usr/share/nginx/html;
|
||||
# Default file to serve
|
||||
index index.html index.htm;
|
||||
|
||||
location / {
|
||||
# Crucial for SPAs:
|
||||
# - Try to serve the requested file ($uri)
|
||||
# - If it's not found, try it as a directory ($uri/)
|
||||
# - If that's not found, serve index.html (letting client-side routing handle it)
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Add gzip compression for better performance
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss text/javascript image/svg+xml;
|
||||
|
||||
# Improve caching for assets
|
||||
location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public";
|
||||
access_log off; # Don't log access for static assets
|
||||
}
|
||||
|
||||
# Deny access to hidden files
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||