feat(p83): wire BUILD_SHA through all Dockerfiles + compose + CI check

check-rebuild-needed.sh war seit Mai funktionsfähig nur fuer 3 von 10
Containern. Die anderen 7 Dockerfiles hatten kein ARG/ENV BUILD_SHA und
docker-compose.yml hat fuer KEINEN Service den Wert durchgereicht — daher
defaultete BUILD_SHA ueberall auf "unknown" und die Drift-Check war
zahnlos.

- ARG BUILD_SHA + ENV BUILD_SHA in 8 zusaetzlichen Dockerfiles
  (ai-compliance-sdk, developer-portal, document-crawler, dsms-gateway,
  compliance-tts-service, docs-src, docs-site, dsms-node)
- docker-compose.yml: BUILD_SHA: \${BUILD_SHA:-unknown} in jedem build:
  Block (10 Services)
- .gitea/workflows/ci.yaml: neuer Job build-sha-integrity validiert dass
  jedes Dockerfile ARG+ENV hat und jeder compose-build den Arg durchreicht.
  Faellt bei jedem PR/Push gegen master, der einen neuen Service oder
  Dockerfile ohne BUILD_SHA einfuehrt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-22 18:29:03 +02:00
parent 4087bb5f18
commit 60b86be706
10 changed files with 135 additions and 0 deletions
+44
View File
@@ -411,6 +411,50 @@ jobs:
pip install --quiet --no-cache-dir pytest pytest-asyncio
python -m pytest test_main.py -v --tb=short
# ── P83: BUILD_SHA integrity (always) ────────────────────────────────────
# Every Dockerfile must declare ARG BUILD_SHA + ENV BUILD_SHA so the
# check-rebuild-needed.sh script can detect "old code in container" drift.
# Every docker-compose build: block must pass BUILD_SHA through as a build
# arg — otherwise the ARG defaults to "unknown" and the check is toothless.
build-sha-integrity:
runs-on: docker
container: alpine:3.20
steps:
- name: Checkout
run: |
apk add --no-cache git python3
git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
- name: Validate every Dockerfile + compose block declares BUILD_SHA
run: |
python3 - <<'PY'
import re, sys, glob
fails = []
# 1. Each Dockerfile must have ARG BUILD_SHA + ENV BUILD_SHA=${BUILD_SHA}
for df in sorted(glob.glob("*/Dockerfile")):
# Skip nested non-canonical Dockerfiles (e.g. admin-compliance/ai-compliance-sdk/Dockerfile)
if df.count("/") > 1: continue
src = open(df).read()
if "ARG BUILD_SHA" not in src:
fails.append(f"{df}: missing ARG BUILD_SHA")
if "ENV BUILD_SHA" not in src:
fails.append(f"{df}: missing ENV BUILD_SHA")
# 2. Every build: block in docker-compose.yml must pass BUILD_SHA
import yaml
compose = yaml.safe_load(open("docker-compose.yml"))
for name, svc in (compose.get("services") or {}).items():
build = svc.get("build")
if not isinstance(build, dict):
continue # skipping pre-built image refs
args = (build.get("args") or {})
if "BUILD_SHA" not in args:
fails.append(f"docker-compose.yml: service '{name}' build.args missing BUILD_SHA")
if fails:
print("::error::BUILD_SHA integrity check failed:")
for f in fails: print(f" - {f}")
sys.exit(1)
print(f"OK: BUILD_SHA wired in all Dockerfiles + compose build blocks.")
PY
# ── OpenAPI contract validation (always) ─────────────────────────────────
validate-canonical-controls:
runs-on: docker
+3
View File
@@ -38,6 +38,9 @@ RUN adduser -D -u 1000 appuser
USER appuser
# Expose port
ARG BUILD_SHA="unknown"
ENV BUILD_SHA=${BUILD_SHA}
EXPOSE 8090
# Health check
+3
View File
@@ -35,6 +35,9 @@ RUN if [ -f /etc/ImageMagick-6/policy.xml ]; then sed -i "s/rights=\"none\"
RUN chown -R ttsuser:ttsuser /app
USER ttsuser
ARG BUILD_SHA="unknown"
ENV BUILD_SHA=${BUILD_SHA}
EXPOSE 8095
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 CMD curl -sf http://127.0.0.1:8095/health || exit 1
+3
View File
@@ -39,6 +39,9 @@ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
# Expose port
ARG BUILD_SHA="unknown"
ENV BUILD_SHA=${BUILD_SHA}
EXPOSE 3000
# Set hostname
+19
View File
@@ -46,6 +46,7 @@ services:
args:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://macmini:8002}
NEXT_PUBLIC_SDK_URL: ${NEXT_PUBLIC_SDK_URL:-https://macmini:8093}
BUILD_SHA: ${BUILD_SHA:-unknown}
container_name: bp-compliance-admin
platform: linux/arm64
expose:
@@ -71,6 +72,8 @@ services:
developer-portal:
build:
args:
BUILD_SHA: ${BUILD_SHA:-unknown}
context: ./developer-portal
dockerfile: Dockerfile
container_name: bp-compliance-developer-portal
@@ -88,6 +91,8 @@ services:
# =========================================================
backend-compliance:
build:
args:
BUILD_SHA: ${BUILD_SHA:-unknown}
context: ./backend-compliance
dockerfile: Dockerfile
container_name: bp-compliance-backend
@@ -142,6 +147,8 @@ services:
# =========================================================
ai-compliance-sdk:
build:
args:
BUILD_SHA: ${BUILD_SHA:-unknown}
context: ./ai-compliance-sdk
dockerfile: Dockerfile
container_name: bp-compliance-ai-sdk
@@ -186,6 +193,8 @@ services:
# =========================================================
compliance-tts-service:
build:
args:
BUILD_SHA: ${BUILD_SHA:-unknown}
context: ./compliance-tts-service
dockerfile: Dockerfile
container_name: bp-compliance-tts
@@ -215,6 +224,8 @@ services:
# =========================================================
dsms-node:
build:
args:
BUILD_SHA: ${BUILD_SHA:-unknown}
context: ./dsms-node
dockerfile: Dockerfile
container_name: bp-compliance-dsms-node
@@ -238,6 +249,8 @@ services:
dsms-gateway:
build:
args:
BUILD_SHA: ${BUILD_SHA:-unknown}
context: ./dsms-gateway
dockerfile: Dockerfile
container_name: bp-compliance-dsms-gateway
@@ -259,6 +272,8 @@ services:
# =========================================================
consent-tester:
build:
args:
BUILD_SHA: ${BUILD_SHA:-unknown}
context: ./consent-tester
dockerfile: Dockerfile
container_name: bp-compliance-consent-tester
@@ -293,6 +308,8 @@ services:
document-crawler:
build:
args:
BUILD_SHA: ${BUILD_SHA:-unknown}
context: ./document-crawler
dockerfile: Dockerfile
container_name: bp-compliance-document-crawler
@@ -326,6 +343,8 @@ services:
# =========================================================
docs:
build:
args:
BUILD_SHA: ${BUILD_SHA:-unknown}
context: .
dockerfile: docs-src/Dockerfile
container_name: bp-compliance-docs
+51
View File
@@ -0,0 +1,51 @@
# ============================================
# BreakPilot Compliance Dokumentation - MkDocs Build
# Multi-stage build fuer minimale Image-Groesse
# ============================================
# Stage 1: Build MkDocs Site
FROM python:3.11-slim AS builder
WORKDIR /docs
RUN pip install --no-cache-dir \
mkdocs==1.6.1 \
mkdocs-material==9.5.47 \
pymdown-extensions==10.12
COPY mkdocs.yml /docs/
COPY docs-src/ /docs/docs-src/
RUN mkdocs build
# Stage 2: Serve with Nginx
FROM nginx:alpine
COPY --from=builder /docs/docs-site /usr/share/nginx/html
RUN echo 'server { \
listen 80; \
server_name localhost; \
root /usr/share/nginx/html; \
index index.html; \
location / { \
try_files $uri $uri/ /index.html; \
} \
gzip on; \
gzip_types text/plain text/css application/json application/javascript text/xml application/xml; \
gzip_min_length 1000; \
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { \
expires 1y; \
add_header Cache-Control "public, immutable"; \
} \
}' > /etc/nginx/conf.d/default.conf
ARG BUILD_SHA="unknown"
ENV BUILD_SHA=${BUILD_SHA}
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1
CMD ["nginx", "-g", "daemon off;"]
+3
View File
@@ -40,6 +40,9 @@ RUN echo 'server { \
} \
}' > /etc/nginx/conf.d/default.conf
ARG BUILD_SHA="unknown"
ENV BUILD_SHA=${BUILD_SHA}
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
+3
View File
@@ -27,6 +27,9 @@ ENV CRAWL_BASE_PATH=/data/crawl
ENV MAX_FILE_SIZE_MB=50
# Expose port
ARG BUILD_SHA="unknown"
ENV BUILD_SHA=${BUILD_SHA}
EXPOSE 8098
# Health check
+3
View File
@@ -22,6 +22,9 @@ ENV IPFS_GATEWAY_URL=http://dsms-node:8080
ENV PORT=8082
# Expose port
ARG BUILD_SHA="unknown"
ENV BUILD_SHA=${BUILD_SHA}
EXPOSE 8082
# Health check
+3
View File
@@ -14,6 +14,9 @@ ENV IPFS_PROFILE=server
# 4001 - Swarm (P2P)
# 5001 - API
# 8080 - Gateway
ARG BUILD_SHA="unknown"
ENV BUILD_SHA=${BUILD_SHA}
EXPOSE 4001
EXPOSE 5001
EXPOSE 8080