fix(pipeline-status): dedup forgejo ci runs by workflow on same SHA #51
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/pipeline-status/forgejo-ci-rollup-dedup"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что сделано
pipeline-status.py:_forgejo_ci_rollup— после фильтра поhead_shaдобавлена дедупликация «latest run per workflow» (maxid), вынесенная в helper-функции_forgejo_workflow_key(ключ =name→workflow_id→id) и_forgejo_latest_runs_per_workflow. Mapping status/conclusion → rollup entry не меняется — меняется только то, какие runs попадают в цикл.tests/test_pipeline_status_ci.py— добавлено 6 тестов_forgejo_ci_rollup_*(мокps._forgejo_request): re-run same SHA+workflow (old failed id=100 + new success id=200 → DONE), real single failure → NOT_DONE, two different workflows (one fails) → NOT_DONE, re-run in_progress → AMBIGUOUS, other SHA filtered → AMBIGUOUS,workflow_idfallback при отсутствииname→ DONE.docs/decisions/096-forgejo-ci-rollup-dedup.md— новый ADR (supersedes portions of ADR-054 re: Forgejo migration): фиксирует причину (re-run создаёт новый run, старый остаётся FAILURE), решение (client-side dedup maxidper workflow), отвергнутые альтернативы (server-side SHA filter, фильтр поevent, ослабление_classify_rollup).Почему
После re-run failed jobs того же SHA оракул
_forgejo_ci_rollupсобирал и старый failed run, и новый success run для одного workflow._classify_rollupплоско итерирует conclusions — первый FAILURE → NOT_DONE, новый SUCCESS игнорируется → pipeline блокируется на CI-фазе даже после успешного re-run. Зафиксировано на PR#46 (fix-коммит2e490cb431= HEAD PR, в API mix runs: старый failed + новый success). ADR-054 ЯВНО отверг альтернативу (C) «SHA + all workflows» на GitHub именно по причине «выбор правильного run из нескольких», но после миграции на ForgejostatusCheckRollupисчез, а reimplementation повторил ту же проблему — без GitHub-side агрегации, которая её решала. Дедупликация maxidper workflow решает «который run» на client-side.Watch out
name(workflow name), НЕhead_branch/event— они одинаковы для re-runs одного SHA. Если в будущем понадобится различать runs поevent(pull_request vs push) — это отдельная фича, текущий контракт покрывает re-run./actions/tasksвозвращает runs поiddesc — явно выбирает maxid. Если Forgejo изменит порядок, поведение сохранится.limit=50: при >50 runs на SHA+workflow дедуп всё равно корректен (берёт maxidиз того что вернулось), но старые runs могут выпасть из окна — это ограничение API, не дедупа. Server-side SHA filter (отдельный PR) снял бы это ограничение.from typing import Any+ типизация новых helper-функций какdict[str, Any]. 6 пре-существующихdict-без-args ошибок mypy на master сохранены (не добавлены этим PR) — это вpipeline-status.pylines 94, 218, 274, 378, 393, 396 (функции_forgejo_request,_forgejo_pr_viewи др.)._forgejo_ci_rollupбыла 11 (>10) после inline-дедупа — вынес логику в 2 helper-функции, теперь green.Pending
head_shaпараметром API (если Forgejo поддерживает) — отдельный PR, сейчас client-side достаточно.create-pr.ts(предотвращает попадание в CI) — отдельный issue.pr-N— отдельный issue.Closes #48
Closes #48
Code Review Summary
Чистый, хорошо декомпозированный fix: дедупликация re-run'ов Forgejo CI по workflow (max
idper workflow key) решает реальный баг с блокировкой pipeline после успешного re-run (PR#46). 6 новых тестов покрывают все сценарии, ADR-096 корректно фиксирует решение и контекст.Positives
_forgejo_workflow_key15 строк,_forgejo_latest_runs_per_workflow16 строк) — mccabe_forgejo_ci_rollupостался в норме, функции <50 строк.int(r.get("id", 0) or 0)корректно обрабатывает None/пустую строку;.strip()наname; явныйmax idвместо зависимости от API ordering._forgejo_workflow_key:name→workflow_id→id(каждый run сам по себе) — покрывает все варианты API-ответа, тестtest_forgejo_ci_rollup_workflow_id_fallbackэто верифицирует._forgejo_ci_rollupreturn-тип иstatusCheckRollupJSON не изменились —run-pipeline/SKILL.mdTemplate D (fix_ci) не требует обновления, oracle просто начинает работать корректно.## Что сделано/## Почему/## Watch out/## Pendingзаполнены осмысленно, Closes #48, branch name descriptive.dicterrors (не добавлены PR — подтверждено сравнением с main); xenon rank B для новых функций; 29/29 тестов прошли.Suggestions (info, not blocking)
int(r.get("id", 0) or 0)— если API вернётidкак float (теоретически),int()сработает, но если как нечисловую строку —ValueError. Текущий контракт Forgejo API возвращаетidкак int, так что это гипотетический edge case. Можно ужесточить черезtry/except, но YAGNI для текущего сценария.limit=50— при >50 runs на SHA+workflow дедуп всё равно корректен (берёт maxidиз того что вернулось), но старые runs могут выпасть из окна. Это ограничение API, не дедупа — корректно отмечено в PR body## Watch outи ADR-096 (server-side SHA filter отложен в отдельный PR)._forgejo_rollup_runs— helper без префикса_testможет выглядеть как production-функция, но_prefix + расположение в test-файле достаточно сигнализируют. Не блокер.Verdict: APPROVE