diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..e69de29 diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000..ed066ba --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,155 @@ +name: Deploy to Production + +on: + push: + branches: + - main + +env: + PROJECT_NAME: sifatbaho + + +permissions: + contents: write + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:15 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: testdb + ports: + - 5435:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + redis: + image: redis:7-alpine + ports: + - 6371:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Copy env + run: | + cp .env.example .env + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile.web + push: false + load: true + tags: ${{ env.PROJECT_NAME }}:test + no-cache: true + + - name: Run migrations and tests + run: | + docker run --rm \ + --network host \ + -e DB_HOST=localhost \ + -e DB_PORT=5435 \ + -e DB_NAME=testdb \ + -e DB_USER=postgres \ + -e REDIS_URL=redis://localhost:6371 \ + -e DB_PASSWORD=postgres \ + -e DJANGO_SETTINGS_MODULE=config.settings.test \ + ${{ env.PROJECT_NAME }}:test \ + sh -c "python manage.py migrate && pytest -v" + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Tag and push to Docker Hub + run: | + docker tag ${{ env.PROJECT_NAME }}:test ${{ secrets.DOCKER_USERNAME }}/${{ env.PROJECT_NAME }}:latest + docker tag ${{ env.PROJECT_NAME }}:test ${{ secrets.DOCKER_USERNAME }}/${{ env.PROJECT_NAME }}:${{ github.run_number }} + docker push ${{ secrets.DOCKER_USERNAME }}/${{ env.PROJECT_NAME }}:latest + docker push ${{ secrets.DOCKER_USERNAME }}/${{ env.PROJECT_NAME }}:${{ github.run_number }} + echo "SUCCESS TAGS: latest, ${{ github.run_number }}" + + - name: Update stack.yaml and version + run: | + sed -i 's|image: ${{ secrets.DOCKER_USERNAME }}/${{ env.PROJECT_NAME }}:.*|image: ${{ secrets.DOCKER_USERNAME }}/${{ env.PROJECT_NAME }}:${{ github.run_number }}|' stack.yaml + sed -i 's/return HttpResponse("OK.*"/return HttpResponse("OK: #${{ github.sha }}"/' config/urls.py + + - name: Commit and push updated version + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add . + git commit -m "🔄 Update image to ${{ github.run_number }} [CI SKIP]" || echo "No changes" + git pull origin main --rebase + git push origin main + + - name: Deploy to server via SSH + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + PROJECTS=/opt/projects/ + DIR=/opt/projects/${{ env.PROJECT_NAME }}/ + + if [ -d "$PROJECTS" ]; then + echo "projects papkasi mavjud" + else + mkdir -p $PROJECTS + echo "projects papkasi yaratildi" + fi + + if [ -d "$DIR" ]; then + echo "loyiha mavjud" + else + cd $PROJECTS + git clone git@gitea.felixits.uz:${{ github.repository }}.git ${{ env.PROJECT_NAME }} + echo "Clone qilindi"; + fi + + cd $DIR + git fetch origin main + git reset --hard origin/main + cp .env.example .env + + update_env() { + local env_file=".env" + cp .env.example "$env_file" + + for kv in "$@"; do + local key="${kv%%=*}" + local value="${kv#*=}" + sed -i "s|^$key=.*|$key=$value|" "$env_file" + done + } + + update_env \ + "DB_HOST=postgres" \ + "DB_NAME=sifatbaho" \ + "DB_PORT=5432" + + export PORT=8084 + docker stack deploy -c stack.yaml ${{ env.PROJECT_NAME }} --with-registry-auth