/
This commit is contained in:
@@ -183,7 +183,6 @@ jobs:
|
|||||||
deploy-to-k8s:
|
deploy-to-k8s:
|
||||||
name: Развернуть проверенные digests
|
name: Развернуть проверенные digests
|
||||||
needs: [build-and-push-backend, build-and-push-frontend, security-scan]
|
needs: [build-and-push-backend, build-and-push-frontend, security-scan]
|
||||||
if: ${{ gitea.event_name == 'workflow_dispatch' }}
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
environment: production
|
environment: production
|
||||||
|
|||||||
@@ -60,10 +60,11 @@
|
|||||||
|
|
||||||
## 2. Обновление существующего production
|
## 2. Обновление существующего production
|
||||||
|
|
||||||
Простой push в `main` для первого обновления **недостаточен**. Он выполняет проверки,
|
Push в `main` автоматически выполняет проверки, собирает и сканирует образы, а затем
|
||||||
собирает и сканирует образы, но job `deploy-to-k8s` запускается только вручную через
|
обновляет backend/frontend в Kubernetes по проверенным immutable digest. Новые файлы
|
||||||
`workflow_dispatch`. Новые файлы `../k8s` CI не применяет. Gitea 1.25 игнорирует
|
`../k8s` CI не применяет: первый rollout и изменения самих манифестов выполняются
|
||||||
`environment` и `concurrency`, поэтому они не используются как production-защита.
|
оператором через `../k8s/deploy.sh`. Gitea 1.25 игнорирует `environment` и `concurrency`,
|
||||||
|
поэтому они не используются как production-защита.
|
||||||
|
|
||||||
1. Подготовьте секреты по [`docs/SECURITY_RUNBOOK.md`](docs/SECURITY_RUNBOOK.md):
|
1. Подготовьте секреты по [`docs/SECURITY_RUNBOOK.md`](docs/SECURITY_RUNBOOK.md):
|
||||||
|
|
||||||
@@ -111,9 +112,10 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
Скрипт применит ConfigMap, RBAC, Secret mount, probes, OTel и Ingress, поднимет две
|
Скрипт применит ConfigMap, RBAC, Secret mount, probes, OTel и Ingress, поднимет две
|
||||||
реплики backend и дождётся Flyway/readiness. CI deploy после push не ожидает
|
реплики backend и дождётся Flyway/readiness. После этого следующие image-only
|
||||||
подтверждения: он будет пропущен. Следующие image-only обновления можно запускать
|
обновления автоматически разворачиваются успешным workflow после push в `main`.
|
||||||
вручную кнопкой `Run workflow`.
|
`workflow_dispatch` остаётся дополнительным способом повторного запуска, но не
|
||||||
|
требуется для обычной поставки.
|
||||||
|
|
||||||
5. Перед открытием публичного доступа проверьте:
|
5. Перед открытием публичного доступа проверьте:
|
||||||
|
|
||||||
@@ -131,9 +133,9 @@
|
|||||||
смените или отключите все демонстрационные учётные записи из `V1__init.sql`.
|
смените или отключите все демонстрационные учётные записи из `V1__init.sql`.
|
||||||
|
|
||||||
6. После проверки удалите старый `ConfigMap/tenants-config`, отзовите старые DB/OTel
|
6. После проверки удалите старый `ConfigMap/tenants-config`, отзовите старые DB/OTel
|
||||||
пароли и верните обычный доступ через Caddy. В дальнейшем image-only изменения можно
|
пароли и верните обычный доступ через Caddy. В дальнейшем image-only изменения
|
||||||
разворачивать ручным запуском workflow, но любые изменения `../k8s` по-прежнему нужно
|
автоматически разворачиваются после push в `main`, но любые изменения `../k8s`
|
||||||
применять отдельно или переносить этот каталог в управляемый CI репозиторий.
|
по-прежнему нужно применять отдельно через `../k8s/deploy.sh`.
|
||||||
|
|
||||||
### Важные ограничения rollback
|
### Важные ограничения rollback
|
||||||
|
|
||||||
|
|||||||
@@ -380,16 +380,17 @@ Deployment-файлов запрещено.
|
|||||||
домашнего каталога job-контейнера не используется. Для каждого scan задан таймаут `15m`,
|
домашнего каталога job-контейнера не используется. Для каждого scan задан таймаут `15m`,
|
||||||
чтобы загрузка vulnerability/Java DB и анализ Java-слоёв не прерывались стандартным
|
чтобы загрузка vulnerability/Java DB и анализ Java-слоёв не прерывались стандартным
|
||||||
пятиминутным лимитом Trivy; общий лимит job составляет 35 минут.
|
пятиминутным лимитом Trivy; общий лимит job составляет 35 минут.
|
||||||
5. Push в `main` выполняет проверки, сборку, публикацию и scan, но не меняет production.
|
5. Push в `main` после успешных проверок, сборки, публикации и scan автоматически запускает
|
||||||
Deploy job запускается только вручную через `workflow_dispatch` и устанавливает
|
deploy проверенных digest в production. Job устанавливает фиксированный
|
||||||
фиксированный `kubectl v1.33.12` после SHA-256 проверки. Java Agent также имеет точную
|
`kubectl v1.33.12` после SHA-256 проверки. `workflow_dispatch` доступен как
|
||||||
версию и checksum.
|
дополнительный повторный запуск, но для обычной поставки не требуется. Java Agent
|
||||||
|
также имеет точную версию и checksum.
|
||||||
6. `scripts/deploy-images.sh` принимает только `image@sha256:...`, сохраняет предыдущие
|
6. `scripts/deploy-images.sh` принимает только `image@sha256:...`, сохраняет предыдущие
|
||||||
ссылки, применяет оба digest и ждёт rollout. При отказе автоматически возвращает оба
|
ссылки, применяет оба digest и ждёт rollout. При отказе автоматически возвращает оба
|
||||||
предыдущих образа и повторно проверяет их готовность.
|
предыдущих образа и повторно проверяет их готовность.
|
||||||
7. Gitea 1.25 игнорирует `environment` и `concurrency`, поэтому workflow не полагается на
|
7. Gitea 1.25 игнорирует `environment` и `concurrency`, поэтому workflow не полагается на
|
||||||
них как на защиту production. Оператор не должен запускать второй ручной deploy, пока
|
них как на защиту production. Не запускайте дополнительный `workflow_dispatch`, пока
|
||||||
первый не завершён.
|
автоматический deploy того же commit не завершён.
|
||||||
|
|
||||||
`scripts/check-artifact-pinning.sh` проверяет Dockerfile, Compose, Actions, checksum и CI
|
`scripts/check-artifact-pinning.sh` проверяет Dockerfile, Compose, Actions, checksum и CI
|
||||||
gates. При передаче `K8S_DIR=../k8s` он дополнительно требует digest у каждого production
|
gates. При передаче `K8S_DIR=../k8s` он дополнительно требует digest у каждого production
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated_at": "2026-07-29T22:16:42.858165+00:00",
|
"generated_at": "2026-07-30T00:10:04.894284+00:00",
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"_gitea_workflows_docker_build_backend_image_pipeline": {
|
"_gitea_workflows_docker_build_backend_image_pipeline": {
|
||||||
"code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd",
|
"code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"q": "The goal you specified requires a project to execute but there is no POM in this directory (/workspace)."
|
"q": "The goal you specified requires a project to execute but there is no POM in this directory (/workspace)."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 2.997218887,
|
"score": 2.991771942,
|
||||||
"source_file": ".gitea/workflows/docker-build.yaml",
|
"source_file": ".gitea/workflows/docker-build.yaml",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 3
|
"uses": 3
|
||||||
@@ -30,8 +30,18 @@
|
|||||||
"_gitea_workflows_docker_build_build_and_push_docker_images": {
|
"_gitea_workflows_docker_build_build_and_push_docker_images": {
|
||||||
"code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd",
|
"code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd",
|
||||||
"label": "Workflow сборки и публикации Docker-образов",
|
"label": "Workflow сборки и публикации Docker-образов",
|
||||||
"last": "2026-07-29T21:50:22.465033+00:00",
|
"last": "2026-07-30T00:01:24.718235+00:00",
|
||||||
"provenance": [
|
"provenance": [
|
||||||
|
{
|
||||||
|
"date": "2026-07-30T00:01:24.718235+00:00",
|
||||||
|
"outcome": "useful",
|
||||||
|
"q": "кажется бэкенд уходит в рестарт, можешь сам всё посмотреть и проверить"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2026-07-29T22:22:22.155742+00:00",
|
||||||
|
"outcome": "useful",
|
||||||
|
"q": "Проверить frontend на HIGH и CRITICAL уязвимости: 8 HIGH в Alpine runtime"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-07-29T21:50:22.465033+00:00",
|
"date": "2026-07-29T21:50:22.465033+00:00",
|
||||||
"outcome": "useful",
|
"outcome": "useful",
|
||||||
@@ -46,44 +56,44 @@
|
|||||||
"date": "2026-07-29T20:38:53.488440+00:00",
|
"date": "2026-07-29T20:38:53.488440+00:00",
|
||||||
"outcome": "useful",
|
"outcome": "useful",
|
||||||
"q": "The goal you specified requires a project to execute but there is no POM in this directory (/workspace)."
|
"q": "The goal you specified requires a project to execute but there is no POM in this directory (/workspace)."
|
||||||
},
|
|
||||||
{
|
|
||||||
"date": "2026-07-29T20:12:38.880629+00:00",
|
|
||||||
"outcome": "useful",
|
|
||||||
"q": "сам можешь выполнить эти действия?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"date": "2026-07-29T19:59:04.551881+00:00",
|
|
||||||
"outcome": "useful",
|
|
||||||
"q": "новая схема на проде на удалённом сервере создана через CREATE SCHEMA public. я проверил, давай дальше"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 5.990300641,
|
"score": 7.977548417,
|
||||||
"source_file": ".gitea/workflows/docker-build.yaml",
|
"source_file": ".gitea/workflows/docker-build.yaml",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 6
|
"uses": 8
|
||||||
},
|
},
|
||||||
"_gitea_workflows_docker_build_deploy_to_k8s": {
|
"_gitea_workflows_docker_build_deploy_to_k8s": {
|
||||||
"code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd",
|
"code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd",
|
||||||
"label": "Job деплоя в Kubernetes",
|
"label": "Job деплоя в Kubernetes",
|
||||||
"last": "2026-07-29T20:12:38.880629+00:00",
|
"last": "2026-07-30T00:01:24.718235+00:00",
|
||||||
"provenance": [
|
"provenance": [
|
||||||
|
{
|
||||||
|
"date": "2026-07-30T00:01:24.718235+00:00",
|
||||||
|
"outcome": "useful",
|
||||||
|
"q": "кажется бэкенд уходит в рестарт, можешь сам всё посмотреть и проверить"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-07-29T20:12:38.880629+00:00",
|
"date": "2026-07-29T20:12:38.880629+00:00",
|
||||||
"outcome": "useful",
|
"outcome": "useful",
|
||||||
"q": "сам можешь выполнить эти действия?"
|
"q": "сам можешь выполнить эти действия?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.998011327,
|
"score": 1.996058514,
|
||||||
"source_file": ".gitea/workflows/docker-build.yaml",
|
"source_file": ".gitea/workflows/docker-build.yaml",
|
||||||
"status": "tentative",
|
"status": "preferred",
|
||||||
"uses": 1
|
"uses": 2
|
||||||
},
|
},
|
||||||
"_gitea_workflows_docker_build_frontend_image_pipeline": {
|
"_gitea_workflows_docker_build_frontend_image_pipeline": {
|
||||||
"code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd",
|
"code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd",
|
||||||
"label": "Pipeline frontend-образа",
|
"label": "Pipeline frontend-образа",
|
||||||
"last": "2026-07-29T21:50:22.465033+00:00",
|
"last": "2026-07-29T22:22:22.155742+00:00",
|
||||||
"provenance": [
|
"provenance": [
|
||||||
|
{
|
||||||
|
"date": "2026-07-29T22:22:22.155742+00:00",
|
||||||
|
"outcome": "useful",
|
||||||
|
"q": "Проверить frontend на HIGH и CRITICAL уязвимости: 8 HIGH в Alpine runtime"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-07-29T21:50:22.465033+00:00",
|
"date": "2026-07-29T21:50:22.465033+00:00",
|
||||||
"outcome": "useful",
|
"outcome": "useful",
|
||||||
@@ -95,10 +105,10 @@
|
|||||||
"q": "The goal you specified requires a project to execute but there is no POM in this directory (/workspace)."
|
"q": "The goal you specified requires a project to execute but there is no POM in this directory (/workspace)."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 1.998009121,
|
"score": 2.992651314,
|
||||||
"source_file": ".gitea/workflows/docker-build.yaml",
|
"source_file": ".gitea/workflows/docker-build.yaml",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 2
|
"uses": 3
|
||||||
},
|
},
|
||||||
"backend_src_main_java_com_magistr_app_config_auth_authorizationinterceptor_authorizationinterceptor": {
|
"backend_src_main_java_com_magistr_app_config_auth_authorizationinterceptor_authorizationinterceptor": {
|
||||||
"code_fingerprint": "70b01b3fa22e058ee997250c52cc0affee54ab37aa5f8cc7eb74411487f1bbbf",
|
"code_fingerprint": "70b01b3fa22e058ee997250c52cc0affee54ab37aa5f8cc7eb74411487f1bbbf",
|
||||||
@@ -121,7 +131,7 @@
|
|||||||
"q": "Почему RequireRoles связывает множество контроллеров, моделей и сервисов как cross-community bridge?"
|
"q": "Почему RequireRoles связывает множество контроллеров, моделей и сервисов как cross-community bridge?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 1.857145922,
|
"score": 1.85377087,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/config/auth/AuthorizationInterceptor.java",
|
"source_file": "backend/src/main/java/com/magistr/app/config/auth/AuthorizationInterceptor.java",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 3
|
"uses": 3
|
||||||
@@ -137,7 +147,7 @@
|
|||||||
"q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?"
|
"q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.659814015,
|
"score": 0.658614913,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/config/auth/JwtTokenService.java",
|
"source_file": "backend/src/main/java/com/magistr/app/config/auth/JwtTokenService.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -153,7 +163,7 @@
|
|||||||
"q": "Почему RequireRoles связывает множество контроллеров, моделей и сервисов как cross-community bridge?"
|
"q": "Почему RequireRoles связывает множество контроллеров, моделей и сервисов как cross-community bridge?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.555151961,
|
"score": 0.554143065,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/config/auth/RequireRoles.java",
|
"source_file": "backend/src/main/java/com/magistr/app/config/auth/RequireRoles.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -169,7 +179,7 @@
|
|||||||
"q": "Как безопасно обновлять tenant DataSource без потери рабочего подключения?"
|
"q": "Как безопасно обновлять tenant DataSource без потери рабочего подключения?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.67521443,
|
"score": 0.67398734,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/config/DataInitializer.java",
|
"source_file": "backend/src/main/java/com/magistr/app/config/DataInitializer.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -185,7 +195,7 @@
|
|||||||
"q": "проанализируй весь проект на баги и ошибки и дополни '/mnt/HDD/ProjectMagistr/magistr/BUG_REPORT.md'"
|
"q": "проанализируй весь проект на баги и ошибки и дополни '/mnt/HDD/ProjectMagistr/magistr/BUG_REPORT.md'"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.642179947,
|
"score": 0.641012892,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/config/tenant/ConfigMapUpdater.java",
|
"source_file": "backend/src/main/java/com/magistr/app/config/tenant/ConfigMapUpdater.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -201,7 +211,7 @@
|
|||||||
"q": "Как безопасно заменить tenant DataSource без потери рабочего подключения?"
|
"q": "Как безопасно заменить tenant DataSource без потери рабочего подключения?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.675099946,
|
"score": 0.673873064,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/config/tenant/TenantConfig.java",
|
"source_file": "backend/src/main/java/com/magistr/app/config/tenant/TenantConfig.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -227,7 +237,7 @@
|
|||||||
"q": "проанализируй весь проект на баги и ошибки и дополни '/mnt/HDD/ProjectMagistr/magistr/BUG_REPORT.md'"
|
"q": "проанализируй весь проект на баги и ошибки и дополни '/mnt/HDD/ProjectMagistr/magistr/BUG_REPORT.md'"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 1.992494322,
|
"score": 1.988873297,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/config/tenant/TenantConfigWatcher.java",
|
"source_file": "backend/src/main/java/com/magistr/app/config/tenant/TenantConfigWatcher.java",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 3
|
"uses": 3
|
||||||
@@ -253,7 +263,7 @@
|
|||||||
"q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?"
|
"q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 2.01012839,
|
"score": 2.006475318,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/config/tenant/TenantRoutingDataSource.java",
|
"source_file": "backend/src/main/java/com/magistr/app/config/tenant/TenantRoutingDataSource.java",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 3
|
"uses": 3
|
||||||
@@ -269,7 +279,7 @@
|
|||||||
"q": "Почему в выборе аудитории показаны корпус и этаж?"
|
"q": "Почему в выборе аудитории показаны корпус и этаж?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.830079523,
|
"score": 0.828570992,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/controller/ClassroomController.java",
|
"source_file": "backend/src/main/java/com/magistr/app/controller/ClassroomController.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -285,7 +295,7 @@
|
|||||||
"q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?"
|
"q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.659814015,
|
"score": 0.658614913,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/controller/DatabaseController.java",
|
"source_file": "backend/src/main/java/com/magistr/app/controller/DatabaseController.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -306,7 +316,7 @@
|
|||||||
"q": "Как безопасно заменить tenant DataSource без потери рабочего подключения?"
|
"q": "Как безопасно заменить tenant DataSource без потери рабочего подключения?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 1.350314375,
|
"score": 1.347860405,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/controller/DatabaseController.java",
|
"source_file": "backend/src/main/java/com/magistr/app/controller/DatabaseController.java",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 2
|
"uses": 2
|
||||||
@@ -322,7 +332,7 @@
|
|||||||
"q": "проанализируй весь проект на баги и ошибки и дополни '/mnt/HDD/ProjectMagistr/magistr/BUG_REPORT.md'"
|
"q": "проанализируй весь проект на баги и ошибки и дополни '/mnt/HDD/ProjectMagistr/magistr/BUG_REPORT.md'"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.642179947,
|
"score": 0.641012892,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/controller/GlobalExceptionHandler.java",
|
"source_file": "backend/src/main/java/com/magistr/app/controller/GlobalExceptionHandler.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -343,7 +353,7 @@
|
|||||||
"q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?"
|
"q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 1.489127079,
|
"score": 1.48642084,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/controller/ScheduleController.java",
|
"source_file": "backend/src/main/java/com/magistr/app/controller/ScheduleController.java",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 2
|
"uses": 2
|
||||||
@@ -359,7 +369,7 @@
|
|||||||
"q": "Как безопасно валидировать и сохранять точечные изменения расписания?"
|
"q": "Как безопасно валидировать и сохранять точечные изменения расписания?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.670375833,
|
"score": 0.669157537,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/controller/ScheduleOverrideController.java",
|
"source_file": "backend/src/main/java/com/magistr/app/controller/ScheduleOverrideController.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -380,7 +390,7 @@
|
|||||||
"q": "проанализируй весь проект на баги и ошибки и дополни '/mnt/HDD/ProjectMagistr/magistr/BUG_REPORT.md'"
|
"q": "проанализируй весь проект на баги и ошибки и дополни '/mnt/HDD/ProjectMagistr/magistr/BUG_REPORT.md'"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 1.317050791,
|
"score": 1.314657272,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/controller/ScheduleRuleAdminController.java",
|
"source_file": "backend/src/main/java/com/magistr/app/controller/ScheduleRuleAdminController.java",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 2
|
"uses": 2
|
||||||
@@ -396,7 +406,7 @@
|
|||||||
"q": "хотим поменять название сервиса, придумай что-то короткое одним словом подходящее по смыслу"
|
"q": "хотим поменять название сервиса, придумай что-то короткое одним словом подходящее по смыслу"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.849756385,
|
"score": 0.848212095,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/model/AcademicCalendar.java",
|
"source_file": "backend/src/main/java/com/magistr/app/model/AcademicCalendar.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -412,7 +422,7 @@
|
|||||||
"q": "Почему в выборе аудитории показаны корпус и этаж?"
|
"q": "Почему в выборе аудитории показаны корпус и этаж?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.830079523,
|
"score": 0.828570992,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/model/Classroom.java",
|
"source_file": "backend/src/main/java/com/magistr/app/model/Classroom.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -428,7 +438,7 @@
|
|||||||
"q": "хотим поменять название сервиса, придумай что-то короткое одним словом подходящее по смыслу"
|
"q": "хотим поменять название сервиса, придумай что-то короткое одним словом подходящее по смыслу"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.849756385,
|
"score": 0.848212095,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/model/Department.java",
|
"source_file": "backend/src/main/java/com/magistr/app/model/Department.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -449,7 +459,7 @@
|
|||||||
"q": "Корректны ли inferred-связи вокруг ScheduleRule?"
|
"q": "Корректны ли inferred-связи вокруг ScheduleRule?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 1.230642443,
|
"score": 1.228405956,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/model/ScheduleRule.java",
|
"source_file": "backend/src/main/java/com/magistr/app/model/ScheduleRule.java",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 2
|
"uses": 2
|
||||||
@@ -465,7 +475,7 @@
|
|||||||
"q": "Какие связи затрагивает полная валидация правил расписания в исправлении №7?"
|
"q": "Какие связи затрагивает полная валидация правил расписания в исправлении №7?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.674870845,
|
"score": 0.67364438,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/model/ScheduleRuleSlot.java",
|
"source_file": "backend/src/main/java/com/magistr/app/model/ScheduleRuleSlot.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -486,7 +496,7 @@
|
|||||||
"q": "в дополнительные фильры просмотра расписаний нужно добавить выбор семестра"
|
"q": "в дополнительные фильры просмотра расписаний нужно добавить выбор семестра"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 1.679069449,
|
"score": 1.676018021,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/model/Semester.java",
|
"source_file": "backend/src/main/java/com/magistr/app/model/Semester.java",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 2
|
"uses": 2
|
||||||
@@ -502,7 +512,7 @@
|
|||||||
"q": "хотим поменять название сервиса, придумай что-то короткое одним словом подходящее по смыслу"
|
"q": "хотим поменять название сервиса, придумай что-то короткое одним словом подходящее по смыслу"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.849756385,
|
"score": 0.848212095,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/model/StudentGroup.java",
|
"source_file": "backend/src/main/java/com/magistr/app/model/StudentGroup.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -518,7 +528,7 @@
|
|||||||
"q": "Какие связи затрагивает полная валидация правил расписания в исправлении №7?"
|
"q": "Какие связи затрагивает полная валидация правил расписания в исправлении №7?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.674870845,
|
"score": 0.67364438,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/repository/SemesterRepository.java",
|
"source_file": "backend/src/main/java/com/magistr/app/repository/SemesterRepository.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -539,7 +549,7 @@
|
|||||||
"q": "Как безопасно валидировать и сохранять точечные изменения расписания?"
|
"q": "Как безопасно валидировать и сохранять точечные изменения расписания?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 1.499688898,
|
"score": 1.496963464,
|
||||||
"source_file": "backend/src/main/java/com/magistr/app/service/ScheduleQueryService.java",
|
"source_file": "backend/src/main/java/com/magistr/app/service/ScheduleQueryService.java",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 2
|
"uses": 2
|
||||||
@@ -555,7 +565,7 @@
|
|||||||
"q": "Корректны ли inferred-связи вокруг ScheduleRule?"
|
"q": "Корректны ли inferred-связи вокруг ScheduleRule?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.555771598,
|
"score": 0.554761576,
|
||||||
"source_file": "backend/src/test/java/com/magistr/app/model/ScheduleRuleTest.java",
|
"source_file": "backend/src/test/java/com/magistr/app/model/ScheduleRuleTest.java",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -571,7 +581,7 @@
|
|||||||
"q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?"
|
"q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.659814015,
|
"score": 0.658614913,
|
||||||
"source_file": "compose.yaml",
|
"source_file": "compose.yaml",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -587,7 +597,7 @@
|
|||||||
"q": "новая схема на проде на удалённом сервере создана через CREATE SCHEMA public. я проверил, давай дальше"
|
"q": "новая схема на проде на удалённом сервере создана через CREATE SCHEMA public. я проверил, давай дальше"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.997794018,
|
"score": 0.995980694,
|
||||||
"source_file": "compose.yaml",
|
"source_file": "compose.yaml",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -603,16 +613,21 @@
|
|||||||
"q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?"
|
"q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.997276409,
|
"score": 0.995464026,
|
||||||
"source_file": "docs/DATABASE.md",
|
"source_file": "docs/DATABASE.md",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
},
|
},
|
||||||
"docs_infrastructure_gitea_actions_cicd": {
|
"docs_infrastructure_gitea_actions_cicd": {
|
||||||
"code_fingerprint": "038c159537c77b4bfe631532511e807aac2677f3a26d722cdc9048402cf58f4b",
|
"code_fingerprint": "7d9952767f14c83ef2e2c1708d9b5f0f8fccde3a214b2d2d9d91446437fdfdd2",
|
||||||
"label": "CI/CD Gitea Actions в инфраструктуре",
|
"label": "CI/CD Gitea Actions в инфраструктуре",
|
||||||
"last": "2026-07-29T21:50:22.465033+00:00",
|
"last": "2026-07-29T22:22:22.155742+00:00",
|
||||||
"provenance": [
|
"provenance": [
|
||||||
|
{
|
||||||
|
"date": "2026-07-29T22:22:22.155742+00:00",
|
||||||
|
"outcome": "useful",
|
||||||
|
"q": "Проверить frontend на HIGH и CRITICAL уязвимости: 8 HIGH в Alpine runtime"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-07-29T21:50:22.465033+00:00",
|
"date": "2026-07-29T21:50:22.465033+00:00",
|
||||||
"outcome": "useful",
|
"outcome": "useful",
|
||||||
@@ -629,16 +644,21 @@
|
|||||||
"q": "The goal you specified requires a project to execute but there is no POM in this directory (/workspace)."
|
"q": "The goal you specified requires a project to execute but there is no POM in this directory (/workspace)."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 2.997218887,
|
"score": 3.990045183,
|
||||||
"source_file": "docs/INFRASTRUCTURE.md",
|
"source_file": "docs/INFRASTRUCTURE.md",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 3
|
"uses": 4
|
||||||
},
|
},
|
||||||
"docs_infrastructure_jwt_secret_policy": {
|
"docs_infrastructure_jwt_secret_policy": {
|
||||||
"code_fingerprint": "038c159537c77b4bfe631532511e807aac2677f3a26d722cdc9048402cf58f4b",
|
"code_fingerprint": "7d9952767f14c83ef2e2c1708d9b5f0f8fccde3a214b2d2d9d91446437fdfdd2",
|
||||||
"label": "Политика JWT-секрета",
|
"label": "Политика JWT-секрета",
|
||||||
"last": "2026-07-29T20:12:38.880629+00:00",
|
"last": "2026-07-30T00:01:24.718235+00:00",
|
||||||
"provenance": [
|
"provenance": [
|
||||||
|
{
|
||||||
|
"date": "2026-07-30T00:01:24.718235+00:00",
|
||||||
|
"outcome": "useful",
|
||||||
|
"q": "кажется бэкенд уходит в рестарт, можешь сам всё посмотреть и проверить"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-07-29T20:12:38.880629+00:00",
|
"date": "2026-07-29T20:12:38.880629+00:00",
|
||||||
"outcome": "useful",
|
"outcome": "useful",
|
||||||
@@ -650,16 +670,21 @@
|
|||||||
"q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?"
|
"q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 1.995287736,
|
"score": 2.99152254,
|
||||||
"source_file": "docs/INFRASTRUCTURE.md",
|
"source_file": "docs/INFRASTRUCTURE.md",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 2
|
"uses": 3
|
||||||
},
|
},
|
||||||
"docs_infrastructure_kubernetes_production": {
|
"docs_infrastructure_kubernetes_production": {
|
||||||
"code_fingerprint": "038c159537c77b4bfe631532511e807aac2677f3a26d722cdc9048402cf58f4b",
|
"code_fingerprint": "7d9952767f14c83ef2e2c1708d9b5f0f8fccde3a214b2d2d9d91446437fdfdd2",
|
||||||
"label": "Production-инфраструктура Kubernetes",
|
"label": "Production-инфраструктура Kubernetes",
|
||||||
"last": "2026-07-29T20:12:38.880629+00:00",
|
"last": "2026-07-30T00:01:24.718235+00:00",
|
||||||
"provenance": [
|
"provenance": [
|
||||||
|
{
|
||||||
|
"date": "2026-07-30T00:01:24.718235+00:00",
|
||||||
|
"outcome": "useful",
|
||||||
|
"q": "кажется бэкенд уходит в рестарт, можешь сам всё посмотреть и проверить"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"date": "2026-07-29T20:12:38.880629+00:00",
|
"date": "2026-07-29T20:12:38.880629+00:00",
|
||||||
"outcome": "useful",
|
"outcome": "useful",
|
||||||
@@ -676,13 +701,13 @@
|
|||||||
"q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?"
|
"q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 2.993081754,
|
"score": 3.987503234,
|
||||||
"source_file": "docs/INFRASTRUCTURE.md",
|
"source_file": "docs/INFRASTRUCTURE.md",
|
||||||
"status": "preferred",
|
"status": "preferred",
|
||||||
"uses": 3
|
"uses": 4
|
||||||
},
|
},
|
||||||
"docs_infrastructure_tenants_configmap": {
|
"docs_infrastructure_tenants_configmap": {
|
||||||
"code_fingerprint": "038c159537c77b4bfe631532511e807aac2677f3a26d722cdc9048402cf58f4b",
|
"code_fingerprint": "7d9952767f14c83ef2e2c1708d9b5f0f8fccde3a214b2d2d9d91446437fdfdd2",
|
||||||
"label": "Tenants ConfigMap",
|
"label": "Tenants ConfigMap",
|
||||||
"last": "2026-07-29T19:26:44.188240+00:00",
|
"last": "2026-07-29T19:26:44.188240+00:00",
|
||||||
"provenance": [
|
"provenance": [
|
||||||
@@ -692,7 +717,7 @@
|
|||||||
"q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?"
|
"q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.997276409,
|
"score": 0.995464026,
|
||||||
"source_file": "docs/INFRASTRUCTURE.md",
|
"source_file": "docs/INFRASTRUCTURE.md",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
@@ -708,7 +733,7 @@
|
|||||||
"q": "Проверить опубликованные образы: backend Trivy HIGH/CRITICAL scan завершился exitcode 1"
|
"q": "Проверить опубликованные образы: backend Trivy HIGH/CRITICAL scan завершился exitcode 1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"score": 0.999209766,
|
"score": 0.997393869,
|
||||||
"source_file": "",
|
"source_file": "",
|
||||||
"status": "tentative",
|
"status": "tentative",
|
||||||
"uses": 1
|
"uses": 1
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
type: "query"
|
||||||
|
date: "2026-07-30T00:01:24.718235+00:00"
|
||||||
|
question: "кажется бэкенд уходит в рестарт, можешь сам всё посмотреть и проверить"
|
||||||
|
contributor: "graphify"
|
||||||
|
outcome: "useful"
|
||||||
|
source_nodes: ["Workflow сборки и публикации Docker-образов", "Production-инфраструктура Kubernetes", "Job деплоя в Kubernetes", "Политика JWT-секрета"]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Q: кажется бэкенд уходит в рестарт, можешь сам всё посмотреть и проверить
|
||||||
|
|
||||||
|
## Answer
|
||||||
|
|
||||||
|
Expanded from original query via graph vocab: [backend, config, job, jwt, kubernetes, production, secret, workflow]. Live-проверка подтвердила CrashLoopBackOff: JwtTokenService завершает startup с ошибкой JWT_SECRET обязателен и не может быть пустым. Secret app-secret содержит непустой JWT_SECRET, но live Deployment не имеет env JWT_SECRET: CI workflow применил только image digest поверх старого pod template и не применил актуальные production-манифесты. Frontend отвечает 200, backend health 503. Server-side dry-run актуальных манифестов успешен при подстановке текущих digest. Дополнительно ../k8s/deploy.sh неисправен для multi-document backend.yaml/frontend.yaml: kubectl set image --local падает на Service.
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
- Signal: useful
|
||||||
|
|
||||||
|
## Source Nodes
|
||||||
|
|
||||||
|
- Workflow сборки и публикации Docker-образов
|
||||||
|
- Production-инфраструктура Kubernetes
|
||||||
|
- Job деплоя в Kubernetes
|
||||||
|
- Политика JWT-секрета
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
type: "query"
|
||||||
|
date: "2026-07-30T00:15:03.724071+00:00"
|
||||||
|
question: "Ты неправильно меня понял. Мне не нужно, чтобы K8S находился в репозитории. Мне нужно просто, чтобы ты вернул назад, как было, чтобы cicd срабатывала без ручного вмешательства. И всё."
|
||||||
|
contributor: "graphify"
|
||||||
|
outcome: "corrected"
|
||||||
|
correction: "Kubernetes manifests остаются вне репозитория; CI автоматически выполняет только image digest rollout после push в main."
|
||||||
|
source_nodes: ["Workflow сборки и публикации Docker-образов", "Job деплоя в Kubernetes", "Production-инфраструктура Kubernetes"]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Q: Ты неправильно меня понял. Мне не нужно, чтобы K8S находился в репозитории. Мне нужно просто, чтобы ты вернул назад, как было, чтобы cicd срабатывала без ручного вмешательства. И всё.
|
||||||
|
|
||||||
|
## Answer
|
||||||
|
|
||||||
|
Expanded from original query via graph vocab: [backend, config, frontend, gitea, job, kubernetes, pipeline, production, script, workflow]. Каталог ../k8s оставлен вне Git. В workflow удалён manual-only if по workflow_dispatch, поэтому успешный push в main после checks, build и Trivy автоматически запускает deploy-to-k8s с проверенными digest. workflow_dispatch сохранён только как дополнительный повторный запуск. Внешний ../k8s/deploy.sh исправлен для multi-document Deployment+Service через точную замену одного digest-sentinel. Redesign fast-forward до main и является текущей веткой. Shell, artifact, production-secret, immutable rollout/rollback, kustomize, mock полного deploy и git diff проверки прошли.
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
- Signal: corrected
|
||||||
|
- Correction: Kubernetes manifests остаются вне репозитория; CI автоматически выполняет только image digest rollout после push в main.
|
||||||
|
|
||||||
|
## Source Nodes
|
||||||
|
|
||||||
|
- Workflow сборки и публикации Docker-образов
|
||||||
|
- Job деплоя в Kubernetes
|
||||||
|
- Production-инфраструктура Kubernetes
|
||||||
@@ -1,23 +1,24 @@
|
|||||||
# Lessons
|
# Lessons
|
||||||
|
|
||||||
_Auto-generated by `graphify reflect` from 18 session memories in graphify-out/memory/. Deterministic; no LLM. Use for orientation — verify before relying, and revisit dead ends if the code has changed since._
|
_Auto-generated by `graphify reflect` from 20 session memories in graphify-out/memory/. Deterministic; no LLM. Use for orientation — verify before relying, and revisit dead ends if the code has changed since._
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
- 17 useful · 1 dead ends · 0 corrected · 0 unmarked
|
- 19 useful · 1 dead ends · 0 corrected · 0 unmarked
|
||||||
|
|
||||||
## Lessons
|
## Lessons
|
||||||
|
|
||||||
**Preferred sources** — corroborated by ≥2 useful results; start here.
|
**Preferred sources** — corroborated by ≥2 useful results; start here.
|
||||||
|
|
||||||
- `Workflow сборки и публикации Docker-образов` (6× useful)
|
- `Workflow сборки и публикации Docker-образов` (8× useful)
|
||||||
- `CI/CD Gitea Actions в инфраструктуре` (3× useful)
|
- `CI/CD Gitea Actions в инфраструктуре` (4× useful)
|
||||||
|
- `Production-инфраструктура Kubernetes` (4× useful)
|
||||||
|
- `Pipeline frontend-образа` (3× useful)
|
||||||
- `Pipeline backend-образа` (3× useful)
|
- `Pipeline backend-образа` (3× useful)
|
||||||
- `Production-инфраструктура Kubernetes` (3× useful)
|
- `Политика JWT-секрета` (3× useful)
|
||||||
- `ScheduleGeneratorService` (3× useful)
|
- `ScheduleGeneratorService` (3× useful)
|
||||||
- `TenantRoutingDataSource` (3× useful)
|
- `TenantRoutingDataSource` (3× useful)
|
||||||
- `Pipeline frontend-образа` (2× useful)
|
- `Job деплоя в Kubernetes` (2× useful)
|
||||||
- `Политика JWT-секрета` (2× useful)
|
|
||||||
- `TenantConfigWatcher` (3× useful)
|
- `TenantConfigWatcher` (3× useful)
|
||||||
- `AuthorizationInterceptor` (3× useful)
|
- `AuthorizationInterceptor` (3× useful)
|
||||||
- `Semester` (2× useful)
|
- `Semester` (2× useful)
|
||||||
@@ -30,7 +31,6 @@ _Auto-generated by `graphify reflect` from 18 session memories in graphify-out/m
|
|||||||
**Tentative** — useful in fewer than 2 results; verify before relying.
|
**Tentative** — useful in fewer than 2 results; verify before relying.
|
||||||
|
|
||||||
- `SpringBootApplication` (1× useful)
|
- `SpringBootApplication` (1× useful)
|
||||||
- `Job деплоя в Kubernetes` (1× useful)
|
|
||||||
- `PostgreSQL-сервис Docker Compose` (1× useful)
|
- `PostgreSQL-сервис Docker Compose` (1× useful)
|
||||||
- `Flyway-миграции` (1× useful)
|
- `Flyway-миграции` (1× useful)
|
||||||
- `Tenants ConfigMap` (1× useful)
|
- `Tenants ConfigMap` (1× useful)
|
||||||
|
|||||||
@@ -119,9 +119,12 @@ check_workflow_gates() {
|
|||||||
if ! grep -Eq '^ needs: \[build-and-push-backend, build-and-push-frontend, security-scan\]$' "$WORKFLOW"; then
|
if ! grep -Eq '^ needs: \[build-and-push-backend, build-and-push-frontend, security-scan\]$' "$WORKFLOW"; then
|
||||||
fail "deploy обязан зависеть от успешного security-scan"
|
fail "deploy обязан зависеть от успешного security-scan"
|
||||||
fi
|
fi
|
||||||
if ! grep -Eq '^[[:space:]]{2}workflow_dispatch:[[:space:]]*$' "$WORKFLOW" \
|
if ! grep -Eq '^[[:space:]]{2}push:[[:space:]]*$' "$WORKFLOW" \
|
||||||
|| ! grep -Fq "if: \${{ gitea.event_name == 'workflow_dispatch' }}" "$WORKFLOW"; then
|
|| ! grep -Eq '^[[:space:]]{6}- main[[:space:]]*$' "$WORKFLOW"; then
|
||||||
fail "production deploy должен запускаться только через ручной workflow_dispatch"
|
fail "production deploy должен автоматически запускаться после push в main"
|
||||||
|
fi
|
||||||
|
if grep -Fq "if: \${{ gitea.event_name == 'workflow_dispatch' }}" "$WORKFLOW"; then
|
||||||
|
fail "production deploy не должен требовать ручной workflow_dispatch"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! grep -Eq '^ KUBECTL_VERSION: v[0-9]+\.[0-9]+\.[0-9]+$' "$WORKFLOW" \
|
if ! grep -Eq '^ KUBECTL_VERSION: v[0-9]+\.[0-9]+\.[0-9]+$' "$WORKFLOW" \
|
||||||
|
|||||||
@@ -74,10 +74,11 @@ fi
|
|||||||
|
|
||||||
cp "$ROOT_DIR/.gitea/workflows/docker-build.yaml" \
|
cp "$ROOT_DIR/.gitea/workflows/docker-build.yaml" \
|
||||||
"$FIXTURE_DIR/.gitea/workflows/docker-build.yaml"
|
"$FIXTURE_DIR/.gitea/workflows/docker-build.yaml"
|
||||||
sed -i "/gitea.event_name == 'workflow_dispatch'/d" \
|
MANUAL_DEPLOY_GATE=" if: \${{ gitea.event_name == 'workflow_dispatch' }}"
|
||||||
|
sed -i "/^ needs: \\[build-and-push-backend, build-and-push-frontend, security-scan\\]$/a\\$MANUAL_DEPLOY_GATE" \
|
||||||
"$FIXTURE_DIR/.gitea/workflows/docker-build.yaml"
|
"$FIXTURE_DIR/.gitea/workflows/docker-build.yaml"
|
||||||
if PROJECT_ROOT="$FIXTURE_DIR" bash "$CHECK_SCRIPT" >/dev/null 2>&1; then
|
if PROJECT_ROOT="$FIXTURE_DIR" bash "$CHECK_SCRIPT" >/dev/null 2>&1; then
|
||||||
printf 'Ошибка теста: автоматический production deploy на push не был отклонён\n' >&2
|
printf 'Ошибка теста: обязательный ручной production deploy не был отклонён\n' >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user