feat: add dynamic versioning and automated deployment with rollback capability

- Implement setuptools-scm for dynamic version management from git tags
- Refactor CI/CD into separate build and deploy jobs with artifact sharing
- Add versioned releases with timestamp-based deployment directories
- Implement health checks and automatic rollback on deployment failure
- Extract deployment logic into reusable shell scripts
- Add Docker layer caching to speed up builds
- Include version info in Django context and build args
This commit is contained in:
badblocks 2025-06-06 14:38:23 -07:00
parent 46619bd5e1
commit f20c4f9474
No known key found for this signature in database
14 changed files with 719 additions and 233 deletions

View file

@ -0,0 +1,5 @@
"""pkmntrade.club - A django project for trading Pokémon TCG Pocket Cards"""
from pkmntrade_club._version import __version__, get_version, get_version_info
__all__ = ['__version__', 'get_version', 'get_version_info']

View file

@ -0,0 +1,61 @@
from importlib.metadata import version, PackageNotFoundError
from setuptools_scm import get_version
"""
Version module for pkmntrade.club
This module provides version information from git tags via setuptools-scm.
"""
try:
__version__ = version("pkmntrade-club")
except PackageNotFoundError:
# Package is not installed, try to get version from setuptools_scm
try:
__version__ = get_version(root='../../..', relative_to=__file__)
except (ImportError, LookupError):
__version__ = "0.0.0+unknown"
def get_version():
"""Return the current version."""
return __version__
def get_version_info():
"""Return detailed version information."""
import re
# Parse version string (e.g., "1.2.3", "1.2.3.dev4+gabc1234", "1.2.3-prerelease")
match = re.match(
r'^(\d+)\.(\d+)\.(\d+)'
r'(?:\.dev(\d+))?'
r'(?:\+g([a-f0-9]+))?'
r'(?:-(.+))?$',
__version__
)
if match:
major, minor, patch, dev, git_sha, prerelease = match.groups()
return {
'version': __version__,
'major': int(major),
'minor': int(minor),
'patch': int(patch),
'dev': int(dev) if dev else None,
'git_sha': git_sha,
'prerelease': prerelease,
'is_release': dev is None and not prerelease,
'is_prerelease': bool(prerelease),
'is_dev': dev is not None
}
return {
'version': __version__,
'major': 0,
'minor': 0,
'patch': 0,
'dev': None,
'git_sha': None,
'prerelease': None,
'is_release': False,
'is_prerelease': False,
'is_dev': True
}

View file

@ -3,4 +3,10 @@ from django.conf import settings
def cache_settings(request):
return {
'CACHE_TIMEOUT': settings.CACHE_TIMEOUT,
}
def version_info(request):
return {
'VERSION': settings.VERSION,
'VERSION_INFO': settings.VERSION_INFO,
}

View file

@ -4,6 +4,8 @@ import environ
import os
import logging
import sys
from django.utils.translation import gettext_lazy as _
from pkmntrade_club._version import __version__, get_version_info
# set default values to local dev values
env = environ.Env(
@ -84,6 +86,9 @@ CACHE_TIMEOUT = env('CACHE_TIMEOUT')
DISABLE_SIGNUPS = env('DISABLE_SIGNUPS')
DISABLE_CACHE = env('DISABLE_CACHE')
VERSION = __version__
VERSION_INFO = get_version_info()
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/
@ -213,6 +218,7 @@ TEMPLATES = [
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"pkmntrade_club.common.context_processors.cache_settings",
"pkmntrade_club.common.context_processors.version_info",
],
},
},