* 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.
104 lines
3.6 KiB
YAML
104 lines
3.6 KiB
YAML
name: Viewer.js vendor and compatibility
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
push:
|
|
branches: [main]
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
# 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' }}
|
|
|
|
jobs:
|
|
frontend-coverage:
|
|
name: frontend coverage (chromium and touch)
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 25
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-python@v7
|
|
with:
|
|
python-version: '3.12'
|
|
cache: pip
|
|
cache-dependency-path: requirements-dev.txt
|
|
- run: python -m pip install -r requirements-dev.txt
|
|
- uses: actions/setup-node@v7
|
|
with:
|
|
node-version: '24'
|
|
cache: npm
|
|
cache-dependency-path: tools/vendor/package-lock.json
|
|
- run: npm ci --prefix tools/vendor --ignore-scripts
|
|
- run: npm run --prefix tools/vendor check
|
|
- run: npm run --prefix tools/vendor test
|
|
- run: npx --prefix tools/vendor playwright install --with-deps chromium
|
|
- name: Frontend unit, viewer, workflow, and coverage checks
|
|
run: npm run --prefix tools/vendor test:coverage
|
|
- name: Upload frontend coverage and Chromium traces
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: frontend-test-reports
|
|
path: |
|
|
tools/vendor/test-results/
|
|
coverage/js/
|
|
!coverage/js/raw/**
|
|
retention-days: 14
|
|
|
|
browser-workflows:
|
|
name: page workflows (${{ matrix.browser }})
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 25
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
browser: [firefox, webkit]
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-python@v7
|
|
with:
|
|
python-version: '3.12'
|
|
cache: pip
|
|
cache-dependency-path: requirements-dev.txt
|
|
- run: python -m pip install -r requirements-dev.txt
|
|
- uses: actions/setup-node@v7
|
|
with:
|
|
node-version: '24'
|
|
cache: npm
|
|
cache-dependency-path: tools/vendor/package-lock.json
|
|
- run: npm ci --prefix tools/vendor --ignore-scripts
|
|
- run: npx --prefix tools/vendor playwright install --with-deps ${{ matrix.browser }}
|
|
- name: Page workflows in ${{ matrix.browser }}
|
|
run: npm run --prefix tools/vendor test:workflows -- --project ${{ matrix.browser }}
|
|
- name: Upload browser traces
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: browser-traces-${{ matrix.browser }}
|
|
path: tools/vendor/test-results/
|
|
retention-days: 14
|
|
|
|
# Branch protection requires the exact context "viewerjs". This job keeps that
|
|
# name and fails unless every frontend job above succeeded, including when one
|
|
# was cancelled or skipped.
|
|
viewerjs:
|
|
needs: [frontend-coverage, browser-workflows]
|
|
if: always()
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
steps:
|
|
- name: Require every frontend job to succeed
|
|
env:
|
|
COVERAGE_RESULT: ${{ needs.frontend-coverage.result }}
|
|
WORKFLOWS_RESULT: ${{ needs.browser-workflows.result }}
|
|
run: |
|
|
echo "frontend-coverage: $COVERAGE_RESULT"
|
|
echo "browser-workflows: $WORKFLOWS_RESULT"
|
|
test "$COVERAGE_RESULT" = success && test "$WORKFLOWS_RESULT" = success
|