refactor(ci): collapse fast setup jobs into preflight

This commit is contained in:
Vincent Koc 2026-03-22 21:52:16 -07:00
parent 97e4f37171
commit 8a59b09fc8
1 changed files with 23 additions and 101 deletions

View File

@ -17,14 +17,24 @@ jobs:
# Preflight: establish the fast global truth for this revision before the
# expensive platform and test lanes fan out.
# 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:
# Run scope detection, changed-extension detection, and fast security checks in
# one visible job so operators have a single preflight box to inspect and rerun.
# Fail-safe: if detection steps are skipped, downstream outputs fall back to
# conservative defaults that keep heavy lanes enabled.
preflight:
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
runs-on: blacksmith-16vcpu-ubuntu-2404
timeout-minutes: 20
outputs:
docs_only: ${{ steps.check.outputs.docs_only }}
docs_changed: ${{ steps.check.outputs.docs_changed }}
docs_only: ${{ steps.docs_scope.outputs.docs_only }}
docs_changed: ${{ steps.docs_scope.outputs.docs_changed }}
run_node: ${{ steps.changed_scope.outputs.run_node || 'false' }}
run_macos: ${{ steps.changed_scope.outputs.run_macos || 'false' }}
run_android: ${{ steps.changed_scope.outputs.run_android || 'false' }}
run_skills_python: ${{ steps.changed_scope.outputs.run_skills_python || 'false' }}
run_windows: ${{ steps.changed_scope.outputs.run_windows || 'false' }}
has_changed_extensions: ${{ steps.changed_extensions.outputs.has_changed_extensions || 'false' }}
changed_extensions_matrix: ${{ steps.changed_extensions.outputs.changed_extensions_matrix || '{"include":[]}' }}
steps:
- name: Checkout
uses: actions/checkout@v6
@ -33,45 +43,21 @@ jobs:
fetch-tags: false
submodules: false
- name: Ensure docs-scope base commit
- name: Ensure preflight base commit
uses: ./.github/actions/ensure-base-commit
with:
base-sha: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }}
fetch-ref: ${{ github.event_name == 'push' && github.ref_name || github.event.pull_request.base.ref }}
- name: Detect docs-only changes
id: check
id: docs_scope
uses: ./.github/actions/detect-docs-changes
# Detect which heavy areas are touched so CI can skip unrelated expensive jobs.
# Fail-safe: if detection fails, downstream jobs run.
changed-scope:
needs: [docs-scope]
if: needs.docs-scope.outputs.docs_only != 'true'
runs-on: blacksmith-16vcpu-ubuntu-2404
timeout-minutes: 20
outputs:
run_node: ${{ steps.scope.outputs.run_node }}
run_macos: ${{ steps.scope.outputs.run_macos }}
run_android: ${{ steps.scope.outputs.run_android }}
run_skills_python: ${{ steps.scope.outputs.run_skills_python }}
run_windows: ${{ steps.scope.outputs.run_windows }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 1
fetch-tags: false
submodules: false
- name: Ensure changed-scope base commit
uses: ./.github/actions/ensure-base-commit
with:
base-sha: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }}
fetch-ref: ${{ github.event_name == 'push' && github.ref_name || github.event.pull_request.base.ref }}
# Detect which heavy areas are touched so CI can skip unrelated expensive jobs.
# Fail-safe: if skipped, downstream lanes run.
- name: Detect changed scopes
id: scope
id: changed_scope
if: steps.docs_scope.outputs.docs_only != 'true'
shell: bash
run: |
set -euo pipefail
@ -84,29 +70,8 @@ jobs:
node scripts/ci-changed-scope.mjs --base "$BASE" --head HEAD
changed-extensions:
needs: [docs-scope, changed-scope]
if: needs.docs-scope.outputs.docs_only != 'true' && needs.changed-scope.outputs.run_node == 'true'
runs-on: blacksmith-16vcpu-ubuntu-2404
timeout-minutes: 20
outputs:
has_changed_extensions: ${{ steps.changed.outputs.has_changed_extensions }}
changed_extensions_matrix: ${{ steps.changed.outputs.changed_extensions_matrix }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 1
fetch-tags: false
submodules: false
- name: Ensure changed-extensions base commit
uses: ./.github/actions/ensure-base-commit
with:
base-sha: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }}
fetch-ref: ${{ github.event_name == 'push' && github.ref_name || github.event.pull_request.base.ref }}
- name: Setup Node environment
if: steps.docs_scope.outputs.docs_only != 'true'
uses: ./.github/actions/setup-node-env
with:
install-bun: "false"
@ -114,7 +79,8 @@ jobs:
use-sticky-disk: "false"
- name: Detect changed extensions
id: changed
id: changed_extensions
if: steps.docs_scope.outputs.docs_only != 'true' && steps.changed_scope.outputs.run_node == 'true'
env:
BASE_SHA: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }}
BASE_REF: ${{ github.event_name == 'push' && github.ref_name || github.event.pull_request.base.ref }}
@ -135,29 +101,6 @@ jobs:
appendFileSync(process.env.GITHUB_OUTPUT, `changed_extensions_matrix=${matrix}\n`, "utf8");
EOF
secrets:
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
runs-on: blacksmith-16vcpu-ubuntu-2404
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v6
with:
submodules: false
- name: Ensure secrets base commit
uses: ./.github/actions/ensure-base-commit
with:
base-sha: ${{ github.event_name == 'push' && github.event.before || github.event.pull_request.base.sha }}
fetch-ref: ${{ github.event_name == 'push' && github.ref_name || github.event.pull_request.base.ref }}
- name: Setup Node environment
uses: ./.github/actions/setup-node-env
with:
install-bun: "false"
use-sticky-disk: "false"
install-deps: "false"
- name: Setup Python
id: setup-python
uses: actions/setup-python@v6
@ -213,27 +156,6 @@ jobs:
- name: Audit production dependencies
run: pre-commit run --all-files pnpm-audit-prod
# Preflight hub: collapse setup jobs into one explicit fanout node so the
# graph matches operator mental model instead of raw YAML ordering.
preflight:
needs: [docs-scope, changed-scope, changed-extensions, secrets]
if: always() && needs.docs-scope.result == 'success' && (needs.changed-scope.result == 'success' || needs.changed-scope.result == 'skipped') && (needs.changed-extensions.result == 'success' || needs.changed-extensions.result == 'skipped') && needs.secrets.result == 'success'
runs-on: blacksmith-16vcpu-ubuntu-2404
timeout-minutes: 20
outputs:
docs_only: ${{ needs.docs-scope.outputs.docs_only }}
docs_changed: ${{ needs.docs-scope.outputs.docs_changed }}
run_node: ${{ needs.changed-scope.outputs.run_node || 'false' }}
run_macos: ${{ needs.changed-scope.outputs.run_macos || 'false' }}
run_android: ${{ needs.changed-scope.outputs.run_android || 'false' }}
run_skills_python: ${{ needs.changed-scope.outputs.run_skills_python || 'false' }}
run_windows: ${{ needs.changed-scope.outputs.run_windows || 'false' }}
has_changed_extensions: ${{ needs.changed-extensions.outputs.has_changed_extensions || 'false' }}
changed_extensions_matrix: ${{ needs.changed-extensions.outputs.changed_extensions_matrix || '{"include":[]}' }}
steps:
- name: Preflight complete
run: echo "Preflight scope complete."
# Fanout: downstream lanes branch from preflight outputs instead of waiting
# on unrelated Linux checks.
# Build dist once for Node-relevant changes and share it with downstream jobs.