diff --git a/.gitea/scripts/lint_pre_flip_continue_on_error.py b/.gitea/scripts/lint_pre_flip_continue_on_error.py index 0c315d239..bdf417efb 100644 --- a/.gitea/scripts/lint_pre_flip_continue_on_error.py +++ b/.gitea/scripts/lint_pre_flip_continue_on_error.py @@ -466,12 +466,40 @@ def fetch_log(target_url: str) -> str | None: def grep_fail_markers(log_text: str) -> list[str]: """Return up to 5 sample matching lines for any FAIL_PATTERNS hit. - Empty list = clean log.""" + Empty list = clean log. + + Heuristic: skip lines where the marker appears inside script source + (e.g. ``echo "::error::..."`` in a ``::group::Run`` block) rather + than actual execution output. The Gitea Actions log prints the raw + script before executing it; ``echo "::error::"`` lines in that + display are false positives. + """ matches: list[str] = [] + in_run_group = False + group_depth = 0 for line in log_text.splitlines(): + stripped = line.strip() + # Track Gitea Actions group markers so we can skip the + # ``::group::Run`` script-source display blocks. + if stripped.startswith("::group::Run"): + in_run_group = True + group_depth = 1 + continue + if stripped == "::endgroup::": + if in_run_group: + in_run_group = False + group_depth = 0 + continue + if in_run_group: + continue for pat in FAIL_PATTERNS: if pat in line: - # Truncate to keep error output bounded. + # Additional false-positive guard: ``echo "::error::"`` + # is script source, not a runtime error emission. + if pat == "::error::": + prefix = line[: line.index(pat)].strip() + if prefix.endswith('echo') or prefix.endswith("echo '") or prefix.endswith('echo "'): + break matches.append(line.strip()[:240]) break if len(matches) >= 5: diff --git a/.gitea/workflows/e2e-api.yml b/.gitea/workflows/e2e-api.yml index 468a53a70..843fe2af5 100644 --- a/.gitea/workflows/e2e-api.yml +++ b/.gitea/workflows/e2e-api.yml @@ -123,8 +123,9 @@ jobs: # integration). See internal#512 for the class defect. runs-on: docker-host # Phase 3 (RFC #219 §1): surface broken workflows without blocking. - # mc#1982: pre-existing continue-on-error mask; root-fix and remove, do not renew silently. - continue-on-error: true + # mc#1982: mask removed. If regressions appear, root-fix the underlying + # test — do NOT renew the mask silently. + continue-on-error: false outputs: api: ${{ steps.decide.outputs.api }} steps: @@ -160,8 +161,9 @@ jobs: # detect-changes for the full rationale. runs-on: docker-host # Phase 3 (RFC #219 §1): surface broken workflows without blocking. - # mc#1982: pre-existing continue-on-error mask; root-fix and remove, do not renew silently. - continue-on-error: true + # mc#1982: mask removed. If regressions appear, root-fix the underlying + # test — do NOT renew the mask silently. + continue-on-error: false timeout-minutes: 15 env: # Unique per-run container names so concurrent runs on the host- diff --git a/.gitea/workflows/handlers-postgres-integration.yml b/.gitea/workflows/handlers-postgres-integration.yml index 7c32de334..21f6e0a96 100644 --- a/.gitea/workflows/handlers-postgres-integration.yml +++ b/.gitea/workflows/handlers-postgres-integration.yml @@ -88,8 +88,9 @@ jobs: # surprises and keeps the routing rule discoverable in one place. runs-on: docker-host # mc#1982 Phase 3 (RFC §1): surface broken workflows without blocking. - # mc#1982: pre-existing continue-on-error mask; root-fix and remove, do not renew silently. - continue-on-error: true + # mc#1982: mask removed. If regressions appear, root-fix the underlying + # test — do NOT renew the mask silently. + continue-on-error: false outputs: handlers: ${{ steps.filter.outputs.handlers }} steps: @@ -119,8 +120,9 @@ jobs: # exists). See detect-changes for the full routing rationale. runs-on: docker-host # mc#1982 Phase 3 (RFC §1): surface broken workflows without blocking. - # mc#1982: pre-existing continue-on-error mask; root-fix and remove, do not renew silently. - continue-on-error: true + # mc#1982: mask removed. If regressions appear, root-fix the underlying + # test — do NOT renew the mask silently. + continue-on-error: false env: # Unique name per run so concurrent jobs don't collide on the # bridge network. ${RUN_ID}-${RUN_ATTEMPT} is unique even across