Updated the CI workflow to run tests for individual projects, ensuring accurate coverage reports are generated for each module. Enhanced the BumperPlaceholders class to handle dangling separators more effectively, improving text resolution logic and maintaining clarity in output.
166 lines
7.4 KiB
YAML
166 lines
7.4 KiB
YAML
name: ci
|
||
|
||
# Один workflow вместо трёх: порядок build → tests → sonar задаётся через `needs`, а между
|
||
# отдельными файлами workflow'ов в Gitea связать этапы нечем. Побочный эффект — этапы идут
|
||
# последовательно, поэтому прогон дольше, зато тесты не стартуют на заведомо битой сборке,
|
||
# а анализ не уходит в SonarCloud с красными тестами.
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
pull_request:
|
||
workflow_dispatch:
|
||
|
||
jobs:
|
||
build-backend:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions/setup-dotnet@v4
|
||
with:
|
||
dotnet-version: 10.0.x
|
||
- name: Restore
|
||
working-directory: backend
|
||
run: dotnet restore TeleWave.slnx
|
||
# Форматирование проверяем до сборки: падает за секунду и сразу показывает, что чинить.
|
||
# Версия csharpier прибита в .config/dotnet-tools.json — глобальная копия разработчика на CI
|
||
# не влияет, иначе её минорка переформатировала бы репозиторий в свой стиль.
|
||
- name: Format check
|
||
working-directory: backend
|
||
run: |
|
||
dotnet tool restore
|
||
dotnet csharpier check .
|
||
# Строгая сборка: TreatWarningsAsErrors=true из Directory.Build.props не отключаем.
|
||
- name: Build (Release)
|
||
working-directory: backend
|
||
run: dotnet build TeleWave.slnx -c Release --no-restore
|
||
|
||
build-frontend:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions/setup-node@v4
|
||
with:
|
||
node-version: 22
|
||
- name: Enable pnpm
|
||
run: corepack enable
|
||
- name: Install
|
||
working-directory: frontend
|
||
run: pnpm install --frozen-lockfile
|
||
- name: Format check
|
||
working-directory: frontend
|
||
run: pnpm format:check
|
||
- name: Lint
|
||
working-directory: frontend
|
||
run: pnpm lint
|
||
- name: Typecheck
|
||
working-directory: frontend
|
||
run: pnpm typecheck
|
||
- name: Build
|
||
working-directory: frontend
|
||
run: pnpm build
|
||
|
||
tests:
|
||
runs-on: ubuntu-latest
|
||
needs: [build-backend, build-frontend]
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions/setup-dotnet@v4
|
||
with:
|
||
dotnet-version: 10.0.x
|
||
- name: Restore
|
||
working-directory: backend
|
||
run: dotnet restore TeleWave.slnx
|
||
# Покрытие здесь не собираем: его считает джоба sonar своим прогоном (в формате opencover),
|
||
# а бейдж покрытия в README берётся из SonarCloud.
|
||
- name: Test
|
||
working-directory: backend
|
||
run: >
|
||
dotnet test TeleWave.slnx
|
||
-c Release
|
||
--no-restore
|
||
--logger "console;verbosity=normal"
|
||
|
||
# Анализ SonarCloud вместе с покрытием: один прогон собирает решение под сканером, гоняет тесты
|
||
# и отправляет результат. Только push в main — декорация pull request'ов у SonarCloud завязана
|
||
# на GitHub/GitLab, из Gitea она не работает, и анализ PR только засорял бы ветки в проекте.
|
||
sonar:
|
||
runs-on: ubuntu-latest
|
||
needs: tests
|
||
if: github.event_name != 'pull_request'
|
||
env:
|
||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||
SONAR_HOST: https://sonarcloud.io
|
||
SONAR_PROJECT_KEY: mrleo1nid_telewave
|
||
SONAR_ORGANIZATION: mrleo1nid
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
# Полная история — иначе Sonar не сопоставит изменения с авторами и «новым кодом».
|
||
fetch-depth: 0
|
||
|
||
# Сканер — java-приложение, на runner-образе Java может не оказаться.
|
||
- uses: actions/setup-java@v4
|
||
if: env.SONAR_TOKEN != ''
|
||
with:
|
||
distribution: temurin
|
||
java-version: 21
|
||
|
||
- uses: actions/setup-dotnet@v4
|
||
if: env.SONAR_TOKEN != ''
|
||
with:
|
||
dotnet-version: 10.0.x
|
||
|
||
- name: Install scanner
|
||
if: env.SONAR_TOKEN != ''
|
||
run: dotnet tool install --global dotnet-sonarscanner
|
||
|
||
# Сканер запускается из корня репозитория, а не из backend/: так в анализ попадает и фронт.
|
||
- name: Begin analysis
|
||
if: env.SONAR_TOKEN != ''
|
||
run: |
|
||
export PATH="$PATH:$HOME/.dotnet/tools"
|
||
dotnet sonarscanner begin \
|
||
/k:"$SONAR_PROJECT_KEY" \
|
||
/o:"$SONAR_ORGANIZATION" \
|
||
/d:sonar.host.url="$SONAR_HOST" \
|
||
/d:sonar.token="$SONAR_TOKEN" \
|
||
/d:sonar.cs.opencover.reportsPaths="**/coverage/**/coverage.opencover.xml" \
|
||
/d:sonar.exclusions="frontend/node_modules/**,frontend/dist/**,frontend/src/routeTree.gen.ts,backend/src/TeleWave.Infrastructure/Migrations/**" \
|
||
/d:sonar.coverage.exclusions="backend/src/TeleWave.Infrastructure/Migrations/**,frontend/**"
|
||
|
||
# Сканер подмешивает в сборку свои анализаторы, а в проекте TreatWarningsAsErrors=true —
|
||
# любое замечание Sonar роняло бы сборку вместо того, чтобы приехать в отчёт. Строгая
|
||
# сборка живёт в джобе build-backend, здесь она нужна только как носитель анализа.
|
||
- name: Build
|
||
if: env.SONAR_TOKEN != ''
|
||
run: dotnet build backend/TeleWave.slnx -c Release /p:TreatWarningsAsErrors=false
|
||
|
||
# Формат opencover, а не cobertura по умолчанию: C#-анализатор Sonar читает именно его.
|
||
# Интеграционные тесты без Docker пропускаются сами (см. PostgresFixture).
|
||
#
|
||
# Проекты гоняются по одному, а не одним прогоном по решению: при общем прогоне сборщик
|
||
# покрытия теряет попадания — отчёт приезжает без модуля TeleWave.Application, и в Sonar
|
||
# покрытые тестами файлы выглядят нулевыми. Отчёты складываются в один каталог, сканер
|
||
# подбирает их маской.
|
||
- name: Test + coverage
|
||
if: env.SONAR_TOKEN != ''
|
||
run: |
|
||
for project in Domain Application Integration; do
|
||
dotnet test "backend/tests/TeleWave.$project.Tests" \
|
||
-c Release \
|
||
--no-build \
|
||
--collect:"XPlat Code Coverage;Format=opencover" \
|
||
--results-directory backend/coverage \
|
||
--logger "console;verbosity=normal"
|
||
done
|
||
|
||
- name: End analysis
|
||
if: env.SONAR_TOKEN != ''
|
||
run: |
|
||
export PATH="$PATH:$HOME/.dotnet/tools"
|
||
dotnet sonarscanner end /d:sonar.token="$SONAR_TOKEN"
|
||
|
||
- name: Skipped
|
||
if: env.SONAR_TOKEN == ''
|
||
run: echo "SONAR_TOKEN не задан — анализ пропущен."
|