Skip to content

[FEATURE] Implement Named Releases with Tag-Based Deployment #467

@nanotaboada

Description

@nanotaboada

Problem

Currently, the CI/CD pipeline publishes Docker packages to GitHub Container Registry (GHCR) on every merge to master, resulting in:

  • Dozens of unnecessary package versions (one per merge)
  • Manual cleanup required to remove unwanted packages
  • No clear distinction between development builds and official releases
  • Lack of memorable release naming convention

Example current behavior:

Merge feat-1 → ghcr.io/.../python-samples-fastapi-restful:latest, :sha-abc123
Merge feat-2 → ghcr.io/.../python-samples-fastapi-restful:latest, :sha-def456
Merge feat-3 → ghcr.io/.../python-samples-fastapi-restful:latest, :sha-789xyz
... (manual cleanup needed)

Proposed Solution

Implement a tag-based release workflow with famous football coaches naming convention (inspired by Ubuntu, Android, macOS naming patterns).

Key Changes:

  1. Separate CI from CD:

    • CI workflow (python-ci.yml) runs on every push/PR → lint, test, coverage only
    • CD workflow (python-cd.yml) runs ONLY when creating version tags → publish packages
  2. Famous Coaches Release Naming:

    • Use legendary football coaches (surnames) A-Z for release codenames
    • Tag format: v{SEMVER}-{COACH} (e.g., v1.0.0-ancelotti)
    • Publish multiple Docker tags per release:
      • Semantic version: :1.0.0
      • Coach name: :ancelotti
      • Latest: :latest
  3. GitHub Releases:

    • Auto-generate release notes with changelog
    • Include coach emoji ♟️ and pull instructions
    • Link to Docker images

Example workflow:

# Development (no packages published)
git checkout -b feat/add-jwt
git commit -m "feat: add JWT authentication"
# Merge PR → CI runs tests, NO package published

# Official release (packages published)
git tag -a v1.0.0-ancelotti -m "Release 1.0.0 - Ancelotti"
git push origin v1.0.0-ancelotti
# → Publishes: :1.0.0, :ancelotti, :latest
# → Creates GitHub Release with notes

Suggested Approach

1. Update CI Workflow (.github/workflows/python-ci.yml)

Rename python-app.yml to python-ci.yml for clarity.

Remove the container job that publishes to GHCR on every merge:

# REMOVE THIS ENTIRE JOB (if present):
container:
  needs: coverage
  runs-on: ubuntu-latest
  if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
  # ... publishing steps ...

Keep only: lint (commitlint, flake8, black) → test → coverage

2. Create CD Workflow (.github/workflows/python-cd.yml)

Trigger: Only on version tags matching v*.*.*-* pattern

Steps:

  1. Extract version components from tag (semver, coach name)
  2. Run full test suite with pytest
  3. Build Docker image with multiple tags
  4. Push to GHCR
  5. Generate changelog from commits
  6. Create GitHub Release with auto-generated notes

Key Features:

  • Extract v1.0.0-ancelotti → semver: 1.0.0, coach: ancelotti
  • Generate changelog: compare with previous tag
  • Multi-platform support (linux/amd64, linux/arm64)
  • Cache pip dependencies for faster builds
  • Use Python 3.13 (per .python-version)

3. Famous Coaches List (A-Z) ♟️

Legendary football coaches who shaped the game:

Letter Coach Name Country/Notable Era Tag Name
A Ancelotti (Carlo) Italy ancelotti
B Bielsa (Marcelo) Argentina bielsa
C Capello (Fabio) Italy capello
D Del Bosque (Vicente) Spain delbosque
E Eriksson (Sven-Göran) Sweden eriksson
F Ferguson (Alex) Scotland ferguson
G Guardiola (Pep) Spain guardiola
H Heynckes (Jupp) Germany heynckes
I Inzaghi (Simone) Italy inzaghi
J Jurgen Klopp Germany klopp
K Kovač (Niko) Croatia kovac
L Löw (Joachim) Germany low
M Mourinho (José) Portugal mourinho
N Nagelsmann (Julian) Germany nagelsmann
O Ottmar Hitzfeld Germany/Switzerland ottmar
P Pochettino (Mauricio) Argentina pochettino
Q Queiroz (Carlos) Portugal queiroz
R Ranieri (Claudio) Italy ranieri
S Simeone (Diego) Argentina simeone
T Tuchel (Thomas) Germany tuchel
U Unai Emery Spain unai
V Van Gaal (Louis) Netherlands vangaal
W Wenger (Arsène) France wenger
X Xavi Hernández Spain xavi
Y Yozhef Sabo Ukraine yozhef
Z Zeman (Zdeněk) Czech Republic zeman

4. Documentation Updates

README.md - Add release instructions:

## 📦 Releases

This project uses famous football coaches as release names ♟️

### Create a Release

```bash
git tag -a v1.0.0-ancelotti -m "Release 1.0.0 - Ancelotti"
git push origin v1.0.0-ancelotti

Pull Docker Images

# By semantic version (recommended)
docker pull ghcr.io/nanotaboada/python-samples-fastapi-restful:1.0.0

# By coach name
docker pull ghcr.io/nanotaboada/python-samples-fastapi-restful:ancelotti

# Latest
docker pull ghcr.io/nanotaboada/python-samples-fastapi-restful:latest

**CHANGELOG.md** - Template for releases:

```markdown
# Changelog

All notable changes to this project will be documented in this file.

## [1.0.0 - Ancelotti] - 2026-XX-XX

### Added
- Initial stable release
- Player CRUD operations with FastAPI
- SQLite database with SQLAlchemy (async)
- Docker support with Compose
- In-memory caching with aiocache
- Comprehensive pytest test suite

### Changed
- N/A

### Fixed
- N/A

Acceptance Criteria

  • CI workflow renamed from python-app.yml to python-ci.yml
  • CI workflow (python-ci.yml) does not publish packages on merge to master
  • CD workflow (python-cd.yml) created and functional
  • Tagging v1.0.0-ancelotti triggers CD workflow
  • CD workflow publishes three Docker tags: :1.0.0, :ancelotti, :latest
  • GitHub Release is automatically created with:
    • Coach-themed title (e.g., "v1.0.0 - Ancelotti ♟️")
    • Auto-generated changelog
    • Docker pull instructions
    • Coach emoji ♟️
  • README.md updated with release instructions
  • CHANGELOG.md template created
  • First test release (v1.0.0-ancelotti) successfully published
  • Old unnecessary packages can be safely deleted
  • Documentation includes coach list (A-Z)
  • Black and flake8 formatting checks pass before release

References

Naming Conventions

  • Ubuntu: Warty Warthog, Jammy Jellyfish (adjective + animal)
  • Android: Cupcake, Oreo, Tiramisu (desserts)
  • macOS: Mavericks, Sonoma (California locations)
  • This Project: Famous football coaches

GitHub Actions

Python-Specific


Note: This is a breaking change to the CI/CD pipeline. After implementation:

  1. Delete old unnecessary packages from GHCR manually one last time
  2. Use tag-based releases going forward
  3. Master branch merges will only run tests, not publish packages
  4. Ensure virtual environment (.venv) is activated before running black/flake8

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestgithub_actionsPull requests that update GitHub Actions codepriority criticalBlocking dependency or production issue. Must be addressed before other work.pythonPull requests that update Python code

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions