diff --git a/.gitea/workflows/continuous_integration.yaml b/.gitea/workflows/continuous_integration.yaml index f8a0fc2..5639319 100644 --- a/.gitea/workflows/continuous_integration.yaml +++ b/.gitea/workflows/continuous_integration.yaml @@ -280,12 +280,21 @@ jobs: publish-test: needs: [changes, backend-build, backend-test, vulnerability-scan, frontend-build, frontend-test, frontend-lint] # always() bypasses the automatic skip-cascade from a gate job that was itself skipped (because - # its side of the repo didn't change) — !failure() && !cancelled() still blocks a run where a - # gate that DID run actually failed. The remaining changes.outputs check makes sure there's - # something to publish at all: a run that touched neither backend nor frontend has nothing new - # to deploy. + # its side of the repo didn't change). Gitea Actions only implements always() from the GitHub + # Actions status-check functions — success()/failure()/cancelled() are not supported — so each + # gate's outcome is checked explicitly via needs..result instead: a skipped gate is fine, + # but a gate that actually ran and failed or was cancelled still blocks the publish. The final + # changes.outputs check makes sure there's something to publish at all: a run that touched + # neither backend nor frontend has nothing new to deploy. if: | - always() && !failure() && !cancelled() && + always() && + needs.changes.result == 'success' && + needs.backend-build.result != 'failure' && needs.backend-build.result != 'cancelled' && + needs.backend-test.result != 'failure' && needs.backend-test.result != 'cancelled' && + needs.vulnerability-scan.result != 'failure' && needs.vulnerability-scan.result != 'cancelled' && + needs.frontend-build.result != 'failure' && needs.frontend-build.result != 'cancelled' && + needs.frontend-test.result != 'failure' && needs.frontend-test.result != 'cancelled' && + needs.frontend-lint.result != 'failure' && needs.frontend-lint.result != 'cancelled' && (needs.changes.outputs.backend == 'true' || needs.changes.outputs.frontend == 'true') runs-on: ubuntu-latest steps: @@ -349,9 +358,17 @@ jobs: # Vite build-time value: one dist/ bundle cannot be tagged as both 'test' and 'production' (FR-05). publish-production: needs: [changes, backend-build, backend-test, vulnerability-scan, frontend-build, frontend-test, frontend-lint] - # See publish-test's comment on the always()/!failure()/!cancelled() combination above. + # See publish-test's comment above on why this checks needs..result explicitly instead of + # failure()/cancelled(), which Gitea Actions doesn't support. if: | - always() && !failure() && !cancelled() && + always() && + needs.changes.result == 'success' && + needs.backend-build.result != 'failure' && needs.backend-build.result != 'cancelled' && + needs.backend-test.result != 'failure' && needs.backend-test.result != 'cancelled' && + needs.vulnerability-scan.result != 'failure' && needs.vulnerability-scan.result != 'cancelled' && + needs.frontend-build.result != 'failure' && needs.frontend-build.result != 'cancelled' && + needs.frontend-test.result != 'failure' && needs.frontend-test.result != 'cancelled' && + needs.frontend-lint.result != 'failure' && needs.frontend-lint.result != 'cancelled' && github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_production == 'true' && (needs.changes.outputs.backend == 'true' || needs.changes.outputs.frontend == 'true') runs-on: ubuntu-latest