name: Unified application CI and deployment on: pull_request: branches: [main] paths: - 'apps/waterfall-wiki/**' - 'packages/brand/**' - 'scripts/**' - 'Dockerfile' - '.dockerignore' - 'compose.yml' - 'pnpm-workspace.yaml' - '.gitea/workflows/app.yml' push: branches: ["**"] paths: - 'apps/waterfall-wiki/**' - 'packages/brand/**' - 'scripts/**' - 'Dockerfile' - '.dockerignore' - 'compose.yml' - 'pnpm-workspace.yaml' - '.gitea/workflows/app.yml' concurrency: group: unified-app-${{ gitea.event.pull_request.number || gitea.ref }} cancel-in-progress: false jobs: static-checks: runs-on: ces-control timeout-minutes: 10 steps: - uses: actions/checkout@v4 with: fetch-depth: 2 - name: Check patch, syntax and source contracts without building run: | git diff --check HEAD^ HEAD for script in scripts/*.sh scripts/preview/*.sh; do bash -n "$script"; done node scripts/check-studio-contracts.mjs node --check scripts/preview/fingerprint.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 }}" . docker build --target runtime -t "waterfall-wiki:${{ gitea.sha }}" . - name: Verify candidate using persistent test infrastructure env: WATERFALL_WIKI_IMAGE: waterfall-wiki:${{ gitea.sha }} WATERFALL_WIKI_TEST_IMAGE: waterfall-wiki-tests:${{ gitea.sha }} GITEA_RUN_ID: ${{ gitea.run_id }} run: bash scripts/integration.sh - name: Deploy unified Web and worker; verify production if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' run: bash scripts/deploy.sh "${{ gitea.sha }}" - name: Save production acceptance evidence id: evidence if: always() && gitea.event_name == 'push' uses: actions/upload-artifact@v3 with: name: unified-production-acceptance path: artifacts/studio-acceptance/ if-no-files-found: ignore retention-days: 7 - name: Remove uploaded local evidence if: always() && steps.evidence.outcome == 'success' run: rm -rf artifacts/studio-acceptance