From 89d3a396799deeab7d1d2b70713563533a7ebcd2 Mon Sep 17 00:00:00 2001 From: nessi Date: Sat, 14 Feb 2026 16:48:10 +0100 Subject: [PATCH 1/4] Add new features and enhancements to CI workflows and backend. Enhanced CI workflows by adding an Alpine-based smoke test for the backend with PostgreSQL 16. Updated the Docker build process to support dynamic base images and added provenance, SBOM, and labels to Docker builds. Extended branch compatibility checks and refined backend configurations for broader usage scenarios. --- .github/workflows/docker-release.yml | 16 +++++++ .github/workflows/pg-compat-matrix.yml | 64 +++++++++++++++++++++++++- backend/Dockerfile | 17 +++++-- 3 files changed, 91 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index e38c925..3e98ec8 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -16,6 +16,8 @@ jobs: runs-on: ubuntu-latest permissions: contents: read + id-token: write + attestations: write env: # Optional repo variable. If unset, DOCKERHUB_USERNAME is used. @@ -70,6 +72,13 @@ jobs: context: ./backend file: ./backend/Dockerfile push: true + provenance: mode=max + sbom: true + labels: | + org.opencontainers.image.title=NexaPG Backend + org.opencontainers.image.vendor=Nesterovic IT-Services e.U. + org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.version=${{ steps.ver.outputs.clean }} tags: | ${{ steps.ns.outputs.value }}/nexapg-backend:${{ steps.ver.outputs.clean }} ${{ steps.ns.outputs.value }}/nexapg-backend:latest @@ -82,8 +91,15 @@ jobs: context: ./frontend file: ./frontend/Dockerfile push: true + provenance: mode=max + sbom: true build-args: | VITE_API_URL=/api/v1 + labels: | + org.opencontainers.image.title=NexaPG Frontend + org.opencontainers.image.vendor=Nesterovic IT-Services e.U. + org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.version=${{ steps.ver.outputs.clean }} tags: | ${{ steps.ns.outputs.value }}/nexapg-frontend:${{ steps.ver.outputs.clean }} ${{ steps.ns.outputs.value }}/nexapg-frontend:latest diff --git a/.github/workflows/pg-compat-matrix.yml b/.github/workflows/pg-compat-matrix.yml index ae28fa8..3dc9954 100644 --- a/.github/workflows/pg-compat-matrix.yml +++ b/.github/workflows/pg-compat-matrix.yml @@ -2,7 +2,7 @@ name: PostgreSQL Compatibility Matrix on: push: - branches: ["main", "master"] + branches: ["main", "master", "development"] pull_request: jobs: @@ -67,3 +67,65 @@ jobs: env: PG_DSN_CANDIDATES: postgresql://postgres:postgres@postgres:5432/compatdb?sslmode=disable,postgresql://postgres:postgres@127.0.0.1:5432/compatdb?sslmode=disable run: python backend/scripts/pg_compat_smoke.py + + backend-alpine-smoke: + name: Backend Alpine smoke (PG16) + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:16 + env: + POSTGRES_DB: compatdb + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U postgres -d compatdb" + --health-interval 5s + --health-timeout 5s + --health-retries 20 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Enable pg_stat_statements in service container + run: | + PG_CID="$(docker ps --filter "ancestor=postgres:16" --format "{{.ID}}" | head -n1)" + if [ -z "$PG_CID" ]; then + echo "Could not find postgres service container for version 16" + docker ps -a + exit 1 + fi + + echo "Using postgres container: $PG_CID" + docker exec "$PG_CID" psql -U postgres -d compatdb -c "ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_statements';" + docker restart "$PG_CID" + + for i in $(seq 1 40); do + if docker exec "$PG_CID" pg_isready -U postgres -d compatdb; then + break + fi + sleep 2 + done + + docker exec "$PG_CID" psql -U postgres -d compatdb -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;" + + - name: Build backend image with Alpine base + run: | + docker build \ + -f backend/Dockerfile \ + --build-arg PYTHON_BASE_IMAGE=python:3.13-alpine \ + -t nexapg-backend-alpine-smoke:ci \ + ./backend + + - name: Run smoke checks in backend Alpine image + env: + PG_DSN_CANDIDATES: postgresql://postgres:postgres@127.0.0.1:5432/compatdb?sslmode=disable + run: | + docker run --rm --network host \ + -e PG_DSN_CANDIDATES="${PG_DSN_CANDIDATES}" \ + nexapg-backend-alpine-smoke:ci \ + python /app/scripts/pg_compat_smoke.py diff --git a/backend/Dockerfile b/backend/Dockerfile index e3057c6..8104270 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,4 +1,5 @@ -FROM python:3.13-slim AS base +ARG PYTHON_BASE_IMAGE=python:3.13-slim +FROM ${PYTHON_BASE_IMAGE} AS base ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 @@ -6,11 +7,17 @@ ENV PIP_NO_CACHE_DIR=1 WORKDIR /app -RUN apt-get update \ - && apt-get upgrade -y \ - && rm -rf /var/lib/apt/lists/* +RUN if command -v apt-get >/dev/null 2>&1; then \ + apt-get update && apt-get upgrade -y && rm -rf /var/lib/apt/lists/*; \ + elif command -v apk >/dev/null 2>&1; then \ + apk upgrade --no-cache; \ + fi -RUN addgroup --system app && adduser --system --ingroup app app +RUN if addgroup --help 2>&1 | grep -q -- '--system'; then \ + addgroup --system app && adduser --system --ingroup app app; \ + else \ + addgroup -S app && adduser -S -G app app; \ + fi COPY requirements.txt /app/requirements.txt RUN pip install --upgrade pip && pip install -r /app/requirements.txt From 15fea78505df36e6cb5a9f91045c4b45bf81af49 Mon Sep 17 00:00:00 2001 From: nessi Date: Sat, 14 Feb 2026 16:52:10 +0100 Subject: [PATCH 2/4] Update Python base image to Alpine version for backend This change switches the base image from "slim" to "alpine" to reduce the overall image size and improve security. The updated image is more lightweight and better suited for environments where optimization is critical. --- backend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 8104270..2d9b095 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,4 +1,4 @@ -ARG PYTHON_BASE_IMAGE=python:3.13-slim +ARG PYTHON_BASE_IMAGE=python:3.13-alpine FROM ${PYTHON_BASE_IMAGE} AS base ENV PYTHONDONTWRITEBYTECODE=1 From 03118e59d75efbd87cfb35748f8d2f758b4b9ad5 Mon Sep 17 00:00:00 2001 From: nessi Date: Sat, 14 Feb 2026 16:58:10 +0100 Subject: [PATCH 3/4] Remove backend Alpine smoke (PG16) job from CI workflow The backend Alpine smoke test targeting PostgreSQL 16 was removed from the CI configuration. This cleanup simplifies the workflow by eliminating redundancy, as the functionality might be covered elsewhere or deemed unnecessary. --- .github/workflows/pg-compat-matrix.yml | 62 -------------------------- 1 file changed, 62 deletions(-) diff --git a/.github/workflows/pg-compat-matrix.yml b/.github/workflows/pg-compat-matrix.yml index 3dc9954..d4d923b 100644 --- a/.github/workflows/pg-compat-matrix.yml +++ b/.github/workflows/pg-compat-matrix.yml @@ -67,65 +67,3 @@ jobs: env: PG_DSN_CANDIDATES: postgresql://postgres:postgres@postgres:5432/compatdb?sslmode=disable,postgresql://postgres:postgres@127.0.0.1:5432/compatdb?sslmode=disable run: python backend/scripts/pg_compat_smoke.py - - backend-alpine-smoke: - name: Backend Alpine smoke (PG16) - runs-on: ubuntu-latest - - services: - postgres: - image: postgres:16 - env: - POSTGRES_DB: compatdb - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - ports: - - 5432:5432 - options: >- - --health-cmd "pg_isready -U postgres -d compatdb" - --health-interval 5s - --health-timeout 5s - --health-retries 20 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Enable pg_stat_statements in service container - run: | - PG_CID="$(docker ps --filter "ancestor=postgres:16" --format "{{.ID}}" | head -n1)" - if [ -z "$PG_CID" ]; then - echo "Could not find postgres service container for version 16" - docker ps -a - exit 1 - fi - - echo "Using postgres container: $PG_CID" - docker exec "$PG_CID" psql -U postgres -d compatdb -c "ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_statements';" - docker restart "$PG_CID" - - for i in $(seq 1 40); do - if docker exec "$PG_CID" pg_isready -U postgres -d compatdb; then - break - fi - sleep 2 - done - - docker exec "$PG_CID" psql -U postgres -d compatdb -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;" - - - name: Build backend image with Alpine base - run: | - docker build \ - -f backend/Dockerfile \ - --build-arg PYTHON_BASE_IMAGE=python:3.13-alpine \ - -t nexapg-backend-alpine-smoke:ci \ - ./backend - - - name: Run smoke checks in backend Alpine image - env: - PG_DSN_CANDIDATES: postgresql://postgres:postgres@127.0.0.1:5432/compatdb?sslmode=disable - run: | - docker run --rm --network host \ - -e PG_DSN_CANDIDATES="${PG_DSN_CANDIDATES}" \ - nexapg-backend-alpine-smoke:ci \ - python /app/scripts/pg_compat_smoke.py From 344071193c4f421fe9629fb02bc6df3d61c94198 Mon Sep 17 00:00:00 2001 From: nessi Date: Sat, 14 Feb 2026 16:58:31 +0100 Subject: [PATCH 4/4] Update NEXAPG_VERSION to 0.2.1 Bumped the version from 0.2.0 to 0.2.1 to reflect recent changes or updates. This ensures the system aligns with the latest versioning conventions. --- backend/app/core/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 899dba8..a0ad1f1 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -2,7 +2,7 @@ from functools import lru_cache from pydantic import field_validator from pydantic_settings import BaseSettings, SettingsConfigDict -NEXAPG_VERSION = "0.2.0" +NEXAPG_VERSION = "0.2.1" class Settings(BaseSettings):