From df85505735ba466d3297f91cd6ca28578004e4e7 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 18 Oct 2026 19:20:26 +0400 Subject: [PATCH] =?UTF-8?q?fix(scripts):=20sync-statements.sh=20=E2=80=94?= =?UTF-8?q?=20=D1=81=D0=B1=D0=BE=D0=B9=20tea=20=D0=BD=D0=B5=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D1=8B=D0=B2=D0=B0=D0=B5=D1=82=20=D1=81=D0=BA=D1=80=D0=B8?= =?UTF-8?q?=D0=BF=D1=82=20=D0=BC=D0=BE=D0=BB=D1=87=D0=B0,=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=20=D0=BA=D0=BE=D0=BF=D0=B8=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20make=20check=20(#120)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- scripts/sync-statements.sh | 38 ++++++++++++++++++++++++--------- scripts/test_sync_statements.sh | 14 ++++++++++++ 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/scripts/sync-statements.sh b/scripts/sync-statements.sh index 4d87595..bdfde2a 100755 --- a/scripts/sync-statements.sh +++ b/scripts/sync-statements.sh @@ -340,6 +340,8 @@ case "$HOST_NAME" in scan-gateway) GITEA_REPO=RSHB/arm-scan-gateway ;; esac +bullets() { if [ -n "$1" ]; then printf '%s\n' "$1" | sed 's/^/- /'; else echo "- (нет коммитов)"; fi; } + # 1. хост if ! git -C "$HOST_DIR" fetch -q origin 2>/dev/null; then echo "sync-statements: fetch хоста не удался, работаю с локальным $HOST_REF" >&2 @@ -409,7 +411,10 @@ if git -C "$HOST_DIR" rev-parse -q --verify "$TMP_BRANCH" >/dev/null; then die "ветка $TMP_BRANCH уже существует в $HOST_NAME — завершите или удалите предыдущую синхронизацию" 2 fi mkdir -p "$(dirname "$WT")" -git -C "$HOST_DIR" worktree add -q -b "$TMP_BRANCH" "$WT" "$HOST_REF" +if ! git -C "$HOST_DIR" worktree add -q -b "$TMP_BRANCH" "$WT" "$HOST_REF"; then + rmdir "$(dirname "$WT")" 2>/dev/null || true + die "не удалось создать worktree $WT" 1 +fi touch "$WT/.bounded" echo "worktree: $WT ($TMP_BRANCH от $HOST_REF)" @@ -424,10 +429,10 @@ if [ "$MODE" = sync ]; then TITLE="arm_statements: копия пакета arm-statements@$T7" BODY="Копия пакета \`api/arm_statements\` в \`$HOST_NAME\` была на \`$OLD7\`, станет \`$T7\` (источник — \`RSHB/arm-statements@${REF#origin/}\`). Коммиты arm-statements \`$OLD7..$T7\` ($N_COMMITS): -$(printf '%s\n' "$COMMITS" | sed 's/^/- /') +$(bullets "$COMMITS") Bounded-задача, выполнена \`docs/scripts/sync-statements.sh\`: копия раскладывается из \`git archive\`, не правится." - ISSUE_URL=$(tea issues create "${TEA_FLAGS[@]}" --title "$TITLE" --description "$BODY" | grep -o 'https://[^ ]*/issues/[0-9]*' | tail -1) + ISSUE_URL=$(tea issues create "${TEA_FLAGS[@]}" --title "$TITLE" --description "$BODY" | grep -o 'https://[^ ]*/issues/[0-9]*' | tail -1) || true ISSUE=${ISSUE_URL##*/} [ -n "$ISSUE" ] || die "не удалось создать issue через tea (worktree оставлен: $WT)" BRANCH="feat/$ISSUE-statements-sync-$T7" @@ -462,29 +467,36 @@ run_make() { # run_make <имя> <цель>: хвост вывода при о } run_make "make venv" venv run_make "make check" check +# make check мог переписать копию (форматтеры, кэши): повторная оценка перед коммитом +evaluate "$WT/api/arm_statements" "$WT/api/requirements.txt" "$([ -n "$HLINES" ] && echo "$WT/api/rules/statement_lines.yaml")" "$HOST_NAME" +if [ "$EVAL_CODE" = 20 ]; then + echo "sync-statements: после make check копия расходится с arm-statements@$T7; коммит не сделан, worktree оставлен: $WT" >&2 + exit 1 +fi +SC_LINE=$(summary) echo "проверки хоста: make check зелёный" # 11. коммит, push, PR git -C "$WT" add -A api/arm_statements -git -C "$WT" -c commit.gpgsign=false commit -q -F - < EOF COMMIT=$(git -C "$WT" rev-parse --short=7 HEAD) -git -C "$WT" push -q -u origin "$BRANCH" +git -C "$WT" push -q -u origin "$BRANCH" || die "push не удался; коммит $COMMIT в ветке $BRANCH, worktree оставлен: $WT" 1 PR_BODY="Закрывает #$ISSUE. -Копия \`api/arm_statements\` в \`$HOST_NAME\` обновлена скриптом \`docs/scripts/sync-statements.sh\`: \`$OLD7\` -> \`$T7\` (источник — \`RSHB/arm-statements@${REF#origin/}\`). +Копия \`api/arm_statements\` в \`$HOST_NAME\` обновлена скриптом \`docs/scripts/sync-statements.sh\`: \`$OLD7..$T7\` (источник — \`RSHB/arm-statements@${REF#origin/}\`). Коммиты arm-statements ($N_COMMITS): -$(printf '%s\n' "$COMMITS" | sed 's/^/- /') +$(bullets "$COMMITS") Проверки: \`make check\` в worktree зелёный; $SC_LINE ${CORE_WARN:+ @@ -497,13 +509,19 @@ ${CORE_WARN:+ 🤖 Generated with [Claude Code](https://claude.com/claude-code)" PR_URL=$(tea pulls create "${TEA_FLAGS[@]}" --head "$BRANCH" --base "${HOST_REF#origin/}" \ --title "chore(arm_statements): копия arm-statements@$T7 (#$ISSUE)" --description "$PR_BODY" \ - | grep -o 'https://[^ ]*/pulls/[0-9]*' | tail -1) + | grep -o 'https://[^ ]*/pulls/[0-9]*' | tail -1) || true # 12. итог +if [ -z "$PR_URL" ]; then + echo + echo "sync-statements: PR не создан (tea не вернул ссылку). Коммит $COMMIT, ветка $BRANCH (запушена), issue: $ISSUE_URL; worktree $WT" >&2 + echo "создать вручную: tea pulls create ${TEA_FLAGS[*]} --head $BRANCH --base ${HOST_REF#origin/}" >&2 + exit 1 +fi echo echo "готово: коммит $COMMIT, ветка $BRANCH" echo "issue: $ISSUE_URL" -echo "PR: ${PR_URL:-создать вручную: tea pulls create ${TEA_FLAGS[*]} --head $BRANCH --base ${HOST_REF#origin/}}" +echo "PR: $PR_URL" [ -z "$CORE_WARN" ] || echo "предупреждение: $CORE_WARN" echo "исполнителю: ревью диапазона не нужно — код проревьюен в arm-statements; merge и «закрывай» по команде человека." echo "worktree $WT и .bounded остаются до закрытия." diff --git a/scripts/test_sync_statements.sh b/scripts/test_sync_statements.sh index bc01731..6be64ab 100755 --- a/scripts/test_sync_statements.sh +++ b/scripts/test_sync_statements.sh @@ -339,5 +339,19 @@ check "$(has -- '--in-place' && echo 0 || echo 1)" "dry-run: хост без к # tea: флаги только после подкоманды check "$(grep -nE '(^|[^[:alnum:]_-])tea[[:space:]]+-' "$SYNC" >/dev/null && echo 1 || echo 0)" "tea: флаги после подкоманды" +# недостижимые прежде ветки: заглушки tea и make в PATH (обычный режим, scan-gateway: копия S1, ядро на S2) +STUB="$WORK/stub"; mkdir -p "$STUB" +printf '#!/bin/sh\nexit 0\n' > "$STUB/make" +printf '#!/bin/sh\nexit 1\n' > "$STUB/tea" +chmod +x "$STUB/make" "$STUB/tea" +OUT=$(PATH="$STUB:$PATH" "$SYNC" "${COMMON[@]}" --host-dir "$WORK/scan-gateway" 2>&1) && rc=0 || rc=$? +check "$([ "$rc" = 1 ] && has 'не удалось создать issue' && echo 0 || echo 1)" "tea упал на issue: сообщение и код 1 (rc=$rc)" +rm_wt "$WORK/scan-gateway" scan-gateway +printf '#!/bin/sh\nif [ "$1" = issues ]; then echo https://git.example/RSHB/arm-scan-gateway/issues/77; exit 0; fi\nexit 1\n' > "$STUB/tea" +OUT=$(PATH="$STUB:$PATH" "$SYNC" "${COMMON[@]}" --host-dir "$WORK/scan-gateway" 2>&1) && rc=0 || rc=$? +check "$([ "$rc" = 1 ] && has 'PR не создан' && has 'tea pulls create' && has 'feat/77-statements-sync' && echo 0 || echo 1)" "tea упал на PR: итог и ручная команда, код 1 (rc=$rc)" +rm_wt "$WORK/scan-gateway" scan-gateway +git -C "$WORK/scan-gateway" branch -D "feat/77-statements-sync-$S27" >/dev/null 2>&1 || true + [ "$fail" = 0 ] || exit 1 echo "ok: sync-statements.sh — все сценарии пройдены"