diff --git a/.github/workflows/ci-trigger-full-suite.yml b/.github/workflows/ci-trigger-full-suite.yml index bc8bfcc48..94de6fec0 100644 --- a/.github/workflows/ci-trigger-full-suite.yml +++ b/.github/workflows/ci-trigger-full-suite.yml @@ -20,10 +20,14 @@ permissions: jobs: trigger: + # Stacked PRs (base is another PR branch) skip here instead of failing on + # every push; the merge gate only applies to the default branch. An explicit + # `/merge` call still reaches the base check below and fails loudly. if: >- inputs.pr_number > 0 - || (github.event.action == 'labeled' && github.event.label.name == 'ready') - || github.event.action == 'synchronize' + || (github.event.pull_request.base.ref == github.event.repository.default_branch + && ((github.event.action == 'labeled' && github.event.label.name == 'ready') + || github.event.action == 'synchronize')) runs-on: ubuntu-latest # Job-level concurrency: only this guarded job acquires the group, so an # unrelated `labeled` event (which skips the job) cannot cancel an in-flight diff --git a/.github/workflows/publish-comfyui.yml b/.github/workflows/publish-comfyui.yml index 031d52b3d..0e104d0f8 100644 --- a/.github/workflows/publish-comfyui.yml +++ b/.github/workflows/publish-comfyui.yml @@ -12,10 +12,43 @@ permissions: issues: write jobs: - publish-node: - name: Publish Custom Node to registry + # Any pyproject.toml edit triggers this workflow, but the registry rejects a + # version it already has ("The node version already exists"). Publish only + # when [project].version changed, as the PyPI workflow does. + check-version-change: runs-on: ubuntu-latest if: ${{ github.repository_owner == 'hao-ai-lab' }} + outputs: + changed: ${{ steps.check.outputs.changed }} + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 2 + - name: Compare [project].version with the previous commit + id: check + shell: python + run: | + import os + import subprocess + import tomllib + + def version(text: str) -> str | None: + return tomllib.loads(text).get("project", {}).get("version") + + new = version(open("pyproject.toml", encoding="utf-8").read()) + previous = subprocess.run(["git", "show", "HEAD~1:pyproject.toml"], capture_output=True, text=True) + old = version(previous.stdout) if previous.returncode == 0 else None + changed = new is not None and new != old + print(f"previous version: {old}, current version: {new}, changed: {changed}") + with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output: + output.write(f"changed={str(changed).lower()}\n") + + publish-node: + name: Publish Custom Node to registry + needs: check-version-change + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'hao-ai-lab' && (needs.check-version-change.outputs.changed == 'true' || github.event_name == 'workflow_dispatch') }} steps: - name: Check out code uses: actions/checkout@v4 @@ -25,4 +58,4 @@ jobs: uses: Comfy-Org/publish-node-action@v1 with: ## Add your own personal access token to your Github Repository secrets and reference it here. - personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }} \ No newline at end of file + personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }} diff --git a/fastvideo/tests/attention/test_cudnn_sdpa_dense.py b/fastvideo/tests/attention/test_cudnn_sdpa_dense.py index d3c369bbe..92f232cff 100644 --- a/fastvideo/tests/attention/test_cudnn_sdpa_dense.py +++ b/fastvideo/tests/attention/test_cudnn_sdpa_dense.py @@ -49,14 +49,11 @@ def test_cudnn_route_presents_bhsd_strided_views(): def test_cudnn_route_is_bit_identical_to_cudnn_dispatched_sdpa(): query, key, value = _qkv(2048) scale = 1.0 / math.sqrt(query.shape[-1]) - previous = torch.backends.cuda.cudnn_sdp_enabled() - torch.backends.cuda.enable_cudnn_sdp(True) - try: - with torch.no_grad(): - reference = torch.nn.functional.scaled_dot_product_attention( - query.transpose(1, 2), key.transpose(1, 2), value.transpose(1, 2), scale=scale).transpose(1, 2) - finally: - torch.backends.cuda.enable_cudnn_sdp(previous) + # Pin the reference to cuDNN: enabling it only makes it eligible, and the dispatcher + # prefers another backend on some GPUs (GB10), which is not bit-identical. + with torch.no_grad(), torch.nn.attention.sdpa_kernel(torch.nn.attention.SDPBackend.CUDNN_ATTENTION): + reference = torch.nn.functional.scaled_dot_product_attention( + query.transpose(1, 2), key.transpose(1, 2), value.transpose(1, 2), scale=scale).transpose(1, 2) with torch.no_grad(): output = cudnn_sdpa_bshd(query, key, value, scale=scale) diff --git a/fastvideo/tests/contract/test_ci_test_collection.py b/fastvideo/tests/contract/test_ci_test_collection.py index c0c11d88b..d98f09cbf 100644 --- a/fastvideo/tests/contract/test_ci_test_collection.py +++ b/fastvideo/tests/contract/test_ci_test_collection.py @@ -187,6 +187,10 @@ def test_merge_comment_has_one_change_aware_trigger_path(): assert "pr.state !== 'open'" in ready_workflow assert "pr.base.repo.full_name !== context.payload.repository.full_name" in ready_workflow assert "pr.base.ref !== context.payload.repository.default_branch" in ready_workflow + # Push/label events on stacked PRs skip the job rather than failing it. + trigger_if = yaml.safe_load(ready_workflow)["jobs"]["trigger"]["if"] + assert "github.event.pull_request.base.ref == github.event.repository.default_branch" in trigger_if + assert trigger_if.startswith("inputs.pr_number > 0 ||") assert "core.setOutput('head_sha', pr.head.sha)" in ready_workflow assert "core.setOutput('base_sha', pr.base.sha)" in ready_workflow assert "api.buildkite.com" in ready_workflow