From 6d59dc8f37c132599ffaffcb8aece2849ab3e90a Mon Sep 17 00:00:00 2001 From: Do Siki Date: Mon, 17 Aug 2026 16:50:39 +0200 Subject: [PATCH] feat: add local staging deploy workflow --- .gitea/workflows/ci.yml | 160 ---------------------------- docs/helyi-staging-deploy.md | 46 ++++++++ scripts/deploy_to_stage_on_local.sh | 57 ++++++++++ 3 files changed, 103 insertions(+), 160 deletions(-) delete mode 100644 .gitea/workflows/ci.yml create mode 100644 docs/helyi-staging-deploy.md create mode 100755 scripts/deploy_to_stage_on_local.sh diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml deleted file mode 100644 index ae8ed9f..0000000 --- a/.gitea/workflows/ci.yml +++ /dev/null @@ -1,160 +0,0 @@ -# CI workflow for Gitea (git.mozdit.hu) -# Runs on every push to main/develop and on PRs to main. -# Deploy is NOT handled here — use deploy.sh on the server (native docker compose). -name: CI — Test & Build - -on: - push: - branches: [main, develop] - pull_request: - branches: [main] - workflow_dispatch: - schedule: - - cron: '17 4 * * *' - -env: - NODE_VERSION: '20' - REGISTRY: git.mozdit.hu - IMAGE_NAME: si/websitedev - -jobs: - test: - name: 🧪 Run Tests & Generate Reports - runs-on: ubuntu-latest - steps: - - name: 📥 Checkout code - uses: actions/checkout@v4 - - - name: 📦 Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: 'npm' - cache-dependency-path: proto/package-lock.json - - - name: 📥 Install dependencies - working-directory: ./proto - run: npm ci - - - name: 🔍 Lint code - working-directory: ./proto - run: npm run lint - - - name: 🧪 Run unit tests - working-directory: ./proto - run: npm run test:unit -- --json --outputFile=unit-results.json --silent - - - name: 🌐 Run browser integration tests - working-directory: ./proto - run: npm run test:browser -- --json --outputFile=browser-results.json --silent - - - name: 📋 Upload test results - uses: actions/upload-artifact@v4 - with: - name: test-results - path: | - proto/unit-results.json - proto/browser-results.json - retention-days: 30 - - build: - name: 🏗️ Build Docker Image - runs-on: ubuntu-latest - needs: test - steps: - - name: 📥 Checkout code - uses: actions/checkout@v4 - - - name: 🏗️ Build Docker image - run: docker build -t mozdit-app:ci ./proto - - - name: 🔍 Verify image health - run: | - docker create --name mozdit-app-ci -e NODE_ENV=production mozdit-app:ci - docker cp mozdit-app-ci:/app/.next/BUILD_ID ./build-id 2>/dev/null || \ - echo "BUILD_ID nem elérhető — build verification skip" - docker rm mozdit-app-ci - - docker-integration: - name: 🐳 Docker integration & API E2E - runs-on: ubuntu-latest - needs: test - steps: - - name: 📥 Checkout code - uses: actions/checkout@v4 - - - name: 📦 Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: 'npm' - cache-dependency-path: proto/package-lock.json - - - name: 📥 Install dependencies - working-directory: ./proto - run: npm ci - - - name: 🐳 Start Docker development stack - run: docker compose -f docker-compose.dev.yml up --build -d - - - name: ⏳ Wait for application health - run: | - for attempt in $(seq 1 30); do - if curl --fail --silent http://localhost:8080/api/health > /dev/null; then - exit 0 - fi - sleep 2 - done - docker compose -f docker-compose.dev.yml logs --tail=100 - exit 1 - - - name: 🔗 Run integration tests - working-directory: ./proto - run: npm run test:integration - - - name: 🔄 Run API E2E tests - working-directory: ./proto - run: npm run test:e2e - - - name: 🧹 Stop Docker development stack - if: always() - run: docker compose -f docker-compose.dev.yml down -v - - staging-smoke: - name: 🌐 Staging Playwright smoke - runs-on: ubuntu-latest - if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' - steps: - - name: 📥 Checkout code - uses: actions/checkout@v4 - - - name: 📦 Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: 'npm' - cache-dependency-path: proto/package-lock.json - - - name: 📥 Install dependencies - working-directory: ./proto - run: npm ci - - - name: 🌐 Install Chromium for Playwright - working-directory: ./proto - run: npx playwright install --with-deps chromium - - - name: 🧪 Run staging smoke suite - working-directory: ./proto - env: - BASE_URL: https://stage.mozdit.hu - run: npm run test:smoke:staging - - - name: 📦 Upload Playwright artifacts - if: always() - uses: actions/upload-artifact@v4 - with: - name: staging-smoke-artifacts - path: | - proto/playwright-report/ - proto/test-results/ - retention-days: 30 diff --git a/docs/helyi-staging-deploy.md b/docs/helyi-staging-deploy.md new file mode 100644 index 0000000..13ff78e --- /dev/null +++ b/docs/helyi-staging-deploy.md @@ -0,0 +1,46 @@ +# Helyi staging kiadás + +A staging kiadás szándékosan nem használ Gitea Actions runnert. A kiadásért felelős fejlesztő saját gépén vezérli a folyamatot; nincs állandó CI-host, runner-regisztráció vagy extra szerveroldali jogosultság. + +## Egy parancsos folyamat + +```bash +./scripts/deploy_to_stage_on_local.sh +``` + +A script rögzített sorrendben fut: + +1. Ellenőrzi, hogy a helyi `main` ág és a Git munkakönyvtár tiszta-e. +2. A `proto` könyvtárban futtatja a determinisztikus `npm ci` telepítést és az unit teszteket. +3. Feltolja a `main` commitot a Gitea-ra. +4. SSH-n belép a staging hostra (`sadmin@llmdev.mozdit.hu`), a `/home/sadmin/websitedev` könyvtárban fast-forward Git frissítést végez, majd futtatja a `./deploy.sh staging` parancsot. +5. A helyi gépről a `https://stage.mozdit.hu` ellen lefuttatja az öt Playwright smoke tesztet. + +Hiba esetén a script azonnal leáll. Ez különösen fontos: sikertelen unit teszt esetén nincs push vagy deploy; sikertelen szerveroldali healthcheck esetén nincs sikeres kiadás jelzés; sikertelen smoke teszt esetén a staging kiadás további ellenőrzést igényel. + +## Előfeltételek a helyi gépen + +- Git-hozzáférés a `origin` Gitea remote-hoz +- SSH-hozzáférés `sadmin@llmdev.mozdit.hu` célhoz +- Node.js és npm +- a Playwright Chromium böngészője. Új gépen egyszer: + +```bash +cd proto +npx playwright install chromium +``` + +## Egyedi célok + +A paraméterek szükség esetén környezeti változóval felülírhatók: + +```bash +STAGE_HOST=felhasznalo@masik-stage-host \ +STAGE_PATH=/srv/websitedev \ +STAGE_URL=https://stage.mozdit.hu \ +./scripts/deploy_to_stage_on_local.sh +``` + +## Gitea Actions + +A `.gitea/workflows/ci.yml` workflow jelenleg szünetel, mert nincs dedikált, biztonságosan elkülönített runner. A régi Gitea Actions futásokat a Gitea felületén a `Cancel` gombbal meg kell szakítani. Ha később dedikált CI-host készül, a workflow visszaállítható és a telepítési modell újraértékelhető. diff --git a/scripts/deploy_to_stage_on_local.sh b/scripts/deploy_to_stage_on_local.sh new file mode 100755 index 0000000..e65269e --- /dev/null +++ b/scripts/deploy_to_stage_on_local.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# Helyi, kézi staging kiadás: unit teszt -> push -> szerveroldali deploy -> staging smoke teszt. + +set -Eeuo pipefail + +readonly STAGE_HOST="${STAGE_HOST:-sadmin@llmdev.mozdit.hu}" +readonly STAGE_PATH="${STAGE_PATH:-/home/sadmin/websitedev}" +readonly STAGE_URL="${STAGE_URL:-https://stage.mozdit.hu}" +readonly DEPLOY_BRANCH="${DEPLOY_BRANCH:-main}" +readonly PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +readonly APP_ROOT="${PROJECT_ROOT}/proto" + +fail() { + printf 'HIBA: %s\n' "$*" >&2 + exit 1 +} + +require_command() { + command -v "$1" >/dev/null 2>&1 || fail "Hiányzó parancs: $1" +} + +ensure_clean_worktree() { + [[ -z "$(git status --porcelain)" ]] || fail "A munkakönyvtár nem tiszta. Commitold vagy tedd félre a változásokat a staging kiadás előtt." +} + +require_command git +require_command npm +require_command ssh + +cd "${PROJECT_ROOT}" +[[ "$(git branch --show-current)" == "${DEPLOY_BRANCH}" ]] || fail "A kiadás csak a ${DEPLOY_BRANCH} ágról engedélyezett." +ensure_clean_worktree + +printf '1/4 Függőségek és unit tesztek…\n' +( + cd "${APP_ROOT}" + npm ci + npm run test:unit +) + +# A tesztek nem módosíthatják a kiadandó commitot. +ensure_clean_worktree + +printf '2/4 Commit feltolása a Gitea-ra…\n' +git push origin "${DEPLOY_BRANCH}" + +printf '3/4 Staging deploy (%s:%s)…\n' "${STAGE_HOST}" "${STAGE_PATH}" +ssh -o BatchMode=yes -o ConnectTimeout=15 "${STAGE_HOST}" \ + "cd '${STAGE_PATH}' && git pull --ff-only origin '${DEPLOY_BRANCH}' && ./deploy.sh staging" + +printf '4/4 Staging smoke teszt (%s)…\n' "${STAGE_URL}" +( + cd "${APP_ROOT}" + BASE_URL="${STAGE_URL}" npm run test:smoke:staging +) + +printf '\nSikeres staging kiadás: %s\n' "$(git rev-parse --short HEAD)"