From 87f3d98621a1cd28dc378a39de7686444af2b793 Mon Sep 17 00:00:00 2001 From: Zuev Date: Thu, 30 Jul 2026 03:18:43 +0300 Subject: [PATCH] / --- .gitea/workflows/docker-build.yaml | 1 - STARTUP_GUIDE.md | 22 +-- docs/INFRASTRUCTURE.md | 13 +- graphify-out/.graphify_learning.json | 155 ++++++++++-------- ...�я_бэкенд_уходит_в_рестарт__можешь_сам_всё_по.md | 25 +++ ...равильно_меня_понял__мне_не_нужно__чтобы_k8s.md | 26 +++ graphify-out/reflections/LESSONS.md | 16 +- scripts/check-artifact-pinning.sh | 9 +- scripts/test-artifact-pinning.sh | 5 +- 9 files changed, 177 insertions(+), 95 deletions(-) create mode 100644 graphify-out/memory/query_20260730_000124_кажется_бэкенд_уходит_в_рестарт__можешь_сам_всё_по.md create mode 100644 graphify-out/memory/query_20260730_001503_ты_неправильно_меня_понял__мне_не_нужно__чтобы_k8s.md diff --git a/.gitea/workflows/docker-build.yaml b/.gitea/workflows/docker-build.yaml index 27271af..5821cf2 100644 --- a/.gitea/workflows/docker-build.yaml +++ b/.gitea/workflows/docker-build.yaml @@ -183,7 +183,6 @@ jobs: deploy-to-k8s: name: Развернуть проверенные digests needs: [build-and-push-backend, build-and-push-frontend, security-scan] - if: ${{ gitea.event_name == 'workflow_dispatch' }} runs-on: ubuntu-latest timeout-minutes: 15 environment: production diff --git a/STARTUP_GUIDE.md b/STARTUP_GUIDE.md index 5a7a85d..7937139 100644 --- a/STARTUP_GUIDE.md +++ b/STARTUP_GUIDE.md @@ -60,10 +60,11 @@ ## 2. Обновление существующего production -Простой push в `main` для первого обновления **недостаточен**. Он выполняет проверки, -собирает и сканирует образы, но job `deploy-to-k8s` запускается только вручную через -`workflow_dispatch`. Новые файлы `../k8s` CI не применяет. Gitea 1.25 игнорирует -`environment` и `concurrency`, поэтому они не используются как production-защита. +Push в `main` автоматически выполняет проверки, собирает и сканирует образы, а затем +обновляет backend/frontend в Kubernetes по проверенным immutable digest. Новые файлы +`../k8s` CI не применяет: первый rollout и изменения самих манифестов выполняются +оператором через `../k8s/deploy.sh`. Gitea 1.25 игнорирует `environment` и `concurrency`, +поэтому они не используются как production-защита. 1. Подготовьте секреты по [`docs/SECURITY_RUNBOOK.md`](docs/SECURITY_RUNBOOK.md): @@ -111,9 +112,10 @@ ``` Скрипт применит ConfigMap, RBAC, Secret mount, probes, OTel и Ingress, поднимет две - реплики backend и дождётся Flyway/readiness. CI deploy после push не ожидает - подтверждения: он будет пропущен. Следующие image-only обновления можно запускать - вручную кнопкой `Run workflow`. + реплики backend и дождётся Flyway/readiness. После этого следующие image-only + обновления автоматически разворачиваются успешным workflow после push в `main`. + `workflow_dispatch` остаётся дополнительным способом повторного запуска, но не + требуется для обычной поставки. 5. Перед открытием публичного доступа проверьте: @@ -131,9 +133,9 @@ смените или отключите все демонстрационные учётные записи из `V1__init.sql`. 6. После проверки удалите старый `ConfigMap/tenants-config`, отзовите старые DB/OTel - пароли и верните обычный доступ через Caddy. В дальнейшем image-only изменения можно - разворачивать ручным запуском workflow, но любые изменения `../k8s` по-прежнему нужно - применять отдельно или переносить этот каталог в управляемый CI репозиторий. + пароли и верните обычный доступ через Caddy. В дальнейшем image-only изменения + автоматически разворачиваются после push в `main`, но любые изменения `../k8s` + по-прежнему нужно применять отдельно через `../k8s/deploy.sh`. ### Важные ограничения rollback diff --git a/docs/INFRASTRUCTURE.md b/docs/INFRASTRUCTURE.md index 2f3e3cf..49c8645 100644 --- a/docs/INFRASTRUCTURE.md +++ b/docs/INFRASTRUCTURE.md @@ -380,16 +380,17 @@ Deployment-файлов запрещено. домашнего каталога job-контейнера не используется. Для каждого scan задан таймаут `15m`, чтобы загрузка vulnerability/Java DB и анализ Java-слоёв не прерывались стандартным пятиминутным лимитом Trivy; общий лимит job составляет 35 минут. -5. Push в `main` выполняет проверки, сборку, публикацию и scan, но не меняет production. - Deploy job запускается только вручную через `workflow_dispatch` и устанавливает - фиксированный `kubectl v1.33.12` после SHA-256 проверки. Java Agent также имеет точную - версию и checksum. +5. Push в `main` после успешных проверок, сборки, публикации и scan автоматически запускает + deploy проверенных digest в production. Job устанавливает фиксированный + `kubectl v1.33.12` после SHA-256 проверки. `workflow_dispatch` доступен как + дополнительный повторный запуск, но для обычной поставки не требуется. Java Agent + также имеет точную версию и checksum. 6. `scripts/deploy-images.sh` принимает только `image@sha256:...`, сохраняет предыдущие ссылки, применяет оба digest и ждёт rollout. При отказе автоматически возвращает оба предыдущих образа и повторно проверяет их готовность. 7. Gitea 1.25 игнорирует `environment` и `concurrency`, поэтому workflow не полагается на - них как на защиту production. Оператор не должен запускать второй ручной deploy, пока - первый не завершён. + них как на защиту production. Не запускайте дополнительный `workflow_dispatch`, пока + автоматический deploy того же commit не завершён. `scripts/check-artifact-pinning.sh` проверяет Dockerfile, Compose, Actions, checksum и CI gates. При передаче `K8S_DIR=../k8s` он дополнительно требует digest у каждого production diff --git a/graphify-out/.graphify_learning.json b/graphify-out/.graphify_learning.json index bfa022e..a44deeb 100644 --- a/graphify-out/.graphify_learning.json +++ b/graphify-out/.graphify_learning.json @@ -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": { "_gitea_workflows_docker_build_backend_image_pipeline": { "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)." } ], - "score": 2.997218887, + "score": 2.991771942, "source_file": ".gitea/workflows/docker-build.yaml", "status": "preferred", "uses": 3 @@ -30,8 +30,18 @@ "_gitea_workflows_docker_build_build_and_push_docker_images": { "code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd", "label": "Workflow сборки и публикации Docker-образов", - "last": "2026-07-29T21:50:22.465033+00:00", + "last": "2026-07-30T00:01:24.718235+00:00", "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", "outcome": "useful", @@ -46,44 +56,44 @@ "date": "2026-07-29T20:38:53.488440+00:00", "outcome": "useful", "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", "status": "preferred", - "uses": 6 + "uses": 8 }, "_gitea_workflows_docker_build_deploy_to_k8s": { "code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd", "label": "Job деплоя в Kubernetes", - "last": "2026-07-29T20:12:38.880629+00:00", + "last": "2026-07-30T00:01:24.718235+00:00", "provenance": [ + { + "date": "2026-07-30T00:01:24.718235+00:00", + "outcome": "useful", + "q": "кажется бэкенд уходит в рестарт, можешь сам всё посмотреть и проверить" + }, { "date": "2026-07-29T20:12:38.880629+00:00", "outcome": "useful", "q": "сам можешь выполнить эти действия?" } ], - "score": 0.998011327, + "score": 1.996058514, "source_file": ".gitea/workflows/docker-build.yaml", - "status": "tentative", - "uses": 1 + "status": "preferred", + "uses": 2 }, "_gitea_workflows_docker_build_frontend_image_pipeline": { "code_fingerprint": "3b51aee192b5af2b63ee1b7f62beca1b4524fbbd2b143c9bd29eb039db90f7bd", "label": "Pipeline frontend-образа", - "last": "2026-07-29T21:50:22.465033+00:00", + "last": "2026-07-29T22:22:22.155742+00:00", "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", "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)." } ], - "score": 1.998009121, + "score": 2.992651314, "source_file": ".gitea/workflows/docker-build.yaml", "status": "preferred", - "uses": 2 + "uses": 3 }, "backend_src_main_java_com_magistr_app_config_auth_authorizationinterceptor_authorizationinterceptor": { "code_fingerprint": "70b01b3fa22e058ee997250c52cc0affee54ab37aa5f8cc7eb74411487f1bbbf", @@ -121,7 +131,7 @@ "q": "Почему RequireRoles связывает множество контроллеров, моделей и сервисов как cross-community bridge?" } ], - "score": 1.857145922, + "score": 1.85377087, "source_file": "backend/src/main/java/com/magistr/app/config/auth/AuthorizationInterceptor.java", "status": "preferred", "uses": 3 @@ -137,7 +147,7 @@ "q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?" } ], - "score": 0.659814015, + "score": 0.658614913, "source_file": "backend/src/main/java/com/magistr/app/config/auth/JwtTokenService.java", "status": "tentative", "uses": 1 @@ -153,7 +163,7 @@ "q": "Почему RequireRoles связывает множество контроллеров, моделей и сервисов как cross-community bridge?" } ], - "score": 0.555151961, + "score": 0.554143065, "source_file": "backend/src/main/java/com/magistr/app/config/auth/RequireRoles.java", "status": "tentative", "uses": 1 @@ -169,7 +179,7 @@ "q": "Как безопасно обновлять tenant DataSource без потери рабочего подключения?" } ], - "score": 0.67521443, + "score": 0.67398734, "source_file": "backend/src/main/java/com/magistr/app/config/DataInitializer.java", "status": "tentative", "uses": 1 @@ -185,7 +195,7 @@ "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", "status": "tentative", "uses": 1 @@ -201,7 +211,7 @@ "q": "Как безопасно заменить tenant DataSource без потери рабочего подключения?" } ], - "score": 0.675099946, + "score": 0.673873064, "source_file": "backend/src/main/java/com/magistr/app/config/tenant/TenantConfig.java", "status": "tentative", "uses": 1 @@ -227,7 +237,7 @@ "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", "status": "preferred", "uses": 3 @@ -253,7 +263,7 @@ "q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?" } ], - "score": 2.01012839, + "score": 2.006475318, "source_file": "backend/src/main/java/com/magistr/app/config/tenant/TenantRoutingDataSource.java", "status": "preferred", "uses": 3 @@ -269,7 +279,7 @@ "q": "Почему в выборе аудитории показаны корпус и этаж?" } ], - "score": 0.830079523, + "score": 0.828570992, "source_file": "backend/src/main/java/com/magistr/app/controller/ClassroomController.java", "status": "tentative", "uses": 1 @@ -285,7 +295,7 @@ "q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?" } ], - "score": 0.659814015, + "score": 0.658614913, "source_file": "backend/src/main/java/com/magistr/app/controller/DatabaseController.java", "status": "tentative", "uses": 1 @@ -306,7 +316,7 @@ "q": "Как безопасно заменить tenant DataSource без потери рабочего подключения?" } ], - "score": 1.350314375, + "score": 1.347860405, "source_file": "backend/src/main/java/com/magistr/app/controller/DatabaseController.java", "status": "preferred", "uses": 2 @@ -322,7 +332,7 @@ "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", "status": "tentative", "uses": 1 @@ -343,7 +353,7 @@ "q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?" } ], - "score": 1.489127079, + "score": 1.48642084, "source_file": "backend/src/main/java/com/magistr/app/controller/ScheduleController.java", "status": "preferred", "uses": 2 @@ -359,7 +369,7 @@ "q": "Как безопасно валидировать и сохранять точечные изменения расписания?" } ], - "score": 0.670375833, + "score": 0.669157537, "source_file": "backend/src/main/java/com/magistr/app/controller/ScheduleOverrideController.java", "status": "tentative", "uses": 1 @@ -380,7 +390,7 @@ "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", "status": "preferred", "uses": 2 @@ -396,7 +406,7 @@ "q": "хотим поменять название сервиса, придумай что-то короткое одним словом подходящее по смыслу" } ], - "score": 0.849756385, + "score": 0.848212095, "source_file": "backend/src/main/java/com/magistr/app/model/AcademicCalendar.java", "status": "tentative", "uses": 1 @@ -412,7 +422,7 @@ "q": "Почему в выборе аудитории показаны корпус и этаж?" } ], - "score": 0.830079523, + "score": 0.828570992, "source_file": "backend/src/main/java/com/magistr/app/model/Classroom.java", "status": "tentative", "uses": 1 @@ -428,7 +438,7 @@ "q": "хотим поменять название сервиса, придумай что-то короткое одним словом подходящее по смыслу" } ], - "score": 0.849756385, + "score": 0.848212095, "source_file": "backend/src/main/java/com/magistr/app/model/Department.java", "status": "tentative", "uses": 1 @@ -449,7 +459,7 @@ "q": "Корректны ли inferred-связи вокруг ScheduleRule?" } ], - "score": 1.230642443, + "score": 1.228405956, "source_file": "backend/src/main/java/com/magistr/app/model/ScheduleRule.java", "status": "preferred", "uses": 2 @@ -465,7 +475,7 @@ "q": "Какие связи затрагивает полная валидация правил расписания в исправлении №7?" } ], - "score": 0.674870845, + "score": 0.67364438, "source_file": "backend/src/main/java/com/magistr/app/model/ScheduleRuleSlot.java", "status": "tentative", "uses": 1 @@ -486,7 +496,7 @@ "q": "в дополнительные фильры просмотра расписаний нужно добавить выбор семестра" } ], - "score": 1.679069449, + "score": 1.676018021, "source_file": "backend/src/main/java/com/magistr/app/model/Semester.java", "status": "preferred", "uses": 2 @@ -502,7 +512,7 @@ "q": "хотим поменять название сервиса, придумай что-то короткое одним словом подходящее по смыслу" } ], - "score": 0.849756385, + "score": 0.848212095, "source_file": "backend/src/main/java/com/magistr/app/model/StudentGroup.java", "status": "tentative", "uses": 1 @@ -518,7 +528,7 @@ "q": "Какие связи затрагивает полная валидация правил расписания в исправлении №7?" } ], - "score": 0.674870845, + "score": 0.67364438, "source_file": "backend/src/main/java/com/magistr/app/repository/SemesterRepository.java", "status": "tentative", "uses": 1 @@ -539,7 +549,7 @@ "q": "Как безопасно валидировать и сохранять точечные изменения расписания?" } ], - "score": 1.499688898, + "score": 1.496963464, "source_file": "backend/src/main/java/com/magistr/app/service/ScheduleQueryService.java", "status": "preferred", "uses": 2 @@ -555,7 +565,7 @@ "q": "Корректны ли inferred-связи вокруг ScheduleRule?" } ], - "score": 0.555771598, + "score": 0.554761576, "source_file": "backend/src/test/java/com/magistr/app/model/ScheduleRuleTest.java", "status": "tentative", "uses": 1 @@ -571,7 +581,7 @@ "q": "Какие подсистемы связывают исправления аутентификации, tenant-конфигурации, расписания и инфраструктуры?" } ], - "score": 0.659814015, + "score": 0.658614913, "source_file": "compose.yaml", "status": "tentative", "uses": 1 @@ -587,7 +597,7 @@ "q": "новая схема на проде на удалённом сервере создана через CREATE SCHEMA public. я проверил, давай дальше" } ], - "score": 0.997794018, + "score": 0.995980694, "source_file": "compose.yaml", "status": "tentative", "uses": 1 @@ -603,16 +613,21 @@ "q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?" } ], - "score": 0.997276409, + "score": 0.995464026, "source_file": "docs/DATABASE.md", "status": "tentative", "uses": 1 }, "docs_infrastructure_gitea_actions_cicd": { - "code_fingerprint": "038c159537c77b4bfe631532511e807aac2677f3a26d722cdc9048402cf58f4b", + "code_fingerprint": "7d9952767f14c83ef2e2c1708d9b5f0f8fccde3a214b2d2d9d91446437fdfdd2", "label": "CI/CD Gitea Actions в инфраструктуре", - "last": "2026-07-29T21:50:22.465033+00:00", + "last": "2026-07-29T22:22:22.155742+00:00", "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", "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)." } ], - "score": 2.997218887, + "score": 3.990045183, "source_file": "docs/INFRASTRUCTURE.md", "status": "preferred", - "uses": 3 + "uses": 4 }, "docs_infrastructure_jwt_secret_policy": { - "code_fingerprint": "038c159537c77b4bfe631532511e807aac2677f3a26d722cdc9048402cf58f4b", + "code_fingerprint": "7d9952767f14c83ef2e2c1708d9b5f0f8fccde3a214b2d2d9d91446437fdfdd2", "label": "Политика JWT-секрета", - "last": "2026-07-29T20:12:38.880629+00:00", + "last": "2026-07-30T00:01:24.718235+00:00", "provenance": [ + { + "date": "2026-07-30T00:01:24.718235+00:00", + "outcome": "useful", + "q": "кажется бэкенд уходит в рестарт, можешь сам всё посмотреть и проверить" + }, { "date": "2026-07-29T20:12:38.880629+00:00", "outcome": "useful", @@ -650,16 +670,21 @@ "q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?" } ], - "score": 1.995287736, + "score": 2.99152254, "source_file": "docs/INFRASTRUCTURE.md", "status": "preferred", - "uses": 2 + "uses": 3 }, "docs_infrastructure_kubernetes_production": { - "code_fingerprint": "038c159537c77b4bfe631532511e807aac2677f3a26d722cdc9048402cf58f4b", + "code_fingerprint": "7d9952767f14c83ef2e2c1708d9b5f0f8fccde3a214b2d2d9d91446437fdfdd2", "label": "Production-инфраструктура Kubernetes", - "last": "2026-07-29T20:12:38.880629+00:00", + "last": "2026-07-30T00:01:24.718235+00:00", "provenance": [ + { + "date": "2026-07-30T00:01:24.718235+00:00", + "outcome": "useful", + "q": "кажется бэкенд уходит в рестарт, можешь сам всё посмотреть и проверить" + }, { "date": "2026-07-29T20:12:38.880629+00:00", "outcome": "useful", @@ -676,13 +701,13 @@ "q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?" } ], - "score": 2.993081754, + "score": 3.987503234, "source_file": "docs/INFRASTRUCTURE.md", "status": "preferred", - "uses": 3 + "uses": 4 }, "docs_infrastructure_tenants_configmap": { - "code_fingerprint": "038c159537c77b4bfe631532511e807aac2677f3a26d722cdc9048402cf58f4b", + "code_fingerprint": "7d9952767f14c83ef2e2c1708d9b5f0f8fccde3a214b2d2d9d91446437fdfdd2", "label": "Tenants ConfigMap", "last": "2026-07-29T19:26:44.188240+00:00", "provenance": [ @@ -692,7 +717,7 @@ "q": "теперь напиши мне инструкцию как это всё выыкатить на прод. у мня уже поднят на проде этот сервис со старой базой данных, но я могу её затереть. ci/cd тоже настроен, по сути я прямо сейчас могу залить это в ветку мейн и оно должно раскататься. каие есть подводные камни после изменений безопасности которые мы внесли?" } ], - "score": 0.997276409, + "score": 0.995464026, "source_file": "docs/INFRASTRUCTURE.md", "status": "tentative", "uses": 1 @@ -708,7 +733,7 @@ "q": "Проверить опубликованные образы: backend Trivy HIGH/CRITICAL scan завершился exitcode 1" } ], - "score": 0.999209766, + "score": 0.997393869, "source_file": "", "status": "tentative", "uses": 1 diff --git a/graphify-out/memory/query_20260730_000124_кажется_бэкенд_уходит_в_рестарт__можешь_сам_всё_по.md b/graphify-out/memory/query_20260730_000124_кажется_бэкенд_уходит_в_рестарт__можешь_сам_всё_по.md new file mode 100644 index 0000000..2dd7b28 --- /dev/null +++ b/graphify-out/memory/query_20260730_000124_кажется_бэкенд_уходит_в_рестарт__можешь_сам_всё_по.md @@ -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-секрета \ No newline at end of file diff --git a/graphify-out/memory/query_20260730_001503_ты_неправильно_меня_понял__мне_не_нужно__чтобы_k8s.md b/graphify-out/memory/query_20260730_001503_ты_неправильно_меня_понял__мне_не_нужно__чтобы_k8s.md new file mode 100644 index 0000000..c7896d6 --- /dev/null +++ b/graphify-out/memory/query_20260730_001503_ты_неправильно_меня_понял__мне_не_нужно__чтобы_k8s.md @@ -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 \ No newline at end of file diff --git a/graphify-out/reflections/LESSONS.md b/graphify-out/reflections/LESSONS.md index 05d1e56..04facc4 100644 --- a/graphify-out/reflections/LESSONS.md +++ b/graphify-out/reflections/LESSONS.md @@ -1,23 +1,24 @@ # 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 -- 17 useful · 1 dead ends · 0 corrected · 0 unmarked +- 19 useful · 1 dead ends · 0 corrected · 0 unmarked ## Lessons **Preferred sources** — corroborated by ≥2 useful results; start here. -- `Workflow сборки и публикации Docker-образов` (6× useful) -- `CI/CD Gitea Actions в инфраструктуре` (3× useful) +- `Workflow сборки и публикации Docker-образов` (8× useful) +- `CI/CD Gitea Actions в инфраструктуре` (4× useful) +- `Production-инфраструктура Kubernetes` (4× useful) +- `Pipeline frontend-образа` (3× useful) - `Pipeline backend-образа` (3× useful) -- `Production-инфраструктура Kubernetes` (3× useful) +- `Политика JWT-секрета` (3× useful) - `ScheduleGeneratorService` (3× useful) - `TenantRoutingDataSource` (3× useful) -- `Pipeline frontend-образа` (2× useful) -- `Политика JWT-секрета` (2× useful) +- `Job деплоя в Kubernetes` (2× useful) - `TenantConfigWatcher` (3× useful) - `AuthorizationInterceptor` (3× 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. - `SpringBootApplication` (1× useful) -- `Job деплоя в Kubernetes` (1× useful) - `PostgreSQL-сервис Docker Compose` (1× useful) - `Flyway-миграции` (1× useful) - `Tenants ConfigMap` (1× useful) diff --git a/scripts/check-artifact-pinning.sh b/scripts/check-artifact-pinning.sh index 0294fde..fcab138 100755 --- a/scripts/check-artifact-pinning.sh +++ b/scripts/check-artifact-pinning.sh @@ -119,9 +119,12 @@ check_workflow_gates() { if ! grep -Eq '^ needs: \[build-and-push-backend, build-and-push-frontend, security-scan\]$' "$WORKFLOW"; then fail "deploy обязан зависеть от успешного security-scan" fi - if ! grep -Eq '^[[:space:]]{2}workflow_dispatch:[[:space:]]*$' "$WORKFLOW" \ - || ! grep -Fq "if: \${{ gitea.event_name == 'workflow_dispatch' }}" "$WORKFLOW"; then - fail "production deploy должен запускаться только через ручной workflow_dispatch" + if ! grep -Eq '^[[:space:]]{2}push:[[:space:]]*$' "$WORKFLOW" \ + || ! grep -Eq '^[[:space:]]{6}- main[[:space:]]*$' "$WORKFLOW"; then + fail "production deploy должен автоматически запускаться после push в main" + fi + if grep -Fq "if: \${{ gitea.event_name == 'workflow_dispatch' }}" "$WORKFLOW"; then + fail "production deploy не должен требовать ручной workflow_dispatch" fi if ! grep -Eq '^ KUBECTL_VERSION: v[0-9]+\.[0-9]+\.[0-9]+$' "$WORKFLOW" \ diff --git a/scripts/test-artifact-pinning.sh b/scripts/test-artifact-pinning.sh index 6f6272c..50d247c 100755 --- a/scripts/test-artifact-pinning.sh +++ b/scripts/test-artifact-pinning.sh @@ -74,10 +74,11 @@ fi cp "$ROOT_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" 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 fi