GitLab release and container image

CI builds the wheel/sdist and container image on version tags, pushes them to the GitLab Container Registry and PyPI Package Registry, and creates the GitLab Release automatically. This howto describes the full release workflow. For registry push details (manual and CI), see Push Docker image and Python package to GitLab registries.

What CI does on a tag

When you push a tag matching v*.*.* (e.g. v0.4.7):

  1. Validate runs (license check) as on other pipelines.

  2. Build runs several jobs:

    • build-wheel: builds the wheel and sdist with uv build, publishes dist/ as artifact, and triggers publish-pypi to push the package to the GitLab PyPI registry.
    • build-image: builds the Docker image, pushes it to the GitLab Container Registry ($CI_REGISTRY_IMAGE), and saves it as artifact rediflow-<tag>.tar.
  3. Release runs create-release: creates the GitLab Release with changelog notes from CHANGELOG.md. Uses glab release create directly (avoids the release keyword which can trigger catalog-publish and 422 errors on non-catalog projects).

  4. Catalog runs publish-catalog (optional, allow_failure: true): publishes the release to the CI/CD Catalog so the templates/ components (e.g. uv-python-build) become discoverable. Requires the project to be set as a CI/CD Catalog project in Settings → General → Visibility, project features, permissions.

Download artifacts from Build → build-wheel (dist/) and Build → build-image (rediflow-*.tar) if needed.

Initial one-time setup

  1. In your GitLab project: Settings → General → Visibility – ensure Container Registry is not disabled (e.g. enabled for members).
  2. No CI variables are required; GitLab provides built-in credentials for registry push. For local push you use your own GitLab login.
  3. Optional (for catalog publish): In Settings → General → Visibility, project features, permissions, turn on CI/CD Catalog project. The publish-catalog job will then publish the release to the CI/CD Catalog; if not enabled, that job fails but the pipeline still passes (allow_failure: true).

Cutting a release (manual steps)

  1. Bump version and changelog
    Update version in pyproject.toml and add an entry under ## [X.Y.Z] in CHANGELOG.md. Commit and push.

  2. Create and push the tag (from your repo root):

    git tag v0.4.7   # use the version you set
    git push origin v0.4.7
    
  3. Wait for CI
    The pipeline for that tag will run. build-wheel produces dist/ (wheel + sdist); build-image produces rediflow-v0.4.7.tar.

  4. Push to registries (automated)
    CI automatically pushes the Docker image to the GitLab Container Registry and the Python package to the GitLab PyPI registry. If you need to push manually (e.g. from a downloaded artifact), see Push Docker image and Python package to GitLab registries.

  5. Create the GitLab Release (automated)
    CI creates the release with changelog notes from CHANGELOG.md. To generate release notes locally (e.g. for manual edits):

    CI_COMMIT_TAG=v0.4.7 uv run python scripts/release_notes_from_changelog.py
    
  6. Optional: publish to public PyPI
    From the build-wheel artifact, upload the wheel and sdist to pypi.org (e.g. twine upload dist/* after twine check dist/*). Use API tokens and a human login as required.

Summary

Step Who / Where
Build wheel/sdist in CI Automated on tag push
Build image in CI Automated on tag push
Push to GitLab registries Automated on tag push (Container + PyPI)
Create GitLab Release Automated on tag push (changelog notes)
Publish to CI/CD Catalog Optional; requires project set as catalog project
Download dist/ artifact You, from build-wheel job (if needed)
Download image artifact You, from build-image job (if needed)
Publish to pypi.org You, manually (twine) if desired