1ca5bcbc6b
docker / test (pull_request) Successful in 34s
test / test (pull_request) Successful in 43s
docker / docker (pull_request) Successful in 39s
docker / test (push) Successful in 34s
docker / lint (push) Successful in 40s
test / test (push) Successful in 42s
lint / lint (push) Successful in 44s
docker / lint (pull_request) Successful in 44s
lint / lint (pull_request) Successful in 42s
docker / docker (push) Successful in 46s
The repo already has a write:package REGISTRY_TOKEN secret (used by docker.yml). Reuse it for uv publish instead of requiring new GITEA_PACKAGE_* secrets: authenticate as GITHUB_ACTOR with the token as password. Update packaging docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
83 lines
2.7 KiB
Markdown
83 lines
2.7 KiB
Markdown
# Packaging & publishing
|
|
|
|
AegisGitea-MCP is distributed as a single Python package, `aegis-gitea-mcp`,
|
|
built with [`uv`](https://docs.astral.sh/uv/) and published to the self-hosted
|
|
Gitea package registry.
|
|
|
|
## Distribution layout
|
|
|
|
One package, two console scripts, one optional extra:
|
|
|
|
| Console script | Entry point | Requires |
|
|
|----------------|-------------|----------|
|
|
| `aegis-gitea-mcp` | `aegis_gitea_mcp.stdio_app:main` | core only |
|
|
| `aegis-gitea-mcp-server` | `aegis_gitea_mcp.server_entry:main` | `[server]` extra |
|
|
|
|
- **Core** (default install): `httpx`, `pydantic`, `pydantic-settings`, `PyYAML`,
|
|
`python-dotenv`, `structlog`, `mcp`. Enough to run the local stdio server.
|
|
- **`[server]` extra**: `fastapi`, `uvicorn[standard]`, `PyJWT[crypto]`,
|
|
`python-multipart`. The public HTTP/OAuth server.
|
|
|
|
The `aegis-gitea-mcp-server` entry point degrades gracefully: invoked without
|
|
the web stack it prints `install 'aegis-gitea-mcp[server]'` instead of a
|
|
`ModuleNotFoundError` traceback.
|
|
|
|
## Build locally
|
|
|
|
```bash
|
|
uv build
|
|
# -> dist/aegis_gitea_mcp-<version>-py3-none-any.whl
|
|
# -> dist/aegis_gitea_mcp-<version>.tar.gz
|
|
```
|
|
|
|
Smoke-test the local stdio server from the built wheel:
|
|
|
|
```bash
|
|
GITEA_URL=https://git.hiddenden.cafe GITEA_TOKEN=<pat> \
|
|
uvx --from ./dist/aegis_gitea_mcp-*.whl aegis-gitea-mcp
|
|
```
|
|
|
|
## Install from the Gitea registry
|
|
|
|
```bash
|
|
uv pip install \
|
|
--index-url https://git.hiddenden.cafe/api/packages/Hiddenden/pypi/simple \
|
|
aegis-gitea-mcp
|
|
```
|
|
|
|
(With `pip`, use `--index-url` the same way.)
|
|
|
|
## Cutting a release
|
|
|
|
Releases are tag-driven. The publish workflow
|
|
(`.gitea/workflows/publish.yml`) triggers on a `v*` tag, runs lint + tests
|
|
first, builds with `uv`, and publishes to the Gitea PyPI registry.
|
|
|
|
1. Bump `version` in `pyproject.toml` (e.g. `0.2.0`).
|
|
2. Open a PR into `dev`, merge `dev` into `main`.
|
|
3. Tag the release commit and push the tag:
|
|
|
|
```bash
|
|
git tag v0.2.0
|
|
git push origin v0.2.0
|
|
```
|
|
|
|
4. The workflow publishes the wheel + sdist and attaches them to the run.
|
|
|
|
### Required CI secrets
|
|
|
|
The publish job reuses the **existing** `REGISTRY_TOKEN` Actions secret — the same
|
|
PAT (`write:package`) that `docker.yml` uses to push images — so no new secret is
|
|
needed. The token authenticates as its owning Gitea user, so `GITHUB_ACTOR` is the
|
|
username and the token is the password.
|
|
|
|
| Secret | Purpose |
|
|
|--------|---------|
|
|
| `REGISTRY_TOKEN` | PAT with `write:package`; used for both image and package pushes |
|
|
|
|
If the secret is absent the job fails loudly rather than publishing anonymously.
|
|
|
|
> Publishing to public PyPI is intentionally **not** configured. A second,
|
|
> separately-gated `uv publish` step would be required and is left as a
|
|
> commented stub in the workflow.
|