Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/preflight.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,37 @@ permissions:
contents: read

jobs:
detect:
name: Detect Affected Jobs
runs-on: ubuntu-latest
outputs:
run_biome_format: ${{ steps.detect.outputs.run_biome_format }}
run_typescript_packages: ${{ steps.detect.outputs.run_typescript_packages }}
run_extension: ${{ steps.detect.outputs.run_extension }}
run_docs: ${{ steps.detect.outputs.run_docs }}
run_landing: ${{ steps.detect.outputs.run_landing }}
run_demo: ${{ steps.detect.outputs.run_demo }}
run_playground: ${{ steps.detect.outputs.run_playground }}
run_desktop_macos: ${{ steps.detect.outputs.run_desktop_macos }}
run_python_sdk: ${{ steps.detect.outputs.run_python_sdk }}
run_rust_sdk: ${{ steps.detect.outputs.run_rust_sdk }}
run_go_sdk: ${{ steps.detect.outputs.run_go_sdk }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Detect affected preflight jobs
id: detect
run: bun run scripts/preflight.ts --list --since "${{ github.event.pull_request.base.sha }}" --github-output "$GITHUB_OUTPUT"

biome-format:
name: Biome Format Check
needs: detect
if: needs.detect.outputs.run_biome_format == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -25,6 +54,8 @@ jobs:

typescript-packages:
name: TypeScript Packages
needs: detect
if: needs.detect.outputs.run_typescript_packages == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -43,6 +74,8 @@ jobs:

extension:
name: Chrome Extension
needs: detect
if: needs.detect.outputs.run_extension == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -63,6 +96,8 @@ jobs:

docs:
name: Docs
needs: detect
if: needs.detect.outputs.run_docs == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -89,6 +124,8 @@ jobs:

landing:
name: Landing Site
needs: detect
if: needs.detect.outputs.run_landing == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -111,6 +148,8 @@ jobs:

demo:
name: Demo Site
needs: detect
if: needs.detect.outputs.run_demo == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -130,6 +169,8 @@ jobs:

playground:
name: Playground
needs: detect
if: needs.detect.outputs.run_playground == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -149,6 +190,8 @@ jobs:

desktop-macos:
name: Desktop macOS Smoke Build
needs: detect
if: needs.detect.outputs.run_desktop_macos == 'true'
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -172,6 +215,8 @@ jobs:

python-sdk:
name: Python SDK
needs: detect
if: needs.detect.outputs.run_python_sdk == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -189,6 +234,8 @@ jobs:

rust-sdk:
name: Rust SDK
needs: detect
if: needs.detect.outputs.run_rust_sdk == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -202,6 +249,8 @@ jobs:

go-sdk:
name: Go SDK
needs: detect
if: needs.detect.outputs.run_go_sdk == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
97 changes: 97 additions & 0 deletions scripts/preflight.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { describe, expect, test } from "bun:test";

import { buildComponents, computeAffected, computeCiJobPlan } from "./preflight";

const components = buildComponents();

function getCiJobPlan(changedFiles: string[]) {
const { ordered, repoWide } = computeAffected(components, changedFiles, false);
return computeCiJobPlan(ordered, changedFiles, repoWide);
}

describe("preflight CI detection", () => {
test("root Bun dependency changes only trigger Bun-backed jobs", () => {
const plan = getCiJobPlan(["package.json"]);

expect(plan.run_biome_format).toBe(false);
expect(plan.run_typescript_packages).toBe(true);
expect(plan.run_extension).toBe(true);
expect(plan.run_docs).toBe(true);
expect(plan.run_landing).toBe(true);
expect(plan.run_demo).toBe(true);
expect(plan.run_playground).toBe(true);
expect(plan.run_desktop_macos).toBe(true);
expect(plan.run_python_sdk).toBe(false);
expect(plan.run_rust_sdk).toBe(false);
expect(plan.run_go_sdk).toBe(false);
});

test("Rust SDK changes propagate to desktop but not other language jobs", () => {
const plan = getCiJobPlan(["packages/rust/slop-ai/Cargo.toml"]);

expect(plan.run_biome_format).toBe(false);
expect(plan.run_typescript_packages).toBe(false);
expect(plan.run_extension).toBe(false);
expect(plan.run_docs).toBe(false);
expect(plan.run_landing).toBe(false);
expect(plan.run_demo).toBe(false);
expect(plan.run_playground).toBe(false);
expect(plan.run_desktop_macos).toBe(true);
expect(plan.run_python_sdk).toBe(false);
expect(plan.run_rust_sdk).toBe(true);
expect(plan.run_go_sdk).toBe(false);
});

test("Biome config changes only trigger the formatting job", () => {
const plan = getCiJobPlan(["biome.json"]);

expect(plan.run_biome_format).toBe(true);
expect(plan.run_typescript_packages).toBe(false);
expect(plan.run_extension).toBe(false);
expect(plan.run_docs).toBe(false);
expect(plan.run_landing).toBe(false);
expect(plan.run_demo).toBe(false);
expect(plan.run_playground).toBe(false);
expect(plan.run_desktop_macos).toBe(false);
expect(plan.run_python_sdk).toBe(false);
expect(plan.run_rust_sdk).toBe(false);
expect(plan.run_go_sdk).toBe(false);
});

test("root TypeScript build script changes trigger only jobs that use it", () => {
const plan = getCiJobPlan(["scripts/build-typescript-packages.ts"]);

expect(plan.run_biome_format).toBe(true);
expect(plan.run_typescript_packages).toBe(true);
expect(plan.run_extension).toBe(false);
expect(plan.run_docs).toBe(false);
expect(plan.run_landing).toBe(false);
expect(plan.run_demo).toBe(true);
expect(plan.run_playground).toBe(true);
expect(plan.run_desktop_macos).toBe(false);
expect(plan.run_python_sdk).toBe(false);
expect(plan.run_rust_sdk).toBe(false);
expect(plan.run_go_sdk).toBe(false);
});

test("TypeScript source changes trigger the Biome formatter job", () => {
const plan = getCiJobPlan(["packages/typescript/sdk/core/src/index.ts"]);

expect(plan.run_biome_format).toBe(true);
expect(plan.run_typescript_packages).toBe(true);
});

test("Biome excludes do not trigger the formatter job", () => {
const plan = getCiJobPlan(["examples/full-stack/tanstack-start/src/routeTree.gen.ts"]);

expect(plan.run_biome_format).toBe(false);
});

test("workflow changes force every preflight job to run", () => {
const plan = getCiJobPlan([".github/workflows/preflight.yml"]);

for (const shouldRun of Object.values(plan)) {
expect(shouldRun).toBe(true);
}
});
});
Loading
Loading