web-easy-smoke #188
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: web-easy-smoke | |
| on: | |
| push: | |
| paths: | |
| - "lib/web-easy/**" | |
| - ".github/workflows/web-easy-smoke.yml" | |
| pull_request: | |
| paths: | |
| - "lib/web-easy/**" | |
| - ".github/workflows/web-easy-smoke.yml" | |
| schedule: | |
| - cron: "0 2 * * *" | |
| workflow_dispatch: | |
| jobs: | |
| smoke: | |
| runs-on: ubuntu-latest | |
| env: | |
| WASM_TOOLS_VERSION: "1.225.0" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Racket | |
| uses: Bogdanp/setup-racket@v1.11 | |
| with: | |
| architecture: x64 | |
| distribution: full | |
| version: stable | |
| - name: Cache Racket user packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.local/share/racket | |
| ~/.cache/racket | |
| key: ${{ runner.os }}-racket-user-${{ hashFiles('.github/workflows/web-easy-smoke.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-racket-user- | |
| - name: Ensure raco static-web | |
| run: | | |
| raco pkg install --auto --skip-installed --no-docs raco-static-web | |
| raco static-web --help >/dev/null | |
| - name: Ensure nanopass | |
| run: raco pkg install --auto --skip-installed --no-docs nanopass | |
| - name: Cache wasm-tools binary | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.local/bin/wasm-tools | |
| key: ${{ runner.os }}-wasm-tools-${{ env.WASM_TOOLS_VERSION }} | |
| - name: Add local bin to PATH | |
| run: echo "$HOME/.local/bin" >> "$GITHUB_PATH" | |
| - name: Install wasm-tools (prebuilt) | |
| run: | | |
| if [ ! -x "$HOME/.local/bin/wasm-tools" ]; then | |
| mkdir -p "$HOME/.local/bin" | |
| curl -L -o /tmp/wasm-tools.tar.gz \ | |
| "https://github.com/bytecodealliance/wasm-tools/releases/download/v${WASM_TOOLS_VERSION}/wasm-tools-${WASM_TOOLS_VERSION}-x86_64-linux.tar.gz" | |
| tar -xzf /tmp/wasm-tools.tar.gz -C /tmp | |
| cp "/tmp/wasm-tools-${WASM_TOOLS_VERSION}-x86_64-linux/wasm-tools" "$HOME/.local/bin/wasm-tools" | |
| chmod +x "$HOME/.local/bin/wasm-tools" | |
| fi | |
| wasm-tools --version | |
| - name: Setup Node (for webracket -r) | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 25.2.1 | |
| - name: Cache Playwright package | |
| uses: actions/cache@v4 | |
| with: | |
| path: .local-tools/node_modules | |
| key: ${{ runner.os }}-playwright-node-modules-${{ hashFiles('.github/workflows/web-easy-smoke.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-playwright-node-modules- | |
| - name: Cache Playwright browsers | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-playwright-browsers-${{ hashFiles('.github/workflows/web-easy-smoke.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-playwright-browsers- | |
| - name: Ensure Playwright Chromium | |
| run: | | |
| npm --prefix .local-tools install --save-dev playwright | |
| npx --prefix .local-tools playwright install --with-deps chromium | |
| - name: Link local webracket collection | |
| run: raco link "$GITHUB_WORKSPACE" | |
| - name: Headless verify preflight | |
| run: | | |
| cd lib/web-easy/smoke | |
| SMOKE_LOCAL_TOOLS_DIR="$GITHUB_WORKSPACE/.local-tools" ./headless.sh verify | |
| - name: Run web-easy smoke checks | |
| run: | | |
| cd lib/web-easy/smoke | |
| echo "[1/3] core tests (real Racket)" | |
| racket ../test/test-web-easy.rkt | |
| echo "[2/5] keyword negative tests" | |
| (cd ../test && ./test-define-key-negative.sh) | |
| echo "[3/5] core tests (webracket -r)" | |
| WEBRACKET_OUT="$(cd ../test && racket ../../../webracket.rkt -r test-web-easy-run.rkt)" | |
| if [ -n "$WEBRACKET_OUT" ] && [ "$WEBRACKET_OUT" != "#<void>" ]; then | |
| printf '%s\n' "$WEBRACKET_OUT" | |
| fi | |
| echo "web-easy webracket tests passed" | |
| echo "[4/5] smoke compile" | |
| ./check-smoke.sh | |
| if [ "${{ github.event_name }}" = "schedule" ]; then | |
| echo "[5/5] nightly deep headless CI (contract + theme + smoke + guard)" | |
| SMOKE_TIMEOUT_MS=600000 SMOKE_WARN_MS=2000 SMOKE_SKIP_COMPILE=1 ./headless.sh ci | |
| echo "nightly deep CI gate passed" | |
| else | |
| echo "[5/5] PR/push lean headless CI (smoke + key contracts; optional visual gate: make smoke-solar-sections-gate)" | |
| SMOKE_TIMEOUT_MS=300000 SMOKE_WARN_MS=2000 SMOKE_SKIP_COMPILE=1 ./headless.sh ci-fast | |
| echo "lean CI gate passed" | |
| fi | |
| - name: Publish headless timing summary | |
| if: always() | |
| run: | | |
| files=( | |
| /tmp/web-easy-contract-timings.tsv | |
| /tmp/web-easy-smoke-timings.tsv | |
| /tmp/web-easy-parity-timings.tsv | |
| /tmp/web-easy-theme-timings.tsv | |
| ) | |
| { | |
| echo "web-easy headless timing summary" | |
| for f in "${files[@]}"; do | |
| if [ -f "$f" ]; then | |
| echo | |
| echo "$(basename "$f"):" | |
| awk -F $'\t' 'NR > 1 { print $2 "\t" $1 }' "$f" | sort -nr | head -n 10 | awk -F $'\t' '{ printf(" %s ms %s\n", $1, $2) }' | |
| else | |
| echo | |
| echo "$(basename "$f"): (missing)" | |
| fi | |
| done | |
| } > /tmp/web-easy-headless-timing-summary.txt | |
| { | |
| echo "### web-easy headless timing summary" | |
| for f in "${files[@]}"; do | |
| if [ -f "$f" ]; then | |
| echo | |
| echo "#### $(basename "$f")" | |
| echo | |
| echo "| duration_ms | page |" | |
| echo "| ---: | --- |" | |
| awk -F $'\t' 'NR > 1 { print $2 "\t" $1 }' "$f" | sort -nr | head -n 10 | awk -F $'\t' '{ printf("| %s | %s |\n", $1, $2) }' | |
| fi | |
| done | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Prepare smoke failure context | |
| if: failure() | |
| run: | | |
| { | |
| echo "web-easy smoke failure context" | |
| echo "sha=${GITHUB_SHA}" | |
| echo "ref=${GITHUB_REF}" | |
| echo "run_id=${GITHUB_RUN_ID}" | |
| echo "run_attempt=${GITHUB_RUN_ATTEMPT}" | |
| echo "time_utc=$(date -u +%Y-%m-%dT%H:%M:%SZ)" | |
| echo | |
| echo "tail: /tmp/web-easy-smoke-headless.log" | |
| if [ -f /tmp/web-easy-smoke-headless.log ]; then | |
| tail -n 80 /tmp/web-easy-smoke-headless.log | |
| else | |
| echo "(missing)" | |
| fi | |
| echo | |
| echo "tail: /tmp/web-easy-dashboard-guard.log" | |
| if [ -f /tmp/web-easy-dashboard-guard.log ]; then | |
| tail -n 80 /tmp/web-easy-dashboard-guard.log | |
| else | |
| echo "(missing)" | |
| fi | |
| } > /tmp/web-easy-smoke-failure-context.txt | |
| - name: Upload smoke failure logs | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: web-easy-smoke-failure-logs | |
| if-no-files-found: warn | |
| path: | | |
| /tmp/web-easy-smoke-headless.log | |
| /tmp/web-easy-dashboard-guard.log | |
| /tmp/web-easy-smoke-failure-context.txt | |
| lib/web-easy/smoke/COMMANDS.tsv | |
| - name: Upload headless timing artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: web-easy-headless-timings | |
| if-no-files-found: warn | |
| path: | | |
| /tmp/web-easy-contract-timings.tsv | |
| /tmp/web-easy-smoke-timings.tsv | |
| /tmp/web-easy-parity-timings.tsv | |
| /tmp/web-easy-theme-timings.tsv | |
| /tmp/web-easy-style-timings.tsv | |
| /tmp/web-easy-all-timings.tsv | |
| /tmp/web-easy-headless-timing-summary.txt |