fix(ci): 依据 Actions 真实日志修复三处失败(runner 无 pnpm / 门禁缺依赖 / 生产配置未入库)
上一轮已把 CI 跑起来并读到真实结果:7 个 job 中 Mini Program 与 Test Shell Guard 通过,Admin Web、Backend、UI Contracts 三个失败,migration 与 e2e 因依赖 backend 被跳过。本轮全部依据 Actions 原始日志定位,而不是本地推测 —— 三者都不是业务代码问题。 1. Admin Web Build:runner 已不再预装 pnpm 日志:Unable to locate executable file: pnpm runner 镜像(ubuntu-24.04 / 2.337.0)的 PATH 里没有 pnpm,而 setup-node 的 cache: 'pnpm' 在 restore 阶段就需要调用 pnpm 可执行文件,于是 job 在第一步失败、 后续步骤全部 skipped。同批的 miniapp job 没配 cache 所以正常通过,正好反向印证。 改为先用 corepack 启用并钉住 pnpm@9.15.9,store 缓存改由 actions/cache 手动配置 (此时 pnpm 才存在于 PATH)。 2. UI Contracts:门禁依赖没装 日志:Cannot find module '.../miniapp/node_modules/typescript/lib/typescript.js' phase04 守卫会用 TypeScript 编译器 API 解析小程序源码,但本 job 此前不装依赖。 本地能跑通只因为工作区早已装过;CI 的每个 job 都在独立 runner 上, miniapp job 安装的依赖不会共享过来。补上 npm install,并修正 workflow 中 「零 npm 依赖、故无需装依赖」的错误注释 —— 与实际不符的声明本身就是缺陷来源。 3. Backend:断言了一个永远不会入库的文件 日志:DeploymentTests.testDockerComposeProdExists 期望 true 实际 false infrastructure/docker-compose.prod.yml 被 .gitignore 列在 「Secrets and certificates」段而排除出版本控制,但这是**误分类**: 该文件不含任何明文密钥,敏感值全部走 ${VAR} 注入、db 密码走 Docker secrets, 文件头注释本身也写着「敏感信息通过 .env 文件注入,不进 Git」。 后果是该测试「本地恒绿(文件在工作区)、CI 恒红(checkout 拿不到)」, 且从本地永远发现不了。现修正 .gitignore 把它纳入版本控制; 真正的密钥仍由 secrets/、certs/、backups/ 等规则挡住。 修复后,此前因 backend 失败而被跳过的 migration 与 e2e 两个 job 也会真正跑起来。
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
# Production Docker Compose
|
||||
# 生产环境配置,敏感信息通过 .env 文件注入,不进 Git
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: danyang-match-postgres
|
||||
environment:
|
||||
POSTGRES_DB: ${DB_NAME:-danyang_match}
|
||||
POSTGRES_USER: ${DB_USER:-danyang}
|
||||
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
|
||||
ports:
|
||||
- "127.0.0.1:5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./backups:/backups
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-danyang} -d ${DB_NAME:-danyang_match}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- danyang-net
|
||||
secrets:
|
||||
- db_password
|
||||
restart: unless-stopped
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: danyang-match-redis
|
||||
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:?请设置REDIS_PASSWORD}
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:?请设置REDIS_PASSWORD}", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- danyang-net
|
||||
restart: unless-stopped
|
||||
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
container_name: danyang-match-minio
|
||||
command: server /data --console-address ":9001"
|
||||
environment:
|
||||
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:?请设置MINIO_ACCESS_KEY}
|
||||
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:?请设置MINIO_SECRET_KEY}
|
||||
volumes:
|
||||
- minio_data:/data
|
||||
networks:
|
||||
- danyang-net
|
||||
restart: unless-stopped
|
||||
|
||||
backend:
|
||||
build:
|
||||
context: ../backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: danyang-match-backend
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker,production
|
||||
SPRING_CONFIG_IMPORT: configtree:/run/secrets/
|
||||
DB_HOST: postgres
|
||||
DB_PORT: 5432
|
||||
DB_NAME: ${DB_NAME:-danyang_match}
|
||||
DB_USER: ${DB_USER:-danyang}
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
REDIS_PASSWORD: ${REDIS_PASSWORD:?请设置REDIS_PASSWORD}
|
||||
MINIO_ENDPOINT: http://minio:9000
|
||||
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:?请设置MINIO_ACCESS_KEY}
|
||||
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:?请设置MINIO_SECRET_KEY}
|
||||
JWT_ACCESS_SECRET: ${JWT_ACCESS_SECRET:?请设置JWT_ACCESS_SECRET}
|
||||
JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET:?请设置JWT_REFRESH_SECRET}
|
||||
CHECKIN_TOKEN_SECRET: ${CHECKIN_TOKEN_SECRET:?请设置CHECKIN_TOKEN_SECRET}
|
||||
ENCRYPTION_KEY: ${ENCRYPTION_KEY:?请设置ENCRYPTION_KEY}
|
||||
WECHAT_APP_ID: ${WECHAT_APP_ID:?请设置WECHAT_APP_ID}
|
||||
WECHAT_APP_SECRET: ${WECHAT_APP_SECRET:?请设置WECHAT_APP_SECRET}
|
||||
VERIFICATION_PROVIDER: ${VERIFICATION_PROVIDER:?请设置VERIFICATION_PROVIDER}
|
||||
SPRING_SECURITY_FALLBACK_PASSWORD: ${SPRING_SECURITY_FALLBACK_PASSWORD:?请设置SPRING_SECURITY_FALLBACK_PASSWORD}
|
||||
FEATURES_APPEAL_ENABLED: ${FEATURES_APPEAL_ENABLED:-false}
|
||||
ports:
|
||||
- "127.0.0.1:8080:8080"
|
||||
networks:
|
||||
- danyang-net
|
||||
secrets:
|
||||
- source: db_password
|
||||
target: spring.datasource.password
|
||||
restart: unless-stopped
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
reservations:
|
||||
memory: 256M
|
||||
|
||||
admin-web:
|
||||
build:
|
||||
context: ../admin-web
|
||||
dockerfile: Dockerfile
|
||||
container_name: danyang-match-admin
|
||||
depends_on:
|
||||
- backend
|
||||
ports:
|
||||
# 管理端端口统一 13520(与 admin-web/vite.config.ts 的开发端口一致,
|
||||
# 由 ui-tests/ui-document-baseline-contracts.mjs 钉住三处一致)。
|
||||
# 仍绑定 127.0.0.1:对外访问走 nginx 的 80/443 + /admin/,此处仅供本机直连排查。
|
||||
- "127.0.0.1:13520:80"
|
||||
networks:
|
||||
- danyang-net
|
||||
restart: unless-stopped
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: danyang-match-nginx
|
||||
depends_on:
|
||||
- backend
|
||||
- admin-web
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./nginx-production.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./certs:/etc/nginx/certs:ro
|
||||
networks:
|
||||
- danyang-net
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
redis_data:
|
||||
minio_data:
|
||||
|
||||
networks:
|
||||
danyang-net:
|
||||
driver: bridge
|
||||
|
||||
secrets:
|
||||
db_password:
|
||||
file: ./secrets/db_password.txt
|
||||
Reference in New Issue
Block a user