Files
ComfyUI_frontend/.github/workflows/pr-qa.yaml

561 lines
24 KiB
YAML

# Automated QA of ComfyUI frontend using Claude CLI + playwright-cli.
# Two modes:
# Focused (qa-changes label): Linux-only, tests areas affected by PR changes
# Full (qa-full label): 3-OS matrix, full test plan
name: 'PR: QA'
on:
# TODO: remove push trigger before merge
push:
branches: [sno-skills]
pull_request:
types: [labeled]
branches: [main]
workflow_dispatch:
inputs:
mode:
description: 'QA mode'
type: choice
options: [focused, full]
default: focused
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
resolve-matrix:
runs-on: ubuntu-latest
outputs:
os: ${{ steps.set.outputs.os }}
mode: ${{ steps.set.outputs.mode }}
skip: ${{ steps.set.outputs.skip }}
steps:
- name: Determine QA mode
id: set
env:
LABEL: ${{ github.event.label.name }}
EVENT_ACTION: ${{ github.event.action }}
EVENT_NAME: ${{ github.event_name }}
INPUT_MODE: ${{ inputs.mode }}
run: |
FULL=false
# Only run on label events if it's one of our labels
if [ "$EVENT_ACTION" = "labeled" ] && \
[ "$LABEL" != "qa-changes" ] && [ "$LABEL" != "qa-full" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
fi
# Full QA triggers
if [ "$EVENT_NAME" = "workflow_dispatch" ] && \
[ "$INPUT_MODE" = "full" ]; then
FULL=true
fi
if [ "$LABEL" = "qa-full" ]; then
FULL=true
fi
if [ "$FULL" = "true" ]; then
echo 'os=["ubuntu-latest","macos-latest","windows-latest"]' >> "$GITHUB_OUTPUT"
echo "mode=full" >> "$GITHUB_OUTPUT"
else
echo 'os=["ubuntu-latest"]' >> "$GITHUB_OUTPUT"
echo "mode=focused" >> "$GITHUB_OUTPUT"
fi
echo "Mode: $([ "$FULL" = "true" ] && echo full || echo focused)"
qa:
needs: resolve-matrix
if: needs.resolve-matrix.outputs.skip != 'true'
strategy:
fail-fast: false
matrix:
os: ${{ fromJson(needs.resolve-matrix.outputs.os) }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
permissions:
pull-requests: write
env:
QA_MODE: ${{ needs.resolve-matrix.outputs.mode }}
steps:
- name: Set QA artifacts path
shell: bash
run: echo "QA_ARTIFACTS=$RUNNER_TEMP/qa-artifacts" >> "$GITHUB_ENV"
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
ref: ${{ github.head_ref || github.ref }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup frontend
uses: ./.github/actions/setup-frontend
with:
include_build_step: true
- name: Setup and start ComfyUI server
uses: ./.github/actions/setup-comfyui-server
with:
launch_server: 'true'
- name: Wait for ComfyUI server
shell: bash
run: |
echo "Waiting for ComfyUI server..."
for i in $(seq 1 60); do
if curl -sf http://127.0.0.1:8188/api/system_stats >/dev/null 2>&1; then
echo "Server ready"; exit 0
fi; sleep 2
done
echo "::error::Server timeout"; exit 1
- name: Install playwright-cli and Codex CLI
shell: bash
run: |
npm install -g @playwright/cli@latest @openai/codex@latest
# Verify playwright-cli is in PATH and install browser
which playwright-cli
playwright-cli --version || true
npx playwright install chromium
- name: Configure playwright-cli output
shell: bash
run: |
mkdir -p "$QA_ARTIFACTS" .playwright
# Auto-record video + save screenshots to artifacts dir
cat > .playwright/cli.config.json <<CEOF
{
"outputDir": "$QA_ARTIFACTS",
"saveVideo": { "width": 1280, "height": 720 }
}
CEOF
echo "playwright-cli config:"
cat .playwright/cli.config.json
- name: Get PR diff for focused QA
if: needs.resolve-matrix.outputs.mode == 'focused'
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr diff ${{ github.event.pull_request.number || '' }} \
--repo ${{ github.repository }} > "${{ runner.temp }}/pr-diff.txt" 2>/dev/null || \
git diff origin/main...HEAD > "${{ runner.temp }}/pr-diff.txt"
# Summarize changed files for the prompt
echo "Changed files:"
grep '^diff --git' "${{ runner.temp }}/pr-diff.txt" | \
sed 's|diff --git a/||;s| b/.*||' | sort -u | tee "${{ runner.temp }}/changed-files.txt"
- name: Write QA prompt
shell: bash
env:
BRANCH: ${{ github.head_ref || github.ref_name }}
PR_NUM: ${{ github.event.pull_request.number || 'N/A' }}
SHA: ${{ github.sha }}
run: |
OS_LOWER=$(echo "$RUNNER_OS" | tr '[:upper:]' '[:lower:]')
if [ "$QA_MODE" = "full" ]; then
cat > "${{ runner.temp }}/qa-prompt.txt" <<PROMPT
You are running a FULL automated QA pass on the ComfyUI frontend.
Read the file .claude/skills/comfy-qa/SKILL.md and follow the FULL QA test plan.
Environment: CI=true, OS=${{ runner.os }}
Server URL: http://127.0.0.1:8188
Branch: ${BRANCH}
PR: #${PR_NUM}
Commit: ${SHA}
CRITICAL: "playwright-cli" is already installed globally in PATH. Do NOT use pnpm dlx or npx.
Chromium is already installed. Just run the commands directly.
You MUST follow these exact steps in order:
1. playwright-cli open http://127.0.0.1:8188
2. playwright-cli video-start
3. playwright-cli snapshot
4. Test the UI (click, fill, navigate — use snapshot between actions to get refs)
5. playwright-cli video-stop ${QA_ARTIFACTS}/qa-session.webm
6. Write report to ${QA_ARTIFACTS}/$(date +%Y-%m-%d)-001-${OS_LOWER}-report.md
Do NOT skip steps 1-2 or 5-6. Do NOT use pnpm/npx to run playwright-cli.
Do NOT create a PR, post PR comments, commit, or push anything.
Skip tests not available in CI (file dialogs, GPU execution).
PROMPT
else
cat > "${{ runner.temp }}/qa-prompt.txt" <<PROMPT
You are running a FOCUSED QA pass on a pull request to the ComfyUI frontend.
Your goal is to verify that the changes in this PR work correctly and don't break related functionality.
Environment: CI=true, OS=${{ runner.os }}
Server URL: http://127.0.0.1:8188
Branch: ${BRANCH}
PR: #${PR_NUM}
Commit: ${SHA}
CHANGED FILES:
$(cat "${{ runner.temp }}/changed-files.txt" 2>/dev/null || echo "Unknown")
DIFF (truncated to 500 lines):
$(head -500 "${{ runner.temp }}/pr-diff.txt" 2>/dev/null || echo "No diff available")
CRITICAL: "playwright-cli" is already installed globally in PATH. Do NOT use pnpm dlx or npx.
Chromium is already installed. Just run the commands directly.
You MUST follow these exact steps in order:
1. playwright-cli open http://127.0.0.1:8188
2. playwright-cli video-start
3. playwright-cli snapshot
4. Test the changed UI areas (click, fill, navigate — use snapshot between actions)
5. Quick smoke test: app loads, canvas renders, sidebar works
6. playwright-cli video-stop ${QA_ARTIFACTS}/qa-session.webm
7. Write report to ${QA_ARTIFACTS}/$(date +%Y-%m-%d)-001-${OS_LOWER}-report.md
Do NOT skip steps 1-2 or 6-7. Do NOT use pnpm/npx to run playwright-cli.
Do NOT create a PR, post PR comments, commit, or push anything.
Skip tests not available in CI (file dialogs, GPU execution).
PROMPT
fi
- name: Run Codex QA
shell: bash
env:
CODEX_API_KEY: ${{ secrets.OPENAI_API_KEY }}
CI: 'true'
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
codex exec \
--model gpt-5.4-mini \
--sandbox danger-full-access \
- < "${{ runner.temp }}/qa-prompt.txt"
- name: Collect artifacts
if: always()
shell: bash
run: |
mkdir -p "$QA_ARTIFACTS"
echo "=== QA artifacts ==="
ls -la "$QA_ARTIFACTS/" 2>/dev/null | head -30
# Check for video from explicit video-stop command
if [ -f "$QA_ARTIFACTS/qa-session.webm" ]; then
echo "Found video: $QA_ARTIFACTS/qa-session.webm ($(du -h "$QA_ARTIFACTS/qa-session.webm" | cut -f1))"
else
echo "No qa-session.webm found at expected path"
# Search for any .webm in artifacts dir or playwright-cli output
VIDEO=$(find "$QA_ARTIFACTS" . -maxdepth 3 -name '*.webm' -not -path '*/node_modules/*' 2>/dev/null | head -1)
if [ -n "$VIDEO" ]; then
echo "Found fallback video: $VIDEO ($(du -h "$VIDEO" | cut -f1))"
cp "$VIDEO" "$QA_ARTIFACTS/qa-session.webm"
else
echo "WARNING: No .webm video found anywhere"
fi
fi
echo "=== Final artifacts ==="
ls -la "$QA_ARTIFACTS/" 2>/dev/null | head -30
- name: Upload QA artifacts
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v6.2.0
with:
name: qa-report-${{ runner.os }}-${{ github.run_id }}
path: ${{ env.QA_ARTIFACTS }}/
retention-days: 14
report:
needs: [resolve-matrix, qa]
if: always() && (github.event.pull_request.number || github.event_name == 'push')
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Resolve PR number
id: pr
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUM: ${{ github.event.pull_request.number }}
run: |
if [ -n "$PR_NUM" ]; then
echo "number=$PR_NUM" >> "$GITHUB_OUTPUT"
else
# Push event: look up open PR for this branch
NUM=$(gh pr list --repo "${{ github.repository }}" \
--head "${{ github.ref_name }}" --state open \
--json number --jq '.[0].number // empty')
echo "number=${NUM}" >> "$GITHUB_OUTPUT"
fi
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup frontend
uses: ./.github/actions/setup-frontend
- name: Download QA artifacts
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
path: qa-artifacts
pattern: qa-report-*
- name: Normalize artifact layout
run: |
# download-artifact v7 extracts flat when there's only 1 artifact.
# If qa-report-* subdirs don't exist, move flat files into the right subdir.
if ! ls -d qa-artifacts/qa-report-* >/dev/null 2>&1; then
echo "No qa-report-* subdirs found — reorganizing flat download"
# Detect OS from report filename (e.g. *-linux-report.md)
for os in Linux macOS Windows; do
OS_LOWER=$(echo "$os" | tr '[:upper:]' '[:lower:]')
if ls qa-artifacts/*-${OS_LOWER}-report.md >/dev/null 2>&1; then
DEST="qa-artifacts/qa-report-${os}-${{ github.run_id }}"
mkdir -p "$DEST"
find qa-artifacts -maxdepth 1 -type f -exec mv {} "$DEST/" \;
[ -d qa-artifacts/videos ] && mv qa-artifacts/videos "$DEST/"
echo "Moved flat files into $DEST"
break
fi
done
fi
echo "=== Artifact structure ==="
find qa-artifacts -type f 2>/dev/null | head -20
- name: Install ffmpeg
run: |
if command -v ffmpeg &>/dev/null; then
echo "ffmpeg already installed"
else
echo "Downloading static ffmpeg..."
TMP=$(mktemp -d)
curl -sL "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz" | tar xJ -C "$TMP"
sudo cp "$TMP"/ffmpeg-*/ffmpeg /usr/local/bin/
rm -rf "$TMP"
fi
ffmpeg -version | head -1
- name: Convert videos to mp4
run: |
for dir in qa-artifacts/qa-report-*; do
[ -d "$dir" ] || continue
WEBM=$(find "$dir" -name '*.webm' -type f | head -1)
if [ -z "$WEBM" ]; then
echo "No .webm video in $dir, skipping"
continue
fi
echo "Converting $WEBM ($(du -h "$WEBM" | cut -f1)) to mp4"
ffmpeg -y -i "$WEBM" \
-c:v libx264 -preset ultrafast -crf 23 -pix_fmt yuv420p \
"$dir/qa-session.mp4" 2>&1 | tail -5 \
|| echo "ffmpeg conversion failed for $WEBM (non-fatal)"
if [ -f "$dir/qa-session.mp4" ]; then
echo "Created: $dir/qa-session.mp4 ($(du -h "$dir/qa-session.mp4" | cut -f1))"
fi
done
- name: Run video review
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
mkdir -p video-reviews
for vid in qa-artifacts/qa-report-*/qa-session.mp4; do
[ -f "$vid" ] || continue
echo "::group::Reviewing $vid"
pnpm exec tsx scripts/qa-video-review.ts \
--artifacts-dir qa-artifacts \
--output-dir video-reviews \
--video-file "$vid" \
--model gpt-4.1-mini || true
echo "::endgroup::"
done
- name: Deploy to Cloudflare Pages
id: deploy-videos
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
RAW_BRANCH: ${{ github.head_ref || github.ref_name }}
run: |
npm install -g wrangler@4.74.0 >/dev/null 2>&1
DEPLOY_DIR=$(mktemp -d)
mkdir -p "$DEPLOY_DIR"
for os in Linux macOS Windows; do
VID="qa-artifacts/qa-report-${os}-${{ github.run_id }}/qa-session.mp4"
if [ -f "$VID" ]; then
cp "$VID" "$DEPLOY_DIR/qa-${os}.mp4"
echo "Found ${os} video ($(du -h "$VID" | cut -f1))"
# Generate GIF thumbnail
ffmpeg -y -ss 10 -i "$VID" -t 8 \
-vf "fps=8,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=64[p];[s1][p]paletteuse=dither=bayer" \
-loop 0 "$DEPLOY_DIR/qa-${os}-thumb.gif" 2>/dev/null \
|| ffmpeg -y -i "$VID" -t 8 \
-vf "fps=8,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=64[p];[s1][p]paletteuse=dither=bayer" \
-loop 0 "$DEPLOY_DIR/qa-${os}-thumb.gif" 2>/dev/null \
|| echo "GIF generation failed for ${os} (non-fatal)"
fi
done
# Build video cards and report sections
CARDS=""
ICONS_Linux="&#x1F427;" ICONS_macOS="&#x1F34E;" ICONS_Windows="&#x1FA9F;"
for os in Linux macOS Windows; do
eval "ICON=\$ICONS_${os}"
OS_LOWER=$(echo "$os" | tr '[:upper:]' '[:lower:]')
# Copy GPT report if available
REPORT_FILE="video-reviews/${OS_LOWER}-qa-video-report.md"
REPORT_LINK=""
REPORT_HTML=""
if [ -f "$REPORT_FILE" ]; then
cp "$REPORT_FILE" "$DEPLOY_DIR/report-${OS_LOWER}.md"
REPORT_LINK="<a class=download href=report-${OS_LOWER}.md>GPT Report</a>"
# Convert markdown to basic HTML for inline display
REPORT_CONTENT=$(sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g' "$REPORT_FILE" \
| sed 's/^## \(.*\)/<h3>\1<\/h3>/; s/^# \(.*\)/<h2>\1<\/h2>/' \
| sed 's/|\(.*\)|/<tr><td>\1<\/td><\/tr>/g' \
| sed '/^$/s/.*/<br>/')
REPORT_HTML="<details class=report><summary>GPT Video Review</summary><div class=report-body>${REPORT_CONTENT}</div></details>"
fi
if [ -f "$DEPLOY_DIR/qa-${os}.mp4" ]; then
CARDS="${CARDS}<div class=card><video controls autoplay muted loop preload=metadata><source src=qa-${os}.mp4 type=video/mp4></video><div class=card-body><span class=platform><span class=icon>${ICON}</span> ${os}</span><span class=links><a class=download href=qa-${os}.mp4 download>Download</a>${REPORT_LINK}</span></div>${REPORT_HTML}</div>"
else
CARDS="${CARDS}<div class=card><div class=empty-card>No recording available</div><div class=card-body><span class=platform><span class=icon>${ICON}</span> ${os}</span><span class='badge missing'>Missing</span></div></div>"
fi
done
cat > "$DEPLOY_DIR/index.html" <<INDEXEOF
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>QA Session Recordings</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}body{background:#0d1117;color:#e6edf3;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;min-height:100vh;padding:2rem 1rem}.container{max-width:1200px;margin:0 auto}header{display:flex;align-items:center;gap:.75rem;margin-bottom:2rem;padding-bottom:1rem;border-bottom:1px solid #30363d}h1{font-size:1.5rem;font-weight:600}.meta{color:#8b949e;font-size:.875rem;margin-top:.25rem}.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:1.25rem}.card{background:#161b22;border:1px solid #30363d;border-radius:.5rem;overflow:hidden;transition:border-color .15s}.card:hover{border-color:#58a6ff}.card video{width:100%;display:block;background:#010409;aspect-ratio:16/9;object-fit:contain}.card-body{padding:.75rem 1rem;display:flex;align-items:center;justify-content:space-between}.platform{display:flex;align-items:center;gap:.5rem;font-weight:500}.icon{font-size:1.25rem}.links{display:flex;gap:.75rem}.badge{font-size:.75rem;padding:.125rem .5rem;border-radius:999px;background:#1f6feb33;color:#58a6ff;border:1px solid #1f6feb55}.badge.missing{background:#da363333;color:#f85149;border-color:#da363355}.empty-card{display:flex;align-items:center;justify-content:center;min-height:200px;color:#484f58;font-size:.875rem}a.download{color:#58a6ff;text-decoration:none;font-size:.8125rem}a.download:hover{text-decoration:underline}.report{border-top:1px solid #30363d;padding:.75rem 1rem;font-size:.8125rem}.report summary{cursor:pointer;color:#8b949e;font-weight:500}.report summary:hover{color:#e6edf3}.report-body{margin-top:.75rem;line-height:1.6;color:#c9d1d9;white-space:pre-wrap;overflow-x:auto}.report-body h2,.report-body h3{margin:1rem 0 .5rem;color:#e6edf3}.report-body h2{font-size:1.1rem}.report-body h3{font-size:.95rem}
</style></head><body><div class=container>
<header><svg width=28 height=28 viewBox="0 0 24 24" fill=none stroke=#58a6ff stroke-width=2 stroke-linecap=round stroke-linejoin=round><polygon points="23 7 16 12 23 17 23 7"/><rect x=1 y=5 width=15 height=14 rx=2 ry=2/></svg><div><h1>QA Session Recordings</h1><div class=meta>ComfyUI Frontend &middot; Automated QA</div></div></header>
<div class=grid>${CARDS}</div>
</div></body></html>
INDEXEOF
cat > "$DEPLOY_DIR/404.html" <<'ERROREOF'
<!DOCTYPE html><html><head><meta charset=utf-8><title>404</title>
<style>body{background:#0d1117;color:#8b949e;font-family:sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0}div{text-align:center}h1{color:#f85149;font-size:3rem;margin-bottom:.5rem}p{font-size:1rem}</style>
</head><body><div><h1>404</h1><p>File not found. The QA recording may have failed or been cancelled.</p></div></body></html>
ERROREOF
BRANCH=$(echo "$RAW_BRANCH" | sed 's/[^a-zA-Z0-9-]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' | cut -c1-28)
URL=$(wrangler pages deploy "$DEPLOY_DIR" \
--project-name="comfyui-qa-videos" \
--branch="$BRANCH" 2>&1 \
| grep -oE 'https://[a-zA-Z0-9.-]+\.pages\.dev\S*' | head -1)
echo "url=${URL:-https://${BRANCH}.comfyui-qa-videos.pages.dev}" >> "$GITHUB_OUTPUT"
echo "Deployed to: ${URL}"
- name: Post unified QA comment on PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VIDEO_BASE: ${{ steps.deploy-videos.outputs.url }}
QA_MODE: ${{ needs.resolve-matrix.outputs.mode }}
run: |
RUN="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
COMMENT_MARKER="<!-- QA_REPORT_COMMENT -->"
MODE_BADGE="🔍 Focused"
if [ "$QA_MODE" = "full" ]; then MODE_BADGE="🔬 Full (3-OS)"; fi
# Build video section with GIF thumbnails linking to full videos
VIDEO_SECTION=""
for os in Linux macOS Windows; do
GIF_URL="${VIDEO_BASE}/qa-${os}-thumb.gif"
VID_URL="${VIDEO_BASE}/qa-${os}.mp4"
if curl -sf --head "$VID_URL" >/dev/null 2>&1; then
if curl -sf --head "$GIF_URL" >/dev/null 2>&1; then
VIDEO_SECTION="${VIDEO_SECTION}[![${os} QA](${GIF_URL})](${VID_URL})"$'\n'
else
VIDEO_SECTION="${VIDEO_SECTION}[${os} video](${VID_URL})"$'\n'
fi
fi
done
# Build video review section from per-platform reports
VIDEO_REVIEW=""
for f in video-reviews/*-qa-video-report.md; do
[ -f "$f" ] || continue
[ -n "$VIDEO_REVIEW" ] && VIDEO_REVIEW="${VIDEO_REVIEW}
---
"
VIDEO_REVIEW="${VIDEO_REVIEW}$(cat "$f")"
done
VIDEO_REVIEW_SECTION=""
if [ -n "$VIDEO_REVIEW" ]; then
VIDEO_REVIEW_SECTION=$(cat <<REVIEWEOF
<details>
<summary>Video Review</summary>
${VIDEO_REVIEW}
</details>
REVIEWEOF
)
fi
BODY=$(cat <<EOF
${COMMENT_MARKER}
## QA ${MODE_BADGE}
${VIDEO_SECTION}
**Run**: [${RUN}](${RUN}) · [Download artifacts](${RUN}#artifacts) · [All videos](${VIDEO_BASE})
${VIDEO_REVIEW_SECTION}
EOF
)
PR_NUM="${{ steps.pr.outputs.number }}"
if [ -z "$PR_NUM" ]; then
echo "No PR found, skipping comment"
exit 0
fi
EXISTING=$(gh api "repos/${{ github.repository }}/issues/${PR_NUM}/comments" \
--jq ".[] | select(.body | contains(\"${COMMENT_MARKER}\")) | .id" | head -1)
if [ -n "$EXISTING" ]; then
gh api --method PATCH "repos/${{ github.repository }}/issues/comments/${EXISTING}" \
--field body="$BODY"
else
gh pr comment "$PR_NUM" \
--repo ${{ github.repository }} --body "$BODY"
fi
- name: Cleanup old video review comments
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUM="${{ steps.pr.outputs.number }}"
if [ -z "$PR_NUM" ]; then exit 0; fi
OLD_MARKER="<!-- QA_VIDEO_REVIEW_COMMENT -->"
gh api "repos/${{ github.repository }}/issues/${PR_NUM}/comments" \
--jq ".[] | select(.body | contains(\"${OLD_MARKER}\")) | .id" | \
while read -r comment_id; do
echo "Deleting old video review comment: $comment_id"
gh api --method DELETE "repos/${{ github.repository }}/issues/comments/${comment_id}" || true
done
- name: Remove QA label
if: >-
github.event.label.name == 'qa-changes' ||
github.event.label.name == 'qa-full'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LABEL_NAME: ${{ github.event.label.name }}
PR_NUMBER: ${{ steps.pr.outputs.number }}
REPO: ${{ github.repository }}
run: |
[ -n "$PR_NUMBER" ] && gh pr edit "$PR_NUMBER" --repo "$REPO" --remove-label "$LABEL_NAME"