[INIT-001] Initial project setup with Clean Architecture (feat)
Some checks failed
CD - Build & Deploy / build-and-push (push) Has been cancelled
CD - Build & Deploy / package-helm (push) Has been cancelled
CD - Build & Deploy / deploy-staging (push) Has been cancelled
CD - Build & Deploy / deploy-production (push) Has been cancelled
CD - Build & Deploy / release (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / security (push) Has been cancelled

- Implemented Clean Architecture with Domain, Application, Infrastructure, Presentation layers
- Added comprehensive project structure following SOLID principles
- Created Kubernetes deployment with Helm charts (HPA, PDB, NetworkPolicy)
- Configured ArgoCD for automated deployment (production + staging)
- Implemented CI/CD pipeline with GitHub Actions
- Added comprehensive documentation (handbook, architecture, coding standards)
- Configured PostgreSQL, Redis, Celery for backend services
- Created modern landing page with Persian fonts (Vazirmatn)
- Added Docker multi-stage build for production
- Configured development tools (pytest, black, flake8, mypy, isort)
- Added pre-commit hooks for code quality
- Implemented Makefile for common operations
This commit is contained in:
Ehsan.Asadi
2025-12-26 15:52:50 +03:30
commit 8a924f6091
135 changed files with 8637 additions and 0 deletions

193
.github/workflows/cd.yml vendored Normal file
View File

@@ -0,0 +1,193 @@
name: CD - Build & Deploy
on:
push:
branches: [ main ]
tags:
- 'v*'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
image-version: ${{ steps.meta.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
platforms: linux/amd64
- name: Image digest
run: echo "Image pushed with digest ${{ steps.build.outputs.digest }}"
package-helm:
runs-on: ubuntu-latest
needs: build-and-push
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install Helm
uses: azure/setup-helm@v3
with:
version: 'latest'
- name: Package Helm chart
run: |
helm package helm/peikarband --destination .
helm repo index . --url https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}
- name: Upload Helm chart artifact
uses: actions/upload-artifact@v3
with:
name: helm-chart
path: |
*.tgz
index.yaml
deploy-staging:
runs-on: ubuntu-latest
needs: [build-and-push, package-helm]
if: github.ref == 'refs/heads/main'
environment:
name: staging
url: https://staging.peikarband.ir
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install kubectl
uses: azure/setup-kubectl@v3
- name: Install Helm
uses: azure/setup-helm@v3
- name: Configure kubectl
run: |
echo "${{ secrets.KUBECONFIG_STAGING }}" | base64 -d > kubeconfig
export KUBECONFIG=kubeconfig
- name: Deploy to Staging
run: |
export KUBECONFIG=kubeconfig
helm upgrade --install peikarband-staging ./helm/peikarband \
--namespace staging \
--create-namespace \
--set image.tag=${{ needs.build-and-push.outputs.image-version }} \
--set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \
--set ingress.hosts[0].host=staging.peikarband.ir \
--wait \
--timeout 5m
deploy-production:
runs-on: ubuntu-latest
needs: [build-and-push, package-helm]
if: startsWith(github.ref, 'refs/tags/v')
environment:
name: production
url: https://peikarband.ir
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install kubectl
uses: azure/setup-kubectl@v3
- name: Install Helm
uses: azure/setup-helm@v3
- name: Configure kubectl
run: |
echo "${{ secrets.KUBECONFIG_PRODUCTION }}" | base64 -d > kubeconfig
export KUBECONFIG=kubeconfig
- name: Deploy to Production
run: |
export KUBECONFIG=kubeconfig
helm upgrade --install peikarband-prod ./helm/peikarband \
--namespace production \
--create-namespace \
--set image.tag=${{ needs.build-and-push.outputs.image-version }} \
--set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \
--set replicaCount=3 \
--set autoscaling.enabled=true \
--values helm/peikarband/values-production.yaml \
--wait \
--timeout 10m
- name: Verify deployment
run: |
export KUBECONFIG=kubeconfig
kubectl rollout status deployment/peikarband-prod -n production
kubectl get pods -n production
release:
runs-on: ubuntu-latest
needs: [build-and-push, package-helm, deploy-production]
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Download Helm chart
uses: actions/download-artifact@v3
with:
name: helm-chart
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: |
*.tgz
index.yaml
generate_release_notes: true
draft: false
prerelease: false

121
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,121 @@
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.11', '3.12']
services:
postgres:
image: postgres:14
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: peikarband_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip packages
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Lint with flake8
run: |
flake8 src/ --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 src/ --count --max-complexity=10 --max-line-length=120 --statistics
- name: Type check with mypy
run: |
mypy src/
- name: Check formatting with black
run: |
black --check src/
- name: Check imports with isort
run: |
isort --check-only src/
- name: Run tests with pytest
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/peikarband_test
REDIS_URL: redis://localhost:6379/0
SECRET_KEY: test-secret-key
JWT_SECRET_KEY: test-jwt-secret
CELERY_BROKER_URL: redis://localhost:6379/1
CELERY_RESULT_BACKEND: redis://localhost:6379/2
run: |
pytest tests/ -v --cov=src --cov-report=xml --cov-report=term-missing
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
fail_ci_if_error: false
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install bandit safety
- name: Run Bandit security scan
run: |
bandit -r src/ -f json -o bandit-report.json || true
- name: Run Safety check
run: |
safety check --json || true