forked from huggingface/diffusers
-
Notifications
You must be signed in to change notification settings - Fork 0
200 lines (180 loc) · 7.88 KB
/
Copy pathpr_comment_gpu_tests.yml
File metadata and controls
200 lines (180 loc) · 7.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
name: GPU Tests from PR Comment
# Lets maintainers (admin / write access) run GPU tests on a PR by commenting:
# /diffusers-bot pytest <args>
# e.g. `/diffusers-bot pytest tests/models/test_modeling_common.py -k "some_test"`.
on:
issue_comment:
types: [created]
# Default to read-only; jobs that comment opt into `pull-requests: write` explicitly.
permissions:
contents: read
concurrency:
# A newer command on the same PR supersedes an in-flight one.
group: diffusers-bot-${{ github.event.issue.number }}
cancel-in-progress: true
env:
DIFFUSERS_IS_CI: yes
OMP_NUM_THREADS: 8
MKL_NUM_THREADS: 8
HF_XET_HIGH_PERFORMANCE: 1
PYTEST_TIMEOUT: 600
# Force version overrides across every `uv pip install`: pin tokenizers and the
# torch/torchvision/torchaudio set baked into the image so `-U` installs can't bump
# torch and break torchvision's C++ ABI. Re-written into the file in the install step.
UV_OVERRIDE: /tmp/uv-overrides.txt
jobs:
gate:
name: Authorize & launch
# Only react to `/diffusers-bot pytest …` comments on open PRs.
if: |
github.event.issue.pull_request &&
github.event.issue.state == 'open' &&
startsWith(github.event.comment.body, '/diffusers-bot pytest')
runs-on: ubuntu-22.04
permissions:
pull-requests: write
outputs:
pytest_args: ${{ steps.parse.outputs.pytest_args }}
comment_id: ${{ steps.comment.outputs.comment_id }}
steps:
- name: Check commenter permission
id: auth
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
COMMENTER: ${{ github.event.comment.user.login }}
run: |
PERM=$(gh api "repos/${REPO}/collaborators/${COMMENTER}/permission" --jq '.permission' 2>/dev/null || echo "none")
echo "Commenter @${COMMENTER} has permission: ${PERM}"
if [[ "$PERM" == "admin" || "$PERM" == "write" ]]; then
echo "authorized=true" >> "$GITHUB_OUTPUT"
else
echo "authorized=false" >> "$GITHUB_OUTPUT"
fi
- name: Reject unauthorized commenter
if: steps.auth.outputs.authorized != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
PR: ${{ github.event.issue.number }}
COMMENTER: ${{ github.event.comment.user.login }}
run: |
gh api -X POST "repos/${REPO}/issues/${PR}/comments" \
-f body="🚫 Sorry @${COMMENTER}, you're not authorized to run \`/diffusers-bot\`. Only maintainers with write or admin access can trigger GPU tests." >/dev/null
echo "::error::Only maintainers with write/admin access can run /diffusers-bot."
exit 1
- name: Acknowledge with 👀
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
COMMENT_ID: ${{ github.event.comment.id }}
run: |
gh api -X POST "repos/${REPO}/issues/comments/${COMMENT_ID}/reactions" -f content="eyes" >/dev/null
- name: Parse pytest args
id: parse
env:
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
# Use only the first line of the comment, strip the command prefix.
FIRST_LINE=$(printf '%s' "$COMMENT_BODY" | head -n1)
ARGS="${FIRST_LINE#/diffusers-bot pytest}"
# Trim surrounding whitespace/CR.
ARGS="$(printf '%s' "$ARGS" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
echo "pytest_args=${ARGS}" >> "$GITHUB_OUTPUT"
- name: Post "running" comment
id: comment
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
PR: ${{ github.event.issue.number }}
COMMENTER: ${{ github.event.comment.user.login }}
PYTEST_ARGS: ${{ steps.parse.outputs.pytest_args }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
BODY="⏳ Running \`pytest ${PYTEST_ARGS}\` on a GPU runner — [view logs](${RUN_URL}).
Triggered by @${COMMENTER}."
CID=$(gh api -X POST "repos/${REPO}/issues/${PR}/comments" -f body="$BODY" --jq '.id')
echo "comment_id=${CID}" >> "$GITHUB_OUTPUT"
gpu_tests:
name: Run pytest on GPU
needs: gate
runs-on:
group: aws-g4dn-2xlarge
container:
image: diffusers/diffusers-pytorch-cuda
options: --gpus all --shm-size "16gb" --ipc host
# Least privilege: this job checks out and runs untrusted fork code, so it gets no
# write token. Comment writes happen only in `gate`/`report`.
permissions:
contents: read
defaults:
run:
shell: bash
steps:
- name: Checkout PR head
uses: actions/checkout@v6
with:
# Works for forks too — no fork credentials needed.
ref: refs/pull/${{ github.event.issue.number }}/head
fetch-depth: 2
- name: NVIDIA-SMI
run: nvidia-smi
- name: Install dependencies
run: |
printf 'tokenizers<0.23.0\ntorch==2.10.0\ntorchvision==0.25.0\ntorchaudio==2.10.0\n' > "$UV_OVERRIDE"
uv pip install -e ".[quality,training,test]"
uv pip install peft@git+https://github.com/huggingface/peft.git
uv pip uninstall accelerate && uv pip install -U accelerate@git+https://github.com/huggingface/accelerate.git
uv pip uninstall transformers huggingface_hub && UV_PRERELEASE=allow uv pip install -U transformers@git+https://github.com/huggingface/transformers.git
- name: Environment
run: diffusers-cli env
- name: Run pytest
env:
# No secrets here: this step runs untrusted fork code (pytest imports the PR's
# conftest.py/plugins), so exposing a token would let a malicious PR exfiltrate
# it. Public Hub models download without auth; gated-repo tests are unsupported.
# https://pytorch.org/docs/stable/notes/randomness.html#avoiding-nondeterministic-algorithms
CUBLAS_WORKSPACE_CONFIG: :16:8
# Forwarded via env (not interpolated into the script) to avoid breakage on
# quotes/special characters in a legitimate command.
PYTEST_ARGS: ${{ needs.gate.outputs.pytest_args }}
run: |
eval "pytest --make-reports=tests_bot_gpu $PYTEST_ARGS"
- name: Failure short reports
if: ${{ failure() }}
run: |
cat reports/tests_bot_gpu_stats.txt || true
cat reports/tests_bot_gpu_failures_short.txt || true
- name: Test suite reports artifacts
if: ${{ always() }}
uses: actions/upload-artifact@v6
with:
name: bot_gpu_test_reports
path: reports
report:
name: Report status
needs: [gate, gpu_tests]
# Always run so the comment is updated on success, failure, or cancellation —
# but only if `gate` actually posted a comment to update.
if: ${{ always() && needs.gate.outputs.comment_id != '' }}
runs-on: ubuntu-22.04
permissions:
pull-requests: write
steps:
- name: Update comment with final status
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
CID: ${{ needs.gate.outputs.comment_id }}
RESULT: ${{ needs.gpu_tests.result }}
PYTEST_ARGS: ${{ needs.gate.outputs.pytest_args }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
case "$RESULT" in
success) EMOJI="✅"; MSG="passed";;
failure) EMOJI="❌"; MSG="failed";;
cancelled) EMOJI="⚠️"; MSG="was cancelled";;
*) EMOJI="⚠️"; MSG="did not run (${RESULT})";;
esac
BODY="${EMOJI} \`pytest ${PYTEST_ARGS}\` ${MSG} on GPU — [view logs](${RUN_URL})."
gh api -X PATCH "repos/${REPO}/issues/comments/${CID}" -f body="$BODY"