diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8bdceb3..0229b81 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -577,7 +577,7 @@ release: allow_failure: true # ============================================================= -# Auto-PR: bump prod image tag в ordinis-infra/values-prod.yaml. +# Auto-PR: bump image tag в ordinis-infra/values-{prod,staging}.yaml. # ============================================================= # Зачем. До этого job'а prod deploys работали через две runtime механики: # @@ -685,32 +685,44 @@ propose-prod-image-bump: git push origin --delete "$BRANCH" 2>/dev/null || true git checkout -b "$BRANCH" - # 2. Patch values-prod.yaml — заменяем image.tag. - # Используем awk c stateful scope-tracking: ищем `image:` block (top-level, - # без leading spaces), затем заменяем ` tag: ...` строку. Не трогаем + # 2. Patch values-prod.yaml + values-staging.yaml — заменяем image.tag. + # + # Patching ОБА файлов в одном MR. Зачем: до 2026-05-13 staging + # values файл не задавал image.tag и default `:latest` + IfNotPresent + # давал stale cache на нодах. Зафиксили (infra MR !22), теперь + # staging тоже на immutable SHA. Чтобы оба env'а не drift'или — + # auto-PR bump'ит обе values файла lock-step. + # + # Awk c stateful scope-tracking: ищем `image:` block (top-level, без + # leading spaces), затем заменяем ` tag: ...` строку. Не трогаем # writer.tag / readApi.tag / etc — у них другая indentation level. - awk -v new_tag="$IMAGE_TAG" ' - BEGIN { in_image_block = 0; replaced = 0 } - /^image:[[:space:]]*$/ { in_image_block = 1; print; next } - # Top-level keys (no indent, ends with `:`) reset scope. - /^[a-zA-Z][a-zA-Z0-9_-]*:/ && !/^image:/ { in_image_block = 0; print; next } - # Заменяем ` tag:` ТОЛЬКО внутри image: block. 2 spaces indent. - in_image_block && /^ tag:/ { - print " tag: \"" new_tag "\"" - replaced = 1 - next - } - { print } - END { if (!replaced) { print "ERROR: image.tag не найдена в values-prod.yaml" > "/dev/stderr"; exit 1 } } - ' charts/ordinis/values-prod.yaml > /tmp/values-prod.new - mv /tmp/values-prod.new charts/ordinis/values-prod.yaml + patch_values_file() { + local file=$1 + awk -v new_tag="$IMAGE_TAG" -v file="$file" ' + BEGIN { in_image_block = 0; replaced = 0 } + /^image:[[:space:]]*$/ { in_image_block = 1; print; next } + # Top-level keys (no indent, ends with `:`) reset scope. + /^[a-zA-Z][a-zA-Z0-9_-]*:/ && !/^image:/ { in_image_block = 0; print; next } + # Заменяем ` tag:` ТОЛЬКО внутри image: block. 2 spaces indent. + in_image_block && /^ tag:/ { + print " tag: \"" new_tag "\"" + replaced = 1 + next + } + { print } + END { if (!replaced) { print "ERROR: image.tag не найдена в " file > "/dev/stderr"; exit 1 } } + ' "$file" > "${file}.new" + mv "${file}.new" "$file" + } + patch_values_file charts/ordinis/values-prod.yaml + patch_values_file charts/ordinis/values-staging.yaml - # 3. Diff sanity: changed только эта строка. - if ! git diff --quiet charts/ordinis/values-prod.yaml; then + # 3. Diff sanity: changed только эта строка(и). + if ! git diff --quiet charts/ordinis/values-prod.yaml charts/ordinis/values-staging.yaml; then echo "=== Diff ===" - git diff charts/ordinis/values-prod.yaml + git diff charts/ordinis/values-prod.yaml charts/ordinis/values-staging.yaml else - echo "INFO: tag уже $IMAGE_TAG в values-prod.yaml — no-op exit." + echo "INFO: tag уже $IMAGE_TAG в обоих values файлах — no-op exit." exit 0 fi @@ -718,13 +730,13 @@ propose-prod-image-bump: # printf '%b' разворачивает \n в реальные newlines внутри одной shell # строки — избегаем multi-line YAML quoting issues (literal block scalar # ломается на unindented continuation lines). - git add charts/ordinis/values-prod.yaml - COMMIT_MSG=$(printf '%b' "chore(release): bump prod image к ${IMAGE_TAG}\n\nAuto-generated ordinis-CI release pipeline.\n\nSource: ${CI_PROJECT_URL}/-/commit/${CI_COMMIT_SHA}\nPipeline: ${CI_PIPELINE_URL}\nTag: ${VERSION}") + git add charts/ordinis/values-prod.yaml charts/ordinis/values-staging.yaml + COMMIT_MSG=$(printf '%b' "chore(release): bump prod+staging image к ${IMAGE_TAG}\n\nAuto-generated ordinis-CI release pipeline. Patches values-prod.yaml AND values-staging.yaml в lock-step.\n\nSource: ${CI_PROJECT_URL}/-/commit/${CI_COMMIT_SHA}\nPipeline: ${CI_PIPELINE_URL}\nTag: ${VERSION}") git commit -m "$COMMIT_MSG" git push origin "$BRANCH" # 5. Create MR через GitLab API. - MR_DESC=$(printf '%b' "Auto-generated ordinis CI release pipeline после semantic-release ${VERSION}.\n\n**Что меняется:** \`image.tag\` в \`charts/ordinis/values-prod.yaml\` → \`${IMAGE_TAG}\` (immutable SHA tag, гарантирует что ноды pull'нут именно этот digest).\n\n**Source:**\n- Ordinis commit: ${CI_PROJECT_URL}/-/commit/${CI_COMMIT_SHA}\n- Tag pipeline: ${CI_PIPELINE_URL}\n\n**Deploy после merge:** infra-pipeline auto-катит helm upgrade в \`ordinis-prod\` namespace через manual-gated \`deploy-prod\` job (как обычно).\n\n**Verify checklist:**\n- [ ] CI 'helm-lint' pipeline зелёный (validate charts)\n- [ ] После merge play 'deploy-prod' job\n- [ ] \`curl /api/v1/version\` показывает \`commit: ${CI_COMMIT_SHORT_SHA}\` и \`tag: ${VERSION}\`\n- [ ] Pods Running 2/2 на обоих writer replicas\n- [ ] Все 5 deployment'ов на одном digest (no split-brain)") + MR_DESC=$(printf '%b' "Auto-generated ordinis CI release pipeline после semantic-release ${VERSION}.\n\n**Что меняется:** \`image.tag\` в \`charts/ordinis/values-prod.yaml\` И \`charts/ordinis/values-staging.yaml\` → \`${IMAGE_TAG}\` (immutable SHA tag, гарантирует что ноды pull'нут именно этот digest, и оба env'а на одном release).\n\n**Source:**\n- Ordinis commit: ${CI_PROJECT_URL}/-/commit/${CI_COMMIT_SHA}\n- Tag pipeline: ${CI_PIPELINE_URL}\n\n**Deploy после merge:** infra-pipeline auto-катит helm upgrade в \`ordinis-staging\` (auto) и \`ordinis-prod\` (manual-gated \`deploy-prod\` job).\n\n**Verify checklist:**\n- [ ] CI 'helm-lint' pipeline зелёный (validate charts)\n- [ ] После merge play 'deploy-prod' job (staging авто-катится)\n- [ ] \`curl https://ordinis.k8s.264.nstart.cloud/api/v1/version\` (prod) показывает \`commit: ${CI_COMMIT_SHORT_SHA}\` и \`tag: ${VERSION}\`\n- [ ] \`curl https://ordinis.k8s.265.nstart.cloud/api/v1/version\` (staging) тот же commit/tag\n- [ ] Pods Running на обоих env (no split-brain)") curl -sS --fail \ --request POST \