Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ea7d782
ci(oceanbase): bound startup and balance migration workers
Zxf-xufeng Nov 6, 2026
a9fc9f1
fix(ci): preserve test results when diagnostics cannot be written
Zxf-xufeng Nov 6, 2026
d8492f5
test(observability): await matching worker failure statistics
Zxf-xufeng Nov 6, 2026
1017332
ci: scope OceanBase acceptance independently from harness replay
Zxf-xufeng Nov 6, 2026
08a3494
fix(ci): reconcile OceanBase budgets and preserve diagnostics
Zxf-xufeng Nov 7, 2026
342cf9a
fix(ci): reconcile scoped acceptance with OceanBase diagnostics
Zxf-xufeng Nov 7, 2026
996c730
fix(ci): cache license tooling and reduce checkout transfers
Zxf-xufeng Nov 7, 2026
105e7a9
fix(ci): make cached license checker independent of libc
Zxf-xufeng Nov 7, 2026
4e2762f
fix(ci): reserve E2E cleanup time and run serial cases once
Zxf-xufeng Nov 8, 2026
ac059e8
test(ci): inspect child worker state under parallel pytest
Zxf-xufeng Nov 8, 2026
ed6f026
fix(ci): bound migration shards and pin mise setup
Zxf-xufeng Nov 8, 2026
5caea8f
fix(ci): pin verified mise binary checksums
Zxf-xufeng Nov 8, 2026
b512749
fix(ci): fall back to verified mise release API downloads
Zxf-xufeng Nov 8, 2026
ee12e46
fix(ci): share verified bootstrap with desktop Linux
Zxf-xufeng Nov 8, 2026
4a670a2
fix(ci): separate cold image pulls and stabilize setup checks
Zxf-xufeng Nov 8, 2026
bac1a28
test(ci): preserve background lifecycle progress on timeout
Zxf-xufeng Nov 8, 2026
28d5afa
fix(ci): restore executable harness entrypoint
Zxf-xufeng Nov 8, 2026
b1c0f03
merge: reconcile latest master with scoped CI execution
Zxf-xufeng Nov 8, 2026
38d4296
fix(ci): budget full server initialization before lifecycle checks
Zxf-xufeng Nov 8, 2026
be601d5
test(memory): preserve sequence locators in retry expectations
Zxf-xufeng Nov 8, 2026
acce1dd
fix(ci): reserve unit-test setup and cache cleanup time
Zxf-xufeng Nov 8, 2026
62967a3
fix(ci): reuse search schemas and preserve native cleanup budgets
Zxf-xufeng Nov 9, 2026
78c1184
test(ci): align integration fixtures with current contracts
Zxf-xufeng Nov 9, 2026
af4ada3
fix(harness): reuse Python during agent bootstrap
Zxf-xufeng Nov 9, 2026
e2a2979
Merge remote-tracking branch 'origin/master' into codex/scope-oceanba…
Zxf-xufeng Nov 9, 2026
7490630
test(oceanbase): support synchronous capability probes in scoring fix…
Zxf-xufeng Nov 9, 2026
18a9b29
Merge remote-tracking branch 'origin/master' into codex/scope-oceanba…
Zxf-xufeng Nov 9, 2026
3cb815f
fix(ci): recover pinned release downloads through GitHub API
Zxf-xufeng Nov 9, 2026
370473d
fix(ci): share verified release downloads across tool bootstraps
Zxf-xufeng Nov 9, 2026
b95e6a5
fix(ci): authorize pinned asset fallback for desktop candidates
Zxf-xufeng Nov 9, 2026
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
73 changes: 73 additions & 0 deletions .github/actions/setup-license-eye/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Setup license-eye
description: Cache the pinned native license checker and compile only on a cache miss

outputs:
executable:
description: Absolute path to the license checker
value: ${{ runner.temp }}/license-eye/bin/license-eye

runs:
using: composite
steps:
- name: Restore the compiled checker
id: cache
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ${{ runner.temp }}/license-eye/bin
key: license-eye-static-v1-${{ runner.os }}-${{ runner.arch }}-a196742f472feaffafea537ce5a2a4c3c53a8de4-go1.25.14

- name: Fetch the pinned checker source
id: source
if: steps.cache.outputs.cache-hit != 'true'
shell: bash
env:
LICENSE_EYE_REVISION: a196742f472feaffafea537ce5a2a4c3c53a8de4
run: |
source_dir="$RUNNER_TEMP/license-eye/source"
mkdir -p "$source_dir"
git -C "$source_dir" init
timeout --signal=TERM --kill-after=10s 180s \
git -C "$source_dir" fetch --depth=1 --no-tags \
https://github.com/apache/skywalking-eyes.git "$LICENSE_EYE_REVISION"
git -C "$source_dir" checkout --detach FETCH_HEAD
test "$(git -C "$source_dir" rev-parse HEAD)" = "$LICENSE_EYE_REVISION"
test -f "$source_dir/go.sum"

- name: Prepare Go only for a cold tool cache
id: go
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
with:
go-version: '1.25.14'
cache-dependency-path: ${{ runner.temp }}/license-eye/source/go.sum

- name: Compile the native checker
id: build
if: steps.cache.outputs.cache-hit != 'true'
shell: bash
working-directory: ${{ runner.temp }}/license-eye/source
env:
GOTOOLCHAIN: local
GO111MODULE: 'on'
# Share the tool across Linux runner images without a host libc dependency.
CGO_ENABLED: '0'
run: |
mkdir -p "$RUNNER_TEMP/license-eye/bin"
go build -o "$RUNNER_TEMP/license-eye/bin/license-eye" \
-ldflags '-X github.com/apache/skywalking-eyes/commands.version=0.9.0' \
cmd/license-eye/main.go

- name: Verify the installed checker
id: verify
shell: bash
run: |
test -x "$RUNNER_TEMP/license-eye/bin/license-eye"
"$RUNNER_TEMP/license-eye/bin/license-eye" --help > /dev/null

# Save before source validation so a license violation does not discard the tool.
- name: Save the compiled checker
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ${{ runner.temp }}/license-eye/bin
key: ${{ steps.cache.outputs.cache-primary-key }}
51 changes: 51 additions & 0 deletions .github/actions/setup-project-tools/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Setup project tools
description: Install pinned mise tools with a verified Linux Release API fallback

inputs:
working-directory:
description: Directory containing the mise tool configuration
default: .

runs:
using: composite
steps:
- name: Install project tools
id: primary
continue-on-error: ${{ runner.os == 'Linux' && runner.arch == 'X64' }}
uses: jdx/mise-action@8418fedb1110381a0d3ba51a7a415d7c1b884550 # v5.2.2
with:
version: "2026.11.3"
working_directory: ${{ inputs.working-directory }}
sha256: >-
${{ runner.os == 'Windows' && '4f796228c826ad6225d608e2029278b31677c8919508574498877543ed3431d8' || 'c2f7e814cb39f60b7f67a0ff36cb805e94128bf2dff09d175309d0f095b8cc3b' }}

- name: Bootstrap verified mise through the Release API
id: fallback
if: steps.primary.outcome == 'failure' && runner.os == 'Linux' && runner.arch == 'X64'
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
archive="$(mktemp)"
binary="$(mktemp)"
trap 'rm -f "$archive" "$binary"' EXIT
# These archive and binary hashes were verified against the release's signed SHASUMS256.txt.
# The API asset is the same v2026.11.3 Linux x64 tarball as the primary download.
timeout --kill-after=10s 180s gh api -H 'Accept: application/octet-stream' \
repos/jdx/mise/releases/assets/716895278 > "$archive"
printf '837acae6defb8c9ad74823f6e38856633bacb04c65c1ac67d952749847543bd9 %s\n' "$archive" | sha256sum --check
tar -xOzf "$archive" mise/bin/mise > "$binary"
printf 'c2f7e814cb39f60b7f67a0ff36cb805e94128bf2dff09d175309d0f095b8cc3b %s\n' "$binary" | sha256sum --check
mise_directory="${MISE_DATA_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/mise}"
mkdir -p "$mise_directory/bin"
install -m 755 "$binary" "$mise_directory/bin/mise"
printf '2026.11.3' > "$mise_directory/bin/mise-version"

- name: Install project tools with the verified bootstrap
if: steps.primary.outcome == 'failure' && steps.fallback.outcome == 'success'
uses: jdx/mise-action@8418fedb1110381a0d3ba51a7a415d7c1b884550 # v5.2.2
with:
version: "2026.11.3"
working_directory: ${{ inputs.working-directory }}
sha256: c2f7e814cb39f60b7f67a0ff36cb805e94128bf2dff09d175309d0f095b8cc3b
113 changes: 47 additions & 66 deletions .github/actions/setup-upgrade-oceanbase/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,80 +3,61 @@ description: Start the disposable MySQL tenant used by installed-release upgrade
runs:
using: composite
steps:
- name: Pull the OceanBase image
shell: bash
env:
OCEANBASE_IMAGE: ghcr.io/oceanbase/oceanbase-ce:4.3.5.6-106000012026040916
run: |
if ! timeout --kill-after=5s 15s docker image inspect "$OCEANBASE_IMAGE" >/dev/null 2>&1; then
timeout --kill-after=10s 600s docker pull "$OCEANBASE_IMAGE"
fi
- name: Start and verify OceanBase
shell: bash
env:
OCEANBASE_IMAGE: ghcr.io/oceanbase/oceanbase-ce:4.3.5.6-106000012026040916
run: |
docker run --detach --name upgrade-oceanbase \
mkdir -p "$RUNNER_TEMP/oceanbase-startup"
timeout --kill-after=10s 180s docker run --pull never --detach --name upgrade-oceanbase \
--publish 127.0.0.1:2881:2881 \
--ulimit nofile=65536:65536 \
--env MODE=slim \
--env OB_DATABASE=pc_upgrade_test \
--env OB_TENANT_PASSWORD=powercontext-e2e \
"$OCEANBASE_IMAGE"
for attempt in $(seq 1 120); do
if docker exec upgrade-oceanbase \
obclient -h127.0.0.1 -P2881 -uroot@test -ppowercontext-e2e \
-Dpc_upgrade_test -e 'SELECT 1' >/dev/null 2>&1; then
# The slim image's default 1 GB maximum is too small for the
# indexes created across the clean migration acceptance cases.
docker exec upgrade-oceanbase \
obclient -h127.0.0.1 -P2881 -uroot@sys \
-e "ALTER SYSTEM SET datafile_maxsize='8G'; ALTER SYSTEM SET datafile_next='512M'; ALTER SYSTEM SET datafile_size='4G';"
datafile_ready=false
for config_attempt in $(seq 1 30); do
docker exec upgrade-oceanbase \
obclient -h127.0.0.1 -P2881 -uroot@sys --batch --skip-column-names \
-e "SHOW PARAMETERS WHERE name IN ('datafile_size', 'datafile_maxsize', 'datafile_next');" \
> "$RUNNER_TEMP/upgrade-datafile.tsv"
if awk '
$5 == "datafile_size" && $7 == "4G" { size = 1 }
$5 == "datafile_maxsize" && $7 == "8G" { maximum = 1 }
$5 == "datafile_next" && $7 == "512M" { increment = 1 }
END { exit !(size && maximum && increment) }
' "$RUNNER_TEMP/upgrade-datafile.tsv"; then
datafile_ready=true
break
fi
sleep 2
done
cat "$RUNNER_TEMP/upgrade-datafile.tsv"
if [ "$datafile_ready" != true ]; then
echo 'OceanBase datafile configuration did not become effective within one minute.' >&2
exit 1
fi
docker exec upgrade-oceanbase \
obclient -h127.0.0.1 -P2881 -uroot@test -ppowercontext-e2e \
-Dpc_upgrade_test \
-e "
CREATE DATABASE pc_upgrade_fresh;
CREATE DATABASE pc_upgrade_code_test;
CREATE DATABASE pc_upgrade_code_fresh;
CREATE DATABASE pc_upgrade_vector_test;
CREATE DATABASE pc_upgrade_vector_fresh;
CREATE DATABASE pc_upgrade_vector_code_test;
CREATE DATABASE pc_upgrade_vector_code_fresh;
CREATE DATABASE pc_upgrade_140_test;
CREATE DATABASE pc_upgrade_140_fresh;
CREATE DATABASE pc_upgrade_140_code_test;
CREATE DATABASE pc_upgrade_140_code_fresh;
CREATE DATABASE pc_upgrade_140_vector_test;
CREATE DATABASE pc_upgrade_140_vector_fresh;
CREATE DATABASE pc_upgrade_140_vector_code_test;
CREATE DATABASE pc_upgrade_140_vector_code_fresh;
SET GLOBAL recyclebin=OFF;
SELECT VERSION();
SHOW VARIABLES LIKE 'ob_compatibility_mode';
SHOW VARIABLES LIKE 'recyclebin';
"
exit 0
fi
if [ "$(docker inspect --format '{{.State.Running}}' upgrade-oceanbase)" != true ]; then
echo 'OceanBase exited before becoming ready.' >&2
exit 1
fi
sleep 5
done
echo 'OceanBase did not become ready within 10 minutes.' >&2
exit 1
python scripts/oceanbase_ci.py wait --container upgrade-oceanbase --database pc_upgrade_test \
--output "$RUNNER_TEMP/oceanbase-startup"
timeout --kill-after=5s 60s docker exec upgrade-oceanbase \
timeout --kill-after=1s 55s obclient -h127.0.0.1 -P2881 -uroot@test -ppowercontext-e2e \
--connect-timeout=5 -Dpc_upgrade_test -e "
CREATE DATABASE pc_upgrade_fresh;
CREATE DATABASE pc_upgrade_code_test;
CREATE DATABASE pc_upgrade_code_fresh;
CREATE DATABASE pc_upgrade_vector_test;
CREATE DATABASE pc_upgrade_vector_fresh;
CREATE DATABASE pc_upgrade_vector_code_test;
CREATE DATABASE pc_upgrade_vector_code_fresh;
CREATE DATABASE pc_upgrade_140_test;
CREATE DATABASE pc_upgrade_140_fresh;
CREATE DATABASE pc_upgrade_140_code_test;
CREATE DATABASE pc_upgrade_140_code_fresh;
CREATE DATABASE pc_upgrade_140_vector_test;
CREATE DATABASE pc_upgrade_140_vector_fresh;
CREATE DATABASE pc_upgrade_140_vector_code_test;
CREATE DATABASE pc_upgrade_140_vector_code_fresh;
"
- name: Collect failed startup diagnostics
if: failure()
shell: bash
run: |
python scripts/oceanbase_ci.py collect --container upgrade-oceanbase \
--output "$RUNNER_TEMP/oceanbase-startup/failure"
timeout 15s docker logs --tail 2000 upgrade-oceanbase \
> "$RUNNER_TEMP/oceanbase-startup/console.log" 2>&1 || true
- name: Save failed startup diagnostics
if: failure()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
with:
name: oceanbase-startup-${{ github.job }}-${{ strategy.job-index || 0 }}
path: ${{ runner.temp }}/oceanbase-startup/
if-no-files-found: warn
retention-days: 7
35 changes: 33 additions & 2 deletions .github/ci-paths.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ full = [
".mise.toml", ".pre-commit-config.yaml", ".github/actions/setup-python-env/**",
".github/workflows/ci-changes.yml", ".github/workflows/master.yml",
".github/ci-paths.toml", "scripts/ci_changes.py", "tests/test_ci_changes.py", "tests/test_ci_pipeline.py",
".github/actions/setup-license-eye/**", "tests/test_ci_license_eye.py",
"tests/conftest.py", "tests/**/conftest.py", "tests/fixtures/**", "integrations/capabilities.toml",
"integrations/langchain/pyproject.toml", "integrations/langgraph/pyproject.toml",
"integrations/opendal/pyproject.toml",
Expand All @@ -29,6 +30,7 @@ tests = [
"scripts/generate_integration_lifecycle.py",
"scripts/run_atomic_memory_clean_migration.py", "scripts/scan_e2e_evidence.sh",
"scripts/check_atomic_memory_migration_shards.py",
"scripts/oceanbase_ci.py", ".github/oceanbase-migration-durations.json",
"scripts/ci_role_smoke.py", "scripts/ci_installation_roles.py",
# Release tooling is covered by unit tests; the packaging and publication workflows are manual.
".github/workflows/desktop-candidate.yml", "scripts/desktop_candidate.py",
Expand All @@ -50,6 +52,7 @@ database = [
".github/workflows/e2e-harness.yml", ".github/actions/setup-upgrade-oceanbase/**",
"tests/native/test_oceanbase_engine_recovery.py",
"tests/*migration*.py", "scripts/check_atomic_memory_migration_shards.py",
"scripts/oceanbase_ci.py", ".github/oceanbase-migration-durations.json",
]
dify = ["integrations/dify/**", "tests/*dify*"]
hermes = ["integrations/hermes/**", "tests/*hermes*", "scripts/generate_integration_lifecycle.py"]
Expand All @@ -73,10 +76,19 @@ website = [
docs_tests = ["docs/**", "README*.md"]
native = ["tests/native/**", "tests/test_service*.py", "tests/test_cursor_secret.py", "tests/test_server.py"]
harness = [
"scripts/oceanbase_ci.py",
"e2e/**", "integrations/bub/**", "scripts/scan_e2e_evidence.sh", "tests/test_e2e_workflow_contract.py",
".github/workflows/e2e-harness.yml",
]
oceanbase_acceptance = [
"scripts/oceanbase_ci.py",
"e2e/bub/compose*.yaml", "e2e/bub/run.sh",
".github/workflows/e2e-harness.yml", "tests/test_e2e_workflow_contract.py",
"tests/e2e/test_atomic_memory_search_authorization_snapshot.py", "tests/e2e/test_atomic_memory_read_snapshot.py",
"tests/e2e/test_runtime_server.py",
"tests/e2e/atomic_memory_migration_backend.py", "tests/e2e/test_runtime_server.py",
"tests/e2e/test_server_metrics_oceanbase.py", "tests/e2e/test_portable_archive.py",
"tests/e2e/server_storage.py", "tests/e2e/dream_support.py", "tests/builtin/persistence/contract.py",
"tests/e2e/atomic_memory_migration_fixture.py", "tests/legacy_memory.py",
]
# ZCode acceptance also exercises the Pi plugin and cross-host handoff fixtures.
zcode = [
Expand All @@ -85,6 +97,7 @@ zcode = [
]
kimi = ["integrations/kimi-code/**", "tests/*kimi*", ".github/workflows/kimi-code-acceptance.yml"]
upgrade = [
"scripts/oceanbase_ci.py",
"scripts/run_atomic_memory_clean_migration.py", "scripts/build_ops_bundle.py",
"release/**", "scripts/upgrade_*.py", "scripts/ci_legacy_upgrade_rejection.py",
"scripts/ci_release_smoke.py", "scripts/ci_ops_bundle_smoke.py", "scripts/capture_release_schema.py",
Expand All @@ -110,20 +123,24 @@ packaging = [
".github/workflows/build-docker.yml", "docker/**",
]
desktop = [
"scripts/download_ci_asset.py", "scripts/prepare_windows_ci_tools.py",
"desktop/**", "tests/test_desktop_fixture_qualification.py", "website/assets/**",
".github/workflows/desktop.yml",
]
managed_resources = [
"scripts/download_ci_asset.py",
"scripts/*managed_resource*", "scripts/build_ops_bundle.py", "scripts/ci_ops_bundle_smoke.py",
"scripts/build_intel_managed_wheel.py", "tests/test_managed_resource_producer.py", "tests/test_ops_resources.py",
".github/workflows/managed-resource-candidates.yml",
]
candidate_replay = [
"scripts/oceanbase_ci.py",
"src/powercontext/builtin/persistence/**", "src/powercontext/builtin/artifacts/**", "pyproject.toml", "uv.lock",
"tests/builtin/persistence/**", "scripts/replay_candidate_migration.py",
".github/workflows/candidate-schema-replay.yml", ".github/actions/setup-upgrade-oceanbase/**",
]
release_schema = [
"scripts/oceanbase_ci.py",
"scripts/capture_release_schema.py", "scripts/upgrade_database_probe.py", "scripts/upgrade_process.py",
"tests/release_upgrades/test_full_server.py", ".github/workflows/capture-release-schema.yml",
".github/actions/setup-upgrade-oceanbase/**",
Expand All @@ -136,11 +153,24 @@ seekdb_lock = [
"src/powercontext/builtin/persistence/**", "pyproject.toml", "uv.lock",
]
skill_guidance = [
"scripts/download_ci_asset.py",
"evaluation/skills/skill-up/**",
"integrations/agent-plugin/powercontext/skills/powercontext-project-context/**",
".github/workflows/skill-guidance.yml",
]

# Audited SQLite/in-memory tests retain ordinary unit/e2e coverage. Exact paths
# avoid exempting future native tests matched by the broad database patterns.
# Exclusions affect direct matches only; shared and full-scope rules take precedence.
# Remove a file from this list if it gains native database cases.
[exclusions]
database = [
"tests/builtin/runtime/test_recall_sufficiency.py",
"tests/builtin/runtime/test_statistics.py", "tests/builtin/runtime/test_model_usage_recorder.py",
"tests/builtin/runtime/test_prepared_context.py", "tests/e2e/test_recall_sufficiency_gate.py",
"tests/e2e/test_context_text_assembly.py",
]

# Packaged guidance and its generators are inputs to the native host tests.
[shared.guidance]
patterns = [
Expand All @@ -155,7 +185,7 @@ suites = ["tests", "dify", "hermes", "dsh", "pi", "opencode", "openclaw", "zcode
patterns = ["src/**", "openapi/**", "pyproject.toml", "uv.lock"]
suites = [
"tests", "evaluation", "database", "dify", "hermes", "dsh", "cindy", "pi", "opencode", "openclaw", "opendal",
"website", "native", "harness", "zcode", "kimi", "upgrade", "observability", "packaging", "desktop",
"website", "native", "harness", "oceanbase_acceptance", "zcode", "kimi", "upgrade", "observability", "packaging", "desktop",
"managed_resources",
]

Expand Down Expand Up @@ -202,6 +232,7 @@ website = ["check-website", "website-link-validation-windows"]
docs_tests = ["docs-tests"]
native = ["native-service"]
harness = ["harness-validation"]
oceanbase_acceptance = ["harness-validation"]
zcode = ["zcode-acceptance"]
kimi = ["kimi-acceptance"]
upgrade = ["seekdb-managed-startup", "upgrade-acceptance"]
Expand Down
Loading
Loading