/ Makefile
Makefile
1 -include .env 2 export 3 4 .PHONY: start 5 start: 6 uv run --no-group gpu uvicorn restai.main:app --host $${RESTAI_HOST:-127.0.0.1} --port $${RESTAI_PORT:-9000} --workers $${RESTAI_WORKERS:-2} 7 8 .PHONY: database 9 database: 10 uv run --no-group gpu database.py 11 12 .PHONY: frontend 13 frontend: 14 cd frontend && npm install 15 cd frontend && npm run build 16 17 .PHONY: dev 18 dev: 19 RESTAI_DEV=true uvicorn restai.main:app --reload --host $${RESTAI_HOST:-127.0.0.1} --port $${RESTAI_PORT:-9000} 20 21 .PHONY: build 22 build: 23 uv build 24 25 .PHONY: install 26 install: 27 mkdir -p frontend/build 28 uv sync --no-group gpu 29 make database 30 make frontend 31 @if command -v nvidia-smi > /dev/null 2>&1 && nvidia-smi > /dev/null 2>&1; then \ 32 echo "GPU detected, running installgpu..."; \ 33 $(MAKE) installgpu; \ 34 fi 35 @echo "" 36 @echo "=== Installation complete ===" 37 @echo "" 38 @read -p "Install RESTai as a systemd service? [y/N] " answer; \ 39 if [ "$$answer" = "y" ] || [ "$$answer" = "Y" ]; then \ 40 $(MAKE) systemd; \ 41 fi 42 @read -p "Install cron jobs (sync + telegram + docker cleanup)? [y/N] " answer; \ 43 if [ "$$answer" = "y" ] || [ "$$answer" = "Y" ]; then \ 44 $(MAKE) cron; \ 45 fi 46 47 .PHONY: systemd 48 systemd: 49 @RESTAI_DIR=$$(pwd); \ 50 RESTAI_USER=$$(whoami); \ 51 RESTAI_UV=$$(which uv); \ 52 echo "[Unit]" > /tmp/restai.service; \ 53 echo "Description=RESTai AI Platform" >> /tmp/restai.service; \ 54 echo "After=network.target" >> /tmp/restai.service; \ 55 echo "" >> /tmp/restai.service; \ 56 echo "[Service]" >> /tmp/restai.service; \ 57 echo "Type=simple" >> /tmp/restai.service; \ 58 echo "User=$$RESTAI_USER" >> /tmp/restai.service; \ 59 echo "WorkingDirectory=$$RESTAI_DIR" >> /tmp/restai.service; \ 60 echo "EnvironmentFile=$$RESTAI_DIR/.env" >> /tmp/restai.service; \ 61 echo "ExecStart=$$RESTAI_UV run --no-group gpu uvicorn restai.main:app --host $${RESTAI_HOST:-127.0.0.1} --port $${RESTAI_PORT:-9000} --workers $${RESTAI_WORKERS:-4}" >> /tmp/restai.service; \ 62 echo "Restart=always" >> /tmp/restai.service; \ 63 echo "RestartSec=5" >> /tmp/restai.service; \ 64 echo "" >> /tmp/restai.service; \ 65 echo "[Install]" >> /tmp/restai.service; \ 66 echo "WantedBy=multi-user.target" >> /tmp/restai.service; \ 67 sudo cp /tmp/restai.service /etc/systemd/system/restai.service; \ 68 rm /tmp/restai.service; \ 69 sudo systemctl daemon-reload; \ 70 sudo systemctl enable restai; \ 71 sudo systemctl start restai; \ 72 echo ""; \ 73 echo "RESTai systemd service installed and started."; \ 74 echo " Status: sudo systemctl status restai"; \ 75 echo " Logs: sudo journalctl -u restai -f"; \ 76 echo " Stop: sudo systemctl stop restai"; \ 77 echo " Restart: sudo systemctl restart restai" 78 79 .PHONY: installgpu 80 installgpu: 81 uv sync 82 make envs 83 uv run --no-group gpu download.py 84 85 .PHONY: envs 86 envs: 87 bash worker_envs/install.sh 88 89 .PHONY: migrate 90 migrate: 91 uv run --no-group gpu migrate.py upgrade 92 93 .PHONY: cron 94 cron: 95 @RESTAI_DIR=$$(pwd); \ 96 CURRENT=$$(crontab -l 2>/dev/null || true); \ 97 if echo "$$CURRENT" | grep -q "restai-sync\|restai-telegram\|restai-docker-cleanup\|restai-routines"; then \ 98 CURRENT=$$(echo "$$CURRENT" | grep -v "restai-sync\|restai-telegram\|restai-docker-cleanup\|restai-routines"); \ 99 echo "Removed old individual cron jobs"; \ 100 fi; \ 101 UV_PATH=$$(which uv); \ 102 ENTRY="* * * * * cd $$RESTAI_DIR && $$UV_PATH run --no-group gpu python crons/runner.py >> /var/log/restai-crons.log 2>&1 # restai-crons"; \ 103 if echo "$$CURRENT" | grep -q "restai-crons"; then \ 104 echo "Already installed: restai-crons"; \ 105 elif [ -z "$$CURRENT" ]; then \ 106 CURRENT="$$ENTRY"; \ 107 echo "Added: restai-crons"; \ 108 else \ 109 CURRENT="$$CURRENT"$$'\n'"$$ENTRY"; \ 110 echo "Added: restai-crons"; \ 111 fi; \ 112 echo "$$CURRENT" | crontab - 113 @echo "Cron jobs installed:" 114 @crontab -l | grep restai || true 115 116 .PHONY: cron-remove 117 cron-remove: 118 @( crontab -l 2>/dev/null | grep -v "restai-crons" ) | crontab - 119 @echo "RESTai cron jobs removed." 120 121 122 .PHONY: update 123 update: 124 @echo "Fetching latest release from GitHub..." 125 @LATEST=$$(git ls-remote --tags --sort=-v:refname origin 'refs/tags/v*' 2>/dev/null | head -1 | sed 's/.*refs\/tags\///'); \ 126 if [ -z "$$LATEST" ]; then \ 127 echo "No release tags found. Pulling latest from current branch..."; \ 128 git pull; \ 129 else \ 130 echo "Latest release: $$LATEST"; \ 131 git fetch --tags; \ 132 git checkout "$$LATEST"; \ 133 fi 134 @echo "Installing dependencies..." 135 uv sync --no-group gpu 136 @echo "Running database migrations..." 137 $(MAKE) migrate 138 @echo "Building frontend..." 139 $(MAKE) frontend 140 @if command -v nvidia-smi > /dev/null 2>&1 && nvidia-smi > /dev/null 2>&1; then \ 141 echo "GPU detected, syncing GPU deps..."; \ 142 $(MAKE) installgpu; \ 143 fi 144 @echo "Update complete." 145 146 .PHONY: docs 147 docs: 148 uv run --no-group gpu docs.py 149 150 .PHONY: version 151 version: 152 @CURRENT=$$(grep '^version' pyproject.toml | head -1 | sed 's/.*"\(.*\)"/\1/'); \ 153 MAJOR=$$(echo $$CURRENT | cut -d. -f1); \ 154 MINOR=$$(echo $$CURRENT | cut -d. -f2); \ 155 PATCH=$$(echo $$CURRENT | cut -d. -f3); \ 156 NEW_PATCH=$$((PATCH + 1)); \ 157 NEW_VERSION="$$MAJOR.$$MINOR.$$NEW_PATCH"; \ 158 echo "Bumping version: $$CURRENT → $$NEW_VERSION"; \ 159 sed -i "s/^version = \"$$CURRENT\"/version = \"$$NEW_VERSION\"/" pyproject.toml; \ 160 echo "Syncing lock file..."; \ 161 uv sync --no-group gpu; \ 162 echo "Committing..."; \ 163 git add pyproject.toml uv.lock; \ 164 git commit -m "v$$NEW_VERSION"; \ 165 echo "Tagging v$$NEW_VERSION..."; \ 166 git tag "v$$NEW_VERSION"; \ 167 echo "Pushing..."; \ 168 git push && git push --tags; \ 169 echo "Creating GitHub release..."; \ 170 gh release create "v$$NEW_VERSION" --title "v$$NEW_VERSION" --generate-notes; \ 171 echo "Done: v$$NEW_VERSION released." 172 173 .PHONY: test 174 test: 175 pytest tests 176 177 .PHONY: code 178 code: 179 black app/*.py 180 181 .PHONY: clean 182 clean: 183 rm -rf frontend/build/* 184 185 .PHONY: dockershell 186 dockershell: 187 @docker run --rm -t -i -v $(shell pwd):/app restai bash 188 189 .PHONY: dockerbuild 190 dockerbuild: 191 @docker build -t restai . 192