Metadata-Version: 2.4
Name: clops-mcp
Version: 0.0.1a2
Summary: Deployment-pipeline scaffold for clops-mcp. Not the real package.
License-Expression: Apache-2.0
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# clops-mcp — deployment scaffold

**This branch is not the project.** It is the smallest thing that can be
released, existing only to prove the release pipeline works before the real code
goes anywhere near it.

The real package lives on `main`.

## Why this exists

The release workflow has run exactly once, on `v0.2.0`, and **failed at the
publish step**. Publishing is the part of a release you cannot rehearse by
reading it — trusted publishing either authenticates or it doesn't, and you find
out at the moment you least want to.

So: rehearse it with something disposable. This branch has no history, no
runtime, and nothing worth reviewing. Tag it, watch the pipeline run end to end,
fix whatever breaks, and repeat until it's boring. Then migrate the real code in
knowing the deployment already works.

## What it contains

```
pyproject.toml              name = clops-mcp, version = 0.0.1a1
clops/__init__.py           __version__ only
clops/_scaffold.py          prints where it was installed from, exits 0
.github/workflows/release.yml
LICENSE
README.md
```

That is everything. No tests, no docs, no dependencies.

## What tagging it proves

Each of these has failed for somebody, and none is provable by inspection:

1. **The tag/version guard** rejects a tag that disagrees with `pyproject.toml`.
2. **`uv build`** produces a wheel and an sdist.
3. **The wheel installs into a clean venv and imports from the wheel** — note the
   `-P` flag in the workflow. Without it, `python -` puts the current directory
   on `sys.path`, the job's checkout shadows the installed package, and the smoke
   test silently checks the source tree instead. This bug was live in the real
   workflow.
4. **`uvx clops-mcp` resolves.** `uvx <name>` runs an executable *also* named
   `<name>`, so a distribution called `clops-mcp` needs a script called
   `clops-mcp`. It didn't have one, and `uvx clops` — the obvious next guess —
   installs an unrelated project from PyPI.
5. **OIDC trusted publishing authenticates** with no token stored anywhere.
6. **The published artifact is installable by a stranger**, which is a different
   claim from "the upload succeeded".
7. **`gh release create`** works with the workflow's own token.

## Setup, once

On **pypi.org**:

> Account settings → Publishing → Add a pending publisher
>
> | Field | Value |
> |---|---|
> | PyPI Project Name | `clops-mcp` |
> | Owner | `clops-mcp` |
> | Repository | `clops-mcp` |
> | Workflow | `release.yml` |
> | Environment | *(blank)* |

"Pending" is the right kind: it authorises a project that does not exist yet, and
the first successful publish creates it.

## Running it

```bash
git push origin scaffold/deploy-proof
git tag v0.0.1a1
git push origin v0.0.1a1
```

Watch: `gh run watch`

To run it again, bump **both** the version in `pyproject.toml` and the tag —
`0.0.1a3`, `0.0.1a4`, and so on. PyPI will not accept a version it already has,
and this is the single most common way a second release attempt fails. Note the
asymmetry with the TestPyPI rehearsal: a burned version number on real PyPI is
burned permanently.

## Already proven on TestPyPI

This exact pipeline ran green against TestPyPI as `clops-mcp 0.0.1a1`: built,
smoke-tested the wheel, published, installed itself back down from the index,
and cut a GitHub release. Only the publish target changed for real PyPI.

Worth recording, because it will happen again: the **first** attempt failed at
the publish step with `503 Service Unavailable`. uv reports that as
*"is trusted publishing correctly configured?"*, which is a guess — the
configuration was correct, and the index was briefly in maintenance. A re-run
seconds later went straight through. Check whether the index is actually up
before you go rewriting a publisher config that was never wrong.

## Version numbers

`0.0.1a2` is a pre-release, so `pip install clops-mcp` will not resolve to it
without `--pre`. A scaffold cannot become somebody's accidental install. The real
package starts at `0.3.0`, which sorts above every `0.0.1aN`.

The point of publishing a stub at all is to **claim the distribution name**
before someone else does. `clops` on PyPI is already an unrelated project;
`clops-mcp` should not go the same way.
