diff --git a/.gitea/workflows/app.yml b/.gitea/workflows/app.yml index 0d3ee7a..372701f 100644 --- a/.gitea/workflows/app.yml +++ b/.gitea/workflows/app.yml @@ -12,7 +12,7 @@ on: - 'pnpm-workspace.yaml' - '.gitea/workflows/app.yml' push: - branches: [main] + branches: ["**"] paths: - 'apps/waterfall-wiki/**' - 'packages/brand/**' @@ -26,20 +26,31 @@ concurrency: group: unified-app-${{ gitea.event.pull_request.number || gitea.ref }} cancel-in-progress: false jobs: - verify-and-release: + static-checks: runs-on: ces-control - timeout-minutes: 60 + timeout-minutes: 10 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Check scripts and content contracts + - name: Check patch, syntax and source contracts without building run: | git diff --check HEAD^ HEAD for script in scripts/*.sh; do bash -n "$script"; done node scripts/check-studio-contracts.mjs node --check scripts/verify-studio-visual.cjs node --check apps/waterfall-wiki/scripts/infinite-canvas-smoke.cjs + node --check apps/waterfall-wiki/scripts/cleanup-ci-bucket.mjs + python3 -c 'import ast,pathlib; ast.parse(pathlib.Path("scripts/wiki-image-lifecycle.py").read_text())' + verify-and-release: + needs: static-checks + if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' + runs-on: ces-control + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Build and verify the unified application once run: | docker build --target integration -t "waterfall-wiki-tests:${{ gitea.sha }}" . diff --git a/.gitea/workflows/python.yml b/.gitea/workflows/python.yml index 64c0cba..9982229 100644 --- a/.gitea/workflows/python.yml +++ b/.gitea/workflows/python.yml @@ -8,7 +8,7 @@ on: - 'scripts/deploy-python.sh' - '.gitea/workflows/python.yml' push: - branches: [main] + branches: ["**"] paths: - '.dockerignore' - 'apps/python/**' @@ -16,7 +16,21 @@ on: - '.gitea/workflows/python.yml' jobs: + static-checks: + runs-on: ces-control + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Check Python and deployment syntax without executing tests + run: | + git diff --check HEAD^ HEAD + bash -n scripts/deploy-python.sh + python3 -c 'import ast,pathlib; [ast.parse(p.read_text(),filename=str(p)) for p in pathlib.Path("apps/python").rglob("*.py")]' verify-and-deploy: + needs: static-checks + if: gitea.ref == 'refs/heads/main' && gitea.event_name == 'push' runs-on: ces-control timeout-minutes: 45 steps: diff --git a/README.md b/README.md index 721a33e..20720e9 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ for script in scripts/*.sh; do bash -n "$script"; done ## 部署与持久化 -Web 应用由 `.gitea/workflows/app.yml` 统一验证与发布。Wiki 和 Studio 已合并成一个 Next.js 应用,一次编译、一个 Web 运行镜像,Web 与后台 worker 使用同一镜像。PostgreSQL/S3 基础服务长期运行,不在日常发布中重建。PR 验证候选版本但不部署;只有 main push 才更新生产。完整步骤见 [统一部署流程](docs/unified-deployment.md)。 +Web 应用由 `.gitea/workflows/app.yml` 统一验证与发布。Wiki 和 Studio 已合并成一个 Next.js 应用,一次编译、一个 Web 运行镜像,Web 与后台 worker 使用同一镜像。PostgreSQL/S3 基础服务长期运行,不在日常发布中重建。工作分支 push/PR 仅做轻量静态检查;只有 main push 才构建、运行测试并更新生产。完整步骤见 [统一部署流程](docs/unified-deployment.md)。 | 服务 | 入口/端口 | | --- | --- | diff --git a/docs/docker-build-cache.md b/docs/docker-build-cache.md index 87b583c..b238571 100644 --- a/docs/docker-build-cache.md +++ b/docs/docker-build-cache.md @@ -16,7 +16,7 @@ ## 验证与限制 -构建、打包与产物验证只在已确认的 `ces-control` runner 执行。Python PR 运行镜像构建和单测,但只有 main push 才会发布 latest 标签。Web PR 沿用现有远程 Docker 验证流程,不再单独构建品牌检查镜像。 +构建、打包与产物验证只在已确认的 `ces-control` runner 执行。Web 与 Python 的工作分支 push/PR 仅运行轻量静态检查;类型检查、单元测试、编译、镜像构建和部署都只在 main push 执行。不再单独构建品牌检查镜像。 本次没有升级 Docker builder,也没有承诺消除 legacy builder 的镜像层提交耗时;缓存层调整后的实际收益需比较后续 CI 日志。源码变化仍需构建,当前采用持久测试基础设施;本次应用合并仍保留完整集成验证,按影响范围选择测试留作后续优化。 diff --git a/docs/unified-deployment.md b/docs/unified-deployment.md index cc6e306..6eb6841 100644 --- a/docs/unified-deployment.md +++ b/docs/unified-deployment.md @@ -18,7 +18,7 @@ Wiki 与 Studio 合并为 `apps/waterfall-wiki` 内一个 Next.js Pages Router 8. 检查健康、账户、已有内容和完整线上验收。验收处于部署脚本回滚边界内;失败尝试恢复数据库备份和上一版应用。 9. 验收通过后更新 current 和成功记录,停止有明确 Compose 所属标签的旧 Studio 容器(保留旧镜像)。上传验收证据;上传成功后删除 runner 临时报告。镜像盘点清理不在发布关键路径执行。 -PR 运行同一候选构建与测试,但部署步骤只允许 main push。首次应用合并保留完整远程验证;尚未按改动选择浏览器用例,不能宣称已消除全部重复测试。发布不自动取消进行中的任务,以免中断数据库迁移;过期版本由部署脚本检查跳过。 +工作分支 push 和面向 main 的 PR 只执行 static-checks,不安装依赖、不编译、不构建镜像、不启动测试环境、不运行单测或浏览器检查。只有 main push 通过静态检查后才执行完整构建、测试与部署;Python 使用相同边界。代价是类型、编译和集成错误到合并后才发现,但失败会阻止后续部署。旧配置已经创建的运行不会因本次 YAML 修改自动变成静态检查。发布不自动取消进行中的任务,以免中断数据库迁移;过期版本由部署脚本检查跳过。 ## 基础设施初始化与维护 diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 5a3b900..cd246a7 100644 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -17,7 +17,7 @@ test "$(git -c safe.directory="$PWD" rev-parse HEAD)" = "$RELEASE_SHA" LATEST_MAIN=$(git -c safe.directory="$PWD" ls-remote origin refs/heads/main | cut -f1) if [ "$LATEST_MAIN" != "$RELEASE_SHA" ]; then git -c safe.directory="$PWD" fetch origin main - if ! git -c safe.directory="$PWD" diff --quiet "$RELEASE_SHA" origin/main -- apps/waterfall-wiki Dockerfile compose.yml scripts/deploy.sh scripts/wiki-image-lifecycle.py scripts/infra.sh scripts/integration.sh scripts/auth-admin.sh .gitea/workflows/app.yml pnpm-workspace.yaml packages/brand; then + if ! git -c safe.directory="$PWD" diff --quiet "$RELEASE_SHA" origin/main -- apps/waterfall-wiki packages/brand Dockerfile .dockerignore compose.yml package.json pnpm-workspace.yaml scripts .gitea/workflows/app.yml; then echo 'Skipping deployment: Wiki has a newer commit'; exit 0 fi fi