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
22 changes: 11 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ name: CI
on:
push:
branches: [master, feature/holographic-memory]
# Pull-request CI is deliberately on demand. `opened`/`synchronize` would
# create a queued workflow run even when every job's `if` skips it; 173
# concurrently opened PRs produced 80 such runs ahead of release publish.
# Add (or remove and re-add) `ci-full` to test the current head.
pull_request:
branches: ['**']
# `ready_for_review` and `labeled` are what lift a pull request from the
# light gates into full CI, so they must start a run.
types: [opened, synchronize, reopened, ready_for_review, labeled]
types: [labeled]

permissions:
contents: read
Expand Down Expand Up @@ -39,8 +41,7 @@ jobs:
#
# * `run-heavy`: the Linux build/test/lint lane. Pushes always; pull
# requests only when trusted (this repository, or a fork targeting an
# integration branch) and either ready for review or labelled `ci-full`.
# A draft runs no job at all (see the `if` below).
# integration branch) and explicitly dispatched with `ci-full`.
# * `run-os`: the macOS and Windows matrices. Pushes, or a pull request
# labelled `ci-os`. macOS has its own 5-slot cap and Windows shards take
# 7 jobs; both verify the same code the Linux lane already covers and
Expand All @@ -56,7 +57,7 @@ jobs:
# and even three light gates apiece queued the release behind ~400 jobs;
# a job that is skipped here costs no runner, and every guarded job reads
# this job's outputs, so skipping it skips them. `ci-full` opts a draft in.
if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'ci-full') }}
if: ${{ github.event_name != 'pull_request' || github.event.label.name == 'ci-full' }}
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
Expand All @@ -75,14 +76,13 @@ jobs:
env:
EVENT: ${{ github.event_name }}
TRUSTED: ${{ github.event.pull_request.head.repo.full_name == github.repository || contains(fromJSON('["master","feature/holographic-memory"]'), github.event.pull_request.base.ref) }}
DRAFT: ${{ github.event.pull_request.draft }}
LABELS: ${{ join(github.event.pull_request.labels.*.name, ' ') }}
run: |
has_label() { [[ " $LABELS " == *" $1 "* ]]; }
heavy=false; os=false; hosts=false; perf=false
if [[ $EVENT != pull_request ]]; then
heavy=true; os=true; hosts=true; perf=true
elif [[ $TRUSTED == true ]] && { [[ $DRAFT != true ]] || has_label ci-full; }; then
elif [[ $TRUSTED == true ]] && has_label ci-full; then
heavy=true
has_label ci-os && os=true
has_label ci-hosts && hosts=true
Expand All @@ -94,7 +94,7 @@ jobs:
echo "run-hosts=$hosts"
echo "run-perf=$perf"
} >>"$GITHUB_OUTPUT"
echo "run-heavy=$heavy run-os=$os run-hosts=$hosts run-perf=$perf (event=$EVENT draft=${DRAFT:-n/a} labels='$LABELS')"
echo "run-heavy=$heavy run-os=$os run-hosts=$hosts run-perf=$perf (event=$EVENT labels='$LABELS')"

# The Linux and macOS test matrices come from the same manifest the
# partition jobs select their targets from, so a partition cannot exist
Expand Down Expand Up @@ -242,7 +242,7 @@ jobs:

benchmark-harness:
name: Benchmark harness self-tests
if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'ci-full') }}
if: ${{ github.event_name != 'pull_request' || github.event.label.name == 'ci-full' }}
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
Expand All @@ -260,7 +260,7 @@ jobs:
# queue entries per push doing what one does.
gates:
name: Repository gates
if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'ci-full') }}
if: ${{ github.event_name != 'pull_request' || github.event.label.name == 'ci-full' }}
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/plugin-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:
- "crates/tracedecay/tests/agent_suite/*skill*"
- ".github/workflows/plugin-validation.yml"
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
types: [labeled]
paths:
- "plugin/**"
- "plugin/cursor-native-extension/**"
Expand All @@ -34,7 +34,7 @@ concurrency:

jobs:
manifest-schema:
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
if: github.event_name != 'pull_request' || github.event.label.name == 'ci-full'
name: Manifest schema
runs-on: ubuntu-latest
timeout-minutes: 5
Expand Down Expand Up @@ -75,7 +75,7 @@ jobs:
done

claude-native-validation:
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
if: github.event_name != 'pull_request' || github.event.label.name == 'ci-full'
name: Claude native plugin validation
runs-on: ubuntu-latest
timeout-minutes: 10
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/sdk-conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: SDK conformance

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
types: [labeled]
paths:
- ".github/workflows/**"
- ".github/release-targets.json"
Expand Down Expand Up @@ -55,7 +55,7 @@ concurrency:

jobs:
publish-workflow-policy:
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
if: github.event_name != 'pull_request' || github.event.label.name == 'ci-full'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -90,7 +90,7 @@ jobs:
.github/workflows/release-please.yml
.github/workflows/release-pr-integrity.yml
packages:
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
if: github.event_name != 'pull_request' || github.event.label.name == 'ci-full'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -111,7 +111,7 @@ jobs:
working-directory: sdks/typescript

production-router:
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
if: github.event_name != 'pull_request' || github.event.label.name == 'ci-full'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down
17 changes: 9 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,16 +257,17 @@ integration branch waits behind, so a run spends only what its state earns:

| State | Runs |
|---|---|
| Draft | Nothing. Mark it ready or add `ci-full` to run CI. |
| Ready for review (or labelled `ci-full`) | Repository gates (commit lint, release guards, rustfmt), benchmark-harness self-tests, and the Linux lane: build, clippy, feature gates, dashboard, Linux test partitions, PR dogfood with the MCP conformance smoke. |
| Labelled `ci-os` | Adds the macOS and Windows matrices. |
| Labelled `ci-hosts` | Adds the stock Hermes / Claude Code / OpenCode integrations. |
| Labelled `perf` | Adds hotpath parity and runs the hotpath profile, coverage, and runtime-core workflows. |
| Pull request without `ci-full` | Nothing. Opening, pushing, and marking ready do not create CI runs. |
| Add `ci-full` | Repository gates, benchmark-harness self-tests, and the Linux lane: build, clippy, feature gates, dashboard, Linux test partitions, PR dogfood with the MCP conformance smoke. |
| Also labelled `ci-os` | Adds the macOS and Windows matrices to that `ci-full` dispatch. |
| Also labelled `ci-hosts` | Adds the stock Hermes / Claude Code / OpenCode integrations. |
| Also labelled `perf` | Adds hotpath parity and runs the hotpath profile, coverage, and runtime-core workflows. |
| Push to `master` | Everything. |

Marking a PR ready or adding a label starts the run; a newer push cancels
the one in flight, on every branch including `master`. Closing or merging a
PR cancels its remaining runs and drops its Actions caches. Nothing runs on a
Add `ci-full` to run CI for the PR's current head. If the head changes, remove
and re-add `ci-full` to test the new commit; opening, pushing, and marking ready
create no run at all. A newer master push cancels the one in flight. Closing or
merging a PR cancels its remaining runs and drops its Actions caches. Nothing runs on a
timer: the packaged-crate distribution battery and the Hawk lint are
`workflow_dispatch` only.

Expand Down
Loading