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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;"]
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user