1
0
mirror of https://github.com/huggingface/diffusers.git synced 2026-10-24 20:59:27 +03:00
Files
diffusers/.github/workflows/bot_pytest.yml
hf-security-analysis[bot] 0377f0c1b3 Pin GitHub Actions to commit SHAs (#14853)
A tag is mutable: whoever controls the action's repository can move
`v4` to different code, and the next run picks it up with no diff to
review. Pinning to the commit SHA freezes the code that runs today.

Co-authored-by: hf-security-analysis[bot] <265538906+hf-security-analysis[bot]@users.noreply.github.com>
2026-09-23 16:05:59 +02:00

151 lines
5.8 KiB
YAML

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"