From 89d3a396799deeab7d1d2b70713563533a7ebcd2 Mon Sep 17 00:00:00 2001 From: nessi Date: Sat, 14 Feb 2026 16:48:10 +0100 Subject: [PATCH] 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