|
1 | 1 | # Runs the custom-node regression suite against a backend that has the manifest |
2 | | -# packs actually installed, so the load/run tiers execute for real. This is a |
3 | | -# GATING check: if a pack fails to install or any tier is skipped, the job goes |
4 | | -# red - a regression gate that let a broken pack through as a "skip" would be |
5 | | -# pointless. Mark `custom-nodes-e2e-status` as the required status check in |
6 | | -# branch protection; it fails closed if path detection or any matrix shard |
7 | | -# fails. |
| 2 | +# packs actually installed, so the load/run tiers execute for real. Within a |
| 3 | +# run the result fails closed: if a pack fails to install or any tier is |
| 4 | +# skipped, the job goes red - a suite that let a broken pack through as a |
| 5 | +# "skip" would be pointless. |
| 6 | +# |
| 7 | +# NOT a PR gate yet: nightly schedule and manual dispatch only. PRs neither |
| 8 | +# trigger this workflow nor wait on any of its checks, and none of its checks |
| 9 | +# may be marked required in branch protection. Before ever adding a |
| 10 | +# pull_request trigger, resolve the untrusted-source surface: the install loop |
| 11 | +# fetches and pip-installs whatever the manifest's deployRefs point at |
| 12 | +# (setup.py executes at install time), so a fork PR editing the manifest could |
| 13 | +# aim it at attacker-controlled source. To test a branch, dispatch with the |
| 14 | +# `branch` input. |
8 | 15 | # |
9 | 16 | # The matrix keeps the six-pack Core depth suite intact and adds the pinned |
10 | 17 | # Cloud snapshot as five breadth shards. The Cloud snapshot produces 87 |
|
15 | 22 | # The gate is deterministic at the SOURCE level: ComfyUI core is pinned at a |
16 | 23 | # verified commit and every pack is installed at the exact deployRef the pinned |
17 | 24 | # Cloud snapshot declares - a commit for git-sourced packs, or a registry |
18 | | -# version's CDN artifact - so no source surface moves underneath a PR. Python |
| 25 | +# version's CDN artifact - so no source surface moves underneath a run. Python |
19 | 26 | # dependencies still resolve fresh, and the runner image updates independently. |
20 | 27 | name: 'CI: Tests Custom Nodes' |
21 | 28 |
|
22 | 29 | on: |
23 | | - pull_request: |
24 | | - branches-ignore: [wip/*, draft/*, temp/*] |
25 | | - push: |
26 | | - branches: [main, master] |
27 | | - merge_group: |
| 30 | + schedule: |
| 31 | + - cron: '15 9 * * *' |
28 | 32 | workflow_dispatch: |
29 | 33 | inputs: |
30 | 34 | detection_proof_row: |
|
51 | 55 |
|
52 | 56 | concurrency: |
53 | 57 | # Dispatches get a per-run group: two manual runs (e.g. comparing branches) |
54 | | - # must not cancel each other, while PR pushes keep the usual per-ref |
55 | | - # supersede behavior. |
| 58 | + # must not cancel each other, while overlapping nightlies supersede per-ref. |
56 | 59 | group: ${{ github.event_name == 'workflow_dispatch' && format('{0}-dispatch-{1}', github.workflow, github.run_id) || format('{0}-{1}', github.workflow, github.ref) }} |
57 | 60 | cancel-in-progress: true |
58 | 61 |
|
59 | 62 | env: |
60 | 63 | COMFYUI_PIN: b08e6cf35fac50d3ca8470dffb3f9a1fbb7187d2 |
61 | 64 |
|
62 | 65 | jobs: |
63 | | - # Path gating lives here, not in a trigger-level `paths:` filter: a required |
64 | | - # check gated by trigger paths never creates a check run on an unrelated PR |
65 | | - # and leaves branch protection stuck Pending. A job-level `if:` still creates |
66 | | - # the check and marks it Skipped (= passing). Mirrors ci-tests-unit.yaml. |
67 | | - changes: |
68 | | - runs-on: ubuntu-latest |
69 | | - permissions: |
70 | | - contents: read |
71 | | - outputs: |
72 | | - should-run: ${{ steps.changes.outputs.should-run }} |
73 | | - steps: |
74 | | - - uses: actions/checkout@v7 |
75 | | - - id: changes |
76 | | - uses: ./.github/actions/changes-filter |
77 | | - |
78 | 66 | # Each job is intentionally one worker: the auto-run tier needs exclusive |
79 | 67 | # access to its backend's queue. Parallelism comes from the shard matrix |
80 | 68 | # instead, and every job owns a separate backend. |
81 | 69 | custom_nodes_e2e: |
82 | | - needs: changes |
83 | 70 | strategy: |
84 | 71 | fail-fast: false |
85 | 72 | matrix: |
@@ -142,17 +129,6 @@ jobs: |
142 | 129 | proof_row: '15' |
143 | 130 | - shard: '5/5' |
144 | 131 | proof_row: '15' |
145 | | - # Run only when non-docs code changed AND the PR is same-repo. Fork PRs can |
146 | | - # edit the manifest's deployRefs, and this job fetches and pip-installs |
147 | | - # whatever they point at (setup.py runs at install time), so an untrusted |
148 | | - # fork must not be able to aim the install at an attacker-controlled source. |
149 | | - # Fork PRs still get the environment-agnostic coverage via the main e2e |
150 | | - # shards. A skipped job counts as passing, so this stays required-safe. |
151 | | - if: >- |
152 | | - github.event_name == 'workflow_dispatch' || |
153 | | - (needs.changes.outputs.should-run == 'true' && |
154 | | - (github.event_name != 'pull_request' || |
155 | | - github.event.pull_request.head.repo.full_name == github.repository)) |
156 | 132 | runs-on: ubuntu-latest |
157 | 133 | # Recent green runs complete in 10-19 minutes per shard. 35 leaves room for a |
158 | 134 | # slow dependency resolve without letting a wedged backend run indefinitely. |
@@ -761,22 +737,13 @@ jobs: |
761 | 737 | custom-nodes-e2e-status: |
762 | 738 | name: custom-nodes-e2e-status |
763 | 739 | if: always() |
764 | | - needs: [changes, custom_nodes_e2e] |
| 740 | + needs: custom_nodes_e2e |
765 | 741 | runs-on: ubuntu-latest |
766 | 742 | steps: |
767 | | - - name: Enforce gate result |
| 743 | + - name: Enforce suite result |
768 | 744 | shell: bash |
769 | 745 | env: |
770 | | - CHANGES_RESULT: ${{ needs.changes.result }} |
771 | | - SHOULD_RUN: ${{ needs.changes.outputs.should-run }} |
772 | 746 | E2E_RESULT: ${{ needs.custom_nodes_e2e.result }} |
773 | | - EVENT_NAME: ${{ github.event_name }} |
774 | | - FORK_PR: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} |
775 | 747 | run: | |
776 | 748 | set -euo pipefail |
777 | | - [ "$CHANGES_RESULT" = success ] || { echo "::error::change detection ended with $CHANGES_RESULT"; exit 1; } |
778 | | - if [ "$EVENT_NAME" != workflow_dispatch ] && { [ "$SHOULD_RUN" != true ] || [ "$FORK_PR" = true ]; }; then |
779 | | - [ "$E2E_RESULT" = skipped ] || { echo "::error::expected a policy skip, got $E2E_RESULT"; exit 1; } |
780 | | - else |
781 | | - [ "$E2E_RESULT" = success ] || { echo "::error::custom-node matrix ended with $E2E_RESULT"; exit 1; } |
782 | | - fi |
| 749 | + [ "$E2E_RESULT" = success ] || { echo "::error::custom-node matrix ended with $E2E_RESULT"; exit 1; } |
0 commit comments