Publishing¶
Releases are driven by Git tags. CI builds the sdist/wheel with uv + hatchling, publishes to PyPI, pushes a GHCR image, and deploys MkDocs to GitHub Pages.
One-time GitHub / PyPI setup¶
GitHub Pages¶
Repo Settings → Pages → Build and deployment → Source: GitHub Actions.
After the first successful docs workflow on main, the site is at:
https://astrum-studio.github.io/meilisync/
PyPI trusted publishing¶
No long-lived PyPI token is stored in GitHub.
- Create the project on PyPI (name
meilisyncif you own it, otherwise changeproject.nameinpyproject.toml). - PyPI → Manage → Publishing → GitHub
- Owner:
Astrum-Studio - Repository:
meilisync - Workflow:
publish.yml - Environment:
pypi
- Owner:
- In GitHub: Settings → Environments →
pypi(create it). Optionally require reviewers.
The publish workflow uses OIDC (id-token: write) and pypa/gh-action-pypi-publish.
GitHub Container Registry¶
GHCR works with GITHUB_TOKEN. No extra secrets.
The image is public if the package is set to public: Packages → meilisync → Package settings → Change visibility.
First push happens automatically from .github/workflows/docker.yml.
Docker Hub (optional)¶
If you also want docker.io/<user>/meilisync:
- Create a Docker Hub access token
- GitHub Settings → Secrets →
DOCKERHUB_TOKEN - GitHub Settings → Variables →
DOCKERHUB_USERNAME
When the variable is set, the Docker workflow logs in and adds Hub tags next to GHCR.
Cut a release¶
- Update
CHANGELOG.md. -
Bump the version (writes
meilisync/version.pyvia Hatch): -
Commit, tag, push:
The tag v0.1.6 triggers:
| Workflow | Result |
|---|---|
publish.yml |
uv build → PyPI + GitHub Release with wheels |
docker.yml |
ghcr.io/astrum-studio/meilisync:0.1.6 and :latest |
ci.yml |
lint, tests, uv build |
The version in the built wheel comes from Hatch reading meilisync/version.py. Keep the Git tag in sync (v + that version).
Local package build¶
Artifacts land in dist/. Do not upload them by hand unless CI is unavailable.