Skip to content

test(ci): pin own-check.ps1's exit-code tiers on Windows (#313) - #314

Merged
PhysShell merged 3 commits into
mainfrom
claude/complex-project-tasks-viyycs
Jul 28, 2026
Merged

test(ci): pin own-check.ps1's exit-code tiers on Windows (#313)#314
PhysShell merged 3 commits into
mainfrom
claude/complex-project-tasks-viyycs

Conversation

@PhysShell

@PhysShell PhysShell commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Что и зачем

Закрывает доказательный разрыв, записанный в merge-коммите PR #312: правка кодов возврата первой стадии была закреплена ассерцией CI только для scripts/own-check.sh, а зеркальная ветка в scripts/own-check.ps1 существовала «в коде и нигде больше». Ни одна другая джоба этот файл не трогает — композитный Action гоняет .sh. PowerShell-обёртка исполняется на Linux достаточно далеко, чтобы доказать ярус отказа первой стадии, но её успешный extraction path строит Windows-style пути и требует Windows.

Новая джоба на windows-latest проверяет ярусы, которые у обёртки действительно есть:

broken stage 1         → >= 2
clean                  → 0
findings + flag        → 1
findings without flag  → 0
finding output         → identical in both modes

Последняя строка — не украшение: флаг -FailOnFinding не имеет права стать вторым, иначе ведущим себя анализом, поэтому оба прогона сравниваются посимвольно.

Ярус «битый конфиг → 2» из issue намеренно отсутствует: у .ps1 нет параметра -Config, и эта поверхность на нём не существует. Утверждать её значило бы дописать скрипт под тест.

Область — один файл, .github/workflows/ci.yml. Ни рефакторинга обёрток, ни улучшений документации.

Три коммита, и почему их стоит читать по отдельности

Предмет проверки оказался исправен с самого начала — дважды ломался измерительный стенд:

Коммит Что случилось
f370acd Джоба добавлена: .ps1 впервые исполняется хоть где-то.
2ea190d Первый прогон напечатал OK: stage-1 failure landed in the hard-error tier (2) и всё равно упал. Обёртка shell: pwsh завершается exit $LASTEXITCODE, а шаги намеренно запускают падающие команды — оставленный код решал судьбу шага независимо от вывода ассерции. Лечится явным exit 0 в конце каждого шага.
dd1f05f Второй прогон искал экстрактор внутри проверяемого дерева: путь связывался с -Root, а не с -Paths. В PowerShell -- завершает разбор параметров, дальше аргументы идут позиционно, а $Root объявлен первым.

Только после этого стало видно, что контракт ярусов держится.

Найденное попутно (в этот PR не входит)

Из третьего пункта следует пользовательский дефект самой обёртки: её собственные .EXAMPLEown-check.ps1 -Format msbuild -- src\MyApp — связывают путь с -Root и сканируют .. Скрипт здесь не менялся: тест, обнаруживший дефект, не должен чинить объект испытания в том же пакете. Заведено отдельно — #315.

Тип изменения

  • feat — новая возможность
  • fix — исправление бага
  • docs — документация
  • refactor / chore / test / ci — без изменения поведения

Как проверено

  • Локально с PowerShell 7.4.6: ярус >= 2 исполнен по-настоящему (на Linux провал первой стадии гарантирован Windows-style путями в extraction path) — LASTEXITCODE = 2 при корректном связывании через -Paths

  • Связывание аргументов проверено на сокращённом блоке параметров:

    Вызов Куда попал путь
    -Format github -- /tmp/tree $Root
    -Format github /tmp/tree $Root
    -Format github -Paths /tmp/tree $Paths
  • Семантика завершения шага воспроизведена локально на форме обёртки GitHub: без явного exit 0 шаг получает код упавшей команды, с ним — 0

  • Тело каждого шага проверено парсером PowerShell до пуша

  • CI зелёный на dd1f05f: 19 джоб, ни одной не-успешной; новая джоба прошла всеми четырьмя шагами

  • python tests/run_tests.py / ruff — не применимо: Python и продуктовый код не менялись

Связанные issue

Closes #313. Refs #312 (где разрыв был записан), #315 (найденный попутно дефект связывания аргументов).

Чеклист

  • изменение покрыто тестом/селфтестом (или объяснено, почему нет) — изменение является тестом
  • README/docs обновлены при необходимости — не требуется
  • коммиты в conventional-commit стиле (feat:, fix:, docs: …)

Generated by Claude Code

claude added 3 commits July 28, 2026 16:38
Closes the evidence gap recorded in the #312 merge commit. The stage-1
normalisation — a broken extractor must land in the >=2 tier instead of
borrowing exit 1 from "analysed, findings present" — was mirrored into the
PowerShell wrapper and proven nowhere. No other job touches that file: the
composite action drives the .sh, and the .ps1 builds its paths with
backslashes, so it cannot run on Linux at all.

A new windows-latest job exercises the tiers the wrapper actually has:
broken stage 1 -> >=2, clean -> 0, findings -> 1 with -FailOnFinding and 0
without. The findings pair also asserts the two runs produce IDENTICAL
output, so the flag can never quietly become a second, differently-behaving
analysis.

The "broken config -> 2" tier from the issue is deliberately absent: the
PowerShell wrapper has no -Config parameter, so that tier does not exist on
this surface. Asserting it would have meant inventing the surface to fit the
test.

One platform detail is load-bearing enough to be a comment rather than folk
knowledge: the assertions read $LASTEXITCODE, never the wrapper process's
exit code. Inside a PowerShell session — which is what `shell: pwsh` is — a
script's `exit N` sets $LASTEXITCODE to N, but `pwsh -Command "& ./x.ps1"`
collapses it to 1 at the process boundary. Measured the wrong way, every tier
here reads as pass/fail and the contract looks broken when it is not; that is
exactly what happened once while writing this.

Verified locally with PowerShell 7.4.6: the stage-1 tier runs on Linux (the
failure is the point) and reports $LASTEXITCODE = 2; every step body was
parse-checked with the PowerShell parser. The remaining tiers need a working
extractor and therefore first run on the Windows runner.

Refs #313.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015de4MezSeUnZBoWq1fFU5M
…ilure does not fail the step

The job's first run printed exactly what it was written to prove —
"OK: stage-1 failure landed in the hard-error tier (2)" — and then reported
the step as failed. The assertion was right; the step's status was not.

GitHub's `shell: pwsh` wrapper finishes with `exit $LASTEXITCODE`. These
steps deliberately run commands that FAIL, so the code left behind by the
last one decides the step's fate no matter what the assertion concluded. Each
step now ends with an explicit `exit 0`, and the reason sits in a comment
above the job rather than in anyone's memory.

Worth noting what this was NOT: the tier contract held on Windows on the
first attempt — a broken stage 1 really did land on 2. The harness around it
was wrong, not the thing it measures.

Refs #313.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015de4MezSeUnZBoWq1fFU5M
…oot, not -Paths

The Windows run failed with the extractor being looked for under the tree
being scanned:

  The provided file path does not exist:
    D:\a\_temp\ps1-clean\frontend\roslyn\OwnSharp.Extractor

The path had bound to -Root. In PowerShell `--` ends parameter parsing and
everything after it binds POSITIONALLY, and own-check.ps1 declares $Root
first, so it takes position 0. Verified against a reduced param block: both
`-Format github -- <path>` and `-Format github <path>` land in $Root, and
only `-Paths <path>` reaches $Paths.

This job now binds -Paths explicitly. It does NOT change the wrapper: that
the script's own .EXAMPLE lines (`own-check.ps1 -Format msbuild -- src\MyApp`)
therefore scan "." instead of src\MyApp is a real user-facing defect, but it
is a different one from the exit-code tiers this job exists to pin, and it is
being reported rather than folded in here.

Also worth recording honestly: the tier>=2 assertion passed in the previous
run while malformed — -Root and -Format were bound by name, so the stray
positional argument went to some other parameter entirely and the tier was
proven for the right verdict by an accident of binding. Re-verified locally
with the corrected invocation: LASTEXITCODE = 2.

Refs #313.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015de4MezSeUnZBoWq1fFU5M
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a Windows CI job that validates own-check.ps1 exit-code tiers for broken, clean, and findings scenarios, including identical annotated output with and without -FailOnFinding.

Changes

PowerShell CI validation

Layer / File(s) Summary
PowerShell exit-tier assertions
.github/workflows/ci.yml
Adds a windows-latest job that installs repository, Python, and .NET prerequisites, then verifies broken stage-1 runs exit at least 2, clean runs exit 0, and findings runs exit 1 only with -FailOnFinding while preserving annotated output.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: claude

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR adds the requested Windows CI coverage for own-check.ps1's hard-error and findings tiers, and the absent -Config case is explicitly unsupported.
Out of Scope Changes check ✅ Passed The changes stay within .github/workflows/ci.yml and match the stated CI-only scope.
Title check ✅ Passed Title clearly and concisely describes the new Windows CI test for own-check.ps1 exit-code tiers.
Description check ✅ Passed Description follows the required template and fills the main sections with relevant details.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/complex-project-tasks-viyycs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@PhysShell
PhysShell merged commit 0e5f61e into main Jul 28, 2026
44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CI: закрепить ярус «сломанная первая стадия» для own-check.ps1 (Windows), как это сделано для .sh

2 participants