From eff7043957f5f4356fab969145d33c0f5c5b92d8 Mon Sep 17 00:00:00 2001 From: Mark Polyak Date: Tue, 31 Mar 2026 15:03:41 +0300 Subject: [PATCH 1/2] fix: treat skipped CI jobs as failure, not pending MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub Actions conclusion "skipped" is a terminal state (job did not run due to a branch/event condition), not an in-progress one. Previously it fell into the else-branch and set has_pending=True, causing the grader to return "CI-проверки ещё выполняются ⏳" instead of a failure result. Co-Authored-By: Claude Sonnet 4.6 --- grading/ci_checker.py | 2 +- tests/test_ci_checker.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/grading/ci_checker.py b/grading/ci_checker.py index 78141e7..0df0a31 100644 --- a/grading/ci_checker.py +++ b/grading/ci_checker.py @@ -147,7 +147,7 @@ def evaluate_ci_results(check_runs: list[CheckRun]) -> CIResult: if run.completed_at: if latest_success is None or run.completed_at > latest_success: latest_success = run.completed_at - elif run.conclusion == "failure": + elif run.conclusion in ("failure", "skipped"): emoji = "❌" else: emoji = "⏳" diff --git a/tests/test_ci_checker.py b/tests/test_ci_checker.py index 8b20dda..c1be966 100644 --- a/tests/test_ci_checker.py +++ b/tests/test_ci_checker.py @@ -180,6 +180,38 @@ def test_empty_check_runs(self): assert result.total_count == 0 assert result.has_pending is True + def test_skipped_with_failure(self): + """Skipped job + failed job should result in failure, not pending.""" + runs = [ + CheckRun("run-autograding-tests", "skipped", "url1"), + CheckRun("Test python scripts", "failure", "url2"), + ] + result = evaluate_ci_results(runs) + assert result.passed is False + assert result.has_pending is False + assert "❌" in result.summary[0] + assert "❌" in result.summary[1] + + def test_skipped_alone_is_failure(self): + """Skipped job alone should result in failure, not pending.""" + runs = [ + CheckRun("run-autograding-tests", "skipped", "url1"), + ] + result = evaluate_ci_results(runs) + assert result.passed is False + assert result.has_pending is False + assert result.passed_count == 0 + + def test_skipped_with_success_is_failure(self): + """Skipped + success should not pass.""" + runs = [ + CheckRun("lint", "skipped", "url1"), + CheckRun("test", "success", "url2"), + ] + result = evaluate_ci_results(runs) + assert result.passed is False + assert result.has_pending is False + def test_latest_success_time(self): """Track latest success time.""" runs = [ From 758453ef360a13136683c68210046edbe8b8cf54 Mon Sep 17 00:00:00 2001 From: Mark Polyak Date: Tue, 31 Mar 2026 15:06:45 +0300 Subject: [PATCH 2/2] Update ci.yaml --- .github/workflows/ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a6f9f15..75d6e40 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,6 +4,7 @@ on: - main - 'claude/**' # Auto-build for all Claude branches - 'feature/**' # Auto-build for all feature branches + - 'fix/**' # Auto-build for all fix branches workflow_dispatch: env: