diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..51c87ad --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,130 @@ +name: Deploy DummyBot + +on: + push: + branches: [main] + workflow_dispatch: + +env: + DEPLOY_HOST: 157.180.77.232 + DEPLOY_USER: root + DEPLOY_PATH: /root/dummybot + APP_PORT: 18080 + +jobs: + deploy: + name: Build & Deploy to ${{ env.DEPLOY_HOST }} + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + extensions: mbstring, pdo, pdo_mysql, bcmath, curl, zip, intl + coverage: none + + - name: Validate composer.json + working-directory: . + run: composer validate --strict --no-check-publish + + - name: Cache Composer + uses: actions/cache@v4 + with: + path: ~/.composer/cache + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-php- + + - name: Install Composer dependencies (no-dev) + run: composer install --no-dev --no-interaction --no-progress --optimize-autoloader + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install npm dependencies + run: npm ci --no-audit --no-fund || npm install --no-audit --no-fund + + - name: Build frontend assets + run: npm run build + + - name: Setup SSH + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.DEPLOY_SSH_KEY }} + + - name: Setup known_hosts + run: | + mkdir -p ~/.ssh + ssh-keyscan -p 22 -H ${{ env.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null + + - name: Deploy to server + run: | + ssh -A ${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }} << 'ENDSSH' + set -e + cd ${{ env.DEPLOY_PATH }} + + echo "→ Fetching latest code" + git fetch origin main + git reset --hard origin/main + git clean -fd + + echo "→ Pulling env file (preserves local config)" + cp -n .env.example .env 2>/dev/null || true + if [ -f /root/dummybot.env ]; then + cp /root/dummybot.env .env + fi + + echo "→ Installing composer dependencies" + composer install --no-dev --no-interaction --no-progress --optimize-autoloader + + echo "→ Installing npm dependencies and building assets" + npm ci --no-audit --no-fund || npm install --no-audit --no-fund + npm run build + + echo "→ Caching build state for rollback" + DEPLOY_TS=$(date -u +%Y%m%d%H%M%S) + echo "$DEPLOY_TS" > .last_deploy + + echo "→ Running migrations" + docker compose exec -T app php artisan migrate --force + + echo "→ Clearing caches" + docker compose exec -T app php artisan config:clear + docker compose exec -T app php artisan route:clear + docker compose exec -T app php artisan view:clear + docker compose exec -T app php artisan event:clear + docker compose exec -T app php artisan optimize + + echo "→ Restarting services" + docker compose up -d --remove-orphans + + echo "→ Healthcheck" + sleep 5 + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:${{ env.APP_PORT }}/up --max-time 10 || echo "fail") + if [ "$HTTP_CODE" != "200" ]; then + echo "HEALTHCHECK FAILED: $HTTP_CODE" + exit 1 + fi + echo "✓ Healthcheck OK ($HTTP_CODE)" + + echo "→ Cleaning up old images" + docker image prune -f >/dev/null 2>&1 || true + ENDSSH + + - name: Notify success + if: success() + run: | + echo "✅ Deploy successful" + echo "🌐 https://${{ env.DEPLOY_HOST }}:${{ env.APP_PORT }}" + + - name: Notify failure + if: failure() + run: | + echo "❌ Deploy failed" + echo "Check the logs above for details" diff --git a/.gitignore b/.gitignore index 92cf450..11c872c 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,13 @@ Thumbs.db # Docker /docker-data/ + +# Deploy +/.deploy-key* +/.deploy.env + +# CI +/.gitea/secrets/ +*.pem +*.key +!storage/oauth-*.key diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 7642f1f..fd74c53 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -9,8 +9,8 @@ use Illuminate\Support\Facades\Hash; class LoginController extends Controller { - public function showLogin() { return view('pages.login'); } - public function showRegister() { return view('pages.register'); } + public function showLogin() { return view('pages.auth', ['mode' => 'login']); } + public function showRegister() { return view('pages.auth', ['mode' => 'register']); } public function login(Request $r) { $cred = $r->validate([ diff --git a/firmware b/firmware index 9fb87a4..478bb65 160000 --- a/firmware +++ b/firmware @@ -1 +1 @@ -Subproject commit 9fb87a4d623f61748d734e0b10940e7ae0c45e6b +Subproject commit 478bb65d32e601ba7bdc0908986b620a8256645b diff --git a/resources/views/layouts/base.blade.php b/resources/views/layouts/base.blade.php index f238ac0..f5414d7 100644 --- a/resources/views/layouts/base.blade.php +++ b/resources/views/layouts/base.blade.php @@ -4,55 +4,199 @@ + @yield('title', 'DummyBot') - - + - - + + + + + + + + + + @stack('head') - + @yield('content') - @stack('scripts') diff --git a/resources/views/pages/app.blade.php b/resources/views/pages/app.blade.php index 7615c88..27016ee 100644 --- a/resources/views/pages/app.blade.php +++ b/resources/views/pages/app.blade.php @@ -1,398 +1,566 @@ @extends('layouts.base') +@section('title', 'Tareas · DummyBot') @section('content') -
- {{-- NAV --}} -