* ci: cancel superseded PR runs and make the bandit job a real gate No PR workflow had a concurrency group, so a new push left the previous run occupying 16 Python matrix runners, the real ComfyUI job and the three viewerjs jobs for up to 25 minutes. Add a group per workflow and PR ref that cancels the older run. Pushes to main use the run id as their group, so no main commit is ever cancelled or dropped as pending. Remove the lint job from code-quality.yml. It ran black and flake8 a second time, partly with --exit-zero, next to the protected "black and flake8" job in test.yml. The security job ran bandit with "|| true" and could never fail. At medium severity it reports 74 findings today, so it now gates on high severity only and prints the medium report without failing. The only two high findings were SHA1 and MD5 used as a gallery entry id and a LoRA preview cache filename; mark both usedforsecurity=False, which leaves every hash value unchanged. Closes #230. * ci: verify superseded PR runs are cancelled * ci: require the bandit high-severity check Review on #231 pointed out that a failing bandit job did not block a merge because its context was not required. Name the job "bandit (high severity)" so the required context is unambiguous, and add it to .github/branch-protection.json and the TESTING.md list of required checks.
183 lines
6.1 KiB
YAML
183 lines
6.1 KiB
YAML
name: Tests
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
push:
|
|
branches: [main]
|
|
|
|
# Superseded PR pushes cancel their older run. Every main push gets its own
|
|
# group (run_id), so no main commit's run is ever cancelled or dropped as pending.
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
|
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
|
|
env:
|
|
PYTHONFAULTHANDLER: "1"
|
|
|
|
jobs:
|
|
test:
|
|
name: py${{ matrix.python-version }} on ${{ matrix.os }}
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- name: Set up Python ${{ matrix.python-version }}
|
|
uses: actions/setup-python@v7
|
|
with:
|
|
python-version: ${{ matrix.python-version }}
|
|
cache: pip
|
|
cache-dependency-path: requirements-dev.txt
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
pip install -r requirements-dev.txt
|
|
|
|
- name: Run tests
|
|
run: python -m unittest discover -s tests -v
|
|
|
|
comfyui:
|
|
name: real ComfyUI compatibility
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 25
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
- uses: actions/setup-node@v7
|
|
with:
|
|
node-version: "24"
|
|
cache: npm
|
|
cache-dependency-path: tools/vendor/package-lock.json
|
|
- name: Read the reviewed runtime pins
|
|
id: runtime
|
|
run: |
|
|
node --input-type=module <<'JS' >> "$GITHUB_OUTPUT"
|
|
import runtime from './tools/vendor/comfyui-runtime.json' with { type: 'json' };
|
|
for (const [key, value] of Object.entries(runtime)) console.log(`${key}=${value}`);
|
|
import crossPack from './tools/vendor/cross-pack-runtime.json' with { type: 'json' };
|
|
console.log(`kikoRepository=${crossPack.repository}`);
|
|
console.log(`kikoRevision=${crossPack.revision}`);
|
|
JS
|
|
- name: Check out pinned ComfyUI
|
|
uses: actions/checkout@v7
|
|
with:
|
|
repository: ${{ steps.runtime.outputs.repository }}
|
|
ref: ${{ steps.runtime.outputs.revision }}
|
|
path: .ci-comfyui
|
|
persist-credentials: false
|
|
- name: Check out pinned KikoTools for compatibility
|
|
uses: actions/checkout@v7
|
|
with:
|
|
repository: ${{ steps.runtime.outputs.kikoRepository }}
|
|
ref: ${{ steps.runtime.outputs.kikoRevision }}
|
|
path: .ci-kikotools
|
|
persist-credentials: false
|
|
- uses: actions/setup-python@v7
|
|
with:
|
|
python-version: ${{ steps.runtime.outputs.pythonVersion }}
|
|
cache: pip
|
|
cache-dependency-path: |
|
|
requirements-dev.txt
|
|
.ci-comfyui/requirements.txt
|
|
tools/vendor/comfyui-runtime.json
|
|
- name: Install CPU runtime and test dependencies
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
pip install "torch==${{ steps.runtime.outputs.torchVersion }}" "torchvision==${{ steps.runtime.outputs.torchvisionVersion }}" --index-url https://download.pytorch.org/whl/cpu
|
|
pip install -r .ci-comfyui/requirements.txt -r requirements-dev.txt "torch==${{ steps.runtime.outputs.torchVersion }}" "torchvision==${{ steps.runtime.outputs.torchvisionVersion }}"
|
|
- run: npm ci --prefix tools/vendor --ignore-scripts
|
|
- run: npx --prefix tools/vendor playwright install --with-deps chromium
|
|
- name: Classic and Nodes 2.0 startup and compatibility
|
|
env:
|
|
PM_COMFY_ROOT: ${{ github.workspace }}/.ci-comfyui
|
|
PM_TEST_PYTHON: python
|
|
run: npm run --prefix tools/vendor test:comfyui
|
|
- name: Real cached and headless execution history
|
|
env:
|
|
PM_COMFY_ROOT: ${{ github.workspace }}/.ci-comfyui
|
|
PM_TEST_PYTHON: python
|
|
run: npm run --prefix tools/vendor test:executions
|
|
- name: Independent and combined pack compatibility
|
|
env:
|
|
PM_COMFY_ROOT: ${{ github.workspace }}/.ci-comfyui
|
|
PM_KIKO_ROOT: ${{ github.workspace }}/.ci-kikotools
|
|
PM_TEST_PYTHON: python
|
|
run: npm run --prefix tools/vendor test:compat
|
|
- name: Upload real-host reports and startup logs
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: real-comfyui-reports
|
|
path: tools/vendor/test-results/
|
|
if-no-files-found: ignore
|
|
retention-days: 14
|
|
|
|
coverage:
|
|
name: coverage gate (85%)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- uses: actions/setup-python@v7
|
|
with:
|
|
python-version: "3.12"
|
|
cache: pip
|
|
cache-dependency-path: requirements-dev.txt
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
pip install -r requirements-dev.txt
|
|
|
|
- name: Measure coverage
|
|
run: |
|
|
python -m coverage run -m unittest discover -s tests
|
|
python -m coverage combine
|
|
python -m coverage report --fail-under=85
|
|
|
|
lint:
|
|
name: black and flake8
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-python@v7
|
|
with:
|
|
python-version: "3.12"
|
|
- run: pip install black flake8
|
|
- run: black --check .
|
|
- run: flake8 .
|
|
|
|
js-test:
|
|
name: frontend modules
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- uses: actions/setup-node@v7
|
|
with:
|
|
node-version: "24"
|
|
|
|
- name: Check shipped extension and page modules parse
|
|
run: |
|
|
shopt -s globstar nullglob
|
|
for f in web/comfy/**/*.js web/comfy/**/*.mjs web/js/**/*.js web/js/**/*.mjs; do
|
|
node --input-type=module --check < "$f" || exit 1
|
|
done
|
|
|
|
- name: Install pinned shared test contracts
|
|
run: npm ci --prefix tools/vendor --ignore-scripts
|
|
|
|
- name: Run JS tests
|
|
run: node --test tests/js/*.test.js
|