-
Notifications
You must be signed in to change notification settings - Fork 7.4k
150 lines (137 loc) · 5.85 KB
/
Copy pathbot_pytest.yml
File metadata and controls
150 lines (137 loc) · 5.85 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
name: "Bot: Pytest"
# Reusable workflow called by diffusers_bot.yml for `/diffusers-bot pytest <args>`.
# Runs pytest on a GPU runner and reports the result back on the PR.
on:
workflow_call:
inputs:
pytest_args:
required: true
type: string
jobs:
gate:
name: Acknowledge
runs-on: ubuntu-22.04
permissions:
pull-requests: write
outputs:
comment_id: ${{ steps.comment.outputs.comment_id }}
steps:
- 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: 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: ${{ inputs.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:
name: Run pytest on GPU
needs: gate
# A newer command on the same PR supersedes an in-flight one. Scoped to this job
# only so the superseded run's `report` still updates its comment.
concurrency:
group: diffusers-bot-pytest-${{ github.event.issue.number }}
cancel-in-progress: true
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
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 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
defaults:
run:
shell: bash
steps:
- name: Checkout PR head
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
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 'torch==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: ${{ inputs.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@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: bot_gpu_test_reports
path: reports
report:
name: Report status
needs: [gate, gpu]
# 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.result }}
PYTEST_ARGS: ${{ inputs.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"