image: name: git.linux-kernel.at:5050/oliver/fedora42-python3:latest entrypoint: - "/bin/sh" - "-c" # Cache pip deps to speed up builds cache: paths: - .pipcache variables: PIP_CACHE_DIR: .pipcache # Test with OpenTelemetry instrumentation (always enabled, export disabled in CI) test_and_coverage: stage: build coverage: "/^TOTAL.*\\s+(\\d+\\%)$/" services: - postgres:latest variables: POSTGRES_DB: django_db POSTGRES_USER: django_user POSTGRES_PASSWORD: django_password POSTGRES_HOST: postgres DATABASE_URL: "postgres://django_user:django_password@postgres/django_db" PYTHONUNBUFFERED: 1 # OpenTelemetry instrumentation always enabled, export controlled by OTEL_EXPORT_ENABLED OTEL_EXPORT_ENABLED: "false" # Disable export in CI to avoid external dependencies OTEL_SERVICE_NAME: "ivatar-ci" OTEL_ENVIRONMENT: "ci" before_script: - virtualenv -p python3 /tmp/.virtualenv - source /tmp/.virtualenv/bin/activate - pip install -U pip - pip install Pillow - pip install -r requirements.txt - pip install python-coveralls - pip install coverage - pip install pycco - pip install django_coverage_plugin script: - source /tmp/.virtualenv/bin/activate - echo 'from ivatar.settings import TEMPLATES' > config_local.py - echo 'TEMPLATES[0]["OPTIONS"]["debug"] = True' >> config_local.py - echo "DEBUG = True" >> config_local.py - echo "from config import CACHES" >> config_local.py - echo "CACHES['default'] = CACHES['filesystem']" >> config_local.py - python manage.py sqldsn - python manage.py collectstatic --noinput - echo "Running tests with OpenTelemetry instrumentation enabled..." - coverage run --source . scripts/run_tests_with_coverage.py - coverage report --fail-under=70 - coverage html artifacts: paths: - htmlcov/ pycco: stage: test before_script: - virtualenv -p python3 /tmp/.virtualenv - source /tmp/.virtualenv/bin/activate - pip install -U pip - pip install Pillow - pip install -r requirements.txt - pip install python-coveralls - pip install coverage - pip install pycco - pip install django_coverage_plugin script: - "/bin/true" - find ivatar/ -type f -name "*.py"|grep -v __pycache__|grep -v __init__.py|grep -v /migrations/ | xargs pycco -p -d pycco -i -s artifacts: paths: - pycco/ expire_in: 14 days pages: stage: deploy dependencies: - test_and_coverage - pycco script: - mv htmlcov/ public/ - mv pycco/ public/ artifacts: paths: - public expire_in: 14 days only: - master #build-image: # image: docker # only: # - master # - devel # services: # - docker:dind # before_script: # - docker info # - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY # script: # - ls -lah # - | # if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then # tag="" # echo "Running on default branch '$CI_DEFAULT_BRANCH': tag = 'latest'" # else # tag=":$CI_COMMIT_REF_SLUG" # echo "Running on branch '$CI_COMMIT_BRANCH': tag = $tag" # fi # - docker build --pull -t "$CI_REGISTRY_IMAGE${tag}" . # - docker push "$CI_REGISTRY_IMAGE${tag}" # Local performance testing job (runs in CI environment) performance_tests_local: stage: test services: - postgres:latest variables: POSTGRES_DB: django_db POSTGRES_USER: django_user POSTGRES_PASSWORD: django_password POSTGRES_HOST: postgres DATABASE_URL: "postgres://django_user:django_password@postgres/django_db" PYTHONUNBUFFERED: 1 # OpenTelemetry configuration for performance testing OTEL_EXPORT_ENABLED: "false" OTEL_SERVICE_NAME: "ivatar-perf-test-local" OTEL_ENVIRONMENT: "ci-performance" before_script: - virtualenv -p python3 /tmp/.virtualenv - source /tmp/.virtualenv/bin/activate - pip install -U pip - pip install Pillow - pip install -r requirements.txt - pip install requests # Additional dependency for performance tests script: - source /tmp/.virtualenv/bin/activate - echo 'from ivatar.settings import TEMPLATES' > config_local.py - echo 'TEMPLATES[0]["OPTIONS"]["debug"] = True' >> config_local.py - echo "DEBUG = True" >> config_local.py - echo "from config import CACHES" >> config_local.py - echo "CACHES['default'] = CACHES['filesystem']" >> config_local.py - python manage.py migrate - python manage.py collectstatic --noinput - echo "Running local performance tests (no cache testing)..." - python3 scripts/performance_tests.py --no-cache-test --output performance_local.json artifacts: paths: - performance_local.json expire_in: 7 days allow_failure: true # Don't fail the pipeline on performance issues, but report them # Performance testing against dev server (devel branch only) performance_tests_dev: stage: deploy image: python:3.11-alpine only: - devel when: on_success # Run automatically after successful deployment verification variables: DEV_URL: "https://dev.libravatar.org" PYTHONUNBUFFERED: 1 before_script: - apk add --no-cache curl - pip install requests Pillow prettytable pyLibravatar dnspython py3dns script: - echo "Running performance tests against dev.libravatar.org..." - python3 scripts/performance_tests.py --base-url $DEV_URL --concurrent-users 5 --avatar-threshold 2500 --response-threshold 2500 --p95-threshold 5000 --ignore-cache-warnings --output performance_dev.json artifacts: paths: - performance_dev.json expire_in: 7 days allow_failure: true # Don't fail deployment on performance issues needs: - job: verify_dev_deployment artifacts: false # Run after deployment verification succeeds # Performance testing against production server (master branch only) performance_tests_prod: stage: deploy image: python:3.11-alpine only: - master when: on_success # Run automatically after successful deployment verification variables: PROD_URL: "https://libravatar.org" PYTHONUNBUFFERED: 1 before_script: - apk add --no-cache curl - pip install requests Pillow prettytable pyLibravatar dnspython py3dns script: - echo "Running performance tests against libravatar.org..." - python3 scripts/performance_tests.py --base-url $PROD_URL --concurrent-users 3 --output performance_prod.json artifacts: paths: - performance_prod.json expire_in: 30 days # Keep production results longer allow_failure: true # Don't fail deployment on performance issues needs: - job: verify_prod_deployment artifacts: false # Run after deployment verification succeeds # Manual performance testing against production (for on-demand testing) performance_tests_prod_manual: stage: deploy image: python:3.11-alpine only: - master when: manual # Manual trigger for on-demand performance testing variables: PROD_URL: "https://libravatar.org" PYTHONUNBUFFERED: 1 before_script: - apk add --no-cache curl - pip install requests Pillow prettytable pyLibravatar dnspython py3dns script: - echo "Running manual performance tests against libravatar.org..." - python3 scripts/performance_tests.py --base-url $PROD_URL --concurrent-users 5 --output performance_prod_manual.json artifacts: paths: - performance_prod_manual.json expire_in: 30 days allow_failure: true # Deployment verification jobs verify_dev_deployment: stage: deploy image: python:3.11-alpine only: - devel variables: DEV_URL: "https://dev.libravatar.org" MAX_RETRIES: 30 RETRY_DELAY: 60 PYTHONUNBUFFERED: 1 before_script: - apk add --no-cache curl git - pip install Pillow script: - echo "Waiting for dev.libravatar.org deployment to complete..." - python3 scripts/check_deployment.py --dev --max-retries $MAX_RETRIES --retry-delay $RETRY_DELAY allow_failure: false verify_prod_deployment: stage: deploy image: python:3.11-alpine only: - master when: on_success variables: PROD_URL: "https://libravatar.org" MAX_RETRIES: 10 RETRY_DELAY: 30 PYTHONUNBUFFERED: 1 before_script: - apk add --no-cache curl git - pip install Pillow script: - echo "Verifying production deployment..." - python3 scripts/check_deployment.py --prod --max-retries $MAX_RETRIES --retry-delay $RETRY_DELAY allow_failure: false include: - template: Jobs/SAST.gitlab-ci.yml - template: Jobs/Dependency-Scanning.gitlab-ci.yml - template: Jobs/Secret-Detection.gitlab-ci.yml