chore: configure releases and develop workflow

This commit is contained in:
2026-09-14 07:07:24 +03:00
parent d4fc28cbbf
commit f01b82d366
12 changed files with 2159 additions and 12 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"frontend": "0244acf429c525b23117f165bbe52ef5403eefd3"
}
+26
View File
@@ -0,0 +1,26 @@
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"
+23 -6
View File
@@ -2,8 +2,8 @@ name: Backend verify
on: on:
push: push:
branches: branches: ['**']
- '**' pull_request:
jobs: jobs:
verify: verify:
@@ -15,12 +15,29 @@ jobs:
- uses: https://github.com/actions/checkout@v4 - uses: https://github.com/actions/checkout@v4
with: with:
path: backend path: backend
- name: Checkout frontend contract - name: Checkout compatible peer revisions
run: git clone --depth 1 --branch main https://git.personal.ksv741.ru/WealthLedger/frontend.git ../frontend env:
- name: Record checked revisions SOURCE_BRANCH: ${{ github.head_ref || github.ref_name }}
TARGET_BRANCH: ${{ github.base_ref || github.ref_name }}
run: | run: |
set -eu
for repo in frontend; do
ref=develop
case "$SOURCE_BRANCH:$TARGET_BRANCH" in
release/*:*|*:main)
ref=$(jq -er --arg repo "$repo" '.[$repo]' .ci/refs.json)
printf '%s\n' "$ref" | grep -Eq '^[0-9a-f]{40}$'
;;
esac
target="../$repo"
if [ "$repo" = main ]; then target=..; fi
git init "$target"
git -C "$target" remote add origin "https://git.personal.ksv741.ru/WealthLedger/$repo.git"
git -C "$target" fetch --depth 1 origin "$ref"
git -C "$target" checkout --detach FETCH_HEAD
git -C "$target" rev-parse HEAD
done
git rev-parse HEAD git rev-parse HEAD
git -C ../frontend rev-parse HEAD
- uses: https://github.com/actions/setup-node@v4 - uses: https://github.com/actions/setup-node@v4
with: with:
node-version-file: backend/.nvmrc node-version-file: backend/.nvmrc
+106
View File
@@ -0,0 +1,106 @@
{
"git": {
"requireBranch": "release/*",
"requireCleanWorkingDir": true,
"requireUpstream": false,
"requireCommits": true,
"commitMessage": "chore(release): ${version}",
"tagName": "v${version}",
"tag": false,
"push": false
},
"npm": {
"publish": false
},
"github": {
"release": false
},
"gitlab": {
"release": false
},
"hooks": {
"after:git:init": "node scripts/check-release.cjs"
},
"plugins": {
"@release-it/conventional-changelog": {
"infile": "CHANGELOG.md",
"preset": {
"name": "conventionalcommits",
"types": [
{
"type": "chore",
"scope": "release",
"effect": "hidden"
},
{
"type": "feat",
"section": "Features",
"effect": "bump"
},
{
"type": "fix",
"section": "Bug Fixes",
"effect": "bump"
},
{
"type": "perf",
"section": "Performance",
"effect": "bump"
},
{
"type": "docs",
"section": "Documentation",
"effect": "bump"
},
{
"type": "spec",
"section": "Specifications",
"effect": "bump"
},
{
"type": "refactor",
"section": "Refactoring",
"effect": "bump"
},
{
"type": "build",
"section": "Build",
"effect": "bump"
},
{
"type": "ci",
"section": "CI",
"effect": "bump"
},
{
"type": "test",
"section": "Tests",
"effect": "bump"
},
{
"type": "style",
"section": "Styles",
"effect": "bump"
},
{
"type": "chore",
"section": "Maintenance",
"effect": "bump"
},
{
"type": "revert",
"section": "Reverts",
"effect": "bump"
}
]
},
"context": {
"host": "https://git.personal.ksv741.ru",
"owner": "WealthLedger",
"repository": "backend",
"linkReferences": true,
"commit": "commit"
}
}
}
}
+7
View File
@@ -21,3 +21,10 @@ Generated Prisma client не редактируется вручную. Credenti
ESLint/TypeScript не доказывают правильность domain boundaries, security или ESLint/TypeScript не доказывают правильность domain boundaries, security или
денежных вычислений: для них нужны semantic review и risk-based tests. денежных вычислений: для них нужны semantic review и risk-based tests.
## Ветки и релизы
Работа — в отдельной ветке от `develop`, затем PR в `develop`; в `main` напрямую
не пушить. Release/hotfix и синхронизация веток — по [root README](../README.md#релизы-и-ветки).
Commits и заголовки PR — Conventional Commits; для спецификаций допустим `spec:`.
Перед подготовкой релиза прочитай root README; версии вручную не повышать.
+1
View File
@@ -0,0 +1 @@
# Changelog
+5 -2
View File
@@ -44,8 +44,9 @@ TypeScript 7 требует поддержки со стороны `ts-jest` и
### CI и обновления зависимостей ### CI и обновления зависимостей
`.gitea/workflows/verify.yml` запускает `npm ci`, генерацию Prisma client, `.gitea/workflows/verify.yml` запускает `npm ci`, генерацию Prisma client,
`npm run verify` и `npm run test:e2e` на каждом push ветки. Frontend snapshot `npm run verify` и `npm run test:e2e` на push и PR. Frontend snapshot для
берётся из `main` соседнего репозитория; лог сохраняет оба SHA. Изменение разработки берётся из `develop`; для `main`, PR в `main` и `release/*` — из
полного SHA в `.ci/refs.json`. Лог сохраняет оба SHA. Изменение
контракта согласуется с этой frontend revision. Успешный unit gate не заменяет контракта согласуется с этой frontend revision. Успешный unit gate не заменяет
SQLite/e2e; ошибка любой suite завершает job с FAIL. SQLite/e2e; ошибка любой suite завершает job с FAIL.
@@ -159,3 +160,5 @@ npm run test:durability -- "$baseline_dir"
выберите совместимую предыдущую revision и проверьте её API-сценарии runner. выберите совместимую предыдущую revision и проверьте её API-сценарии runner.
Durability оставляет временные DB, логи и `result.json` по пути из вывода для Durability оставляет временные DB, логи и `result.json` по пути из вывода для
диагностики; он не откатывает schema пользовательской базы. диагностики; он не откатывает schema пользовательской базы.
Версии и ветки: [процесс релиза](../README.md#релизы-и-ветки).
+4
View File
@@ -0,0 +1,4 @@
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: { "type-enum": [2, "always", ["feat", "fix", "perf", "docs", "spec", "refactor", "build", "ci", "test", "style", "chore", "revert"]] },
};
+1961 -2
View File
File diff suppressed because it is too large Load Diff
+10 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "wealth-ledger-backend", "name": "wealth-ledger-backend",
"version": "0.0.1", "version": "0.0.0",
"description": "", "description": "",
"author": "", "author": "",
"private": true, "private": true,
@@ -28,7 +28,10 @@
"test:sqlite": "node test/sqlite.cjs", "test:sqlite": "node test/sqlite.cjs",
"test:durability": "node test/bank-cards-durability.cjs", "test:durability": "node test/bank-cards-durability.cjs",
"test:openapi-contract": "node test/sqlite.cjs openapi-contract.e2e-spec.ts", "test:openapi-contract": "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 test -- --runInBand && npm run build",
"release:preview": "release-it --dry-run --ci",
"release:prepare": "release-it --ci",
"commitlint": "commitlint"
}, },
"dependencies": { "dependencies": {
"@grpc/grpc-js": "1.14.4", "@grpc/grpc-js": "1.14.4",
@@ -57,11 +60,14 @@
"rxjs": "7.8.2" "rxjs": "7.8.2"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "21.2.2",
"@commitlint/config-conventional": "21.2.2",
"@eslint/eslintrc": "3.3.7", "@eslint/eslintrc": "3.3.7",
"@eslint/js": "10.0.1", "@eslint/js": "10.0.1",
"@nestjs/cli": "12.0.0", "@nestjs/cli": "12.0.0",
"@nestjs/schematics": "12.0.1", "@nestjs/schematics": "12.0.1",
"@nestjs/testing": "12.0.1", "@nestjs/testing": "12.0.1",
"@release-it/conventional-changelog": "12.0.0",
"@types/bcrypt": "6.0.0", "@types/bcrypt": "6.0.0",
"@types/cookie-parser": "1.4.10", "@types/cookie-parser": "1.4.10",
"@types/express": "5.0.6", "@types/express": "5.0.6",
@@ -69,6 +75,7 @@
"@types/node": "24.13.4", "@types/node": "24.13.4",
"@types/passport-jwt": "4.0.1", "@types/passport-jwt": "4.0.1",
"@types/supertest": "7.2.1", "@types/supertest": "7.2.1",
"conventional-changelog-conventionalcommits": "10.4.0",
"eslint": "10.10.0", "eslint": "10.10.0",
"eslint-config-prettier": "10.1.8", "eslint-config-prettier": "10.1.8",
"eslint-plugin-prettier": "5.5.6", "eslint-plugin-prettier": "5.5.6",
@@ -76,6 +83,7 @@
"jest": "30.5.1", "jest": "30.5.1",
"prettier": "3.9.6", "prettier": "3.9.6",
"prisma": "7.10.0", "prisma": "7.10.0",
"release-it": "21.0.2",
"source-map-support": "0.5.21", "source-map-support": "0.5.21",
"supertest": "7.2.2", "supertest": "7.2.2",
"ts-jest": "29.4.12", "ts-jest": "29.4.12",
+3
View File
@@ -24,5 +24,8 @@
], ],
"dependencyDashboardApproval": true "dependencyDashboardApproval": true
} }
],
"baseBranchPatterns": [
"develop"
] ]
} }
+10
View File
@@ -0,0 +1,10 @@
const assert = require("node:assert/strict");
const { execFileSync } = require("node:child_process");
const { version } = require("../package.json");
const git = (...args) => execFileSync("git", args, { encoding: "utf8" }).trim();
assert.equal(git("status", "--porcelain"), "", "Commit all changes before preparing a release");
const tags = git("tag", "--merged", "HEAD", "--list", "v[0-9]*", "--sort=-version:refname")
.split("\n").filter(tag => /^v\d+\.\d+\.\d+$/.test(tag));
assert.equal(version, tags[0]?.slice(1) ?? "0.0.0",
"Version is already prepared or release tags are missing. Fetch tags; finish the existing release before preparing another.");