diff --git a/.gitea/workflows/image.yml b/.gitea/workflows/image.yml index 5979547..ecaf38b 100644 --- a/.gitea/workflows/image.yml +++ b/.gitea/workflows/image.yml @@ -12,7 +12,7 @@ jobs: publish: runs-on: ubuntu-latest env: - IMAGE: git.personal.ksv741.ru/wealthledger/backend + IMAGE: nexus.ksv741.keenetic.pro/wealthledger/backend RELEASE_TAG: ${{ gitea.ref_name }} REVISION: ${{ gitea.sha }} DOCKER_CONFIG: ${{ runner.temp }}/wealthledger-backend-docker @@ -31,14 +31,14 @@ jobs: - run: npx --no-install prisma generate - run: npm run verify - run: npm run test:e2e - - name: Login with dedicated package writer + - name: Login with dedicated Nexus writer env: - REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} - REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + REGISTRY_USERNAME: ${{ secrets.NEXUS_USERNAME }} + REGISTRY_TOKEN: ${{ secrets.NEXUS_PASSWORD }} run: | test -n "$REGISTRY_USERNAME" && test -n "$REGISTRY_TOKEN" install -d -m 700 "$DOCKER_CONFIG" - printf '%s' "$REGISTRY_TOKEN" | docker login git.personal.ksv741.ru --username "$REGISTRY_USERNAME" --password-stdin + printf '%s' "$REGISTRY_TOKEN" | docker login nexus.ksv741.keenetic.pro --username "$REGISTRY_USERNAME" --password-stdin - name: Publish immutable release tag run: | VERSION="${RELEASE_TAG#v}" diff --git a/.gitea/workflows/verify.yml b/.gitea/workflows/verify.yml index 7878842..204159a 100644 --- a/.gitea/workflows/verify.yml +++ b/.gitea/workflows/verify.yml @@ -10,6 +10,8 @@ jobs: 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 - uses: https://github.com/actions/setup-node@v4 @@ -22,3 +24,11 @@ jobs: run: npm run verify - name: Run isolated SQLite and runtime OpenAPI suites run: npm run test:e2e + - name: Analyze develop with SonarQube + if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/develop' + # v2.3.0: same Docker-based scanner used for SonarQube 9.9. + uses: https://github.com/SonarSource/sonarqube-scan-action@aecaf43ae57e412bd97d70ef9ce6076e672fe0a9 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: -Dsonar.qualitygate.wait=true diff --git a/.gitignore b/.gitignore index c01f41d..a87206a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ lerna-debug.log* # Tests /coverage +/.scannerwork /.nyc_output # IDEs and editors diff --git a/CHANGELOG.md b/CHANGELOG.md index 98265cf..63d0dee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## [0.2.1](https://git.personal.ksv741.ru/WealthLedger/backend/compare/v0.2.0...v0.2.1) (2026-09-18) + +### Documentation + +* use shared Nexus account [#25](https://git.personal.ksv741.ru/WealthLedger/backend/issues/25) ([9437b6a](https://git.personal.ksv741.ru/WealthLedger/backend/commit/9437b6a311cd51230b8381c8643c6ea308454d38)) + +### CI + +* add backend SonarQube analysis [#23](https://git.personal.ksv741.ru/WealthLedger/backend/issues/23) ([1946192](https://git.personal.ksv741.ru/WealthLedger/backend/commit/1946192be975eeea75432ec39b27d19952742b15)) +* publish backend images to Nexus [#25](https://git.personal.ksv741.ru/WealthLedger/backend/issues/25) ([0ec7ae5](https://git.personal.ksv741.ru/WealthLedger/backend/commit/0ec7ae51af080288a31dc6e65a738a4bd6396436)) + ## [0.2.0](https://git.personal.ksv741.ru/WealthLedger/backend/compare/v0.1.0...v0.2.0) (2026-09-16) ### Features diff --git a/README.md b/README.md index dc94750..f47a94f 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,13 @@ npm run test:container -- wealthledger-backend:production Gitea `image.yml` запускается на защищённом release tag `vX.Y.Z`, проверяет package/lock version и canonical gates. Runner `ubuntu-latest` должен иметь -Docker/buildx. Dedicated package writer задаётся Actions secrets -`REGISTRY_USERNAME`/`REGISTRY_TOKEN`; server использует отдельную read-only -identity. Публикуются semver tags, без `latest`; существующие -release tags не перезаписываются. Production выбирает опубликованный version tag. +Docker/buildx. Образы хранятся в Nexus: +`nexus.ksv741.keenetic.pro/wealthledger/backend`. Пользователь `wealthledger-ci` +задаётся Actions secrets `NEXUS_USERNAME`/`NEXUS_PASSWORD`; эта же учётная +запись используется сервером для загрузки образов. Docker endpoint и token realm должны использовать +HTTPS; в `docker-hosted` включается запрет redeploy. Прежние Gitea secrets +сохраняются на время перехода и не передаются в Nexus. +Публикуются semver tags, без `latest`; существующие release tags не перезаписываются. Production выбирает опубликованный version tag. Compose topology принадлежит workspace, эксплуатационная последовательность — [документация](https://git.personal.ksv741.ru/WealthLedger/docs), @@ -58,9 +61,9 @@ npm run verify ``` Он запускает zero-warning lint, -application/test typechecks, Jest и build. `npm run lint:fix` — отдельная -записывающая команда, `npm run test:cov` — диагностика без общего числового -threshold. `npm run test:e2e` отдельно проверяет все HTTP suites на новых базах +application/test typechecks, Jest с покрытием и build. `npm run lint:fix` — отдельная +записывающая команда. `npm run test:cov` также доступен отдельно; общего числового +threshold нет. `npm run test:e2e` отдельно проверяет все HTTP suites на новых базах и соответствие генерируемого OpenAPI настроенному приложению. Для полной backend-проверки выполните обе команды. @@ -102,6 +105,38 @@ Required checks настраиваются отдельно в Gitea: налич runtime-валидацию. В обычном коде нужны инициализация или сужение типа после проверки значения. +## SonarQube + +Проект `wealthledger-backend` на `https://sonarqube.ksv741.keenetic.pro` +использует `sonar-project.properties`. Анализируются исходники `src`; unit specs +и HTTP specs учитываются как тесты. Внешние T-Bank proto contracts исключены, +generated Prisma client находится за пределами `sonar.sources`. + +`npm run verify` запускает unit tests с покрытием один раз. Jest штатно создаёт +`coverage/lcov.info`; scanner импортирует этот отчёт. Покрытие HTTP/e2e tests +в него не входит, сами HTTP suites остаются обязательным отдельным шагом CI. + +Создайте в SonarQube проект с ключом `wealthledger-backend`, а в Gitea → backend → +Settings → Actions → Secrets добавьте `SONAR_TOKEN` с правом анализа этого проекта. +Токен не сохраняется в файлах. Community Edition 9.9.8 получает анализ только +при push в `develop`, после успешных `verify` и SQLite/e2e checks. CI ожидает +Quality Gate; отрицательный результат или ошибка scanner завершает job с ошибкой. +PR и другие ветки проходят штатные проверки без отправки анализа. +Переименование основной ветки SonarQube не требуется; `sonar.branch.name` не задаётся. + +Runner должен поддерживать Docker actions и иметь доступ к GitHub, Docker Hub +и HTTPS-адресу SonarQube с действующим сертификатом для этого имени. +Официальный Docker action закреплён на commit версии 2.3.0, как в frontend. +`tsconfig.sonar.json` содержит совместимые со старым анализатором настройки +модулей и decorators с target ES2022, без новых compiler options приложения. +Штатная компиляция приложения остаётся на ES2023. +После обновления сервера пересмотрите scanner и необходимость отдельного tsconfig. + +Локально после `nvm use --silent`, `npm ci` и генерации Prisma client выполните +`npm run verify`, затем `sonar-scanner` с совместимым SonarScanner CLI и +`SONAR_TOKEN` в окружении. Первый запуск CI после merge должен подтвердить +загрузку отчёта и покрытия: локальные проверки не доказывают доступность сервера. + ## Документация - [AGENTS: правила и источники](AGENTS.md) diff --git a/package-lock.json b/package-lock.json index 1db687f..96f5cc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wealth-ledger-backend", - "version": "0.2.0", + "version": "0.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "wealth-ledger-backend", - "version": "0.2.0", + "version": "0.2.1", "license": "UNLICENSED", "dependencies": { "@grpc/grpc-js": "1.14.4", diff --git a/package.json b/package.json index 9c5aed9..07d1188 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wealth-ledger-backend", - "version": "0.2.0", + "version": "0.2.1", "description": "", "author": "", "private": true, @@ -30,7 +30,7 @@ "test:container": "node test/container-smoke.cjs", "test:durability": "node test/bank-cards-durability.cjs", "test:openapi-contract": "npm run build && node test/sqlite.cjs openapi-contract.e2e-spec.ts", - "verify": "npm run lint && npm run typecheck:app && npm run typecheck:test && npm test -- --runInBand && npm run build", + "verify": "npm run lint && npm run typecheck:app && npm run typecheck:test && npm run test:cov -- --runInBand && npm run build", "release:preview": "release-it --dry-run --ci", "release:prepare": "release-it --ci", "commitlint": "commitlint" diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..7c8078f --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,12 @@ +sonar.projectKey=wealthledger-backend +sonar.projectName=WealthLedger backend +sonar.host.url=https://sonarqube.ksv741.keenetic.pro +sonar.sourceEncoding=UTF-8 + +sonar.sources=src +sonar.tests=src,test +sonar.test.inclusions=src/**/*.spec.ts,test/**/*.e2e-spec.ts +sonar.exclusions=src/**/*.spec.ts,src/integrations/tbank/proto/contracts/** +sonar.javascript.lcov.reportPaths=coverage/lcov.info +# SonarQube 9.9 embeds an older TypeScript analyzer than the application compiler. +sonar.typescript.tsconfigPaths=tsconfig.sonar.json diff --git a/tsconfig.sonar.json b/tsconfig.sonar.json new file mode 100644 index 0000000..763f85e --- /dev/null +++ b/tsconfig.sonar.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "module": "nodenext", + "moduleResolution": "nodenext", + "target": "ES2022", + "esModuleInterop": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true + }, + "include": ["src/**/*.ts", "test/**/*.ts"], + "exclude": ["node_modules", "dist", "generated"] +}