Skip to content

fix(dropdown): align overflow and shortcut behavior with the public c… #1815

fix(dropdown): align overflow and shortcut behavior with the public c…

fix(dropdown): align overflow and shortcut behavior with the public c… #1815

Workflow file for this run

name: ci
on:
pull_request:
push:
permissions:
contents: read
# Cancel previous runs on the same branch/PR — the single biggest win for
# unblocking queued PRs when authors force-push or push fixups.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
dependency-review:
if: github.event_name == 'pull_request'
name: dependency review
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
steps:
- name: Detect dependency review support
id: support
env:
GITHUB_TOKEN: ${{ github.token }}
REPOSITORY: ${{ github.repository }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
response_path="$(mktemp)"
headers_path="$(mktemp)"
status_code="$(
curl -sS \
-D "${headers_path}" \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-o "${response_path}" \
-w "%{http_code}" \
"https://api.github.com/repos/${REPOSITORY}/dependency-graph/compare/${BASE_SHA}...${HEAD_SHA}"
)"
message="$(jq -r '.message // ""' "${response_path}" 2>/dev/null || true)"
rate_limit_remaining="$(awk 'tolower($1)=="x-ratelimit-remaining:" { print $2 }' "${headers_path}" | tr -d '\r')"
retry_after="$(awk 'tolower($1)=="retry-after:" { print $2 }' "${headers_path}" | tr -d '\r')"
skip_dependency_review() {
local reason="$1"
echo "supported=false" >> "${GITHUB_OUTPUT}"
echo "::warning::Dependency review skipped because ${reason}. Enable Dependency graph / Advanced Security for this repository and event context to enforce this gate."
{
echo "### Dependency review skipped"
echo
echo "${reason}."
echo
echo "- HTTP status: ${status_code}"
echo "- API message: ${message:-unknown}"
if [[ -n "${rate_limit_remaining}" ]]; then
echo "- X-RateLimit-Remaining: ${rate_limit_remaining}"
fi
if [[ -n "${retry_after}" ]]; then
echo "- Retry-After: ${retry_after}"
fi
echo "- Action: enable Dependency graph / Advanced Security for this repository and event context to enforce this gate"
} >> "${GITHUB_STEP_SUMMARY}"
}
case "${status_code}" in
200)
echo "supported=true" >> "${GITHUB_OUTPUT}"
;;
404)
skip_dependency_review "GitHub dependency review support is unavailable for this repository or event context"
;;
403)
if [[ "${rate_limit_remaining:-}" == "0" || -n "${retry_after}" ]]; then
echo "Dependency review preflight hit GitHub API rate limiting" >&2
echo "X-RateLimit-Remaining: ${rate_limit_remaining:-unknown}" >&2
echo "Retry-After: ${retry_after:-none}" >&2
cat "${response_path}" >&2
exit 1
fi
if echo "${message}" | grep -qiE '(^forbidden$|dependency graph|advanced security|repository is a fork|disabled|not enabled|unavailable)'; then
skip_dependency_review "GitHub dependency review returned HTTP 403 without rate-limit signals for this repository or event context"
else
echo "Dependency review preflight failed with HTTP 403: ${message:-unknown}" >&2
cat "${response_path}" >&2
exit 1
fi
;;
*)
echo "Dependency review preflight failed with HTTP ${status_code}" >&2
cat "${response_path}" >&2
exit 1
;;
esac
- uses: actions/checkout@v4
if: steps.support.outputs.supported == 'true'
with:
submodules: false
- name: Review dependency changes
if: steps.support.outputs.supported == 'true'
uses: actions/dependency-review-action@v4
# Fast gate: run the repo's blocking static analysis and quality policy once
# on Linux/Node 22 before the slower matrix and smoke jobs fan out.
quality-gates:
name: quality gates
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: false
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- name: Install repo utilities
run: |
if ! command -v rg >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y ripgrep
fi
- name: Install
run: npm ci
- name: Drawlist codegen guardrail
run: npm run codegen:check
- name: Lint
run: npm run lint
- name: Typecheck
run: npm run typecheck
- name: Build
run: npm run build
- name: Full TS project graph
run: npm run typecheck:ci
- name: Strict publishable source TS pass
run: npm run typecheck:strict
- name: Check core portability
run: npm run check:core-portability
- name: Check native vendor integrity
run: npm run check:native-vendor
- name: Check Unicode pins (submodule sync)
run: npm run check:unicode
- name: Repo guardrails
run: npm run quality:guardrails
- name: Dependency graph guardrail
run: npm run quality:deps
- name: API surface guardrail
run: npm run quality:api
- name: Dead code advisory
id: quality_deadcode
continue-on-error: true
run: npm run quality:deadcode
- name: Dead code advisory summary
if: ${{ steps.quality_deadcode.outcome != 'success' }}
run: echo "::warning::Knip remains advisory in this PR. Review the dead-code report separately from the blocking quality gates."
template-smoke:
name: create-rezi smoke
needs: [quality-gates]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: false
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- name: Install
run: npm ci
- name: Build
run: npm run build
- name: Smoke scaffolded templates
run: npm run smoke:create-rezi-templates
# Compute matrix: 5 runners on PRs (all Node versions on Linux + latest on
# macOS/Windows), full 3×3 on push to main.
matrix-config:
name: configure matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set.outputs.matrix }}
steps:
- id: set
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo 'matrix={"include":[{"os":"ubuntu-latest","node-version":"18"},{"os":"ubuntu-latest","node-version":"20"},{"os":"ubuntu-latest","node-version":"22"},{"os":"macos-latest","node-version":"22"},{"os":"windows-latest","node-version":"22"}]}' >> "$GITHUB_OUTPUT"
else
echo 'matrix={"os":["ubuntu-latest","macos-latest","windows-latest"],"node-version":["18","20","22"]}' >> "$GITHUB_OUTPUT"
fi
ci:
needs: [quality-gates, template-smoke, matrix-config]
name: node ${{ matrix.node-version }} / ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.matrix-config.outputs.matrix) }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: false
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
- name: Install
run: npm ci
- name: Build
run: npm run build
- name: Tests
run: npm run test
- name: Repro replay fixtures (headless, explicit gate)
if: runner.os == 'Linux'
run: |
CONCURRENCY=$(node -p "parseInt(process.versions.node)>=19?'--test-concurrency=1':''")
node --test $CONCURRENCY packages/core/dist/repro/__tests__/replay.harness.test.js
- name: Setup Rust (stable)
uses: dtolnay/rust-toolchain@stable
- name: Build native addon
run: npm run build:native
- name: Terminal e2e (Linux full)
if: runner.os == 'Linux'
run: npm run test:e2e
- name: Terminal e2e (Linux reduced)
if: runner.os == 'Linux'
run: npm run test:e2e:reduced
- name: Terminal e2e equivalent (non-Linux reduced)
if: runner.os != 'Linux'
run: npm run test:e2e:reduced
- name: Native smoke + worker integration (Unix PTY)
if: runner.os != 'Windows'
run: |
python3 - <<'PY'
import os
import pty
import sys
status = pty.spawn(["bash", "-lc", "npm run test:native:smoke"])
if os.WIFEXITED(status):
sys.exit(os.WEXITSTATUS(status))
if os.WIFSIGNALED(status):
sys.exit(128 + os.WTERMSIG(status))
sys.exit(1)
PY
- name: Native smoke + worker integration (Windows)
if: runner.os == 'Windows'
run: npm run test:native:smoke
bun:
needs: [quality-gates]
name: bun / ubuntu-latest
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: false
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.9"
- name: Install
run: bun install
- name: Build
run: bun run build
- name: Tests
run: bun run test
- name: Terminal e2e (reduced)
run: bun run test:e2e:reduced
perf-regression:
name: perf regression gate
if: github.event_name == 'pull_request'
needs: [quality-gates]
runs-on: ubuntu-latest
steps:
- name: Checkout (with submodules)
uses: actions/checkout@v4
with:
submodules: false
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
- name: Install
run: npm ci
- name: Build packages
run: npm run build
- name: Build benchmark package
run: npx tsc -p packages/bench/tsconfig.json
- id: perf_bench
name: Run reduced benchmark suite (non-blocking)
continue-on-error: true
run: npm run bench:ci -- --output-dir .artifacts/bench/ci
- id: perf_compare
name: Compare reduced benchmark results against baseline (non-blocking)
if: ${{ always() }}
continue-on-error: true
run: |
npm run bench:ci:compare -- \
--baseline benchmarks/ci-baseline/results.json \
--current .artifacts/bench/ci/results.json \
--config benchmarks/ci-baseline/config.json \
--report-json .artifacts/bench/ci/compare.json \
--report-md .artifacts/bench/ci/compare.md
- name: Perf regression summary (non-blocking)
if: ${{ always() }}
run: |
echo "bench outcome: ${{ steps.perf_bench.outcome }}"
echo "compare outcome: ${{ steps.perf_compare.outcome }}"
if [ "${{ steps.perf_bench.outcome }}" != "success" ] || [ "${{ steps.perf_compare.outcome }}" != "success" ]; then
echo "::warning::Perf regression gate is non-blocking for CI stability. Review perf-regression artifacts."
fi
- name: Upload perf regression artifacts
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: perf-regression-artifacts
if-no-files-found: warn
path: |
.artifacts/bench/ci/results.json
.artifacts/bench/ci/results.md
.artifacts/bench/ci/compare.json
.artifacts/bench/ci/compare.md
.artifacts/bench/ci/manifest.json
.artifacts/bench/ci/profile.json