# Frozen media bundles PyPI wheels listed in `frozen_packages` are **frozen**: version-pinned in root `pyproject.toml`, excluded from CI auto-bump, and not republished unless their package version is manually bumped. This is separate from **hub archive** (`archived/`, `archive_templates.py`) — archiving removes templates from the active hub index; frozen-bundle policy governs **pip wheel churn**. ## Why these bundles are frozen PyPI enforces a **~100 MB per-file** upload limit per wheel. Filled media wheels are frozen so routine template work does **not** rebuild or republish them (which would consume PyPI project quota and risks hitting the 100 MB ceiling). | Bundle | PyPI package | Pinned version | Wheel size (PyPI) | Notes | |--------|--------------|----------------|-------------------|--------| | `media-api` | `comfyui-workflow-templates-media-api` | 0.3.84 | **95.5 MB** | Near limit | | `media-image` | `comfyui-workflow-templates-media-image` | 0.3.160 | **85.3 MB** | Near limit | | `media-video` | `comfyui-workflow-templates-media-video` | 0.3.101 | **99.5 MB** | At limit | | `media-other` | `comfyui-workflow-templates-media-other` | 0.3.229 | **85.0 MB** | Near limit | | `media-assets-01` | `comfyui-workflow-templates-media-assets-01` | 0.1.48 | **89.8 MB** | Near limit | Re-check sizes: `curl -s https://pypi.org/pypi/comfyui-workflow-templates-media-assets-01/json` (wheel `size` field for the pinned version). **New template media** goes to **`media-assets-02`**. When that wheel approaches the limit, freeze it and open `media-assets-03`. Unfreezing and shipping a new frozen wheel should be a **deliberate, rare** decision — e.g. a major split, asset cleanup, or architectural change — not part of normal template PRs. ## Config files | File | Role | |------|------| | [`scripts/data/version_policy.json`](../data/version_policy.json) | `frozen_packages`, `frozen_bundles` map, `recommended_asset_bundle` (`media-assets-02`) | | [`scripts/data/frozen_bundle_inventory.json`](../data/frozen_bundle_inventory.json) | Snapshot: which template IDs are assigned to each frozen bundle in `bundles.json` | Regenerate inventory after editing frozen-bundle rows in `bundles.json`: ```bash python scripts/sync/sync_frozen_inventory.py ``` ## Scripts | Script | Role | |--------|------| | [`scripts/sync/sync_frozen_inventory.py`](../sync/sync_frozen_inventory.py) | Write `frozen_bundle_inventory.json` from `bundles.json` + policy | | [`scripts/ci/ci_version_manager.py`](../ci/ci_version_manager.py) | Auto-bump on release PRs; skips `frozen_packages` | | [`scripts/ci/check_frozen_policy.py`](../ci/check_frozen_policy.py) | PR comment when frozen-bundle rules are violated | | [`scripts/lib/version_policy.py`](../lib/version_policy.py) | Shared loaders and inventory builders | CI: [`.github/workflows/version-check.yml`](../../.github/workflows/version-check.yml) (check + optional bump), [`.github/workflows/publish.yml`](../../.github/workflows/publish.yml) (PyPI). ## Design rules ### New templates - Put **media assets** (thumbnails, etc.) in bundle **`media-assets-02`** in `bundles.json`. - Do **not** add new templates to frozen bundles: `media-api`, `media-image`, `media-video`, `media-other`, or `media-assets-01`. Workflow / index JSON ships via the **`json`** package regardless of bundle assignment. ### New provider logos `index_logo` remains assigned to frozen `media-other`. Logos already published in that wheel are listed once in `scripts/data/version_policy.json` → `frozen_logo_assets`. Any **new** file under `templates/logo/` that is **not** in that inventory automatically ships via `additive_logo_bundle` / `recommended_asset_bundle` (`media-assets-02`). You do not need to update the policy list for each new provider logo. Prefer single-extension filenames (e.g. `sync_so.webp`, not `sync.so.webp`). The core manifest may attach a per-asset `"bundle": "media-assets-02"` override so the loader resolves additive logos from the active package without republishing frozen `media-other` or `media-assets-01`. ### Archive / remove from frozen bundles - **Removing** template IDs from frozen bundles in `bundles.json` is OK (e.g. after `archive_templates.py`). - Does **not** require bumping frozen media package versions. - Does **not** trigger the frozen-bundle PR warning. Run `sync_frozen_inventory.py` after removals so the inventory matches `bundles.json`. ### Add or edit frozen-bundle content CI posts a PR comment (informational, non-blocking) when a PR: - **Adds** template IDs to a frozen bundle in `bundles.json` - Changes media assets (thumbnails, previews, etc.) for a template still assigned to a frozen bundle - Modifies a frozen `packages/media_*` or `packages/media_assets_*` tree, or frozen pins in root `pyproject.toml` Workflow JSON changes for frozen-bundle templates are **not** flagged — those ship via the `json` package. ### Version bumps [`ci_version_manager.py`](../ci/ci_version_manager.py) runs only when the PR author changes the **root** `pyproject.toml` version. | PR type | Auto-bump | |---------|-----------| | Template / archive only (root version unchanged) | None | | Release PR (root version bumped) | `json`, `media-assets-02`, `core`, etc. — **not** `frozen_packages` | Frozen packages are **skipped** during bump analysis (no months-long `git log` / `git diff` since their last version). PR-scoped media edits under a frozen bundle are still detected via `merge_base..HEAD` and fail the release with a clear error. File-list git queries are cached across packages so post-`sync_bundles` working trees do not re-scan once per package. ### Publishing [`publish.yml`](../../.github/workflows/publish.yml) triggers on `pyproject.toml` changes on `main`, or manual dispatch. - Normal merge **without** `release` label → GitHub release only, no PyPI. - With `release` label → publishes packages whose versions changed in the merge commit. - **Force publish** bypasses the label but still only uploads packages where **local version ≠ PyPI**. Frozen media wheels are **not** republished if their version was not bumped. See also: [`docs/PUBLISHING.md`](../../docs/PUBLISHING.md), [`docs/cicd/README.md`](../../docs/cicd/README.md). ## Intentional frozen media release To ship a new frozen wheel: 1. Manually bump `packages/media_/pyproject.toml` (or `packages/media_assets_01/pyproject.toml`) 2. Update the matching pin in root `pyproject.toml` 3. Optionally remove the package from `frozen_packages` for one release PR 4. Merge with `release` label (or force publish after merge) ## Local dry-run ```bash python scripts/ci/check_frozen_policy.py --base-ref origin/main ```