diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..d1810b3
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,2 @@
+# Repo owner
+* @NikitaBuffy
\ No newline at end of file
diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml
new file mode 100644
index 0000000..422dc40
--- /dev/null
+++ b/.github/workflows/backend.yml
@@ -0,0 +1,56 @@
+name: Java CI
+
+on:
+ pull_request:
+ branches:
+ - backend
+ workflow_dispatch:
+
+jobs:
+ build-and-test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Set up JDK
+ uses: actions/setup-java@v4
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+
+ - name: Cache Maven dependencies
+ uses: actions/cache@v4
+ with:
+ path: ~/.m2
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+
+ - name: Build project
+ run: |
+ cd backend
+ mvn clean verify
+
+ - name: Upload backend build artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: backend-jar
+ path: /backend/target/*.jar
+
+ - name: Cache SonarQube packages
+ uses: actions/cache@v4
+ with:
+ path: ~/.sonar/cache
+ key: ${{ runner.os }}-sonar
+ restore-keys: ${{ runner.os }}-sonar
+
+ - name: Analyze with SonarQube
+ env:
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
+ SONAR_PROJECT_KEY: ${{ secrets.SONAR_PROJECT_KEY }}
+ run: |
+ cd backend
+ mvn org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=$SONAR_PROJECT_KEY -Dsonar.projectName='lenka-messenger' -Dsonar.pullrequest.key=${{ github.event.number}} -Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }} -Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }} -Dsonar.scm.revision=${{ github.event.pull_request.head.sha }}
\ No newline at end of file
diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
new file mode 100644
index 0000000..42f301b
--- /dev/null
+++ b/.github/workflows/frontend.yml
@@ -0,0 +1,66 @@
+name: Vue CI
+
+on:
+ pull_request:
+ branches:
+ - frontend
+ workflow_dispatch:
+
+jobs:
+ build-and-analyze:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '18'
+
+ - name: Cache Node.js dependencies
+ uses: actions/cache@v4
+ with:
+ path: ~/.npm
+ key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-node-
+
+ - name: Install dependencies
+ run: |
+ cd frontend
+ npm install
+
+ - name: Build frontend
+ run: |
+ cd frontend
+ npm run build
+
+ - name: Upload frontend build artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: frontend-dist
+ path: frontend/dist/
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+
+ - name: Cache SonarQube packages
+ uses: actions/cache@v4
+ with:
+ path: ~/.sonar/cache
+ key: ${{ runner.os }}-sonar
+ restore-keys: ${{ runner.os }}-sonar
+
+ - name: Analyze with SonarQube
+ env:
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
+ SONAR_PROJECT_KEY: ${{ secrets.SONAR_PROJECT_KEY }}
+ run: |
+ cd frontend
+ npx sonar-scanner -Dsonar.projectKey=$SONAR_PROJECT_KEY -Dsonar.projectName='lenka-messenger' -Dsonar.sources=src -Dsonar.pullrequest.key=${{ github.event.number}} -Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }} -Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }} -Dsonar.scm.revision=${{ github.event.pull_request.head.sha }} -Dsonar.host.url=$SONAR_HOST_URL
\ No newline at end of file
diff --git a/.github/workflows/main-restrict.yml b/.github/workflows/main-restrict.yml
new file mode 100644
index 0000000..0e5a9cd
--- /dev/null
+++ b/.github/workflows/main-restrict.yml
@@ -0,0 +1,23 @@
+name: Restrict PR to Main
+
+on:
+ pull_request:
+ branches:
+ - main
+
+jobs:
+ restrict-branches:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check source branch
+ run: |
+ echo "Checking source branch..."
+ ALLOWED_BRANCHES=("backend" "frontend" "devops")
+ SOURCE_BRANCH=$(echo "${{ github.event.pull_request.head.ref }}")
+
+ if [[ ! " ${ALLOWED_BRANCHES[@]} " =~ " ${SOURCE_BRANCH} " ]]; then
+ echo "Pull Request from branch '${SOURCE_BRANCH}' to 'main' is not allowed!"
+ exit 1
+ else
+ echo "Pull Request from '${SOURCE_BRANCH}' is allowed."
+ fi
\ No newline at end of file
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..32e367a
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,89 @@
+name: Main CD
+
+on:
+ pull_request:
+ types: [closed]
+ branches:
+ - main
+ workflow_dispatch:
+
+jobs:
+ cd-backend:
+ if: github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'backend'
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
+
+ - name: Log in to Docker Hub
+ uses: docker/login-action@v2
+ with:
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+
+ - name: Download Backend Artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: backend-jar
+ path: backend/target/
+
+ - name: Build and Push Backend Image
+ run: |
+ cd backend
+ docker build -t nickpominov/lm-backend:latest .
+ docker push nickpominov/lm-backend:latest
+
+ - name: Deploy Backend to Remote Server
+ uses: appleboy/ssh-action@v0.1.7
+ with:
+ host: ${{ secrets.SERVER_IP }}
+ username: ${{ secrets.SSH_USERNAME }}
+ password: ${{ secrets.SSH_PASSWORD }}
+ port: 22
+ script: |
+ cd /srv/lenka-messenger
+ docker-compose -f docker-compose.prod.yaml up -d --no-deps lm-backend
+
+ cd-frontend:
+ if: github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'frontend'
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
+
+ - name: Log in to Docker Hub
+ uses: docker/login-action@v2
+ with:
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+
+ - name: Download Frontend Artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: frontend-dist
+ path: frontend/dist/
+
+ - name: Build and Push Frontend Image
+ run: |
+ cd frontend
+ docker build -t nickpominov/lm-frontend:latest .
+ docker push nickpominov/lm-frontend:latest
+
+ - name: Deploy Frontend to Remote Server
+ uses: appleboy/ssh-action@v0.1.7
+ with:
+ host: ${{ secrets.SERVER_IP }}
+ username: ${{ secrets.SSH_USERNAME }}
+ password: ${{ secrets.SSH_PASSWORD }}
+ port: 22
+ script: |
+ cd /srv/lenka-messenger
+ docker-compose -f docker-compose.prod.yaml up -d --no-deps lm-frontend
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 8627e50..7f75622 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,6 @@
# Logs
/logs/
+
+# Environment
+.env
\ No newline at end of file
diff --git a/backend/Dockerfile b/backend/Dockerfile
new file mode 100644
index 0000000..f33ddb7
--- /dev/null
+++ b/backend/Dockerfile
@@ -0,0 +1,3 @@
+FROM amazoncorretto:21-alpine-jdk
+COPY target/*.jar lm-backend.jar
+ENTRYPOINT ["java", "-jar", "/lm-backend.jar"]
\ No newline at end of file
diff --git a/backend/pom.xml b/backend/pom.xml
index 79ef988..3b7b262 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -25,14 +25,14 @@
org.springframework.boot
spring-boot-starter-actuator
-
-
-
-
-
-
-
-
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
org.springframework.boot
spring-boot-starter-web
@@ -42,11 +42,11 @@
spring-boot-starter-websocket
-
-
-
-
-
+
+ org.postgresql
+ postgresql
+ runtime
+
org.projectlombok
lombok
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index 286afee..62c3ecf 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -1 +1,12 @@
+server.port=8080
spring.application.name=lenka-messenger
+
+spring.jpa.hibernate.ddl-auto=none
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+spring.jpa.properties.hibernate.format_sql=true
+spring.sql.init.mode=always
+
+spring.datasource.driverClassName=org.postgresql.Driver
+spring.datasource.url=${SPRING_DATASOURCE_URL}
+spring.datasource.username=${POSTGRES_USER}
+spring.datasource.password=${POSTGRES_PASSWORD}
\ No newline at end of file
diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml
new file mode 100644
index 0000000..8264936
--- /dev/null
+++ b/docker-compose.dev.yaml
@@ -0,0 +1,58 @@
+version: '3.9'
+
+services:
+ lm-backend:
+ build:
+ context: ./backend
+ container_name: lm-backend
+ ports:
+ - "8080:8080"
+ depends_on:
+ - postgres
+ environment:
+ - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/lenkamessenger
+ - POSTGRES_USER=postgres
+ - POSTGRES_PASSWORD=postgres
+ networks:
+ - app-network
+ restart: unless-stopped
+
+ lm-frontend:
+ build:
+ context: ./frontend
+ container_name: lm-frontend
+ ports:
+ - "3000:80"
+ networks:
+ - app-network
+ restart: unless-stopped
+
+ postgres:
+ image: postgres:14-alpine
+ container_name: postgres
+ ports:
+ - "6551:5432"
+ volumes:
+ - /var/lib/postgresql/data
+ environment:
+ - POSTGRES_DB=lenkamessenger
+ - POSTGRES_USER=postgres
+ - POSTGRES_PASSWORD=postgres
+ - TZ=GMT
+ networks:
+ - app-network
+
+ pgadmin:
+ image: dpage/pgadmin4
+ container_name: pgadmin
+ environment:
+ PGADMIN_DEFAULT_EMAIL: admin@admin.ru
+ PGADMIN_DEFAULT_PASSWORD: admin
+ ports:
+ - "5050:80"
+ networks:
+ - app-network
+
+networks:
+ app-network:
+ driver: bridge
\ No newline at end of file
diff --git a/docker-compose.prod.yaml b/docker-compose.prod.yaml
new file mode 100644
index 0000000..198fdd3
--- /dev/null
+++ b/docker-compose.prod.yaml
@@ -0,0 +1,56 @@
+version: '3.9'
+
+services:
+ lm-backend:
+ image: nickpominov/lm-backend:latest
+ container_name: lm-backend
+ ports:
+ - "8080:8080"
+ depends_on:
+ - postgres
+ environment:
+ - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/lenkamessenger
+ - POSTGRES_USER=${POSTGRES_USER}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+ networks:
+ - app-network
+ restart: unless-stopped
+
+ lm-frontend:
+ image: nickpominov/lm-frontend:latest
+ container_name: lm-frontend
+ ports:
+ - "3000:80"
+ networks:
+ - app-network
+ restart: unless-stopped
+
+ postgres:
+ image: postgres:14-alpine
+ container_name: postgres
+ ports:
+ - "6551:5432"
+ volumes:
+ - /srv/postgresql-data:/var/lib/postgresql/data
+ environment:
+ - POSTGRES_DB=lenkamessenger
+ - POSTGRES_USER=${POSTGRES_USER}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+ - TZ=GMT
+ networks:
+ - app-network
+
+ pgadmin:
+ image: dpage/pgadmin4
+ container_name: pgadmin
+ environment:
+ PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
+ PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
+ ports:
+ - "5050:80"
+ networks:
+ - app-network
+
+networks:
+ app-network:
+ driver: bridge
\ No newline at end of file
diff --git a/frontend/Dockerfile b/frontend/Dockerfile
new file mode 100644
index 0000000..39ba972
--- /dev/null
+++ b/frontend/Dockerfile
@@ -0,0 +1,3 @@
+FROM caddy:alpine
+COPY ./dist /usr/share/caddy
+EXPOSE 80
\ No newline at end of file
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 8f3e196..2427ae6 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -1,6 +1,6 @@
-
+