3.5 KiB
Packaging and publishing
AegisGitea MCP is built with 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
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:
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:
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):
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
devpublishesaegis-gitea-mcp-devatX.Y.Z.dev<run number>, unique per run. - A push to
mainpublishesaegis-gitea-mcpat the plainX.Y.Z.uv publish --check-urlskips files that already exist, so a push that did not bump the version is a clean no-op.
Cutting a stable release
- Bump
versioninpyproject.tomlon a branch offdev. - Open a pull request into
devand merge it. That publishes a fresh dev build. - Promote
devtomain. The push tomainpublishes 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.