Skip to content

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

@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/.../webapi:latest, :sha-abc123
Merge feat-2 → ghcr.io/.../webapi:latest, :sha-def456
Merge feat-3 → ghcr.io/.../webapi:latest, :sha-789xyz
... (manual cleanup needed)

Proposed Solution

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

Key Changes:

  1. Separate CI from CD:

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

    • Use famous football stadiums A-Z for release codenames
    • Tag format: v{SEMVER}-{STADIUM} (e.g., v1.0.0-azteca)
    • Publish multiple Docker tags per release:
      • Semantic version: :1.0.0
      • Stadium name: :azteca
      • Latest: :latest
  3. GitHub Releases:

    • Auto-generate release notes with changelog
    • Include stadium 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-azteca -m "Release 1.0.0 - Azteca"
git push origin v1.0.0-azteca
# → Publishes: :1.0.0, :azteca, :latest
# → Creates GitHub Release with notes

Suggested Approach

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

Rename dotnet.yml to dotnet-ci.yml for clarity.

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

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

Keep only: build → test → coverage

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

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

Steps:

  1. Extract version components from tag (semver, stadium name)
  2. Run build and tests in Release configuration
  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-azteca → semver: 1.0.0, stadium: azteca
  • Generate changelog: compare with previous tag
  • Multi-platform support (currently linux/amd64)
  • Cache layers for faster builds

3. Stadium List (A-Z) - World Cup Edition

Predefined list of 26 stadiums that hosted FIFA World Cup matches:

Letter Stadium Name Location Tag Name
A Azteca Mexico (1970, 1986, 2026) azteca
B Bernabéu Spain (1982) bernabeu
C Centenario Uruguay (1930) centenario
D Düsseldorf (Merkur Spiel-Arena) Germany (2006) dusseldorf
E Ekaterinburg Arena Russia (2018) ekaterinburg
F Frankfurt Waldstadion Germany (1974, 2006) frankfurt
G Gelsenkirchen Germany (2006) gelsenkirchen
H Hard Rock Stadium USA (2026) hardrock
I Ibn Batouta Stadium Morocco (2030) ibnbatouta
J Johannesburg Soccer City South Africa (2010) johannesburg
K Kazan Arena Russia (2018) kazan
L Lusail Qatar (2022) lusail
M Maracanã Brazil (1950, 2014) maracana
N Nantes Beaujoire France (1998) nantes
O Olympiastadion Berlin Germany (1974, 2006) olympiastadion
P Parc des Princes France (1938, 1998) parcdesprince
Q Qatar 974 Qatar (2022) qatar974
R Rose Bowl USA (1994) rosebowl
S San Siro Italy (1934, 1990) sansiro
T Toronto BMO Field Canada (2026) toronto
U Ullevi Sweden (1958) ullevi
V Volgograd Arena Russia (2018) volgograd
W Wembley England (1966) wembley
X Xiamen Egret Stadium (famous fallback) xiamen
Y Yokohama International Stadium Japan (2002) yokohama
Z Zentralstadion Leipzig Germany (1974, 2006) zentralstadion

4. Documentation Updates

README.md - Add release instructions:

## 📦 Releases

This project uses stadium-themed release names:

### Create a Release
```bash
git tag -a v1.0.0-azteca -m "Release 1.0.0 - Azteca"
git push origin v1.0.0-azteca

Pull Docker Images

# By semantic version (recommended)
docker pull ghcr.io/nanotaboada/dotnet-samples-aspnetcore-webapi:1.0.0

# By stadium name
docker pull ghcr.io/nanotaboada/dotnet-samples-aspnetcore-webapi:azteca

# Latest
docker pull ghcr.io/nanotaboada/dotnet-samples-aspnetcore-webapi:latest

CHANGELOG.md - Template for releases:

# Changelog

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

## [1.0.0 - Azteca] - 2026-01-21

### Added
- Initial stable release
- Player CRUD operations
- SQLite database with EF Core
- Docker support with Compose
- Comprehensive test coverage

### Changed
- N/A

### Fixed
- N/A

Acceptance Criteria

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

References

Naming Conventions

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

GitHub Actions

Examples


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

Metadata

Metadata

Assignees

No one assigned

    Labels

    dotnetPull requests that update .NET codeenhancementNew feature or requestgithub actionsPull requests that update GitHub Actions codepriority:criticalBlocking dependency or production issue. Must be addressed before other work.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions