feat: run.sh restart/stop/status + real DB connector + GitLab CI
1. run.sh: start/stop/restart/status/logs/build/test - PID file management in .pids/ - Colored output, health check wait, log files - Auto alembic migrate on start 2. DB Connector (replaces mock aiomysql): - MySQL: aiomysql (connect/query/dml/test) - PostgreSQL: asyncpg (connect/query/dml/test) - SQLite: sqlite3 via executor (connect/query/dml/test) - Unified interface: DBConnector.test_connection/execute_query/execute_dml - Connection test returns version + latency 3. GitLab CI/CD pipeline: - test: backend pytest + frontend build - build: Docker images (manual trigger) - deploy: SSH deploy (manual trigger) - Cache: pip + node_modules Tests: 128 passing, frontend build: OK
This commit is contained in:
1 parent
64e0c37972
commit
2cfd45c9d1
10 files changed
+712
-126
No files matched your search
@@ -0,0 +1,97 @@
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
||||
|
||||
# Cache
|
||||
cache:
|
||||
key: "${CI_COMMIT_REF_SLUG}"
|
||||
paths:
|
||||
- backend/venv/
|
||||
- frontend/node_modules/
|
||||
- .cache/pip/
|
||||
|
||||
# ===== Test Stage =====
|
||||
|
||||
backend-test:
|
||||
stage: test
|
||||
image: python:3.11-slim
|
||||
before_script:
|
||||
- cd backend
|
||||
- python -m venv venv
|
||||
- source venv/bin/activate
|
||||
- pip install -r requirements.txt -q
|
||||
script:
|
||||
- source venv/bin/activate
|
||||
- python -m pytest tests/ -v --tb=short --junitxml=report.xml
|
||||
artifacts:
|
||||
reports:
|
||||
junit: backend/report.xml
|
||||
when: always
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
- if: '$CI_COMMIT_BRANCH == "master"'
|
||||
|
||||
frontend-build:
|
||||
stage: test
|
||||
image: node:20-alpine
|
||||
before_script:
|
||||
- cd frontend
|
||||
- npm ci
|
||||
script:
|
||||
- npm run build
|
||||
artifacts:
|
||||
paths:
|
||||
- frontend/dist/
|
||||
expire_in: 1 day
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
- if: '$CI_COMMIT_BRANCH == "master"'
|
||||
|
||||
# ===== Build Stage =====
|
||||
|
||||
docker-build:
|
||||
stage: build
|
||||
image: docker:24
|
||||
services:
|
||||
- docker:24-dind
|
||||
variables:
|
||||
DOCKER_TLS_CERTDIR: "/certs"
|
||||
before_script:
|
||||
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" 2>/dev/null || true
|
||||
script:
|
||||
- docker build -t $CI_REGISTRY_IMAGE/backend:$CI_COMMIT_SHORT_SHA ./backend
|
||||
- docker build -t $CI_REGISTRY_IMAGE/frontend:$CI_COMMIT_SHORT_SHA ./frontend
|
||||
- docker push $CI_REGISTRY_IMAGE/backend:$CI_COMMIT_SHORT_SHA 2>/dev/null || true
|
||||
- docker push $CI_REGISTRY_IMAGE/frontend:$CI_COMMIT_SHORT_SHA 2>/dev/null || true
|
||||
- echo "Build complete: $CI_COMMIT_SHORT_SHA"
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "master"'
|
||||
when: manual
|
||||
tags:
|
||||
- docker
|
||||
|
||||
# ===== Deploy Stage =====
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
image: alpine:3.19
|
||||
before_script:
|
||||
- apk add --no-cache openssh-client
|
||||
- eval $(ssh-agent -s)
|
||||
- echo "$DEPLOY_SSH_KEY" | tr -d '\r' | ssh-add -
|
||||
- mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
||||
- echo "$DEPLOY_SSH_HOST_KEY" > ~/.ssh/known_hosts 2>/dev/null || true
|
||||
script:
|
||||
- ssh $DEPLOY_USER@$DEPLOY_HOST "cd $DEPLOY_PATH && docker compose pull && docker compose up -d && echo 'Deploy done'"
|
||||
environment:
|
||||
name: production
|
||||
url: http://$DEPLOY_HOST
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "master"'
|
||||
when: manual
|
||||
tags:
|
||||
- deploy
|
||||
Reference in new issue
Block a user