name: Detect affected areas description: >- Classify a PR's changed files into CI work lanes (python, frontend, site, scan, deps, mcp_catalog) so the orchestrator can conditionally call only the sub-workflows a PR can affect. Outputs are always "true" on push/dispatch events and fail open (everything "true") when the diff cannot be computed. outputs: python: description: Run Python tests / ruff / ty / windows-footguns. value: ${{ steps.classify.outputs.python }} frontend: description: Run the TypeScript typecheck matrix + desktop build. value: ${{ steps.classify.outputs.frontend }} docker_meta: description: Docker setup and meta files have changed. value: ${{ steps.classify.outputs.docker_meta }} site: description: Build the Docusaurus docs site. value: ${{ steps.classify.outputs.site }} scan: description: Run the supply-chain critical-pattern scanner. value: ${{ steps.classify.outputs.scan }} deps: description: Check pyproject.toml dependency upper bounds. value: ${{ steps.classify.outputs.deps }} mcp_catalog: description: Require MCP catalog security review label. value: ${{ steps.classify.outputs.mcp_catalog }} runs: using: composite steps: - name: Classify changed files id: classify shell: bash env: GH_TOKEN: ${{ github.token }} REPO: ${{ github.repository }} EVENT_NAME: ${{ github.event_name }} BASE_SHA: ${{ github.event.pull_request.base.sha }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: | set -euo pipefail # Only pull_request events are gated. Other events (push, release, # dispatch) leave CHANGED empty, so the classifier fails open and every # lane runs. Post-merge / on-demand validation is never weakened. if [ "$EVENT_NAME" = "pull_request" ]; then # Use the compare endpoint with the pinned base/head SHAs from the # event payload instead of the "current PR files" endpoint. The SHAs # are frozen at trigger time, so the file list is deterministic even # if the PR receives a new push between trigger and detect. CHANGED="$(gh api \ --paginate \ "repos/${REPO}/compare/${BASE_SHA}...${HEAD_SHA}" \ --jq '.files[].filename' || true)" fi echo "Changed files:" printf '%s\n' "${CHANGED:-(none)}" printf '%s\n' "${CHANGED:-}" | python3 scripts/ci/classify_changes.py