Major version upgrade to 2.0

- Update IVATAR_VERSION from 1.8.0 to 2.0 in config.py
- Update version in setup.cfg from 1.7.0 to 2.0
- Enhanced /deployment/version/ endpoint to include application_version
- Added /version/ alias endpoint for backward compatibility
- Updated OpenTelemetry documentation and configuration

This major version bump reflects the significant improvements made:
- Comprehensive OpenTelemetry instrumentation
- 270x performance improvements in avatar generation
- Enhanced security fixes and UI improvements
- Extensive test coverage and CI/CD enhancements
- Modern Django compatibility and code quality improvements
This commit is contained in:
Oliver Falk
2025-10-31 13:58:01 +01:00
parent 86a0ef6f03
commit 550b9bf0b9
7 changed files with 30 additions and 9 deletions

View File

@@ -44,7 +44,7 @@ OpenTelemetry is integrated into ivatar to provide:
| `OTEL_ENVIRONMENT` | Environment (production/development) | `development` | No | | `OTEL_ENVIRONMENT` | Environment (production/development) | `development` | No |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint | None | No | | `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint | None | No |
| `OTEL_PROMETHEUS_ENDPOINT` | Local Prometheus server (dev only) | None | No | | `OTEL_PROMETHEUS_ENDPOINT` | Local Prometheus server (dev only) | None | No |
| `IVATAR_VERSION` | Application version | `1.8.0` | No | | `IVATAR_VERSION` | Application version | `2.0` | No |
| `HOSTNAME` | Instance identifier | `unknown` | No | | `HOSTNAME` | Instance identifier | `unknown` | No |
### Multi-Instance Configuration ### Multi-Instance Configuration
@@ -56,7 +56,6 @@ export OTEL_EXPORT_ENABLED=true
export OTEL_SERVICE_NAME=ivatar-production export OTEL_SERVICE_NAME=ivatar-production
export OTEL_ENVIRONMENT=production export OTEL_ENVIRONMENT=production
export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.internal:4317 export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.internal:4317
export IVATAR_VERSION=1.8.0
export HOSTNAME=prod-instance-01 export HOSTNAME=prod-instance-01
``` ```
@@ -70,7 +69,7 @@ export OTEL_SERVICE_NAME=ivatar-development
export OTEL_ENVIRONMENT=development export OTEL_ENVIRONMENT=development
export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.internal:4317 export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.internal:4317
export OTEL_PROMETHEUS_ENDPOINT=0.0.0.0:9467 export OTEL_PROMETHEUS_ENDPOINT=0.0.0.0:9467
export IVATAR_VERSION=1.8.0-dev export IVATAR_VERSION=2.0-dev
export HOSTNAME=dev-instance-01 export HOSTNAME=dev-instance-01
``` ```

View File

@@ -179,7 +179,6 @@ OTEL_ENVIRONMENT=production
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.internal:4317 OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.internal:4317
OTEL_PROMETHEUS_ENDPOINT=0.0.0.0:9464 OTEL_PROMETHEUS_ENDPOINT=0.0.0.0:9464
OTEL_SAMPLING_RATIO=0.1 # 10% sampling for high volume OTEL_SAMPLING_RATIO=0.1 # 10% sampling for high volume
IVATAR_VERSION=1.8.0
HOSTNAME=prod-instance-01 HOSTNAME=prod-instance-01
``` ```
@@ -193,7 +192,6 @@ OTEL_ENVIRONMENT=development
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.internal:4317 OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.internal:4317
OTEL_PROMETHEUS_ENDPOINT=0.0.0.0:9464 OTEL_PROMETHEUS_ENDPOINT=0.0.0.0:9464
OTEL_SAMPLING_RATIO=1.0 # 100% sampling for debugging OTEL_SAMPLING_RATIO=1.0 # 100% sampling for debugging
IVATAR_VERSION=1.8.0-dev
HOSTNAME=dev-instance-01 HOSTNAME=dev-instance-01
``` ```

View File

@@ -67,7 +67,7 @@ SOCIAL_AUTH_FEDORA_KEY = None # Also known as client_id
SOCIAL_AUTH_FEDORA_SECRET = None # Also known as client_secret SOCIAL_AUTH_FEDORA_SECRET = None # Also known as client_secret
SITE_NAME = os.environ.get("SITE_NAME", "libravatar") SITE_NAME = os.environ.get("SITE_NAME", "libravatar")
IVATAR_VERSION = "1.8.0" IVATAR_VERSION = "2.0"
SCHEMAROOT = "https://www.libravatar.org/schemas/export/0.2" SCHEMAROOT = "https://www.libravatar.org/schemas/export/0.2"

View File

@@ -22,6 +22,8 @@ from opentelemetry.instrumentation.pymysql import PyMySQLInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor
from .settings import VERSION as IVATAR_VERSION
# Note: Memcached instrumentation not available in OpenTelemetry Python # Note: Memcached instrumentation not available in OpenTelemetry Python
logger = logging.getLogger("ivatar") logger = logging.getLogger("ivatar")
@@ -62,7 +64,7 @@ class OpenTelemetryConfig:
return Resource.create( return Resource.create(
{ {
"service.name": self.service_name, "service.name": self.service_name,
"service.version": os.environ.get("IVATAR_VERSION", "1.8.0"), "service.version": os.environ.get("IVATAR_VERSION", IVATAR_VERSION),
"service.namespace": "libravatar", "service.namespace": "libravatar",
"deployment.environment": self.environment, "deployment.environment": self.environment,
"service.instance.id": os.environ.get("HOSTNAME", "unknown"), "service.instance.id": os.environ.get("HOSTNAME", "unknown"),

View File

@@ -73,6 +73,11 @@ urlpatterns = [ # pylint: disable=invalid-name
DeploymentVersionView.as_view(), DeploymentVersionView.as_view(),
name="deployment_version", name="deployment_version",
), ),
path(
"version/",
DeploymentVersionView.as_view(),
name="version",
),
] ]
MAINTENANCE = False MAINTENANCE = False

View File

@@ -979,11 +979,28 @@ class DeploymentVersionView(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
""" """
Return cached deployment version information Return cached deployment version information including application version
""" """
from django.conf import settings
version_info = _get_cached_version_info() version_info = _get_cached_version_info()
if "error" in version_info: if "error" in version_info:
# Even on error, include the application version if available
try:
version_info["application_version"] = getattr(
settings, "IVATAR_VERSION", "unknown"
)
except Exception:
pass
return JsonResponse(version_info, status=500) return JsonResponse(version_info, status=500)
# Add application version to the response
try:
version_info["application_version"] = getattr(
settings, "IVATAR_VERSION", "unknown"
)
except Exception:
version_info["application_version"] = "unknown"
return JsonResponse(version_info) return JsonResponse(version_info)

View File

@@ -1,6 +1,6 @@
[metadata] [metadata]
name = libravatar name = libravatar
version = 1.7.0 version = 2.0
description = A Django application implementing libravatar.org description = A Django application implementing libravatar.org
long_description = file: README.md long_description = file: README.md
url = https://libravatar.org url = https://libravatar.org