@@ -700,8 +700,21 @@ jobs:
700700 # dist -- so it does not exist on a fresh checkout until something builds it. Same class of gap
701701 # as "Build engine package" above; runs before UI lint/typecheck/tests/build all in this same
702702 # job, so building it here once covers all four.
703+ #
704+ # `!cancelled()` on this step and every UI step below it (through "UI tests (ui)"): this job runs
705+ # a long, unrelated chain of drift checks before reaching here (migrations, schema, env-reference,
706+ # docs, manifest, engine-parity, branding, .nvmrc, release-manifest, observability, the MCP
707+ # version audit just above, ...) -- any ONE of those failing without continue-on-error otherwise
708+ # skips every step after it by GitHub Actions' own default, INCLUDING this build. "UI tests
709+ # (ui-miner)"/"UI tests (miner-extension)" already had this guard (see their own comment below);
710+ # this build step and everything through "UI tests (ui)" didn't, so a same-day MCP release
711+ # tripping the version-audit step above skipped ui-kit's build entirely, and ui-miner's tests
712+ # (which DID still run, guarded) then failed with a confusing "Failed to resolve import
713+ # '@loopover/ui-kit/components/...'" that looked like a real code bug instead of a skipped
714+ # upstream build -- confirmed live, PR #8182. The job as a whole still fails if any step fails;
715+ # this only stops one unrelated failure from hiding/masking every UI result behind it.
703716 - name : Build UI-kit package
704- if : ${{ github.event_name == 'push' || needs.changes.outputs.ui == 'true' }}
717+ if : ${{ !cancelled() && ( github.event_name == 'push' || needs.changes.outputs.ui == 'true') }}
705718 run : npx turbo run build --filter=@loopover/ui-kit
706719 # apps/loopover-ui's fumadocs-mdx virtual modules (collections/browser, collections/server, imported by
707720 # docs-client-loader.tsx/docs-source.ts) are gitignored generated output, normally produced by npm ci's
@@ -711,7 +724,7 @@ jobs:
711724 # gap as "Build UI-kit package" above (a required, gitignored artifact absent on a fresh/cached
712725 # checkout); runs unconditionally here so cache hit or miss makes no difference.
713726 - name : Generate docs content collections
714- if : ${{ github.event_name == 'push' || needs.changes.outputs.ui == 'true' }}
727+ if : ${{ !cancelled() && ( github.event_name == 'push' || needs.changes.outputs.ui == 'true') }}
715728 run : npm run postinstall --workspace @loopover/ui
716729 # Routed through Turborepo -- "Build UI-kit package" above already built ui-kit's dist once for all of
717730 # lint/typecheck/tests/build in this same job (GitHub Actions steps run strictly sequentially), so
@@ -723,36 +736,39 @@ jobs:
723736 # package.json ui:lint/ui:typecheck scripts themselves, since ui-deploy.yml and CONTRIBUTING.md's
724737 # documented local gate sequence both call those directly and rely on their own ui:kit:build prefix.
725738 - name : UI lint
726- if : ${{ github.event_name == 'push' || needs.changes.outputs.ui == 'true' }}
739+ if : ${{ !cancelled() && ( github.event_name == 'push' || needs.changes.outputs.ui == 'true') }}
727740 run : npx turbo run lint --filter=@loopover/ui --filter=@loopover/ui-miner
728741 - name : UI typecheck
729- if : ${{ github.event_name == 'push' || needs.changes.outputs.ui == 'true' }}
742+ if : ${{ !cancelled() && ( github.event_name == 'push' || needs.changes.outputs.ui == 'true') }}
730743 run : npx turbo run typecheck --filter=@loopover/ui --filter=@loopover/ui-miner
731744 # Split into 3 independent steps (was one `&&`-chained step) -- turbo.json deliberately has no `test`
732745 # task for any package (per the plan doc: test orchestration stays out of Turborepo entirely, so
733746 # Codecov's codecov/patch keeps one centralized source of truth), so this can't use the same
734747 # union-`--filter` fix already applied to "UI lint"/"UI typecheck" two steps above. Plain `&&` meant a
735748 # failing @loopover/ui test silently prevented @loopover/ui-miner's and @loopover/miner-extension's
736749 # tests from ever running in that invocation -- same class of failure-masking bug those two steps'
737- # own comment already describes, just still present here. `!cancelled()` on steps 2/ 3 (not `always()`)
750+ # own comment already describes, just still present here. `!cancelled()` on all 3 (not `always()`)
738751 # matches the pattern already used by "Save Turborepo cache"/"Save TypeScript incremental build
739752 # cache" elsewhere in this file: still run after an earlier step's failure, just not after the job
740753 # was cancelled outright. The job as a whole still fails if any of the three fails.
741754 - name : UI tests (ui)
742- if : ${{ github.event_name == 'push' || needs.changes.outputs.ui == 'true' }}
755+ if : ${{ !cancelled() && ( github.event_name == 'push' || needs.changes.outputs.ui == 'true') }}
743756 run : npm --workspace @loopover/ui run test
744757 - name : UI tests (ui-miner)
745758 if : ${{ !cancelled() && (github.event_name == 'push' || needs.changes.outputs.ui == 'true') }}
746759 run : npm --workspace @loopover/ui-miner run test
747760 - name : UI tests (miner-extension)
748761 if : ${{ !cancelled() && (github.event_name == 'push' || needs.changes.outputs.ui == 'true') }}
749762 run : npm --workspace @loopover/miner-extension run test
750- # Same rationale and --filter union semantics as "UI lint"/"UI typecheck" above.
763+ # Same rationale and --filter union semantics as "UI lint"/"UI typecheck" above -- and the same
764+ # `!cancelled()` need as "Build UI-kit package" through "UI tests (ui)" above: an earlier
765+ # unrelated step failing (a drift check, the MCP version audit) would otherwise skip these too,
766+ # silently hiding real Extension lint/typecheck results behind it.
751767 - name : Extension lint
752- if : ${{ github.event_name == 'push' || needs.changes.outputs.ui == 'true' }}
768+ if : ${{ !cancelled() && ( github.event_name == 'push' || needs.changes.outputs.ui == 'true') }}
753769 run : npx turbo run lint --filter=@loopover/extension --filter=@loopover/miner-extension
754770 - name : Extension typecheck
755- if : ${{ github.event_name == 'push' || needs.changes.outputs.ui == 'true' }}
771+ if : ${{ !cancelled() && ( github.event_name == 'push' || needs.changes.outputs.ui == 'true') }}
756772 run : npx turbo run typecheck --filter=@loopover/extension --filter=@loopover/miner-extension
757773 # `npm run ui:build` also regenerates apps/loopover-ui/public/openapi.json (needed for a
758774 # standalone build), but this step's trigger condition is a strict subset of "OpenAPI drift
@@ -768,7 +784,7 @@ jobs:
768784 # and running this exact invocation regenerates it correctly (the cross-package outputs edge is
769785 # honored, not just replayed from cache).
770786 - name : UI build
771- if : ${{ github.event_name == 'push' || needs.changes.outputs.ui == 'true' }}
787+ if : ${{ !cancelled() && ( github.event_name == 'push' || needs.changes.outputs.ui == 'true') }}
772788 run : npx turbo run build --filter=@loopover/ui
773789 # Paired with "Restore Turborepo cache" above (same key, same gate condition) -- deliberately
774790 # positioned here, after every turbo-routed step in this job (Build engine package, Build MCP, Build
0 commit comments