Skip to content

Commit a7079a3

Browse files
authored
Merge branch 'main' into glary/design-system-brand-yellow-f2ff59
2 parents 96e23e8 + ed091e4 commit a7079a3

244 files changed

Lines changed: 9670 additions & 2100 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci-oss-assets-validation.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jobs:
112112
--summary \
113113
--excludePackages '@comfyorg/comfyui-frontend;@comfyorg/design-system;@comfyorg/ingest-types;@comfyorg/registry-types;@comfyorg/shared-frontend-utils;@comfyorg/tailwind-utils;@comfyorg/comfyui-electron-types' \
114114
--clarificationsFile .github/license-clarifications.json \
115-
--onlyAllow 'MIT;MIT*;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;0BSD;BlueOak-1.0.0;Python-2.0;CC0-1.0;Unlicense;(MIT OR Apache-2.0);(MIT OR GPL-3.0);(Apache-2.0 OR MIT);(MPL-2.0 OR Apache-2.0);CC-BY-4.0;CC-BY-3.0;GPL-3.0-only'; then
115+
--onlyAllow 'MIT;MIT*;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;0BSD;BlueOak-1.0.0;Python-2.0;CC0-1.0;Unlicense;(MIT OR Apache-2.0);(MIT OR GPL-3.0);(Apache-2.0 OR MIT);(MPL-2.0 OR Apache-2.0);MPL-2.0;CC-BY-4.0;CC-BY-3.0;GPL-3.0-only'; then
116116
echo ''
117117
echo '✅ All production dependency licenses are approved!'
118118
else

.github/workflows/ci-perf-report.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
runs-on: ubuntu-latest
3232
timeout-minutes: 30
3333
container:
34-
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.21
34+
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.22
3535
credentials:
3636
username: ${{ github.actor }}
3737
password: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/ci-tests-e2e.yaml

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
runs-on: ubuntu-latest
5757
timeout-minutes: 60
5858
container:
59-
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.21
59+
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.22
6060
credentials:
6161
username: ${{ github.actor }}
6262
password: ${{ secrets.GITHUB_TOKEN }}
@@ -114,7 +114,7 @@ jobs:
114114
needs: setup
115115
runs-on: ubuntu-latest
116116
container:
117-
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.21
117+
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.22
118118
credentials:
119119
username: ${{ github.actor }}
120120
password: ${{ secrets.GITHUB_TOKEN }}
@@ -203,17 +203,24 @@ jobs:
203203
# expanded check names so PRs with no e2e-relevant changes aren't stuck.
204204
e2e-status:
205205
if: ${{ always() }}
206-
needs: [changes, playwright-tests-chromium-sharded, playwright-tests]
206+
needs:
207+
[
208+
changes,
209+
playwright-tests-chromium-sharded,
210+
playwright-tests,
211+
playwright-video-new-tests
212+
]
207213
runs-on: ubuntu-latest
208214
steps:
209215
- name: Check E2E results
210216
env:
211217
SHOULD_RUN: ${{ needs.changes.outputs.should-run }}
212218
SHARDED: ${{ needs.playwright-tests-chromium-sharded.result }}
213219
BROWSERS: ${{ needs.playwright-tests.result }}
220+
VIDEO: ${{ needs.playwright-video-new-tests.result }}
214221
run: |
215222
[[ "$SHOULD_RUN" != "true" ]] && echo "E2E skipped" && exit 0
216-
[[ "$SHARDED" != "success" || "$BROWSERS" != "success" ]] && echo "E2E failed" && exit 1
223+
[[ "$SHARDED" != "success" || "$BROWSERS" != "success" || ( "$VIDEO" != "success" && "$VIDEO" != "skipped" ) ]] && echo "E2E failed" && exit 1
217224
echo "E2E passed"
218225
219226
# Records video only for spec files newly added in this PR, to keep cost bounded.
@@ -223,7 +230,7 @@ jobs:
223230
runs-on: ubuntu-latest
224231
timeout-minutes: 15
225232
container:
226-
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.21
233+
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.22
227234
credentials:
228235
username: ${{ github.actor }}
229236
password: ${{ secrets.GITHUB_TOKEN }}
@@ -275,8 +282,79 @@ jobs:
275282
if: steps.detect.outputs.has-new-tests == 'true'
276283
run: pnpm install --frozen-lockfile
277284

278-
- name: Run new test(s) with video recording
285+
- name: Find safely recordable new tests
279286
if: steps.detect.outputs.has-new-tests == 'true'
287+
id: recordable
288+
env:
289+
NEW_SPEC_FILES: ${{ steps.detect.outputs.files }}
290+
run: |
291+
FILES=$(echo "$NEW_SPEC_FILES" | tr '\n' ' ')
292+
AUDIT_EXIT=0
293+
AUDIT_OUTPUT=$(pnpm exec playwright test --project=audit --list --pass-with-no-tests $FILES 2>&1) || AUDIT_EXIT=$?
294+
echo "$AUDIT_OUTPUT"
295+
296+
if [ "$AUDIT_EXIT" -ne 0 ]; then
297+
exit "$AUDIT_EXIT"
298+
fi
299+
300+
if ! echo "$AUDIT_OUTPUT" | grep -Fxq 'Total: 0 tests in 0 files'; then
301+
{
302+
echo '## New-test video walkthrough'
303+
echo
304+
echo '### Cannot skip safely: audit tests have no regular CI coverage'
305+
echo
306+
echo 'At least one newly added test is routed to the `audit` project. Unlike the other projects excluded by Chromium, no regular CI job executes audit tests.'
307+
echo 'This video job only records the `chromium` project, so it fails rather than allowing the PR to pass without executing the new audit test.'
308+
echo
309+
echo 'Detected files:'
310+
echo '```text'
311+
echo "$NEW_SPEC_FILES"
312+
echo '```'
313+
echo
314+
echo 'Audit discovery output:'
315+
echo '```text'
316+
echo "$AUDIT_OUTPUT"
317+
echo '```'
318+
} >> "$GITHUB_STEP_SUMMARY"
319+
exit 1
320+
fi
321+
322+
LIST_EXIT=0
323+
LIST_OUTPUT=$(pnpm exec playwright test --project=chromium --list --pass-with-no-tests $FILES 2>&1) || LIST_EXIT=$?
324+
echo "$LIST_OUTPUT"
325+
326+
if [ "$LIST_EXIT" -ne 0 ]; then
327+
exit "$LIST_EXIT"
328+
fi
329+
330+
if ! echo "$LIST_OUTPUT" | grep -Fxq 'Total: 0 tests in 0 files'; then
331+
echo "has-tests=true" >> "$GITHUB_OUTPUT"
332+
exit 0
333+
fi
334+
335+
echo "has-tests=false" >> "$GITHUB_OUTPUT"
336+
{
337+
echo '## New-test video walkthrough'
338+
echo
339+
echo '### Skipped safely: no Chromium-eligible tests'
340+
echo
341+
echo 'The workflow detected newly added Playwright spec files, but none of their tests are eligible for the `chromium` project used to record walkthroughs.'
342+
echo 'This commonly happens when every test uses a project-routing tag excluded by Chromium: `@perf`, `@cloud`, or `@mobile`.'
343+
echo 'The regular project-specific E2E jobs still run these tests. This video job succeeds without creating an empty report or video artifact.'
344+
echo
345+
echo 'Detected files:'
346+
echo '```text'
347+
echo "$NEW_SPEC_FILES"
348+
echo '```'
349+
echo
350+
echo 'Playwright discovery output:'
351+
echo '```text'
352+
echo "$LIST_OUTPUT"
353+
echo '```'
354+
} >> "$GITHUB_STEP_SUMMARY"
355+
356+
- name: Run new test(s) with video recording
357+
if: steps.recordable.outputs.has-tests == 'true'
280358
env:
281359
RECORD_VIDEO: 'true'
282360
SLOW_MO: '1000'
@@ -286,7 +364,7 @@ jobs:
286364
pnpm exec playwright test --project=chromium $FILES
287365
288366
- name: Upload new-test report (with embedded video)
289-
if: ${{ !cancelled() && steps.detect.outputs.has-new-tests == 'true' }}
367+
if: ${{ !cancelled() && steps.recordable.outputs.has-tests == 'true' }}
290368
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
291369
with:
292370
name: playwright-report-new-tests

.github/workflows/pr-update-playwright-expectations.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ jobs:
8181
needs: setup
8282
runs-on: ubuntu-latest
8383
container:
84-
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.21
84+
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.22
8585
credentials:
8686
username: ${{ github.actor }}
8787
password: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release-draft-create.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ jobs:
106106
ref: ${{ github.event.pull_request.merge_commit_sha }}
107107
secrets: inherit
108108

109+
# GITHUB_TOKEN releases emit no events, so the reconciler's own trigger never fires.
110+
enforce_latest:
111+
name: Enforce Latest Release
112+
needs: draft_release
113+
permissions:
114+
contents: write
115+
uses: ./.github/workflows/release-enforce-latest.yaml
116+
secrets:
117+
PR_GH_TOKEN: ${{ secrets.PR_GH_TOKEN }}
118+
109119
comment_release_summary:
110120
name: Comment Release Summary
111121
needs:
@@ -125,6 +135,7 @@ jobs:
125135
fetch-depth: 2
126136

127137
- name: Post release summary comment
138+
continue-on-error: true
128139
uses: ./.github/actions/comment-release-links
129140
with:
130141
issue-number: ${{ github.event.pull_request.number }}
Lines changed: 19 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,38 @@
11
name: Enforce Greatest-Semver-Wins Latest Release
22

3-
# Keeps GitHub's "latest release" flag pinned to the highest stable semver
4-
# tag, so `--front-end-version latest` can never resolve to an older release
5-
# than what's already shipped.
6-
#
7-
# Un-publishing the current latest release is treated as an implicit
8-
# rollback: latest reassigns to the next-highest published stable release.
9-
# This is intentional.
3+
# Un-publishing the latest release rolls Latest back on purpose.
104

115
on:
126
release:
137
types: [published, edited, unpublished, deleted]
148
workflow_dispatch: {}
9+
workflow_call:
10+
secrets:
11+
PR_GH_TOKEN:
12+
required: true
1513
schedule:
16-
- cron: '0 4 * * *' # daily backstop in case a release webhook is dropped
14+
- cron: '0 4 * * *'
1715

18-
# Serialize runs so two near-simultaneous release edits can't race each
19-
# other's `gh release edit --latest` calls. Do NOT cancel-in-progress: a
20-
# queued run still needs to re-check state after the run ahead of it finishes.
2116
concurrency:
2217
group: enforce-latest-release
23-
cancel-in-progress: false
2418

2519
jobs:
2620
enforce-latest:
2721
runs-on: ubuntu-latest
28-
# Defense in depth: GH_TOKEN edits don't retrigger `release` events, but
29-
# this guards against a future PAT/App-token swap that would.
30-
if: github.triggering_actor != 'github-actions[bot]'
22+
# On workflow_call the actor is whoever merged the release PR, often a bot.
23+
if: github.event_name != 'release' || github.triggering_actor != 'github-actions[bot]'
3124
permissions:
32-
contents: write # required: gh release edit / releases API write access
25+
contents: write
3326
steps:
34-
- name: Reconcile "latest" flag to the highest stable semver release
27+
# workflow_call inherits the caller's refs/pull/N/merge, gone once it closes.
28+
- uses: actions/checkout@v7
29+
with:
30+
ref: main
31+
sparse-checkout: scripts/cicd/reconcile-latest-release.sh
32+
sparse-checkout-cone-mode: false
33+
34+
- name: Reconcile Latest to the highest stable semver release
3535
env:
36-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36+
GH_TOKEN: ${{ secrets.PR_GH_TOKEN }}
3737
REPO: ${{ github.repository }}
38-
run: |
39-
set -euo pipefail
40-
41-
echo "Fetching all releases for $REPO..."
42-
RELEASES_JSON=$(gh release list --repo "$REPO" --limit 1000 \
43-
--json tagName,isDraft,isPrerelease,isLatest)
44-
45-
COUNT=$(echo "$RELEASES_JSON" | jq 'length')
46-
if [ "$COUNT" -ge 1000 ]; then
47-
echo "::warning::Release count hit --limit 1000 cap. Results may be truncated."
48-
fi
49-
50-
STABLE_TAGS=$(echo "$RELEASES_JSON" | jq -r \
51-
'.[] | select(.isDraft == false and .isPrerelease == false) | .tagName')
52-
53-
if [ -z "$STABLE_TAGS" ]; then
54-
echo "::warning::No stable (non-draft, non-prerelease) releases found. '--front-end-version latest' will 404 until one exists."
55-
exit 0
56-
fi
57-
58-
# Defensive filter: only strict [v]X.Y.Z tags -- skips "-rc"/"-beta"
59-
# tags mis-flagged as stable, and other monorepo tags (design-system,
60-
# desktop-ui, npm-types, etc.) that aren't ours.
61-
CANDIDATES=()
62-
while IFS= read -r tag; do
63-
if [[ "$tag" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
64-
CANDIDATES+=("$tag")
65-
fi
66-
done <<< "$STABLE_TAGS"
67-
68-
if [ "${#CANDIDATES[@]}" -eq 0 ]; then
69-
echo "::warning::No semver-shaped stable tags found among releases. '--front-end-version latest' will 404 until one exists."
70-
exit 0
71-
fi
72-
73-
# greatest-semver-wins: sort numerically (v-prefix stripped), not by
74-
# tag name or publish date.
75-
TRUE_LATEST_VER=$(printf '%s\n' "${CANDIDATES[@]}" | sed 's/^v//' | sort -V | tail -1)
76-
77-
TRUE_LATEST_TAG=""
78-
for tag in "${CANDIDATES[@]}"; do
79-
if [[ "${tag#v}" == "$TRUE_LATEST_VER" ]]; then
80-
TRUE_LATEST_TAG="$tag"
81-
break
82-
fi
83-
done
84-
85-
[ -n "$TRUE_LATEST_TAG" ] || { echo "::error::BUG: could not resolve TRUE_LATEST_TAG"; exit 1; }
86-
87-
echo "Highest stable semver release: $TRUE_LATEST_TAG"
88-
89-
CURRENT_LATEST_TAG=$(echo "$RELEASES_JSON" | jq -r \
90-
'[.[] | select(.isLatest == true)][0].tagName // empty')
91-
echo "GitHub-flagged 'latest' release: ${CURRENT_LATEST_TAG:-<none>}"
92-
93-
if [ "$CURRENT_LATEST_TAG" == "$TRUE_LATEST_TAG" ]; then
94-
echo "OK: 'latest' already matches the highest stable semver release. No action needed."
95-
exit 0
96-
fi
97-
98-
echo "::warning::'latest' is currently '${CURRENT_LATEST_TAG:-<none>}' but the highest stable semver release is '$TRUE_LATEST_TAG'. Reassigning 'latest' to '$TRUE_LATEST_TAG'."
99-
100-
gh release edit "$TRUE_LATEST_TAG" --repo "$REPO" --latest
101-
102-
{
103-
echo "## Latest-release auto-correction"
104-
echo ""
105-
echo "- Previously flagged as \`latest\`: \`${CURRENT_LATEST_TAG:-<none>}\`"
106-
echo "- Highest stable semver release: \`$TRUE_LATEST_TAG\`"
107-
echo "- Action taken: re-assigned \`latest\` to \`$TRUE_LATEST_TAG\` via \`gh release edit --latest\`"
108-
} >> "$GITHUB_STEP_SUMMARY"
38+
run: ./scripts/cicd/reconcile-latest-release.sh

0 commit comments

Comments
 (0)