95 lines
3.5 KiB
Markdown
95 lines
3.5 KiB
Markdown
# Packaging and publishing
|
|
|
|
AegisGitea MCP is built with [uv](https://docs.astral.sh/uv/) (hatchling backend) and published
|
|
to the self-hosted Gitea package registry on every merge. There are two channels:
|
|
|
|
| Channel | Package | Published on | Version |
|
|
|---|---|---|---|
|
|
| stable | `aegis-gitea-mcp` | push to `main` | `X.Y.Z` from `pyproject.toml` |
|
|
| dev | `aegis-gitea-mcp-dev` | push to `dev` | `X.Y.Z.dev<N>`, N is the CI run number |
|
|
|
|
Both build from the same source and install the same import module, `aegis_gitea_mcp`, and the
|
|
same console script, `aegis-gitea-mcp`. They differ only in the distribution name and version.
|
|
Install one or the other in an environment, not both, because they would collide on the module.
|
|
|
|
## What is in the package
|
|
|
|
One distribution, one console script:
|
|
|
|
| Console script | Entry point |
|
|
|---|---|
|
|
| `aegis-gitea-mcp` | `aegis_gitea_mcp.cli:main` (subcommands `serve`, `setup`, `version`; `serve` is the default) |
|
|
|
|
Dependencies are the `mcp` SDK (2.3 or newer, below 3), `httpx`, `pydantic`, `pydantic-settings`,
|
|
`jsonschema`, `cryptography` and `uvicorn`. There are no extras: both transports and per-user
|
|
OAuth are in the default install. The generated tool catalog (`catalog/tools.json`) ships inside
|
|
the package.
|
|
|
|
## Build locally
|
|
|
|
```bash
|
|
uv build
|
|
# dist/aegis_gitea_mcp-<version>-py3-none-any.whl
|
|
# dist/aegis_gitea_mcp-<version>.tar.gz
|
|
```
|
|
|
|
Smoke-test the built wheel over stdio:
|
|
|
|
```bash
|
|
GITEA_URL=https://git.example.com GITEA_TOKEN=<your-gitea-token> \
|
|
uvx --from ./dist/aegis_gitea_mcp-*.whl aegis-gitea-mcp
|
|
```
|
|
|
|
Dependencies are pinned in `uv.lock`; `uv sync` reproduces the environment.
|
|
|
|
## Install from the Gitea registry
|
|
|
|
Stable:
|
|
|
|
```bash
|
|
uv pip install \
|
|
--extra-index-url https://git.hiddenden.cafe/api/packages/Hiddenden/pypi/simple/ \
|
|
aegis-gitea-mcp
|
|
|
|
# or run it without installing into an environment:
|
|
uvx --index https://git.hiddenden.cafe/api/packages/Hiddenden/pypi/simple/ aegis-gitea-mcp
|
|
```
|
|
|
|
Dev (newest pre-release build):
|
|
|
|
```bash
|
|
uv pip install --pre \
|
|
--extra-index-url https://git.hiddenden.cafe/api/packages/Hiddenden/pypi/simple/ \
|
|
aegis-gitea-mcp-dev
|
|
```
|
|
|
|
The registry holds only this project's packages and does not proxy PyPI, so it is added as an
|
|
extra index and the dependencies (`mcp`, `httpx`, ...) still come from PyPI. With `pip` use
|
|
`--extra-index-url` the same way.
|
|
|
|
## Publishing
|
|
|
|
Publishing is merge-driven, not tag-driven. `.gitea/workflows/publish.yml` triggers on a push to
|
|
`dev` or `main`, runs the lint and test gates first, builds with `uv build`, and publishes with
|
|
`uv publish`. The package name and version are patched into `pyproject.toml` at build time only
|
|
and never committed.
|
|
|
|
- A push to `dev` publishes `aegis-gitea-mcp-dev` at `X.Y.Z.dev<run number>`, unique per run.
|
|
- A push to `main` publishes `aegis-gitea-mcp` at the plain `X.Y.Z`. `uv publish --check-url`
|
|
skips files that already exist, so a push that did not bump the version is a clean no-op.
|
|
|
|
### Cutting a stable release
|
|
|
|
1. Bump `version` in `pyproject.toml` on a branch off `dev`.
|
|
2. Open a pull request into `dev` and merge it. That publishes a fresh dev build.
|
|
3. Promote `dev` to `main`. The push to `main` publishes the stable version.
|
|
|
|
### CI secret
|
|
|
|
Publishing uses the `REGISTRY_TOKEN` Actions secret, a personal access token with
|
|
`write:package`, the same one the image build uses. The token authenticates as its owner, so the
|
|
job's actor is the username and the token is the password. If the secret is missing the job
|
|
fails instead of publishing anonymously.
|
|
|
|
Publishing to public PyPI is intentionally not configured.
|