ci: skip unaffected pull request checks (#2315)

* ci: skip unaffected pull request checks

* fix(ci): run the PR intent scan on every pull request

---------

Co-authored-by: Repository contributors <undisclosed>
This commit is contained in:
JATMN
2026-10-21 14:09:41 -07:00
committed by GitHub
co-authored by Repository contributors
parent 0b8daaeb04
commit 1f6f747309
2 changed files with 73 additions and 3 deletions
+70
View File
@@ -10,7 +10,34 @@ permissions:
contents: read
jobs:
changes:
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
pull-requests: read
outputs:
code: ${{ steps.filter.outputs.code }}
web: ${{ steps.filter.outputs.web }}
steps:
- uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: filter
if: ${{ github.event_name == 'pull_request' }}
with:
filters: |
code:
- '.github/**'
- '!{*.md,**/*.md,docs/**}'
web:
- 'web/**'
- 'package.json'
- 'bun.lock'
- '.bun-version'
- '.github/workflows/pr-checks.yml'
smoke-and-tests:
needs: changes
if: ${{ github.event_name == 'push' || needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 15
@@ -44,6 +71,37 @@ jobs:
- name: Smoke and static checks
run: bun run check:static
pr-intent-scan:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: "22"
- name: Set up Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version-file: .bun-version
- name: Cache Bun packages
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-bun-root-${{ hashFiles('bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-root-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Suspicious PR intent scan
env:
PR_SCAN_BASE: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || 'origin/main' }}
@@ -51,6 +109,8 @@ jobs:
run: bun run security:pr-scan -- --base "$PR_SCAN_BASE" --head "$PR_SCAN_HEAD"
unit-tests:
needs: changes
if: ${{ github.event_name == 'push' || needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
@@ -90,6 +150,8 @@ jobs:
run: bun run scripts/run-tests.ts --shards=8 --shard-index=${{ matrix.shard }} --feature=UNATTENDED_RETRY --max-concurrency=1
dedicated-tests:
needs: changes
if: ${{ github.event_name == 'push' || needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 15
@@ -125,6 +187,8 @@ jobs:
run: bun run test:context-efficiency
launcher-compatibility:
needs: changes
if: ${{ github.event_name == 'push' || needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 5
strategy:
@@ -167,6 +231,8 @@ jobs:
NODE_DISABLE_COMPILE_CACHE=1 node bin/openclaude --version
launcher-node-floor:
needs: changes
if: ${{ github.event_name == 'push' || needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 5
@@ -204,6 +270,8 @@ jobs:
run: node bin/openclaude --version
typecheck:
needs: changes
if: ${{ github.event_name == 'push' || needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 5
@@ -236,6 +304,8 @@ jobs:
run: bun run typecheck:type-tests
web:
needs: changes
if: ${{ github.event_name == 'push' || needs.changes.outputs.web == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 5
+3 -3
View File
@@ -244,7 +244,7 @@ bun run dev:profile
## Validation
CI runs a fixed set of checks on every PR (see `.github/workflows/pr-checks.yml`). This section is the **authoritative local pre-push validation contract** — `AGENTS.md` defers to it. **Run every locally applicable check before every push to an open PR, including follow-up pushes during review.** Do not wait for GitHub CI to discover failures you could have caught locally — wasted Actions minutes are a real cost on this repo.
PR Checks skips the static check, unit shard, dedicated test, launcher, and typecheck jobs when a PR changes only Markdown files or files under `docs/`, unless any change is under `.github/`. CI runs the PR intent scan on every PR, including documentation-only PRs. The web job is selected independently by website paths; every job runs on pushes to `main` (see `.github/workflows/pr-checks.yml`). This section is the **authoritative local pre-push validation contract** — `AGENTS.md` defers to it. **Run every locally applicable check before every push to an open PR, including follow-up pushes during review.** Do not wait for GitHub CI to discover failures you could have caught locally — wasted Actions minutes are a real cost on this repo.
The security scan requires the commit ancestry needed to find the PR's merge base. Check whether your clone is shallow:
@@ -309,8 +309,8 @@ Notes on the local preflight:
- `bun run check` runs `check:static` (the any-usage budget, smoke build, and deadcode checks), then the full unit pass (`test:full`) — do not run those separately, or you execute work twice.
- `bun run test` isolates each test file's globals and requires Bun's completed JUnit report as well as a successful exit. `test:full` runs all eight native Bun shards serially to release memory between groups. Use `bun run scripts/run-tests.ts --shards=N --shard-index=K` with the same test flags to run only shard K of N. `test:full` then applies the same completion check to the conversation-arc pass and the context-efficiency pass with `HISTORY_SNIP` enabled. Every shard must produce a complete report; a failed shard does not prevent the remaining shards from running. A test that terminates the runner early fails the command, even if it exits with code zero. Each shard has a ten-minute deadline (override with `--shard-timeout-ms=<milliseconds>`), reports its start/end and elapsed time, and kills its process group on timeout or cancellation. A timeout stops the remaining shards and exits nonzero. On Linux, shard output is relayed from temporary regular files to avoid Bun’s isolated-stdio pipe registration bug; diagnostics remain visible during execution. Temporary reports and logs are removed after the check. CI runs `check:static` in `smoke-and-tests`, runs the eight unit shards as parallel `unit-tests` jobs, and runs each dedicated feature pass once in `dedicated-tests`. Each unit shard builds the CLI before testing. CI caps these jobs at 15 minutes each and the other jobs at five minutes.
- Fetching upstream `main` by URL avoids assuming that a fork checkout's `origin` points at Twigpine/openclaude. `FETCH_HEAD` is the fetched upstream tip. The scan deliberately uses local `HEAD` so it includes commits that have not been pushed yet; CI uses the pushed PR head SHA after the push.
- The web CI job remains unconditional as an integration backstop. Contributors do not need to run the web suite locally for changes that cannot affect the site.
- This preflight covers the same command families as CI, but it does not reproduce CI exactly in one shell. CI runs static checks with Node 22 available for smoke checks, runs the unit shards and dedicated feature passes under Node 22, separately builds and checks launcher compatibility under Node 22 and 24.11.x, separately builds and launches under exact Node 22.0.0, and executes every job on a clean runner.
- The web CI job runs on PRs that change `web/**`, root `package.json` or `bun.lock`, `.bun-version`, or `.github/workflows/pr-checks.yml`, and on every push to `main`. Contributors do not need to run the web suite locally for changes that cannot affect the site.
- This preflight covers the same command families as CI, but it does not reproduce CI exactly in one shell. When selected, CI runs static checks with Node 22 available for smoke checks, runs the unit shards and dedicated feature passes under Node 22, separately builds and checks launcher compatibility under Node 22 and 24.11.x, separately builds and launches under exact Node 22.0.0, and executes every job on a clean runner.
If a local or GitHub CI check fails, first determine whether the PR owns the failure. Treat a failure as pre-existing only when you can reproduce it on the PR's current base (or link to the same failure on a current `main` CI run) and the PR neither changes the causal surface nor claims to fix that problem.