1
0
forked from baron/baron-sso

fix(deploy): align staging frontend runtime with production images

This commit is contained in:
2026-06-05 09:24:44 +09:00
parent ded9dfc56b
commit 4bae1dd00d
13 changed files with 585 additions and 107 deletions

View File

@@ -64,13 +64,19 @@ for file in "$STAGING_COMPOSE" "$PULL_COMPOSE"; do
done
assert_contains "$STAGING_COMPOSE" 'image: ${ORGFRONT_IMAGE_NAME}:${IMAGE_TAG}'
assert_contains "$PULL_COMPOSE" "context: ./orgfront"
assert_contains "$DEPLOY_TEMPLATE" "../../orgfront:/app"
assert_contains "$DEPLOY_TEMPLATE" "./orgfront/vite.config.ts:/app/vite.config.ts:ro"
assert_contains "$DEPLOY_TEMPLATE" "./orgfront/auth.ts:/app/src/lib/auth.ts:ro"
assert_contains "$PULL_COMPOSE" "context: ."
assert_contains "$PULL_COMPOSE" "dockerfile: ./orgfront/Dockerfile"
assert_contains "$PULL_COMPOSE" "VITE_ORGFRONT_PUBLIC_URL: \${ORGFRONT_URL:-}"
assert_not_contains "$PULL_COMPOSE" "./orgfront:/app"
assert_contains "$DEPLOY_TEMPLATE" "dockerfile: ./orgfront/Dockerfile"
assert_contains "$DEPLOY_TEMPLATE" "VITE_ORGFRONT_PUBLIC_URL: \${ORGFRONT_URL}"
assert_not_contains "$DEPLOY_TEMPLATE" "../../orgfront:/app"
assert_not_contains "$DEPLOY_TEMPLATE" "./orgfront/vite.config.ts:/app/vite.config.ts:ro"
assert_not_contains "$DEPLOY_TEMPLATE" "./orgfront/auth.ts:/app/src/lib/auth.ts:ro"
assert_contains "$BUILD_RC" "Build and push orgfront RC image"
assert_contains "$BUILD_RC" "context: ./orgfront"
assert_contains "$BUILD_RC" "context: ."
assert_contains "$BUILD_RC" "file: ./orgfront/Dockerfile"
assert_contains "$BUILD_RC" "/baron_sso/orgfront:"
assert_contains "$CODE_CHECK" "run_orgfront_tests"

View File

@@ -0,0 +1,102 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
assert_contains() {
local file="$1"
local pattern="$2"
if ! grep -Fq -- "$pattern" "$file"; then
echo "ERROR: missing pattern in $file: $pattern" >&2
exit 1
fi
}
assert_not_contains() {
local file="$1"
local pattern="$2"
if grep -Fq -- "$pattern" "$file"; then
echo "ERROR: forbidden pattern remains in $file: $pattern" >&2
exit 1
fi
}
build_rc="$ROOT_DIR/.gitea/workflows/build_RC.yml"
staging_release="$ROOT_DIR/.gitea/workflows/staging_release.yml"
production_release="$ROOT_DIR/.gitea/workflows/production_release.yml"
production_compose="$ROOT_DIR/docker/docker-compose.template.yaml"
for file in "$build_rc" "$staging_release" "$production_release" "$production_compose"; do
if [[ ! -f "$file" ]]; then
echo "ERROR: expected file not found: $file" >&2
exit 1
fi
done
for app in adminfront devfront orgfront; do
assert_contains "$build_rc" "Build and push $app RC image"
assert_contains "$build_rc" "file: ./$app/Dockerfile"
assert_contains "$build_rc" "build-args: |"
assert_contains "$build_rc" "VITE_OIDC_AUTHORITY=\${{ vars.VITE_OIDC_AUTHORITY }}"
done
assert_contains "$build_rc" "Validate RC build configuration"
assert_contains "$build_rc" "Missing required RC build value"
assert_contains "$build_rc" "Check Gitea repo variables/secrets"
assert_contains "$build_rc" "VITE_ADMIN_PUBLIC_URL=\${{ vars.ADMINFRONT_URL }}"
assert_contains "$build_rc" "VITE_DEVFRONT_PUBLIC_URL=\${{ vars.DEVFRONT_URL }}"
assert_contains "$build_rc" "VITE_ORGFRONT_PUBLIC_URL=\${{ vars.ORGFRONT_URL }}"
assert_contains "$build_rc" "ORGFRONT_URL=\${{ vars.ORGFRONT_URL }}"
assert_contains "$staging_release" "CLICKHOUSE_PASSWORD=\${{ secrets.CLICKHOUSE_PASSWORD }}"
assert_not_contains "$staging_release" "CLICKHOUSE_PASSWORD=\${{ vars.CLICKHOUSE_PASSWORD }}"
assert_contains "$staging_release" "PROFILE_CACHE_TTL=\${{ vars.PROFILE_CACHE_TTL }}"
assert_contains "$staging_release" "KRATOS_UI_NODE_VERSION=\${{ vars.KRATOS_UI_NODE_VERSION }}"
assert_contains "$staging_release" "Missing required staging .env value"
assert_contains "$staging_release" "Check Gitea repo variables/secrets"
assert_contains "$staging_release" "scp scripts/render_ory_config.sh"
assert_contains "$staging_release" "scp compose.ory.yaml"
assert_not_contains "$staging_release" "scp docker/compose.ory.yaml"
assert_contains "$staging_release" "bash scripts/render_ory_config.sh"
assert_contains "$staging_release" "chmod -R 777 config/.generated/ory"
assert_contains "$production_release" "for image in backend userfront adminfront devfront orgfront; do"
assert_contains "$production_release" 'docker://${HARBOR_HOSTNAME}/baron_sso/${image}:${BASE_TAG}'
assert_contains "$production_release" 'docker://${HARBOR_HOSTNAME}/baron_sso/${image}:${RE_TAG}'
assert_contains "$production_release" "ADMINFRONT_IMAGE_NAME: \${{ vars.HARBOR_HOSTNAME }}/baron_sso/adminfront"
assert_contains "$production_release" "DEVFRONT_IMAGE_NAME: \${{ vars.HARBOR_HOSTNAME }}/baron_sso/devfront"
assert_contains "$production_release" "ORGFRONT_IMAGE_NAME: \${{ vars.HARBOR_HOSTNAME }}/baron_sso/orgfront"
assert_contains "$production_release" "USERFRONT_URL=\${{ vars.PROD_FRONTEND_URL }}"
assert_contains "$production_release" "BACKEND_URL=\${{ vars.PROD_BACKEND_URL }}"
assert_contains "$production_release" "USERFRONT_PORT=\${{ vars.PROD_FRONTEND_PORT }}"
assert_contains "$production_release" "PROD_BACKEND_PORT=\${{ vars.PROD_BACKEND_PORT }}"
assert_contains "$production_release" "BACKEND_PORT=3000"
assert_contains "$production_release" "ADMINFRONT_URL=\${{ vars.ADMINFRONT_URL }}"
assert_contains "$production_release" "DEVFRONT_URL=\${{ vars.DEVFRONT_URL }}"
assert_contains "$production_release" "ORGFRONT_URL=\${{ vars.ORGFRONT_URL }}"
assert_contains "$production_release" "VITE_OIDC_AUTHORITY=\${{ vars.VITE_OIDC_AUTHORITY }}"
assert_contains "$production_release" "ADMINFRONT_CALLBACK_URLS=\${{ vars.ADMINFRONT_CALLBACK_URLS }}"
assert_contains "$production_release" "DEVFRONT_CALLBACK_URLS=\${{ vars.DEVFRONT_CALLBACK_URLS }}"
assert_contains "$production_release" "ORGFRONT_CALLBACK_URLS=\${{ vars.ORGFRONT_CALLBACK_URLS }}"
assert_contains "$production_release" "ADMINFRONT_PORT=\${{ vars.ADMINFRONT_PORT }}"
assert_contains "$production_release" "DEVFRONT_PORT=\${{ vars.DEVFRONT_PORT }}"
assert_contains "$production_release" "ORGFRONT_PORT=\${{ vars.ORGFRONT_PORT }}"
assert_contains "$production_release" "export ADMINFRONT_IMAGE_NAME='\${ADMINFRONT_IMAGE_NAME}'"
assert_contains "$production_release" "export DEVFRONT_IMAGE_NAME='\${DEVFRONT_IMAGE_NAME}'"
assert_contains "$production_release" "export ORGFRONT_IMAGE_NAME='\${ORGFRONT_IMAGE_NAME}'"
assert_contains "$production_release" "Missing required production .env value"
assert_not_contains "$production_release" "PROD_USERFRONT_URL"
assert_not_contains "$production_release" "PROD_USERFRONT_PORT"
for app in adminfront devfront orgfront; do
assert_contains "$production_compose" "$app:"
done
assert_contains "$production_compose" 'image: ${ADMINFRONT_IMAGE_NAME}:${IMAGE_TAG}'
assert_contains "$production_compose" 'image: ${DEVFRONT_IMAGE_NAME}:${IMAGE_TAG}'
assert_contains "$production_compose" 'image: ${ORGFRONT_IMAGE_NAME}:${IMAGE_TAG}'
assert_contains "$production_compose" 'API_PROXY_TARGET=http://baron_backend:${BACKEND_PORT:-3000}'
assert_contains "$production_compose" '${PROD_BACKEND_PORT:-3010}:3000'
assert_contains "$production_compose" '${USERFRONT_PORT:-80}:5000'
assert_contains "$production_compose" 'BACKEND_PORT=3000'
assert_contains "$production_compose" 'http://127.0.0.1:3000/health'
echo "production image release policy checks passed"

View File

@@ -30,6 +30,9 @@ adminfront_vite="adminfront/vite.config.ts"
adminfront_runtime="adminfront/scripts/runtime-mode.sh"
devfront_runtime="devfront/scripts/runtime-mode.sh"
orgfront_runtime="orgfront/scripts/runtime-mode.sh"
adminfront_dockerfile="adminfront/Dockerfile"
devfront_dockerfile="devfront/Dockerfile"
orgfront_dockerfile="orgfront/Dockerfile"
for file in \
"$staging_pull" \
@@ -42,7 +45,10 @@ for file in \
"$orgfront_vite" \
"$adminfront_runtime" \
"$devfront_runtime" \
"$orgfront_runtime"
"$orgfront_runtime" \
"$adminfront_dockerfile" \
"$devfront_dockerfile" \
"$orgfront_dockerfile"
do
if [ ! -f "$file" ]; then
echo "missing expected file: $file" >&2
@@ -72,8 +78,11 @@ for app in adminfront devfront orgfront; do
assert_contains "$pull_compose" "$app:"
assert_contains "$pull_compose" "context: ."
assert_contains "$pull_compose" "dockerfile: ./$app/Dockerfile"
assert_contains "$pull_compose" "VITE_OIDC_AUTHORITY: \${VITE_OIDC_AUTHORITY:-}"
assert_not_contains "$pull_compose" "context: ./$app"
assert_not_contains "$pull_compose" "./$app:/app"
done
assert_not_contains "$pull_compose" "/app/node_modules"
assert_contains "$pull_compose" "dockerfile: userfront/Dockerfile"
assert_not_contains "$pull_compose" 'target: ${USERFRONT_BUILD_TARGET:-dev}'
assert_not_contains "$pull_compose" "target: dev"
@@ -82,8 +91,12 @@ assert_contains "$pull_compose" "http://127.0.0.1:5173/"
assert_contains "$pull_compose" "http://127.0.0.1:5175/"
assert_contains "$pull_compose" 'APP_ENV=${APP_ENV:-stage}'
assert_contains "$deploy_compose" "sh ./scripts/runtime-mode.sh"
assert_contains "$deploy_compose" "dockerfile: ./adminfront/Dockerfile"
assert_contains "$deploy_compose" "dockerfile: ./devfront/Dockerfile"
assert_contains "$deploy_compose" "dockerfile: ./orgfront/Dockerfile"
assert_not_contains "$deploy_compose" "sh ./scripts/runtime-mode.sh"
assert_not_contains "$deploy_compose" "command: npm run dev"
assert_not_contains "$deploy_compose" "image: node:20-alpine"
assert_contains "$deploy_gateway" "root /usr/share/nginx/html;"
assert_contains "$deploy_gateway" 'try_files $uri $uri/ /index.html;'
assert_not_contains "$deploy_gateway" "baron_userfront"
@@ -96,6 +109,21 @@ for app in adminfront devfront orgfront; do
assert_not_contains ".gitea/workflows/build_RC.yml" "context: ./$app"
done
for app in adminfront devfront orgfront; do
dockerfile="$app/Dockerfile"
assert_contains "$dockerfile" "COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./"
assert_contains "$dockerfile" "RUN pnpm install --frozen-lockfile --ignore-scripts"
assert_contains "$dockerfile" "FROM node:24-alpine AS production"
assert_contains "$dockerfile" "COPY scripts/serve_frontend_prod.mjs ./serve_frontend_prod.mjs"
assert_contains "$dockerfile" "RUN npm run build"
assert_contains "$dockerfile" 'CMD ["node", "./serve_frontend_prod.mjs"]'
assert_not_contains "$dockerfile" "cd common && pnpm install"
assert_not_contains "$dockerfile" "npm install -g serve"
assert_not_contains "$dockerfile" "runtime-mode.sh"
done
assert_contains "scripts/serve_frontend_prod.mjs" "pathname === \"/api\" || pathname.startsWith(\"/api/\")"
assert_contains "scripts/serve_frontend_prod.mjs" "API_PROXY_TARGET"
assert_contains "$adminfront_vite" "/tmp/baron-sso-adminfront-dist"
assert_contains "$adminfront_vite" "/tmp/baron-sso-adminfront-vite-cache"
assert_contains "adminfront/biome.json" '".vite"'