From ac965561fe411eb4c1d767e96fd3a863df45b2ab Mon Sep 17 00:00:00 2001 From: Michael Cahill Date: Sat, 7 Mar 2026 16:12:00 -0800 Subject: [PATCH] M01: add stub repositories for deterministic CI - Create scripts/dev/create_stub_repos.py to satisfy paths.py assertion and import chain without cloning external repos - Add Create stub repositories step before Setup environment in run_tests - Remove Cache repositories step (stubs are deterministic, no network) Made-with: Cursor --- .github/workflows/run_tests.yaml | 8 ++--- scripts/dev/create_stub_repos.py | 62 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 scripts/dev/create_stub_repos.py diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index 870ec8b6a..10a19b9c6 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -25,12 +25,6 @@ jobs: with: path: models key: "2023-12-30" - - name: Cache repositories - id: cache-repos - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 - with: - path: repositories - key: "repos-2023-12-30" - name: Install test dependencies run: pip install wait-for-it -r requirements-test.txt env: @@ -53,6 +47,8 @@ jobs: env: PIP_DISABLE_PIP_VERSION_CHECK: "1" PIP_PROGRESS_BAR: "off" + - name: Create stub repositories + run: python scripts/dev/create_stub_repos.py - name: Setup environment run: python launch.py --skip-prepare-environment --skip-torch-cuda-test --exit env: diff --git a/scripts/dev/create_stub_repos.py b/scripts/dev/create_stub_repos.py new file mode 100644 index 000000000..dc78068bc --- /dev/null +++ b/scripts/dev/create_stub_repos.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +""" +Create minimal stub repositories for CI. +Satisfies paths.py assertion and import chain without cloning external repos. +Deterministic, no network required. +""" +import os + +_here = os.path.dirname(os.path.abspath(__file__)) +SCRIPT_DIR = os.path.dirname(os.path.dirname(_here)) +REPOS = os.path.join(SCRIPT_DIR, "repositories") + + +def touch(path: str, content: str = "") -> None: + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, "w", encoding="utf-8") as f: + f.write(content) + + +def main() -> None: + sd = "stable-diffusion-stability-ai" + # paths.py asserts ldm/models/diffusion/ddpm.py + touch(os.path.join(REPOS, sd, "ldm", "models", "diffusion", "ddpm.py"), "# stub\n") + touch(os.path.join(REPOS, sd, "ldm", "__init__.py")) + touch(os.path.join(REPOS, sd, "ldm", "modules", "__init__.py")) + touch(os.path.join(REPOS, sd, "ldm", "modules", "encoders", "__init__.py")) + # ldm.modules.encoders.modules: FrozenCLIPEmbedder, FrozenOpenCLIPEmbedder, CLIPTextModel + ldm_modules = ( + "class FrozenCLIPEmbedder:\n pass\n" + "class FrozenOpenCLIPEmbedder:\n pass\n" + "class CLIPTextModel:\n pass\n" + ) + touch(os.path.join(REPOS, sd, "ldm", "modules", "encoders", "modules.py"), ldm_modules) + + # generative-models: sgm.modules.encoders.modules + gm = "generative-models" + touch(os.path.join(REPOS, gm, "sgm", "__init__.py")) + touch(os.path.join(REPOS, gm, "sgm", "modules", "__init__.py")) + touch(os.path.join(REPOS, gm, "sgm", "modules", "encoders", "__init__.py")) + sgm_modules = ( + "class FrozenCLIPEmbedder:\n pass\n" + "class FrozenOpenCLIPEmbedder2:\n pass\n" + "class ConcatTimestepEmbedderND:\n pass\n" + ) + touch(os.path.join(REPOS, gm, "sgm", "modules", "encoders", "modules.py"), sgm_modules) + + # k-diffusion: k_diffusion.sampling + kd = "k-diffusion" + touch(os.path.join(REPOS, kd, "k_diffusion", "__init__.py")) + touch(os.path.join(REPOS, kd, "k_diffusion", "sampling.py"), "# stub\n") + + # BLIP: models/blip.py + touch(os.path.join(REPOS, "BLIP", "models", "blip.py"), "# stub\n") + + # stable-diffusion-webui-assets (optional, paths may warn) + touch(os.path.join(REPOS, "stable-diffusion-webui-assets", ".gitkeep")) + + print("Stub repositories created.") + + +if __name__ == "__main__": + main()