Every code-referencing claim in the docs, the README and the rules files was checked against src/, and each finding was re-derived independently before it was applied. 35 held, 5 were false positives. Two of them were code, not text. `InvisibleOptions` promises in its docstring to mirror `InvisibleEngine`, and two defaults had silently stopped: `max_resolution=None` reached `_target_size`'s `max_resolution > 0` and raised `TypeError` on every library call that left the options alone, and `cpu_offload=True` made a library run slower than the identical CLI run. Both are fixed, and `TestInvisibleOptionsMirrorTheEngine` compares the two signatures field by field rather than pinning the two values that happen to be known. A companion assertion in `TestTargetSize` reads the engine's own declared default, so a drift on the engine side -- which the mirror check alone would accept, because both sides would still agree -- fails too. The user-facing docs: README called `invisible` GPU-optional where it raises without CUDA, and gave the image `metadata` command `video metadata`'s output rule, promising the source survives a command that overwrites it. Yuanbao was missing from the supported-mark list. `veo` was listed among the video policies that require a run anchor, though its row sets no `anchor_iou`. `known-limitations` called ControlNet the default profile and contradicted itself ninety lines below. An unescaped pipe truncated the `hailuo` table row. The `dev` extra, the CI shape, ffmpeg's role, the sdist boundary and the strength-curve range were corrected, and `remove_all`/`remove_batch`, the pill gate, `erase --keep-metadata` and `all`'s CUDA failure mode were documented. Research notes that described removed modules, extras and flags in the present tense now say so once in the page banner instead of sentence by sentence, which covers the whole page rather than the lines that happened to be noticed, and one fixture is referred to by role rather than by name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4.4 KiB
Release and distribution
This page describes the release behavior defined in this repository. External registry state can change independently, so verify it during a release.
Release sources of truth
The package version appears in:
pyproject.toml;src/remove_ai_watermarks/__init__.py;- the root package entry generated in
uv.lock.
Update the first two, then refresh the lock file with uv. Do not edit a
line-number-specific location in uv.lock; its package order changes.
Publish flow
PyPI publishing is triggered by a published GitHub Release, not by a tag push alone.
The expected sequence:
- update the version sources and lock file;
- run the complete project gate;
- commit the release change;
- create an annotated
vX.Y.Ztag; - push the commit and tag;
- publish the GitHub Release.
.github/workflows/publish.yml then:
- checks that the release tag matches
pyproject.toml; - builds the package with uv;
- publishes with
uv publishthrough PyPI trusted publishing.
The workflow uses GitHub OIDC through the pypi environment. It does not read a
PyPI API token from the repository.
Post-release distribution
.github/workflows/distribute.yml runs on the same published-release event. It
waits for the matching source distribution to appear on PyPI, then:
- updates the Homebrew tap formula URL and SHA-256;
- updates the repository conda recipe version and source-distribution SHA-256;
- triggers a factory rebuild of the Hugging Face Space.
The workflow can also be started manually with an optional version input. Conda-forge updates are outside this workflow.
If a distribution job fails because a repository or Hugging Face credential is invalid, rotate the corresponding GitHub secret and rerun the failed job. A manual Homebrew formula update is the fallback when its automation is blocked.
The conda job uses the published artifact rather than a locally built archive
as the hash source and commits the resulting recipe change to main. Runtime
dependency mapping remains review-controlled: keep it aligned with the default
metadata dependencies in pyproject.toml, do not copy optional pixel extras
into the default recipe, and document any conda-forge package that is
unavailable and must be omitted.
The optional video extra carries PyAV with Python-version-specific bounds; it
does not belong in the default metadata-focused conda recipe.
Source distribution boundary
The wheel includes the package under src/.
The source distribution uses an explicit allowlist for /src, /LICENSE,
/README.md, and /pyproject.toml through
[tool.hatch.build.targets.sdist] in pyproject.toml. It also defensively
excludes /data, /tmp, and /.sc. Keep both controls: calibration captures,
test corpora, generated research outputs, and local session state do not belong
in the published package archive. .gitignore covers tmp/ and .sc/, so those
never reach a commit, but ignore rules are not the build boundary -- hatchling may
include untracked files, and data/ is deliberately tracked, so the sdist exclude
is the only control keeping it out of the archive.
Build backend
The package uses hatchling through the unpinned hatchling build requirement in
pyproject.toml. Uploading uses uv rather than the older twine-based action.
Other channels
The repository includes a conda recipe under packaging/conda/recipe.yaml.
The ComfyUI nodes are maintained and versioned in their own repository. After
the matching source distribution appears on PyPI, distribute.yml dispatches
that repository's sync workflow with the exact library version and waits for it
to finish. The sync updates the dependency floor, runs compatibility tests,
bumps the node patch version, and publishes to the ComfyUI Registry only when
those tests pass. Its daily schedule remains as a recovery path if a release
dispatch is interrupted. The COMFYUI_RELEASE_TOKEN repository secret is a
fine-grained token limited to the ComfyUI node repository, with Actions read and
write access.
Release verification
After publication, verify:
- both wheel and source distribution exist on PyPI;
- the package version matches the tag;
- the Homebrew formula points to the new source distribution;
- the distribution workflow completed successfully;
- the repository's conda recipe matches the published version and source distribution;
- the ComfyUI Registry node requires the new library version;
- a clean install can run
remove-ai-watermarks --version.