From 51288ddeecd051ddfc36ac5482345be570bd64b7 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Tue, 12 May 2026 15:55:48 +0000 Subject: [PATCH 1/2] Fix: Replace brittle bash shell comparisons in status-check job with native expression conditions (Closes #8797) --- .forgejo/workflows/ci.yml | 63 ++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 6a6d01c57..fce9b6a60 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -555,39 +555,62 @@ jobs: fi echo "OK: Push access verified -- FORGEJO_TOKEN has write permission on ${REPO}" echo "=== Push access smoke-test passed ===" + status-check: + # Branch-protection gate: evaluates native expression conditions to check + # that all required merge-gate jobs (lint, typecheck, security, quality, + # unit_tests, coverage) succeeded. Uses && instead of brittle bash || chains + # for reliable branch-protection gating on master and develop branches. + # Non-blocking jobs (integration_tests, build, docker, helm) are reported + # by the informational-status job below and do NOT affect merge eligibility. if: always() - needs: [lint, typecheck, security, quality, unit_tests, integration_tests, coverage, build, docker, helm, push-validation] + needs: [lint, typecheck, security, quality, unit_tests, coverage] runs-on: docker container: image: python:3.13-slim steps: - - name: Check required job results + - name: Check required job results (pass/fail) + # Passes only when ALL required merge-gate checks succeeded. + # Uses native expression && operators for reliable evaluation at + # the Actions engine level instead of fragile bash comparisons. + run: echo "All required CI checks passed" + if: >- + (needs.lint.result == 'success') && + (needs.typecheck.result == 'success') && + (needs.security.result == 'success') && + (needs.quality.result == 'success') && + (needs.unit_tests.result == 'success') && + (needs.coverage.result == 'success') + + - name: Report required job results for diagnostics + # Only runs when the pass step was skipped (i.e. some dependency failed). + if: failure() run: | + echo "=== status-check diagnostics ===" echo "lint: ${{ needs.lint.result }}" echo "typecheck: ${{ needs.typecheck.result }}" echo "security: ${{ needs.security.result }}" echo "quality: ${{ needs.quality.result }}" echo "unit_tests: ${{ needs.unit_tests.result }}" - echo "integration_tests: ${{ needs.integration_tests.result }}" echo "coverage: ${{ needs.coverage.result }}" + echo "=== status-check diagnostics ===" + + informational-status: + # Informational consolidation for non-blocking jobs (integration_tests, + # build, docker, helm). Not a required check — does NOT affect merge + # eligibility. Runs when the branch-protection status-check gate completes. + if: always() && needs.status-check.result != 'cancelled' + needs: [status-check, integration_tests, build, docker, helm] + runs-on: docker + container: + image: python:3.13-slim + steps: + - name: Non-blocking job results + run: | + echo "=== Informational job status ===" + echo "integration_tests: ${{ needs.integration_tests.result }}" echo "build: ${{ needs.build.result }}" echo "docker: ${{ needs.docker.result }}" echo "helm: ${{ needs.helm.result }}" - echo "push-validation: ${{ needs.push-validation.result }}" - - if [ "${{ needs.lint.result }}" != "success" ] || \ - [ "${{ needs.typecheck.result }}" != "success" ] || \ - [ "${{ needs.security.result }}" != "success" ] || \ - [ "${{ needs.quality.result }}" != "success" ] || \ - [ "${{ needs.unit_tests.result }}" != "success" ] || \ - [ "${{ needs.integration_tests.result }}" != "success" ] || \ - [ "${{ needs.coverage.result }}" != "success" ] || \ - [ "${{ needs.build.result }}" != "success" ] || \ - [ "${{ needs.docker.result }}" != "success" ] || \ - [ "${{ needs.helm.result }}" != "success" ] || \ - [ "${{ needs.push-validation.result }}" != "success" ]; then - echo "FAILED: One or more required jobs did not succeed" - exit 1 - fi - echo "All required CI checks passed" + echo "status-check (gate): ${{ needs.status-check.result }}" + echo "=== Informational job status ===" -- 2.52.0 From 4ccf52fd9010d6aafb9a2fd3cc8fc45075219ac3 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Wed, 13 May 2026 18:46:59 +0000 Subject: [PATCH 2/2] Improve informational-status to include push-validation results The original monolithic status-check job included push-validation in its needs list and printed its result alongside all CI job statuses. When the status-check was refactored into two focused jobs (status-check for merge gates, informational-status for non-blocking reporting), push-validation was inadvertently left out of informational-status's dependency chain and reporting output. This restores complete visibility by adding push-validation to informational-status: it becomes a noted job in the final CI status report without affecting merge eligibility (informational-status is non-blocking). --- .forgejo/workflows/ci.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index fce9b6a60..0575c957c 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -597,10 +597,12 @@ jobs: informational-status: # Informational consolidation for non-blocking jobs (integration_tests, - # build, docker, helm). Not a required check — does NOT affect merge - # eligibility. Runs when the branch-protection status-check gate completes. + # build, docker, helm, push-validation). Not a required check — does NOT + # affect merge eligibility. Runs when the branch-protection status-check + # gate completes. Includes push-validation since it was originally one of + # the checked jobs in the original monolithic status-check step. if: always() && needs.status-check.result != 'cancelled' - needs: [status-check, integration_tests, build, docker, helm] + needs: [status-check, integration_tests, build, docker, helm, push-validation] runs-on: docker container: image: python:3.13-slim @@ -612,5 +614,6 @@ jobs: echo "build: ${{ needs.build.result }}" echo "docker: ${{ needs.docker.result }}" echo "helm: ${{ needs.helm.result }}" + echo "push-validation: ${{ needs.push-validation.result }}" echo "status-check (gate): ${{ needs.status-check.result }}" echo "=== Informational job status ===" -- 2.52.0