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
|
pip install --quiet --no-cache-dir pytest pytest-asyncio
|
||||||
python -m pytest test_main.py -v --tb=short
|
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) ─────────────────────────────────
|
# ── OpenAPI contract validation (always) ─────────────────────────────────
|
||||||
validate-canonical-controls:
|
validate-canonical-controls:
|
||||||
runs-on: docker
|
runs-on: docker
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ RUN adduser -D -u 1000 appuser
|
|||||||
USER appuser
|
USER appuser
|
||||||
|
|
||||||
# Expose port
|
# Expose port
|
||||||
|
ARG BUILD_SHA="unknown"
|
||||||
|
ENV BUILD_SHA=${BUILD_SHA}
|
||||||
|
|
||||||
EXPOSE 8090
|
EXPOSE 8090
|
||||||
|
|
||||||
# Health check
|
# 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
|
RUN chown -R ttsuser:ttsuser /app
|
||||||
USER ttsuser
|
USER ttsuser
|
||||||
|
|
||||||
|
ARG BUILD_SHA="unknown"
|
||||||
|
ENV BUILD_SHA=${BUILD_SHA}
|
||||||
|
|
||||||
EXPOSE 8095
|
EXPOSE 8095
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 CMD curl -sf http://127.0.0.1:8095/health || exit 1
|
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
|
USER nextjs
|
||||||
|
|
||||||
# Expose port
|
# Expose port
|
||||||
|
ARG BUILD_SHA="unknown"
|
||||||
|
ENV BUILD_SHA=${BUILD_SHA}
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
# Set hostname
|
# Set hostname
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ services:
|
|||||||
args:
|
args:
|
||||||
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://macmini:8002}
|
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://macmini:8002}
|
||||||
NEXT_PUBLIC_SDK_URL: ${NEXT_PUBLIC_SDK_URL:-https://macmini:8093}
|
NEXT_PUBLIC_SDK_URL: ${NEXT_PUBLIC_SDK_URL:-https://macmini:8093}
|
||||||
|
BUILD_SHA: ${BUILD_SHA:-unknown}
|
||||||
container_name: bp-compliance-admin
|
container_name: bp-compliance-admin
|
||||||
platform: linux/arm64
|
platform: linux/arm64
|
||||||
expose:
|
expose:
|
||||||
@@ -71,6 +72,8 @@ services:
|
|||||||
|
|
||||||
developer-portal:
|
developer-portal:
|
||||||
build:
|
build:
|
||||||
|
args:
|
||||||
|
BUILD_SHA: ${BUILD_SHA:-unknown}
|
||||||
context: ./developer-portal
|
context: ./developer-portal
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: bp-compliance-developer-portal
|
container_name: bp-compliance-developer-portal
|
||||||
@@ -88,6 +91,8 @@ services:
|
|||||||
# =========================================================
|
# =========================================================
|
||||||
backend-compliance:
|
backend-compliance:
|
||||||
build:
|
build:
|
||||||
|
args:
|
||||||
|
BUILD_SHA: ${BUILD_SHA:-unknown}
|
||||||
context: ./backend-compliance
|
context: ./backend-compliance
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: bp-compliance-backend
|
container_name: bp-compliance-backend
|
||||||
@@ -142,6 +147,8 @@ services:
|
|||||||
# =========================================================
|
# =========================================================
|
||||||
ai-compliance-sdk:
|
ai-compliance-sdk:
|
||||||
build:
|
build:
|
||||||
|
args:
|
||||||
|
BUILD_SHA: ${BUILD_SHA:-unknown}
|
||||||
context: ./ai-compliance-sdk
|
context: ./ai-compliance-sdk
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: bp-compliance-ai-sdk
|
container_name: bp-compliance-ai-sdk
|
||||||
@@ -186,6 +193,8 @@ services:
|
|||||||
# =========================================================
|
# =========================================================
|
||||||
compliance-tts-service:
|
compliance-tts-service:
|
||||||
build:
|
build:
|
||||||
|
args:
|
||||||
|
BUILD_SHA: ${BUILD_SHA:-unknown}
|
||||||
context: ./compliance-tts-service
|
context: ./compliance-tts-service
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: bp-compliance-tts
|
container_name: bp-compliance-tts
|
||||||
@@ -215,6 +224,8 @@ services:
|
|||||||
# =========================================================
|
# =========================================================
|
||||||
dsms-node:
|
dsms-node:
|
||||||
build:
|
build:
|
||||||
|
args:
|
||||||
|
BUILD_SHA: ${BUILD_SHA:-unknown}
|
||||||
context: ./dsms-node
|
context: ./dsms-node
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: bp-compliance-dsms-node
|
container_name: bp-compliance-dsms-node
|
||||||
@@ -238,6 +249,8 @@ services:
|
|||||||
|
|
||||||
dsms-gateway:
|
dsms-gateway:
|
||||||
build:
|
build:
|
||||||
|
args:
|
||||||
|
BUILD_SHA: ${BUILD_SHA:-unknown}
|
||||||
context: ./dsms-gateway
|
context: ./dsms-gateway
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: bp-compliance-dsms-gateway
|
container_name: bp-compliance-dsms-gateway
|
||||||
@@ -259,6 +272,8 @@ services:
|
|||||||
# =========================================================
|
# =========================================================
|
||||||
consent-tester:
|
consent-tester:
|
||||||
build:
|
build:
|
||||||
|
args:
|
||||||
|
BUILD_SHA: ${BUILD_SHA:-unknown}
|
||||||
context: ./consent-tester
|
context: ./consent-tester
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: bp-compliance-consent-tester
|
container_name: bp-compliance-consent-tester
|
||||||
@@ -293,6 +308,8 @@ services:
|
|||||||
|
|
||||||
document-crawler:
|
document-crawler:
|
||||||
build:
|
build:
|
||||||
|
args:
|
||||||
|
BUILD_SHA: ${BUILD_SHA:-unknown}
|
||||||
context: ./document-crawler
|
context: ./document-crawler
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: bp-compliance-document-crawler
|
container_name: bp-compliance-document-crawler
|
||||||
@@ -326,6 +343,8 @@ services:
|
|||||||
# =========================================================
|
# =========================================================
|
||||||
docs:
|
docs:
|
||||||
build:
|
build:
|
||||||
|
args:
|
||||||
|
BUILD_SHA: ${BUILD_SHA:-unknown}
|
||||||
context: .
|
context: .
|
||||||
dockerfile: docs-src/Dockerfile
|
dockerfile: docs-src/Dockerfile
|
||||||
container_name: bp-compliance-docs
|
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
|
}' > /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
ARG BUILD_SHA="unknown"
|
||||||
|
ENV BUILD_SHA=${BUILD_SHA}
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
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
|
ENV MAX_FILE_SIZE_MB=50
|
||||||
|
|
||||||
# Expose port
|
# Expose port
|
||||||
|
ARG BUILD_SHA="unknown"
|
||||||
|
ENV BUILD_SHA=${BUILD_SHA}
|
||||||
|
|
||||||
EXPOSE 8098
|
EXPOSE 8098
|
||||||
|
|
||||||
# Health check
|
# Health check
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ ENV IPFS_GATEWAY_URL=http://dsms-node:8080
|
|||||||
ENV PORT=8082
|
ENV PORT=8082
|
||||||
|
|
||||||
# Expose port
|
# Expose port
|
||||||
|
ARG BUILD_SHA="unknown"
|
||||||
|
ENV BUILD_SHA=${BUILD_SHA}
|
||||||
|
|
||||||
EXPOSE 8082
|
EXPOSE 8082
|
||||||
|
|
||||||
# Health check
|
# Health check
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ ENV IPFS_PROFILE=server
|
|||||||
# 4001 - Swarm (P2P)
|
# 4001 - Swarm (P2P)
|
||||||
# 5001 - API
|
# 5001 - API
|
||||||
# 8080 - Gateway
|
# 8080 - Gateway
|
||||||
|
ARG BUILD_SHA="unknown"
|
||||||
|
ENV BUILD_SHA=${BUILD_SHA}
|
||||||
|
|
||||||
EXPOSE 4001
|
EXPOSE 4001
|
||||||
EXPOSE 5001
|
EXPOSE 5001
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|||||||
Reference in New Issue
Block a user