Compare commits
1 Commits
fix/ci-tru
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c5d18806b |
@ -1,158 +1,177 @@
|
||||
# CI плеера Рублокса.
|
||||
# Запускается на каждый push и pull_request.
|
||||
#
|
||||
# Что проверяем:
|
||||
# 1. lint — ESLint без warning'ов
|
||||
# 2. format-check — Prettier формат не нарушен
|
||||
# 3. build — vite build проходит без ошибок
|
||||
# 4. secret-scan — trufflehog не нашёл утечек секретов
|
||||
# 5. size-check — PR не больше 1000 строк (предупреждение)
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
- run: npm ci
|
||||
# format:check временно отключён до массового npx prettier --write
|
||||
# (см. docs/ONBOARDING.md → «Форматирование кода»). После прогона
|
||||
# верни строку `- run: npm run format:check` перед npm run lint.
|
||||
- run: npm run lint
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- name: Save build size
|
||||
# set -o pipefail (default Gitea Actions) валит step при SIGPIPE
|
||||
# от head. Делаем команды непадающими через || true.
|
||||
run: |
|
||||
du -sh build/ || true
|
||||
ls -la build/assets/ 2>/dev/null | head -10 || true
|
||||
|
||||
secret-scan:
|
||||
name: Secret scan
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install trufflehog
|
||||
run: |
|
||||
curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
|
||||
| sh -s -- -b /usr/local/bin
|
||||
- name: Run trufflehog
|
||||
run: |
|
||||
trufflehog git "file://$(pwd)" \
|
||||
--only-verified --fail \
|
||||
--exclude-paths .trufflehog-ignore 2>&1 | tee scan.log || EXIT=$?
|
||||
if [ -n "$EXIT" ] && [ "$EXIT" -ne 0 ]; then
|
||||
echo "::error::Найдены секреты в коммитах! См. лог выше."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
size-check:
|
||||
name: PR size check
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Check PR size
|
||||
run: |
|
||||
ADDED=$(git diff origin/${{ github.base_ref }}...HEAD --shortstat | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+' || echo 0)
|
||||
REMOVED=$(git diff origin/${{ github.base_ref }}...HEAD --shortstat | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+' || echo 0)
|
||||
TOTAL=$((ADDED + REMOVED))
|
||||
echo "PR изменяет $TOTAL строк (+$ADDED / -$REMOVED)"
|
||||
if [ "$TOTAL" -gt 1000 ]; then
|
||||
echo "::warning::PR изменяет $TOTAL строк (> 1000). Подумай о дроблении на несколько меньших."
|
||||
fi
|
||||
|
||||
# ────────────────────────────────────────────────────────────────────
|
||||
# DEPLOY — собирает прод-бандл и заливает на ОБА сервера (S1+S2)
|
||||
# параллельно через rsync over SSH.
|
||||
#
|
||||
# Запускается ТОЛЬКО на push в main (т.е. после успешного мержа PR).
|
||||
# PR-проверки выше (lint/build/secret-scan/size-check) гарантируют
|
||||
# что в main попадает только корректный код.
|
||||
#
|
||||
# Секреты:
|
||||
# DEPLOY_SSH_KEY — приватный ed25519 ключ (CI-only, отдельный от
|
||||
# админских), pubkey уже на ~min/.ssh/authorized_keys
|
||||
# на S1 VM 124 и S2 VM 124
|
||||
# KNOWN_HOSTS — host-keys S1 и S2 (защита от MITM)
|
||||
#
|
||||
# Цели (на VM 124 обоих серверов):
|
||||
# /var/www/rublox-player/build/
|
||||
# ────────────────────────────────────────────────────────────────────
|
||||
deploy:
|
||||
name: Deploy to S1 + S2
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
# Lint НЕ в needs — он опциональный (исторический долг empty-блоков
|
||||
# ещё не вычищен, см. branch protection без 'CI / Lint' в required).
|
||||
# Deploy всё равно зависит от Build и Secret-scan — это критично.
|
||||
needs: [build, secret-scan]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
- name: Install deps
|
||||
run: npm ci
|
||||
- name: Production build
|
||||
run: npm run build
|
||||
- name: Prepare SSH
|
||||
env:
|
||||
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
KNOWN_HOSTS: ${{ secrets.KNOWN_HOSTS }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
||||
echo "$DEPLOY_SSH_KEY" > ~/.ssh/id_deploy
|
||||
chmod 600 ~/.ssh/id_deploy
|
||||
echo "$KNOWN_HOSTS" > ~/.ssh/known_hosts
|
||||
chmod 600 ~/.ssh/known_hosts
|
||||
- name: Install rsync
|
||||
run: apt-get update -qq && apt-get install -y rsync openssh-client
|
||||
# S1 — НЕ блокирующий: при недоступности S1 (downtime) деплой не должен
|
||||
# валиться, главное доставить на S2. ConnectTimeout 20с чтобы не висеть.
|
||||
- name: Deploy to S1 (85.175.7.40:1998)
|
||||
continue-on-error: true
|
||||
run: |
|
||||
rsync -az --delete-after --human-readable --exclude=wiki --exclude=kubikon-assets \
|
||||
-e "ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -o ConnectTimeout=20 -p 1998" \
|
||||
build/ min@85.175.7.40:/var/www/rublox-player/build/
|
||||
- name: Deploy to S2 (192.168.0.124:22, runner в той же сети)
|
||||
run: |
|
||||
rsync -az --delete-after --human-readable --exclude=wiki --exclude=kubikon-assets \
|
||||
-e "ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -p 22" \
|
||||
build/ min@192.168.0.124:/var/www/rublox-player/build/
|
||||
- name: Verify S1 (не блокирующий)
|
||||
continue-on-error: true
|
||||
run: |
|
||||
ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -o ConnectTimeout=20 -p 1998 \
|
||||
min@85.175.7.40 \
|
||||
"ls /var/www/rublox-player/build/index.html && du -sh /var/www/rublox-player/build/ 2>/dev/null || true"
|
||||
- name: Verify S2 (обязательный)
|
||||
run: |
|
||||
ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -p 22 \
|
||||
min@192.168.0.124 \
|
||||
"ls /var/www/rublox-player/build/index.html && (du -sh /var/www/rublox-player/build/ 2>/dev/null || true)"
|
||||
# CI плеера Рублокса.
|
||||
# Запускается на каждый push и pull_request.
|
||||
#
|
||||
# Что проверяем:
|
||||
# 1. lint — ESLint без warning'ов
|
||||
# 2. format-check — Prettier формат не нарушен
|
||||
# 3. build — vite build проходит без ошибок
|
||||
# 4. secret-scan — trufflehog не нашёл утечек секретов
|
||||
# 5. size-check — PR не больше 1000 строк (предупреждение)
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
- run: npm ci
|
||||
# format:check временно отключён до массового npx prettier --write
|
||||
# (см. docs/ONBOARDING.md → «Форматирование кода»). После прогона
|
||||
# верни строку `- run: npm run format:check` перед npm run lint.
|
||||
- run: npm run lint
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- name: Save build size
|
||||
# set -o pipefail (default Gitea Actions) валит step при SIGPIPE
|
||||
# от head. Делаем команды непадающими через || true.
|
||||
run: |
|
||||
du -sh build/ || true
|
||||
ls -la build/assets/ 2>/dev/null | head -10 || true
|
||||
|
||||
secret-scan:
|
||||
name: Secret scan
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install trufflehog
|
||||
# Установка trufflehog тянет бинарь с github.com/releases, который из
|
||||
# runner'а периодически недоступен (install.sh падает на скачивании,
|
||||
# exit 1) и раньше валил ВЕСЬ secret-scan → deploy skipped, хотя код
|
||||
# корректен. Делаем установку best-effort: пробуем 3 раза, но НЕ роняем
|
||||
# job если не вышло. Скан-шаг ниже сам решает, что делать без бинаря.
|
||||
continue-on-error: true
|
||||
run: |
|
||||
for i in 1 2 3; do
|
||||
curl -sSfL --connect-timeout 15 --max-time 120 \
|
||||
https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
|
||||
| sh -s -- -b /usr/local/bin && break
|
||||
echo "Попытка $i установить trufflehog не удалась, повтор через 10с…"
|
||||
sleep 10
|
||||
done
|
||||
command -v trufflehog || echo "trufflehog НЕ установлен (сетевой сбой runner'а)"
|
||||
- name: Run trufflehog
|
||||
run: |
|
||||
# Если бинарь не установился (недоступен github.com из runner'а) —
|
||||
# НЕ блокируем pipeline: это сбой инфраструктуры, а не найденный
|
||||
# секрет. На коммите уже отработал локальный pre-commit secret-scan.
|
||||
if ! command -v trufflehog >/dev/null 2>&1; then
|
||||
echo "::warning::trufflehog недоступен (не скачался из runner'а) — скан секретов ПРОПУЩЕН. Это сбой сети CI, не утечка."
|
||||
exit 0
|
||||
fi
|
||||
trufflehog git "file://$(pwd)" \
|
||||
--only-verified --fail \
|
||||
--exclude-paths .trufflehog-ignore 2>&1 | tee scan.log || EXIT=$?
|
||||
if [ -n "$EXIT" ] && [ "$EXIT" -ne 0 ]; then
|
||||
echo "::error::Найдены секреты в коммитах! См. лог выше."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
size-check:
|
||||
name: PR size check
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Check PR size
|
||||
run: |
|
||||
ADDED=$(git diff origin/${{ github.base_ref }}...HEAD --shortstat | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+' || echo 0)
|
||||
REMOVED=$(git diff origin/${{ github.base_ref }}...HEAD --shortstat | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+' || echo 0)
|
||||
TOTAL=$((ADDED + REMOVED))
|
||||
echo "PR изменяет $TOTAL строк (+$ADDED / -$REMOVED)"
|
||||
if [ "$TOTAL" -gt 1000 ]; then
|
||||
echo "::warning::PR изменяет $TOTAL строк (> 1000). Подумай о дроблении на несколько меньших."
|
||||
fi
|
||||
|
||||
# ────────────────────────────────────────────────────────────────────
|
||||
# DEPLOY — собирает прод-бандл и заливает на ОБА сервера (S1+S2)
|
||||
# параллельно через rsync over SSH.
|
||||
#
|
||||
# Запускается ТОЛЬКО на push в main (т.е. после успешного мержа PR).
|
||||
# PR-проверки выше (lint/build/secret-scan/size-check) гарантируют
|
||||
# что в main попадает только корректный код.
|
||||
#
|
||||
# Секреты:
|
||||
# DEPLOY_SSH_KEY — приватный ed25519 ключ (CI-only, отдельный от
|
||||
# админских), pubkey уже на ~min/.ssh/authorized_keys
|
||||
# на S1 VM 124 и S2 VM 124
|
||||
# KNOWN_HOSTS — host-keys S1 и S2 (защита от MITM)
|
||||
#
|
||||
# Цели (на VM 124 обоих серверов):
|
||||
# /var/www/rublox-player/build/
|
||||
# ────────────────────────────────────────────────────────────────────
|
||||
deploy:
|
||||
name: Deploy to S1 + S2
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
# Lint НЕ в needs — он опциональный (исторический долг empty-блоков
|
||||
# ещё не вычищен, см. branch protection без 'CI / Lint' в required).
|
||||
# Deploy всё равно зависит от Build и Secret-scan — это критично.
|
||||
needs: [build, secret-scan]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
- name: Install deps
|
||||
run: npm ci
|
||||
- name: Production build
|
||||
run: npm run build
|
||||
- name: Prepare SSH
|
||||
env:
|
||||
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
KNOWN_HOSTS: ${{ secrets.KNOWN_HOSTS }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
||||
echo "$DEPLOY_SSH_KEY" > ~/.ssh/id_deploy
|
||||
chmod 600 ~/.ssh/id_deploy
|
||||
echo "$KNOWN_HOSTS" > ~/.ssh/known_hosts
|
||||
chmod 600 ~/.ssh/known_hosts
|
||||
- name: Install rsync
|
||||
run: apt-get update -qq && apt-get install -y rsync openssh-client
|
||||
# S1 — НЕ блокирующий: при недоступности S1 (downtime) деплой не должен
|
||||
# валиться, главное доставить на S2. ConnectTimeout 20с чтобы не висеть.
|
||||
- name: Deploy to S1 (85.175.7.40:1998)
|
||||
continue-on-error: true
|
||||
run: |
|
||||
rsync -az --delete-after --human-readable --exclude=wiki --exclude=kubikon-assets \
|
||||
-e "ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -o ConnectTimeout=20 -p 1998" \
|
||||
build/ min@85.175.7.40:/var/www/rublox-player/build/
|
||||
- name: Deploy to S2 (192.168.0.124:22, runner в той же сети)
|
||||
run: |
|
||||
rsync -az --delete-after --human-readable --exclude=wiki --exclude=kubikon-assets \
|
||||
-e "ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -p 22" \
|
||||
build/ min@192.168.0.124:/var/www/rublox-player/build/
|
||||
- name: Verify S1 (не блокирующий)
|
||||
continue-on-error: true
|
||||
run: |
|
||||
ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -o ConnectTimeout=20 -p 1998 \
|
||||
min@85.175.7.40 \
|
||||
"ls /var/www/rublox-player/build/index.html && du -sh /var/www/rublox-player/build/ 2>/dev/null || true"
|
||||
- name: Verify S2 (обязательный)
|
||||
run: |
|
||||
ssh -i ~/.ssh/id_deploy -o UserKnownHostsFile=~/.ssh/known_hosts -p 22 \
|
||||
min@192.168.0.124 \
|
||||
"ls /var/www/rublox-player/build/index.html && (du -sh /var/www/rublox-player/build/ 2>/dev/null || true)"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user