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: .*/${{ env.PROJECT_NAME }}:.*|image: ${{ secrets.DOCKER_USERNAME }}/${{ env.PROJECT_NAME }}:${{ github.run_number }}|g" 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: | set -e PROJECTS=/opt/projects DIR=/opt/projects/${{ env.PROJECT_NAME }} REPO_URL=https://${{ secrets.GITEATOKEN }}@gitea.felixits.uz/${{ github.repository }}.git mkdir -p "$PROJECTS" if [ -d "$DIR/.git" ]; then echo "loyiha mavjud" else rm -rf "$DIR" cd "$PROJECTS" git clone "$REPO_URL" "${{ env.PROJECT_NAME }}" echo "Clone qilindi" fi cd "$DIR" git remote set-url origin "$REPO_URL" git fetch origin main git reset --hard origin/main cp .env.example .env update_env() { local env_file=".env" for kv in "$@"; do local key="${kv%%=*}" local value="${kv#*=}" if grep -q "^$key=" "$env_file"; then sed -i "s|^$key=.*|$key=$value|" "$env_file" else echo "$key=$value" >> "$env_file" fi done } update_env \ "DB_HOST=postgres" \ "DB_NAME=sifatbaho" \ "DB_PORT=5432" export PORT=8085 docker stack deploy -c stack.yaml ${{ env.PROJECT_NAME }} --with-registry-auth