From 53b27949631cadda10f988ff1920ac813d175ccc Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Mon, 28 Sep 2026 14:12:38 +0300 Subject: [PATCH] ci: reduce duplicate actions and serialize checks --- .gitea/workflows/commits.yml | 26 --------------- .gitea/workflows/security.yml | 31 ----------------- .gitea/workflows/verify.yml | 63 ++++++++++++++++++++++++++++++++++- README.md | 27 ++++++++++++--- 4 files changed, 84 insertions(+), 63 deletions(-) delete mode 100644 .gitea/workflows/commits.yml delete mode 100644 .gitea/workflows/security.yml diff --git a/.gitea/workflows/commits.yml b/.gitea/workflows/commits.yml deleted file mode 100644 index 2372d2c..0000000 --- a/.gitea/workflows/commits.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Conventional commits - -on: - pull_request: - types: [opened, synchronize, reopened, edited] - -jobs: - commits: - runs-on: ubuntu-latest - steps: - - uses: https://github.com/actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - uses: https://github.com/actions/setup-node@v4 - with: - node-version-file: .nvmrc - - run: npm ci --ignore-scripts - - name: Check PR title and commits - env: - PR_TITLE: ${{ github.event.pull_request.title }} - BASE_SHA: ${{ github.event.pull_request.base.sha }} - HEAD_SHA: ${{ github.event.pull_request.head.sha }} - run: | - printf '%s\n' "$PR_TITLE" | npm run commitlint -- --strict - npm run commitlint -- --strict --from "$BASE_SHA" --to "$HEAD_SHA" diff --git a/.gitea/workflows/security.yml b/.gitea/workflows/security.yml deleted file mode 100644 index 7c779f1..0000000 --- a/.gitea/workflows/security.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Backend security - -on: - push: - branches: - - '**' - pull_request: - schedule: - - cron: '17 5 * * *' - -jobs: - security: - runs-on: ubuntu-latest - steps: - - uses: https://github.com/actions/checkout@v4 - with: - fetch-depth: 0 - - name: Record checked revision - run: git rev-parse HEAD - - name: Scan history with Gitleaks 8.30.1 - run: | - curl --fail --location --silent --show-error https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz -o /tmp/gitleaks.tar.gz - echo '551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb /tmp/gitleaks.tar.gz' | sha256sum --check - mkdir -p /tmp/gitleaks-bin - tar -xzf /tmp/gitleaks.tar.gz -C /tmp/gitleaks-bin gitleaks - /tmp/gitleaks-bin/gitleaks git --log-opts=--all --redact=100 --no-banner - - uses: https://github.com/actions/setup-node@v4 - with: - node-version-file: .nvmrc - - name: Audit runtime and development dependencies - run: npm audit --include=dev --audit-level=low diff --git a/.gitea/workflows/verify.yml b/.gitea/workflows/verify.yml index 204159a..7087f11 100644 --- a/.gitea/workflows/verify.yml +++ b/.gitea/workflows/verify.yml @@ -2,11 +2,72 @@ name: Backend verify on: push: - branches: ['**'] + branches: [develop, main] pull_request: + types: [opened, synchronize, reopened, edited] + schedule: + - cron: '47 5 * * *' + +# Gitea >= 1.26. A new revision supersedes only the same PR/branch/event. +concurrency: + group: backend-verify-${{ gitea.event_name }}-${{ gitea.event.pull_request.number || gitea.ref }} + cancel-in-progress: true jobs: + commits: + if: gitea.event_name == 'pull_request' + timeout-minutes: 15 + runs-on: ubuntu-latest + steps: + - uses: https://github.com/actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + - uses: https://github.com/actions/setup-node@v4 + with: + node-version-file: .nvmrc + - run: npm ci --ignore-scripts + - name: Check PR title and commits + env: + PR_TITLE: ${{ github.event.pull_request.title }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + printf '%s\n' "$PR_TITLE" | npm run commitlint -- --strict + npm run commitlint -- --strict --from "$BASE_SHA" --to "$HEAD_SHA" + + security: + needs: commits + if: >- + !cancelled() && + (needs.commits.result == 'success' || needs.commits.result == 'skipped') + timeout-minutes: 15 + runs-on: ubuntu-latest + steps: + - uses: https://github.com/actions/checkout@v4 + with: + fetch-depth: 0 + - name: Record checked revision + run: git rev-parse HEAD + - name: Scan history with Gitleaks 8.30.1 + run: | + curl --fail --location --silent --show-error https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz -o /tmp/gitleaks.tar.gz + echo '551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb /tmp/gitleaks.tar.gz' | sha256sum --check + mkdir -p /tmp/gitleaks-bin + tar -xzf /tmp/gitleaks.tar.gz -C /tmp/gitleaks-bin gitleaks + /tmp/gitleaks-bin/gitleaks git --log-opts=--all --redact=100 --no-banner + - uses: https://github.com/actions/setup-node@v4 + with: + node-version-file: .nvmrc + - name: Audit runtime and development dependencies + run: npm audit --include=dev --audit-level=low + verify: + needs: [commits, security] + if: >- + !cancelled() && needs.security.result == 'success' && + gitea.event_name != 'schedule' + timeout-minutes: 45 runs-on: ubuntu-latest steps: - uses: https://github.com/actions/checkout@v4 diff --git a/README.md b/README.md index fa6844f..c2ec7f1 100644 --- a/README.md +++ b/README.md @@ -74,17 +74,34 @@ TypeScript 7 требует поддержки со стороны `ts-jest` и ### CI и обновления зависимостей -`.gitea/workflows/verify.yml` запускает `npm ci`, генерацию Prisma client, -`npm run verify` и `npm run test:e2e` на push и PR. Используется только checkout +Единый `.gitea/workflows/verify.yml` запускает `commits → security → verify` +последовательно на PR; на push в `develop`/`main` — `security → verify`. +Рабочие ветки проверяются после открытия PR, без дублирующего push-запуска. +Изменение заголовка PR тоже повторяет проверки Conventional Commits. +Новый запуск отменяет устаревший для того же PR/ветки и типа события +(требуется Gitea 1.26+). Ежедневно в 05:47 UTC выполняется только `security`. +Job `verify` запускает `npm ci`, генерацию Prisma client, +`npm run verify` и `npm run test:e2e`. Используется только checkout backend и его зависимости; OpenAPI генерируется во время проверки, SHA записывается в лог. Успешный unit gate не заменяет SQLite/e2e; ошибка любой suite завершает job с FAIL. -`security.yml` сканирует всю Git-историю Gitleaks 8.30.1 с полностью скрытыми -значениями и выполняет `npm audit --include=dev --audit-level=low` при push, -PR и ежедневно. `.gitleaksignore` перечисляет только проверенные исторические +Job `security` сканирует всю Git-историю Gitleaks 8.30.1 с полностью скрытыми +значениями и выполняет `npm audit --include=dev --audit-level=low`. +`.gitleaksignore` перечисляет только проверенные исторические совпадения: детерминированные fixtures, placeholder и badge из Nest starter. Новые коммиты этими исключениями не покрываются. +Имена jobs `commits`, `security`, `verify` сохранены, но Gitea включает имя +workflow в статус. При внедрении администратор должен заменить required checks +для защищённых веток на `Backend verify / commits (pull_request)`, +`Backend verify / security (pull_request)` и +`Backend verify / verify (pull_request)`, удалив старые имена и push-статусы, +если они требовались. Все три PR-проверки должны оставаться обязательными. +Публикация образов по тегам остаётся в `image.yml`. +Последовательность jobs ограничивает один запуск; для ограничения нагрузки всего сервера настройте +`runner.capacity: 1` у общего runner и учтите остальные зарегистрированные +runners. Конфигурация runner управляется вне этого репозитория. + Renovate группирует minor/patch updates, а major требует согласования в Dependency Dashboard. Автоматический merge не включён. Прямые зависимости фиксируются точными версиями: `.npmrc` задаёт `save-exact=true` для npm install,