Skip to content

Releasing

Releases are published to PyPI from GitLab CI by trusted publishing: no password or token is stored anywhere.

One-time setup

On pypi.org, Your account → Publishing → Add a new pending publisher → GitLab (after the first release: the project's Settings → Publishing):

Field Value
PyPI project name rainbow-fmt
Namespace thebjorn
Project name rainbow-fmt
Top-level pipeline file path .gitlab-ci.yml
Environment name pypi

Making a release

The version lives in three files that must agree: pyproject.toml, src/rainbow_fmt/__init__.py and dkbuild.yml (package.version, which also lists __init__.py under package.versioned so that dktools finds it in the src layout). Between releases they hold the last released version; there is no .dev suffix.

  1. Rename the Unreleased section of CHANGELOG.md to the new version and date; merge to main and wait for a green pipeline.
  2. On main, run dk upversion -t for a patch release, dk upversion -i -t for a minor one or dk upversion -m -t for a major one (dk upversion -s 1.2.3 -t sets an exact version). It bumps the three files, commits them (tagged-upversion), tags v + version and pushes the commit and the tag. Without -t it only edits the files.
  3. The tag's pipeline runs lint, tests, benchmark and build; then the publish job checks that the wheel is rainbow_fmt-<version>-…, runs twine check, exchanges the job's OIDC token for a short-lived PyPI token (ci/mint_pypi_token.py) and uploads the sdist and the wheel.

PyPI never accepts the same version twice: a broken release is fixed with a new version (and the old one can be yanked on PyPI). A tag whose version does not match the wheel (the files were not bumped) fails at the first line of the publish job and publishes nothing.

The editable install's metadata is read at install time: after a bump, python -m pip install -e '.[dev]' again, or tests/test_package.py (which compares the two) fails.

The documentation site

rainbow-fmt.dev is docs/ built by MkDocs with the Material theme (mkdocs.yml; mkdocs-material is a dev dependency) and hosted on Cloudflare Pages. mkdocs serve previews it locally. The docs job builds it with --strict on every pipeline, so a link or anchor that goes nowhere fails the pipeline (tests/test_docs_site.py does the same locally); the deploy-docs job uploads the result with wrangler pages deploy on every push to main that passed lint, tests, benchmark and build. Links from the docs to files outside docs/ (STYLEGUIDE.md, LICENSE, the VS Code extension) are GitLab URLs, since the site serves only docs/.

One-time setup

  1. Create the Pages project, named rainbow-fmt. From a checkout after mkdocs build --strict: npx wrangler login, then npx wrangler pages deploy site --project-name rainbow-fmt --branch main, which creates the project on its first run. Or in the Cloudflare dashboard, Workers & Pages → Create application → Get started → Drag and drop your files, and drop the site/ folder. A direct-upload project cannot be switched to Git integration later; it does not need to be, since CI uploads.
  2. In the project, Custom domains → Set up a custom domain → rainbow-fmt.dev. The zone is in the same account, so Cloudflare adds the CNAME record and the certificate itself. Add www.rainbow-fmt.dev the same way if wanted.
  3. My Profile → API Tokens → Create Token, a custom token with the permission Account → Cloudflare Pages → Edit. The account ID is on the Workers & Pages overview page.
  4. GitLab, Settings → CI/CD → Variables: CLOUDFLARE_API_TOKEN (masked, protected) and CLOUDFLARE_ACCOUNT_ID.