CI: skip heavy jobs on docs-only changes (#11328)

main
max 2026-02-07 14:43:47 -08:00 committed by GitHub
parent 9201e140cb
commit 8da20027c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 162 additions and 7 deletions

View File

@ -0,0 +1,41 @@
name: Detect docs-only changes
description: >
Outputs docs_only=true when all changed files are under docs/ or are
markdown (.md/.mdx). Fail-safe: if detection fails, outputs false (run
everything). Uses git diff — no API calls, no extra permissions needed.
outputs:
docs_only:
description: "'true' if all changes are docs/markdown, 'false' otherwise"
value: ${{ steps.check.outputs.docs_only }}
runs:
using: composite
steps:
- name: Detect docs-only changes
id: check
shell: bash
run: |
if [ "${{ github.event_name }}" = "push" ]; then
BASE="${{ github.event.before }}"
else
# Use the exact base SHA from the event payload — stable regardless
# of base branch movement (avoids origin/<ref> drift).
BASE="${{ github.event.pull_request.base.sha }}"
fi
# Fail-safe: if we can't diff, assume non-docs (run everything)
CHANGED=$(git diff --name-only "$BASE" HEAD 2>/dev/null || echo "UNKNOWN")
if [ "$CHANGED" = "UNKNOWN" ] || [ -z "$CHANGED" ]; then
echo "docs_only=false" >> "$GITHUB_OUTPUT"
exit 0
fi
# Check if all changed files are docs or markdown
NON_DOCS=$(echo "$CHANGED" | grep -vE '^docs/|\.md$|\.mdx$' || true)
if [ -z "$NON_DOCS" ]; then
echo "docs_only=true" >> "$GITHUB_OUTPUT"
echo "Docs-only change detected — skipping heavy jobs"
else
echo "docs_only=false" >> "$GITHUB_OUTPUT"
fi

View File

@ -10,7 +10,26 @@ concurrency:
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
# Detect docs-only changes to skip heavy jobs (test, build, Windows, macOS, Android).
# Lint and format always run. Fail-safe: if detection fails, run everything.
docs-scope:
runs-on: ubuntu-latest
outputs:
docs_only: ${{ steps.check.outputs.docs_only }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false
- name: Detect docs-only changes
id: check
uses: ./.github/actions/detect-docs-only
install-check: install-check:
needs: [docs-scope]
if: needs.docs-scope.outputs.docs_only != 'true'
runs-on: blacksmith-4vcpu-ubuntu-2404 runs-on: blacksmith-4vcpu-ubuntu-2404
steps: steps:
- name: Checkout - name: Checkout
@ -71,6 +90,8 @@ jobs:
pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true
checks: checks:
needs: [docs-scope]
if: needs.docs-scope.outputs.docs_only != 'true'
runs-on: blacksmith-4vcpu-ubuntu-2404 runs-on: blacksmith-4vcpu-ubuntu-2404
strategy: strategy:
fail-fast: false fail-fast: false
@ -79,18 +100,12 @@ jobs:
- runtime: node - runtime: node
task: tsgo task: tsgo
command: pnpm tsgo command: pnpm tsgo
- runtime: node
task: lint
command: pnpm build && pnpm lint
- runtime: node - runtime: node
task: test task: test
command: pnpm canvas:a2ui:bundle && pnpm test command: pnpm canvas:a2ui:bundle && pnpm test
- runtime: node - runtime: node
task: protocol task: protocol
command: pnpm protocol:check command: pnpm protocol:check
- runtime: node
task: format
command: pnpm format
- runtime: bun - runtime: bun
task: test task: test
command: pnpm canvas:a2ui:bundle && bunx vitest run command: pnpm canvas:a2ui:bundle && bunx vitest run
@ -161,6 +176,84 @@ jobs:
- name: Run ${{ matrix.task }} (${{ matrix.runtime }}) - name: Run ${{ matrix.task }} (${{ matrix.runtime }})
run: ${{ matrix.command }} run: ${{ matrix.command }}
# Lint and format always run, even on docs-only changes.
checks-lint:
runs-on: blacksmith-4vcpu-ubuntu-2404
strategy:
fail-fast: false
matrix:
include:
- task: lint
command: pnpm build && pnpm lint
- task: format
command: pnpm format
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: false
- name: Checkout submodules (retry)
run: |
set -euo pipefail
git submodule sync --recursive
for attempt in 1 2 3 4 5; do
if git -c protocol.version=2 submodule update --init --force --depth=1 --recursive; then
exit 0
fi
echo "Submodule update failed (attempt $attempt/5). Retrying…"
sleep $((attempt * 10))
done
exit 1
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22.x
check-latest: true
- name: Setup pnpm (corepack retry)
run: |
set -euo pipefail
corepack enable
for attempt in 1 2 3; do
if corepack prepare pnpm@10.23.0 --activate; then
pnpm -v
exit 0
fi
echo "corepack prepare failed (attempt $attempt/3). Retrying..."
sleep $((attempt * 10))
done
exit 1
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Runtime versions
run: |
node -v
npm -v
bun -v
pnpm -v
- name: Capture node path
run: echo "NODE_BIN=$(dirname \"$(node -p \"process.execPath\")\")" >> "$GITHUB_ENV"
- name: Install dependencies
env:
CI: true
run: |
export PATH="$NODE_BIN:$PATH"
which node
node -v
pnpm -v
pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true || pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true
- name: Run ${{ matrix.task }}
run: ${{ matrix.command }}
secrets: secrets:
runs-on: blacksmith-4vcpu-ubuntu-2404 runs-on: blacksmith-4vcpu-ubuntu-2404
steps: steps:
@ -187,6 +280,8 @@ jobs:
fi fi
checks-windows: checks-windows:
needs: [docs-scope]
if: needs.docs-scope.outputs.docs_only != 'true'
runs-on: blacksmith-4vcpu-windows-2025 runs-on: blacksmith-4vcpu-windows-2025
env: env:
NODE_OPTIONS: --max-old-space-size=4096 NODE_OPTIONS: --max-old-space-size=4096
@ -300,7 +395,8 @@ jobs:
# running 4 separate jobs per PR (as before) starved the queue. One job # running 4 separate jobs per PR (as before) starved the queue. One job
# per PR allows 5 PRs to run macOS checks simultaneously. # per PR allows 5 PRs to run macOS checks simultaneously.
macos: macos:
if: github.event_name == 'pull_request' needs: [docs-scope]
if: github.event_name == 'pull_request' && needs.docs-scope.outputs.docs_only != 'true'
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- name: Checkout - name: Checkout
@ -585,6 +681,8 @@ jobs:
PY PY
android: android:
needs: [docs-scope]
if: needs.docs-scope.outputs.docs_only != 'true'
runs-on: blacksmith-4vcpu-ubuntu-2404 runs-on: blacksmith-4vcpu-ubuntu-2404
strategy: strategy:
fail-fast: false fail-fast: false

View File

@ -11,7 +11,23 @@ concurrency:
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
docs-scope:
runs-on: ubuntu-latest
outputs:
docs_only: ${{ steps.check.outputs.docs_only }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect docs-only changes
id: check
uses: ./.github/actions/detect-docs-only
install-smoke: install-smoke:
needs: [docs-scope]
if: needs.docs-scope.outputs.docs_only != 'true'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout CLI - name: Checkout CLI