From f2dd7dc4749d64360c688828ce0e1fc36856247f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Mon, 5 Oct 2026 14:42:03 -0400 Subject: [PATCH] =?UTF-8?q?CI=20=C2=B7=20Showcase:=20move=20the=20site's?= =?UTF-8?q?=20pin=20to=20the=20catalog's=20main=20once=20its=20checks=20pa?= =?UTF-8?q?ss,=20build=20and=20deploy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/showcase.yml | 123 +++++++++++++++++++++++++++++++++ AGENTS.md | 1 + 2 files changed, 124 insertions(+) create mode 100644 .github/workflows/showcase.yml diff --git a/.github/workflows/showcase.yml b/.github/workflows/showcase.yml new file mode 100644 index 0000000..d1367be --- /dev/null +++ b/.github/workflows/showcase.yml @@ -0,0 +1,123 @@ +name: Showcase + +# Moves the site's showcase pin to the catalog's main once its checks pass, then deploys. +on: + schedule: + - cron: "*/30 * * * *" + workflow_dispatch: + inputs: + deploy: + description: Build and deploy even if the pin is current + type: boolean + default: false + +permissions: + contents: read + +concurrency: + group: showcase + cancel-in-progress: false + +env: + CATALOG: ZacharyZhang-NY/Ely-GPUI-Showcases + +jobs: + check: + runs-on: ubuntu-latest + outputs: + commit: ${{ steps.head.outputs.commit }} + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + - id: head + env: + GH_TOKEN: ${{ github.token }} + FORCE: ${{ inputs.deploy }} + run: | + head=$(gh api "repos/$CATALOG/commits/main" --jq .sha) + pinned=$(tr -d '[:space:]' < frontend/showcase.lock) + if [ "$head" = "$pinned" ]; then + echo "showcase: pinned at ${head:0:7}, the catalog's main" + [ "$FORCE" = "true" ] && echo "commit=$head" >> "$GITHUB_OUTPUT" + exit 0 + fi + runs=$(gh api "repos/$CATALOG/commits/$head/check-runs" --jq '.check_runs') + total=$(echo "$runs" | jq length) + waiting=$(echo "$runs" | jq '[.[] | select(.status != "completed")] | length') + failed=$(echo "$runs" | jq '[.[] | select(.status == "completed" and (.conclusion | IN("success", "skipped", "neutral") | not))] | length') + if [ "$total" -eq 0 ] || [ "$waiting" -gt 0 ]; then + echo "showcase: ${head:0:7}'s checks have not finished; next run looks again" + exit 0 + fi + if [ "$failed" -gt 0 ]; then + echo "::error::showcase: ${head:0:7} failed its catalog checks; the pin stays at ${pinned:0:7}" + exit 1 + fi + echo "showcase: ${pinned:0:7} -> ${head:0:7}" + echo "commit=$head" >> "$GITHUB_OUTPUT" + + deploy: + needs: check + if: needs.check.outputs.commit != '' + runs-on: ubuntu-latest + permissions: + contents: write + env: + COMMIT: ${{ needs.check.outputs.commit }} + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: "1.95" + targets: wasm32-unknown-unknown + - uses: Swatinem/rust-cache@v2 + with: + key: web + - name: wasm-bindgen at Cargo.lock's version + run: | + version=$(sed -n '/^name = "wasm-bindgen"$/{n;s/^version = "\(.*\)"$/\1/p;}' Cargo.lock) + echo "WASM_BINDGEN=wasm-bindgen@$version" >> "$GITHUB_ENV" + - uses: taiki-e/install-action@v2 + with: + tool: ${{ env.WASM_BINDGEN }} + - name: wasm-opt + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release download -R WebAssembly/binaryen -p 'binaryen-*-x86_64-linux.tar.gz' -D "$RUNNER_TEMP" + tar -xzf "$RUNNER_TEMP"/binaryen-*-x86_64-linux.tar.gz -C "$RUNNER_TEMP" + echo "$(ls -d "$RUNNER_TEMP"/binaryen-*/)bin" >> "$GITHUB_PATH" + - uses: pnpm/action-setup@v6 + with: + version: 11 + - uses: actions/setup-node@v7 + with: + node-version: 24 + cache: pnpm + cache-dependency-path: frontend/pnpm-lock.yaml + - run: echo "$COMMIT" > frontend/showcase.lock + - run: scripts/web.sh frontend/public/gallery + env: + ELY_GALLERY_ASSETS: https://elygpui.com/gallery/assets/ + - working-directory: frontend + run: | + pnpm install --frozen-lockfile + pnpm test + pnpm build + pnpm run deploy + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }} + - name: Commit the pin + run: | + git config user.name 'github-actions[bot]' + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + git add frontend/showcase.lock + git diff --cached --quiet && exit 0 + git commit -m "Site ยท Showcase: pin Ely-GPUI-Showcases at ${COMMIT:0:7}" + for attempt in 1 2 3; do + git pull --rebase origin main && git push origin HEAD:main && exit 0 + sleep 5 + done + exit 1 diff --git a/AGENTS.md b/AGENTS.md index 28ca1a1..c3b0aa9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -259,6 +259,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark. - 2026-09-29: the ported debug gallery draws its heaviest page about 1.6 times slower than on gpui 0.2.2 (tooling: 9 fps, worst frame 117 ms, against 14 fps and 72 ms), with gpui's accessibility tree on or off (`Application::new_inaccessible` measured the same). Ely's code did not change there; the frame cost is gpui's. - 2026-09-29: the web gallery runs on one thread, since a static site sends no cross-origin isolation, and draws through WebGL2 where WebGPU is missing. Its pictures are served beside the wasm, not embedded: the wasm stays under Cloudflare's 25 MiB, and a story fetches only its own. `wasm-opt -Oz` takes the wasm from 23.0 to 20.0 MB; gzip and brotli stay near 7.9 and 5.5 MB. - 2026-10-04: the Showcase follows gpui-kit.com/apps: apps live in their own public repo and arrive by pull request. The site pins a commit of it in `frontend/showcase.lock` and moves only when someone bumps the pin, so stars refresh on the site with each bump. READMEs take Markdown and PNG pictures alone, no HTML or video, so the site needs no sanitizer. The catalog started empty. +- 2026-10-05: the pin moves by itself: `.github/workflows/showcase.yml` looks at the catalog's main every 30 minutes and, once that commit's checks pass, builds the gallery and the site, deploys through `CLOUDFLARE_API_TOKEN` (secret) and `CLOUDFLARE_ACCOUNT_ID` (variable), then commits the pin; a run with `deploy` set redeploys at the current pin. A catalog commit that fails its checks keeps the pin. The catalog runs its checks on every pull request without approval, save from accounts new to GitHub; they get no secrets and a read-only token. - 2026-10-04: chapter 44, Rendering, holds `RenderSurface` alone. gpui at 1a28cff paints `RenderImage`s everywhere, `CVPixelBuffer`s (NV12) on macOS's Metal renderer alone, and shares no device or shader hook, so shader, camera and GPU views are the host's, feeding the surface, and zero-copy or Metal, OpenGL, Vulkan and Direct3D surfaces are blocked (`tasks/ch44.md`). CI tests the crate and builds the gallery on Linux, Windows and macOS, arm64 and x86_64. - 2026-10-05: an overlay its owner removes without calling `Close` still hands focus back: `take_focus` records each holder and what it took focus from, `give_back` forgets it, and when the focused element leaves the tree the root scope walks back past every gone holder to the focus before them all, else takes it; nested overlays removed together return to what the outer one took focus from. Before, a dialog whose action set its owner's state to closed left focus on the root, and keys reached nothing until a click. - 2026-10-05: `Select::label` and `TextInput::label` name the control for assistive technology without drawing anything; a text input with neither label nor placeholder had no name, and a select read only its value, so a field named by a description list beside it was anonymous in the AX tree.