fix(scripts): sync-statements.sh — сбой tea не обрывает скрипт молча, повторная проверка копии после make check (#120)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-18 19:20:26 +04:00
parent 17c0fd20f9
commit df85505735
2 changed files with 42 additions and 10 deletions

View File

@ -340,6 +340,8 @@ case "$HOST_NAME" in
scan-gateway) GITEA_REPO=RSHB/arm-scan-gateway ;; scan-gateway) GITEA_REPO=RSHB/arm-scan-gateway ;;
esac esac
bullets() { if [ -n "$1" ]; then printf '%s\n' "$1" | sed 's/^/- /'; else echo "- (нет коммитов)"; fi; }
# 1. хост # 1. хост
if ! git -C "$HOST_DIR" fetch -q origin 2>/dev/null; then if ! git -C "$HOST_DIR" fetch -q origin 2>/dev/null; then
echo "sync-statements: fetch хоста не удался, работаю с локальным $HOST_REF" >&2 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 die "ветка $TMP_BRANCH уже существует в $HOST_NAME — завершите или удалите предыдущую синхронизацию" 2
fi fi
mkdir -p "$(dirname "$WT")" 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" touch "$WT/.bounded"
echo "worktree: $WT ($TMP_BRANCH от $HOST_REF)" echo "worktree: $WT ($TMP_BRANCH от $HOST_REF)"
@ -424,10 +429,10 @@ if [ "$MODE" = sync ]; then
TITLE="arm_statements: копия пакета arm-statements@$T7" TITLE="arm_statements: копия пакета arm-statements@$T7"
BODY="Копия пакета \`api/arm_statements\` в \`$HOST_NAME\` была на \`$OLD7\`, станет \`$T7\` (источник — \`RSHB/arm-statements@${REF#origin/}\`). BODY="Копия пакета \`api/arm_statements\` в \`$HOST_NAME\` была на \`$OLD7\`, станет \`$T7\` (источник — \`RSHB/arm-statements@${REF#origin/}\`).
Коммиты arm-statements \`$OLD7..$T7\` ($N_COMMITS): Коммиты arm-statements \`$OLD7..$T7\` ($N_COMMITS):
$(printf '%s\n' "$COMMITS" | sed 's/^/- /') $(bullets "$COMMITS")
Bounded-задача, выполнена \`docs/scripts/sync-statements.sh\`: копия раскладывается из \`git archive\`, не правится." 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##*/} ISSUE=${ISSUE_URL##*/}
[ -n "$ISSUE" ] || die "не удалось создать issue через tea (worktree оставлен: $WT)" [ -n "$ISSUE" ] || die "не удалось создать issue через tea (worktree оставлен: $WT)"
BRANCH="feat/$ISSUE-statements-sync-$T7" BRANCH="feat/$ISSUE-statements-sync-$T7"
@ -462,29 +467,36 @@ run_make() { # run_make <имя> <цель>: хвост вывода при о
} }
run_make "make venv" venv run_make "make venv" venv
run_make "make check" check 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 зелёный" echo "проверки хоста: make check зелёный"
# 11. коммит, push, PR # 11. коммит, push, PR
git -C "$WT" add -A api/arm_statements git -C "$WT" add -A api/arm_statements
git -C "$WT" -c commit.gpgsign=false commit -q -F - <<EOF git -C "$WT" -c commit.gpgsign=false commit -q -F - <<EOF || die "коммит не удался; worktree оставлен: $WT" 1
chore(arm_statements): копия arm-statements@$T7 (#$ISSUE) chore(arm_statements): копия arm-statements@$T7 (#$ISSUE)
Копия api/arm_statements: $OLD7..$T7 ($N_COMMITS коммитов), скрипт docs/scripts/sync-statements.sh. Копия api/arm_statements: $OLD7..$T7 ($N_COMMITS коммитов), скрипт docs/scripts/sync-statements.sh.
Коммиты arm-statements: Коммиты arm-statements:
$(printf '%s\n' "$COMMITS" | sed 's/^/- /') $(bullets "$COMMITS")
$SC_LINE $SC_LINE
Co-Authored-By: sync-statements.sh <noreply@aepif.ru> Co-Authored-By: sync-statements.sh <noreply@aepif.ru>
EOF EOF
COMMIT=$(git -C "$WT" rev-parse --short=7 HEAD) 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. 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): Коммиты arm-statements ($N_COMMITS):
$(printf '%s\n' "$COMMITS" | sed 's/^/- /') $(bullets "$COMMITS")
Проверки: \`make check\` в worktree зелёный; $SC_LINE Проверки: \`make check\` в worktree зелёный; $SC_LINE
${CORE_WARN:+ ${CORE_WARN:+
@ -497,13 +509,19 @@ ${CORE_WARN:+
🤖 Generated with [Claude Code](https://claude.com/claude-code)" 🤖 Generated with [Claude Code](https://claude.com/claude-code)"
PR_URL=$(tea pulls create "${TEA_FLAGS[@]}" --head "$BRANCH" --base "${HOST_REF#origin/}" \ PR_URL=$(tea pulls create "${TEA_FLAGS[@]}" --head "$BRANCH" --base "${HOST_REF#origin/}" \
--title "chore(arm_statements): копия arm-statements@$T7 (#$ISSUE)" --description "$PR_BODY" \ --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. итог # 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
echo "готово: коммит $COMMIT, ветка $BRANCH" echo "готово: коммит $COMMIT, ветка $BRANCH"
echo "issue: $ISSUE_URL" 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" [ -z "$CORE_WARN" ] || echo "предупреждение: $CORE_WARN"
echo "исполнителю: ревью диапазона не нужно — код проревьюен в arm-statements; merge и «закрывай» по команде человека." echo "исполнителю: ревью диапазона не нужно — код проревьюен в arm-statements; merge и «закрывай» по команде человека."
echo "worktree $WT и .bounded остаются до закрытия." echo "worktree $WT и .bounded остаются до закрытия."

View File

@ -339,5 +339,19 @@ check "$(has -- '--in-place' && echo 0 || echo 1)" "dry-run: хост без к
# tea: флаги только после подкоманды # tea: флаги только после подкоманды
check "$(grep -nE '(^|[^[:alnum:]_-])tea[[:space:]]+-' "$SYNC" >/dev/null && echo 1 || echo 0)" "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 [ "$fail" = 0 ] || exit 1
echo "ok: sync-statements.sh — все сценарии пройдены" echo "ok: sync-statements.sh — все сценарии пройдены"