mirror of
https://github.com/nearai/ironclaw.git
synced 2026-09-02 23:56:24 +08:00
ci: speed up CI feedback loop (#2566)
* ci: speed up feedback loop — concurrency, dynamic matrix, path skip, faster staging - Add cancel-in-progress concurrency groups to 6 workflows (test, code_style, e2e, regression-test-check, pr-label-classify, pr-label-scope) so pushes to the same branch cancel stale CI runs instead of queuing behind them. - Collapse test/clippy matrix on PRs from 3 configs to 1 (all-features). Full 3-config matrix still runs on staging promotion and push-to-main. Cuts PR compilation from ~3x to ~1x. - Reduce staging-ci poll interval from 60 minutes to 10 minutes, cutting worst-case promotion latency by 6x. - Add path-based skip to test.yml and code_style.yml: a lightweight changes-detection job checks if any code files changed (src/, crates/, Cargo.*, etc.). Docs-only PRs skip all Rust compilation while the rollup job still passes for branch protection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: collapse nested ifs in trace_contains_tool_call match arms Clippy 1.95 added/tightened `clippy::collapsible_match`. The two nested `if`s in this helper are equivalent to additional match-arm guards, which is what the lint suggests. No behavior change. Inherited from #2268's merge into staging; would have failed `Clippy (all-features)` on every PR until fixed. * test: rustfmt struct destructure in collapsed match arm * ci: drop --benches from clippy invocations `--benches` pulls in `criterion` (heavy dep) but only covers 2 bench files in `crates/ironclaw_safety/`. Lints rarely differ in bench code, and `bench-compile` in test.yml already provides the type-check signal. Cold-cache impact: ~30s+ saved per Linux/Windows leg (criterion + plotters + ciborium chain). Warm-cache: marginal but non-zero. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: ilblackdragon@gmail.com <ilblackdragon@gmail.com>
This commit is contained in:
18
.github/actions/install-cargo-component/action.yml
vendored
Normal file
18
.github/actions/install-cargo-component/action.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: Install cargo-component
|
||||
description: Install cargo-component using a precompiled binary (taiki-e/install-action).
|
||||
|
||||
# Replaces ad-hoc `cargo install cargo-component --locked || true` calls. The
|
||||
# precompiled-binary path takes a few seconds vs. several minutes for a source
|
||||
# install, and we no longer swallow install failures.
|
||||
#
|
||||
# The version is pinned for build reproducibility — same rationale as
|
||||
# `--locked` for source installs. Bump alongside the cargo-component dependency
|
||||
# in dependabot's `cargo-component*` group (see .github/dependabot.yml).
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Install cargo-component
|
||||
uses: taiki-e/install-action@62b0f2dec647a8e604c6a0fda0e38530180dce20 # v2
|
||||
with:
|
||||
tool: cargo-component@0.21.1
|
||||
182
.github/workflows/code_style.yml
vendored
182
.github/workflows/code_style.yml
vendored
@@ -12,9 +12,70 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: code-style-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# ── Skip when only docs/config changed on a PR ──
|
||||
changes:
|
||||
name: Detect code changes
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
has_code: ${{ steps.non_pr.outputs.has_code || steps.pr_check.outputs.has_code }}
|
||||
steps:
|
||||
- id: non_pr
|
||||
if: github.event_name != 'pull_request'
|
||||
run: echo "has_code=true" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
if: github.event_name == 'pull_request'
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- id: pr_check
|
||||
if: github.event_name == 'pull_request'
|
||||
env:
|
||||
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
||||
run: |
|
||||
CODE_CHANGES=$(git diff --name-only "$BASE_SHA"...HEAD -- \
|
||||
'src/' 'crates/' 'channels-src/' 'tools-src/' 'tests/' 'migrations/' \
|
||||
'Cargo.toml' 'Cargo.lock' 'Dockerfile' 'build.rs' \
|
||||
| head -1)
|
||||
if [ -n "$CODE_CHANGES" ]; then
|
||||
echo "has_code=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "has_code=false" >> "$GITHUB_OUTPUT"
|
||||
echo "No code changes — style checks will be skipped"
|
||||
fi
|
||||
|
||||
# ── Dynamic matrix: SLIM (1 leg) for non-main PRs; FULL (3 legs) for PRs
|
||||
# to main and pushes to long-lived branches.
|
||||
clippy-matrix:
|
||||
name: Configure clippy matrix
|
||||
needs: changes
|
||||
if: needs.changes.outputs.has_code == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set.outputs.matrix }}
|
||||
steps:
|
||||
- id: set
|
||||
run: |
|
||||
FULL='[{"name":"all-features","flags":"--all-features"},{"name":"default","flags":""},{"name":"libsql-only","flags":"--no-default-features --features libsql"}]'
|
||||
SLIM='[{"name":"all-features","flags":"--all-features"}]'
|
||||
|
||||
# Full matrix on push (cache-warming + verification across configs)
|
||||
# and on PRs targeting main (final promotion gate). Other PRs use
|
||||
# SLIM since lint findings are almost never feature-gated.
|
||||
if [ "${{ github.event_name }}" = "push" ] || [ "${{ github.base_ref }}" = "main" ]; then
|
||||
echo "matrix=${FULL}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "matrix=${SLIM}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
format:
|
||||
name: Formatting
|
||||
needs: changes
|
||||
if: needs.changes.outputs.has_code == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -30,6 +91,8 @@ jobs:
|
||||
|
||||
gateway-js-syntax:
|
||||
name: Gateway JS syntax
|
||||
needs: changes
|
||||
if: needs.changes.outputs.has_code == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -45,6 +108,8 @@ jobs:
|
||||
|
||||
deny-check:
|
||||
name: cargo-deny
|
||||
needs: changes
|
||||
if: needs.changes.outputs.has_code == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -56,22 +121,13 @@ jobs:
|
||||
|
||||
clippy:
|
||||
name: Clippy (${{ matrix.name }})
|
||||
# Push events only run the all-features leg. That leg builds a superset
|
||||
# of artifacts, so it deterministically wins the shared cache slot on
|
||||
# main/staging refreshes and PR legs always restore from a useful
|
||||
# starting point. PRs still run all three to enforce lint coverage.
|
||||
if: github.event_name == 'pull_request' || matrix.name == 'all-features'
|
||||
needs: [changes, clippy-matrix]
|
||||
if: needs.changes.outputs.has_code == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: all-features
|
||||
flags: "--all-features"
|
||||
- name: default
|
||||
flags: ""
|
||||
- name: libsql-only
|
||||
flags: "--no-default-features --features libsql"
|
||||
include: ${{ fromJSON(needs.clippy-matrix.outputs.matrix) }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
@@ -83,29 +139,33 @@ jobs:
|
||||
components: clippy
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
# Share a single cache across the clippy matrix. `target/` built for
|
||||
# --all-features is a superset of the other two legs, so restoring
|
||||
# from whichever variant saved last is still faster than a cold build
|
||||
# and avoids storing three near-duplicate copies in the GHA cache.
|
||||
# Single shared slot across the clippy matrix. The all-features leg
|
||||
# builds a superset of the other configs; subset legs (push only)
|
||||
# restore from it. Only all-features writes the slot, and only on
|
||||
# main/staging pushes — preventing a subset leg from winning the
|
||||
# cache race and pinning the slot to a partial build.
|
||||
shared-key: clippy
|
||||
save-if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging') }}
|
||||
save-if: ${{ matrix.name == 'all-features' && github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging') }}
|
||||
# `--benches` is intentionally omitted: lints rarely diverge in bench code,
|
||||
# and pulling in `criterion` adds ~30s+ of dependency compilation per run.
|
||||
# `bench-compile` in test.yml provides the type-check signal for benches.
|
||||
- name: Check lints
|
||||
run: cargo clippy --all --benches --tests --examples ${{ matrix.flags }} -- -D warnings
|
||||
run: cargo clippy --all --tests --examples ${{ matrix.flags }} -- -D warnings
|
||||
|
||||
clippy-windows:
|
||||
name: Clippy Windows (${{ matrix.name }})
|
||||
if: github.base_ref == 'main'
|
||||
needs: [changes, clippy-matrix]
|
||||
# PR-to-main runs the full Windows matrix; pushes to long-lived branches
|
||||
# run it for cache warming. Other PRs skip Windows lint — windows-build
|
||||
# in test.yml provides the Windows compile signal.
|
||||
if: >
|
||||
needs.changes.outputs.has_code == 'true' &&
|
||||
(github.event_name == 'push' || github.base_ref == 'main')
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: all-features
|
||||
flags: "--all-features"
|
||||
- name: default
|
||||
flags: ""
|
||||
- name: libsql-only
|
||||
flags: "--no-default-features --features libsql"
|
||||
include: ${{ fromJSON(needs.clippy-matrix.outputs.matrix) }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
@@ -117,19 +177,21 @@ jobs:
|
||||
components: clippy
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
# Share the per-variant Windows target cache with test.yml's
|
||||
# windows-build job. That job runs on `push` to main (where save-if
|
||||
# allows writes), so clippy-windows — which only runs on main PRs —
|
||||
# can restore from a warm cache instead of cold-building every time.
|
||||
# Per-variant Windows cache, shared with test.yml's windows-build
|
||||
# job. windows-build runs on push (where save-if allows writes), so
|
||||
# clippy-windows restores from a warm cache on PRs.
|
||||
key: windows-${{ matrix.name }}
|
||||
save-if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging') }}
|
||||
# `--benches` omitted; see comment on the Linux clippy job above.
|
||||
- name: Check lints
|
||||
run: cargo clippy --all --benches --tests --examples ${{ matrix.flags }} -- -D warnings
|
||||
run: cargo clippy --all --tests --examples ${{ matrix.flags }} -- -D warnings
|
||||
|
||||
no-panics:
|
||||
name: No panics in production code
|
||||
# Compares the PR's changes against the PR base; not meaningful on push.
|
||||
if: github.event_name == 'pull_request'
|
||||
needs: changes
|
||||
# Diff is computed against the PR base SHA, which is unavailable on push.
|
||||
# Gate to PRs only; the roll-up tolerates a skipped result on push.
|
||||
if: github.event_name == 'pull_request' && needs.changes.outputs.has_code == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -150,20 +212,46 @@ jobs:
|
||||
name: Code Style (fmt + gateway-js-syntax + clippy + deny)
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
needs: [format, gateway-js-syntax, clippy, clippy-windows, deny-check, no-panics]
|
||||
needs:
|
||||
- changes
|
||||
- clippy-matrix
|
||||
- format
|
||||
- gateway-js-syntax
|
||||
- clippy
|
||||
- clippy-windows
|
||||
- deny-check
|
||||
- no-panics
|
||||
steps:
|
||||
- run: |
|
||||
if [[ "${{ needs.format.result }}" != "success" || "${{ needs.gateway-js-syntax.result }}" != "success" || "${{ needs.clippy.result }}" != "success" || "${{ needs.deny-check.result }}" != "success" ]]; then
|
||||
echo "One or more jobs failed"
|
||||
exit 1
|
||||
fi
|
||||
# no-panics only runs on pull_request events, so skipped is acceptable on push but failure is not
|
||||
if [[ "${{ needs.no-panics.result }}" != "success" && "${{ needs.no-panics.result }}" != "skipped" ]]; then
|
||||
echo "no-panics failed: ${{ needs.no-panics.result }}"
|
||||
exit 1
|
||||
fi
|
||||
# clippy-windows only runs on main PRs, so skipped is acceptable but failure is not
|
||||
if [[ "${{ needs.clippy-windows.result }}" != "success" && "${{ needs.clippy-windows.result }}" != "skipped" ]]; then
|
||||
echo "Windows clippy failed: ${{ needs.clippy-windows.result }}"
|
||||
exit 1
|
||||
# Docs-only PRs intentionally skip every gated job — that's a pass.
|
||||
if [[ "${{ needs.changes.outputs.has_code }}" == "false" ]]; then
|
||||
echo "No code changes — style checks skipped correctly"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Always-required jobs.
|
||||
for job_result in \
|
||||
"format=${{ needs.format.result }}" \
|
||||
"gateway-js-syntax=${{ needs.gateway-js-syntax.result }}" \
|
||||
"clippy=${{ needs.clippy.result }}" \
|
||||
"deny-check=${{ needs.deny-check.result }}"; do
|
||||
name="${job_result%%=*}"
|
||||
result="${job_result##*=}"
|
||||
if [[ "$result" != "success" ]]; then
|
||||
echo "$name failed: $result"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Conditional jobs: must succeed when run, may be skipped on
|
||||
# events where their `if:` filter excludes them.
|
||||
for job_result in \
|
||||
"no-panics=${{ needs.no-panics.result }}" \
|
||||
"clippy-windows=${{ needs.clippy-windows.result }}"; do
|
||||
name="${job_result%%=*}"
|
||||
result="${job_result##*=}"
|
||||
if [[ "$result" != "success" && "$result" != "skipped" ]]; then
|
||||
echo "$name failed: $result"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
10
.github/workflows/coverage.yml
vendored
10
.github/workflows/coverage.yml
vendored
@@ -86,10 +86,7 @@ jobs:
|
||||
uses: taiki-e/install-action@62b0f2dec647a8e604c6a0fda0e38530180dce20 # cargo-llvm-cov
|
||||
|
||||
- name: Install cargo-component
|
||||
run: |
|
||||
if ! command -v cargo-component >/dev/null 2>&1; then
|
||||
cargo install cargo-component --locked
|
||||
fi
|
||||
uses: ./.github/actions/install-cargo-component
|
||||
|
||||
- name: Build WASM channels (for integration tests)
|
||||
run: ./scripts/build-wasm-extensions.sh --channels
|
||||
@@ -150,10 +147,7 @@ jobs:
|
||||
uses: taiki-e/install-action@62b0f2dec647a8e604c6a0fda0e38530180dce20 # cargo-llvm-cov
|
||||
|
||||
- name: Install cargo-component
|
||||
run: |
|
||||
if ! command -v cargo-component >/dev/null 2>&1; then
|
||||
cargo install cargo-component --locked
|
||||
fi
|
||||
uses: ./.github/actions/install-cargo-component
|
||||
|
||||
- name: Build WASM channels
|
||||
run: ./scripts/build-wasm-extensions.sh --channels
|
||||
|
||||
4
.github/workflows/e2e.yml
vendored
4
.github/workflows/e2e.yml
vendored
@@ -19,6 +19,10 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: e2e-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# ── Step 1: compile once ──────────────────────────────────────────────────
|
||||
build:
|
||||
|
||||
4
.github/workflows/pr-label-classify.yml
vendored
4
.github/workflows/pr-label-classify.yml
vendored
@@ -9,6 +9,10 @@ permissions:
|
||||
pull-requests: write
|
||||
issues: read # needed for search/issues API (contributor count)
|
||||
|
||||
concurrency:
|
||||
group: pr-classify-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
classify:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
4
.github/workflows/pr-label-scope.yml
vendored
4
.github/workflows/pr-label-scope.yml
vendored
@@ -9,6 +9,10 @@ permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: pr-scope-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
scope:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
4
.github/workflows/regression-test-check.yml
vendored
4
.github/workflows/regression-test-check.yml
vendored
@@ -6,6 +6,10 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: regression-check-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
regression-test:
|
||||
name: Regression test enforcement
|
||||
|
||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -279,9 +279,9 @@ jobs:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
- name: Install Rust toolchain + wasm target
|
||||
run: |
|
||||
rustup target add wasm32-wasip2
|
||||
cargo install cargo-component --locked || true
|
||||
run: rustup target add wasm32-wasip2
|
||||
- name: Install cargo-component
|
||||
uses: ./.github/actions/install-cargo-component
|
||||
- uses: swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
key: wasm-extensions
|
||||
|
||||
2
.github/workflows/staging-ci.yml
vendored
2
.github/workflows/staging-ci.yml
vendored
@@ -2,7 +2,7 @@ name: Staging CI (Batched)
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 * * * *" # Every 60 minutes
|
||||
- cron: "*/10 * * * *" # Every 10 minutes (down from 60)
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
force:
|
||||
|
||||
94
.github/workflows/test.yml
vendored
94
.github/workflows/test.yml
vendored
@@ -16,24 +16,73 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: test-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# ── Skip expensive jobs when only docs/config changed on a PR ──
|
||||
changes:
|
||||
name: Detect code changes
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
has_code: ${{ steps.non_pr.outputs.has_code || steps.pr_check.outputs.has_code }}
|
||||
steps:
|
||||
- id: non_pr
|
||||
if: github.event_name != 'pull_request'
|
||||
run: echo "has_code=true" >> "$GITHUB_OUTPUT"
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
if: github.event_name == 'pull_request'
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- id: pr_check
|
||||
if: github.event_name == 'pull_request'
|
||||
env:
|
||||
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
||||
run: |
|
||||
CODE_CHANGES=$(git diff --name-only "$BASE_SHA"...HEAD -- \
|
||||
'src/' 'crates/' 'channels-src/' 'tools-src/' 'tests/' 'migrations/' \
|
||||
'Cargo.toml' 'Cargo.lock' 'Dockerfile' 'build.rs' \
|
||||
| head -1)
|
||||
if [ -n "$CODE_CHANGES" ]; then
|
||||
echo "has_code=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "has_code=false" >> "$GITHUB_OUTPUT"
|
||||
echo "No code changes detected — expensive jobs will be skipped"
|
||||
fi
|
||||
|
||||
# ── Dynamic matrix: PRs run only all-features; full matrix on staging/push ──
|
||||
matrix-config:
|
||||
name: Configure matrix
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
test_matrix: ${{ steps.set.outputs.test_matrix }}
|
||||
windows_matrix: ${{ steps.set.outputs.windows_matrix }}
|
||||
steps:
|
||||
- id: set
|
||||
run: |
|
||||
FULL='[{"name":"all-features","flags":"--no-default-features --features postgres,libsql,html-to-markdown,bedrock,import"},{"name":"default","flags":""},{"name":"libsql-only","flags":"--no-default-features --features libsql"}]'
|
||||
SLIM='[{"name":"all-features","flags":"--no-default-features --features postgres,libsql,html-to-markdown,bedrock,import"}]'
|
||||
|
||||
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
||||
echo "test_matrix=${SLIM}" >> "$GITHUB_OUTPUT"
|
||||
echo "windows_matrix=${SLIM}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "test_matrix=${FULL}" >> "$GITHUB_OUTPUT"
|
||||
echo "windows_matrix=${FULL}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
tests:
|
||||
name: Tests (${{ matrix.name }})
|
||||
needs: [changes, matrix-config]
|
||||
if: needs.changes.outputs.has_code == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: all-features
|
||||
# Keep product feature coverage broad without pulling in the
|
||||
# test-only `integration` feature, which is exercised separately
|
||||
# in the heavy integration job below.
|
||||
flags: "--no-default-features --features postgres,libsql,html-to-markdown,bedrock,import"
|
||||
- name: default
|
||||
flags: ""
|
||||
- name: libsql-only
|
||||
flags: "--no-default-features --features libsql"
|
||||
include: ${{ fromJSON(needs.matrix-config.outputs.test_matrix) }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
@@ -49,7 +98,7 @@ jobs:
|
||||
key: ${{ matrix.name }}
|
||||
save-if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging') }}
|
||||
- name: Install cargo-component
|
||||
run: cargo install cargo-component --locked || true
|
||||
uses: ./.github/actions/install-cargo-component
|
||||
- name: Build WASM channels (for integration tests)
|
||||
run: ./scripts/build-wasm-extensions.sh --channels
|
||||
- name: Run Tests
|
||||
@@ -59,6 +108,8 @@ jobs:
|
||||
|
||||
heavy-integration-tests:
|
||||
name: Heavy Integration Tests
|
||||
needs: changes
|
||||
if: needs.changes.outputs.has_code == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
@@ -111,6 +162,7 @@ jobs:
|
||||
|
||||
windows-build:
|
||||
name: Windows Build (${{ matrix.name }})
|
||||
needs: matrix-config
|
||||
if: >
|
||||
github.event_name != 'pull_request' ||
|
||||
github.base_ref != 'staging'
|
||||
@@ -118,13 +170,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: all-features
|
||||
flags: "--no-default-features --features postgres,libsql,html-to-markdown,bedrock,import"
|
||||
- name: default
|
||||
flags: ""
|
||||
- name: libsql-only
|
||||
flags: "--no-default-features --features libsql"
|
||||
include: ${{ fromJSON(needs.matrix-config.outputs.windows_matrix) }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
@@ -162,7 +208,7 @@ jobs:
|
||||
key: wasm-extensions
|
||||
save-if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging') }}
|
||||
- name: Install cargo-component
|
||||
run: cargo install cargo-component --locked || true
|
||||
uses: ./.github/actions/install-cargo-component
|
||||
- name: Build all WASM extensions against current WIT
|
||||
run: ./scripts/build-wasm-extensions.sh
|
||||
- name: Instantiation test (host linker compatibility)
|
||||
@@ -172,6 +218,8 @@ jobs:
|
||||
|
||||
bench-compile:
|
||||
name: Benchmark Compilation
|
||||
needs: changes
|
||||
if: needs.changes.outputs.has_code == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -224,9 +272,15 @@ jobs:
|
||||
name: Run Tests
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
needs: [tests, heavy-integration-tests, telegram-tests, wasm-wit-compat, docker-build, windows-build, version-check, bench-compile]
|
||||
needs: [changes, matrix-config, tests, heavy-integration-tests, telegram-tests, wasm-wit-compat, docker-build, windows-build, version-check, bench-compile]
|
||||
steps:
|
||||
- run: |
|
||||
# If no code changes on a PR, expensive jobs were correctly skipped
|
||||
if [[ "${{ needs.changes.outputs.has_code }}" == "false" ]]; then
|
||||
echo "No code changes — all tests skipped correctly"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Unit tests must always pass
|
||||
if [[ "${{ needs.tests.result }}" != "success" ]]; then
|
||||
echo "Unit tests failed"
|
||||
|
||||
@@ -39,6 +39,7 @@ I18n.register('ko', {
|
||||
'tab.chat': '채팅',
|
||||
'tab.memory': '기억',
|
||||
'tab.jobs': '작업',
|
||||
'tab.projects': '프로젝트',
|
||||
'tab.missions': '미션',
|
||||
'tab.routines': '루틴',
|
||||
'tab.settings': '설정',
|
||||
|
||||
@@ -39,6 +39,7 @@ I18n.register('zh-CN', {
|
||||
'tab.chat': '聊天',
|
||||
'tab.memory': '记忆',
|
||||
'tab.jobs': '任务',
|
||||
'tab.projects': '项目',
|
||||
'tab.missions': '使命',
|
||||
'tab.routines': '定时任务',
|
||||
'tab.settings': '设置',
|
||||
|
||||
@@ -194,21 +194,20 @@ impl LiveTestHarness {
|
||||
let needle_lc = needle.to_ascii_lowercase();
|
||||
for event in self.rig.captured_status_events() {
|
||||
match event {
|
||||
StatusUpdate::ToolStarted { name, detail, .. }
|
||||
if name.to_ascii_lowercase().contains(&tool_lc) =>
|
||||
StatusUpdate::ToolStarted {
|
||||
name,
|
||||
detail: Some(d),
|
||||
..
|
||||
} if name.to_ascii_lowercase().contains(&tool_lc)
|
||||
&& d.to_ascii_lowercase().contains(&needle_lc) =>
|
||||
{
|
||||
if let Some(d) = detail
|
||||
&& d.to_ascii_lowercase().contains(&needle_lc)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
StatusUpdate::ToolResult { name, preview, .. }
|
||||
if name.to_ascii_lowercase().contains(&tool_lc) =>
|
||||
if name.to_ascii_lowercase().contains(&tool_lc)
|
||||
&& preview.to_ascii_lowercase().contains(&needle_lc) =>
|
||||
{
|
||||
if preview.to_ascii_lowercase().contains(&needle_lc) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user