Skip to content

Commit 9f7485e

Browse files
committed
test: port release validation stabilizers
1 parent c51fa0d commit 9f7485e

15 files changed

Lines changed: 306 additions & 69 deletions

.github/actions/setup-node-env/action.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ inputs:
2626
runs:
2727
using: composite
2828
steps:
29+
- name: Normalize container toolcache
30+
shell: bash
31+
run: |
32+
set -euo pipefail
33+
if [[ -d /__t && ! -e /opt/hostedtoolcache ]]; then
34+
mkdir -p /opt
35+
ln -s /__t /opt/hostedtoolcache
36+
fi
37+
2938
- name: Setup Node.js
3039
uses: actions/setup-node@v6
3140
with:

.github/actions/setup-pnpm-store-cache/ensure-node.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ openclaw_find_toolcache_node() {
4343
"${RUNNER_TOOL_CACHE:-}" \
4444
"${AGENT_TOOLSDIRECTORY:-}" \
4545
"${ACTIONS_RUNNER_TOOL_CACHE:-}" \
46+
"${OPENCLAW_CONTAINER_TOOL_CACHE:-/__t}" \
4647
"/opt/hostedtoolcache" \
4748
"/home/runner/_work/_tool" \
4849
"/Users/runner/hostedtoolcache" \

.github/workflows/openclaw-cross-os-release-checks-reusable.yml

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,18 +553,54 @@ jobs:
553553
use-actions-cache: "false"
554554

555555
- name: Download candidate artifact
556+
id: download_candidate
557+
continue-on-error: true
558+
uses: actions/download-artifact@v8
559+
with:
560+
name: openclaw-cross-os-release-checks-candidate-${{ github.run_id }}
561+
path: ${{ runner.temp }}/openclaw-cross-os-release-checks/candidate
562+
563+
- name: Retry candidate artifact download
564+
if: ${{ steps.download_candidate.outcome == 'failure' }}
556565
uses: actions/download-artifact@v8
557566
with:
558567
name: openclaw-cross-os-release-checks-candidate-${{ github.run_id }}
559568
path: ${{ runner.temp }}/openclaw-cross-os-release-checks/candidate
560569

561570
- name: Download baseline artifact
562571
if: ${{ matrix.suite == 'packaged-upgrade' }}
572+
id: download_baseline
573+
continue-on-error: true
574+
uses: actions/download-artifact@v8
575+
with:
576+
name: openclaw-cross-os-release-checks-baseline-${{ github.run_id }}
577+
path: ${{ runner.temp }}/openclaw-cross-os-release-checks/baseline
578+
579+
- name: Retry baseline artifact download
580+
if: ${{ matrix.suite == 'packaged-upgrade' && steps.download_baseline.outcome == 'failure' }}
563581
uses: actions/download-artifact@v8
564582
with:
565583
name: openclaw-cross-os-release-checks-baseline-${{ github.run_id }}
566584
path: ${{ runner.temp }}/openclaw-cross-os-release-checks/baseline
567585

586+
- name: Verify release-check inputs
587+
shell: bash
588+
env:
589+
CANDIDATE_TGZ: ${{ runner.temp }}/openclaw-cross-os-release-checks/candidate/${{ needs.prepare.outputs.candidate_file_name }}
590+
BASELINE_TGZ: ${{ runner.temp }}/openclaw-cross-os-release-checks/baseline/${{ needs.prepare.outputs.baseline_file_name }}
591+
OUTPUT_DIR: ${{ runner.temp }}/openclaw-cross-os-release-checks/${{ matrix.artifact_name }}-${{ matrix.suite }}
592+
SUITE: ${{ matrix.suite }}
593+
run: |
594+
mkdir -p "${OUTPUT_DIR}"
595+
if [[ ! -f "${CANDIDATE_TGZ}" ]]; then
596+
echo "::error::candidate artifact missing: ${CANDIDATE_TGZ}"
597+
exit 1
598+
fi
599+
if [[ "${SUITE}" == "packaged-upgrade" ]] && [[ ! -f "${BASELINE_TGZ}" ]]; then
600+
echo "::error::baseline artifact missing: ${BASELINE_TGZ}"
601+
exit 1
602+
fi
603+
568604
- name: Run cross-OS release checks
569605
shell: bash
570606
env:
@@ -615,7 +651,8 @@ jobs:
615651
if [[ -f "${SUMMARY_PATH}" ]]; then
616652
cat "${SUMMARY_PATH}" >> "$GITHUB_STEP_SUMMARY"
617653
else
618-
echo "No summary generated." >> "$GITHUB_STEP_SUMMARY"
654+
mkdir -p "$(dirname "${SUMMARY_PATH}")"
655+
echo "No summary generated." | tee "${SUMMARY_PATH}" >> "$GITHUB_STEP_SUMMARY"
619656
fi
620657
621658
- name: Upload release-check artifacts

.github/workflows/openclaw-live-and-e2e-checks-reusable.yml

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ on:
102102
- beta
103103
- stable
104104
- full
105+
use_github_hosted_runners:
106+
description: Use GitHub-hosted runners instead of Blacksmith runners
107+
required: false
108+
default: false
109+
type: boolean
105110
advisory:
106111
description: Treat failures as advisory for the caller
107112
required: false
@@ -208,6 +213,11 @@ on:
208213
required: false
209214
default: stable
210215
type: string
216+
use_github_hosted_runners:
217+
description: Use GitHub-hosted runners instead of Blacksmith runners
218+
required: false
219+
default: true
220+
type: boolean
211221
secrets:
212222
OPENAI_API_KEY:
213223
required: false
@@ -474,7 +484,7 @@ jobs:
474484
needs: validate_selected_ref
475485
if: inputs.include_live_suites && !inputs.live_models_only && (inputs.live_suite_filter == '' || inputs.live_suite_filter == 'live-cache')
476486
continue-on-error: ${{ inputs.advisory }}
477-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
487+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
478488
timeout-minutes: 20
479489
env:
480490
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
@@ -524,7 +534,7 @@ jobs:
524534
needs: validate_selected_ref
525535
if: inputs.include_repo_e2e && inputs.live_suite_filter == ''
526536
continue-on-error: ${{ inputs.advisory }}
527-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
537+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
528538
timeout-minutes: ${{ inputs.release_test_profile == 'full' && 90 || 60 }}
529539
env:
530540
OPENCLAW_VITEST_MAX_WORKERS: "2"
@@ -556,7 +566,7 @@ jobs:
556566
needs: validate_selected_ref
557567
if: inputs.include_repo_e2e && (inputs.live_suite_filter == '' || inputs.live_suite_filter == 'openshell-e2e')
558568
continue-on-error: ${{ inputs.advisory }}
559-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
569+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
560570
timeout-minutes: ${{ matrix.timeout_minutes }}
561571
strategy:
562572
fail-fast: false
@@ -630,7 +640,7 @@ jobs:
630640
if: inputs.include_release_path_suites && inputs.docker_lanes == ''
631641
name: Docker E2E (${{ matrix.label }})
632642
continue-on-error: ${{ inputs.advisory }}
633-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
643+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
634644
timeout-minutes: ${{ matrix.timeout_minutes }}
635645
strategy:
636646
fail-fast: false
@@ -921,7 +931,7 @@ jobs:
921931
needs: validate_selected_ref
922932
if: inputs.docker_lanes != ''
923933
continue-on-error: ${{ inputs.advisory }}
924-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-4vcpu-ubuntu-2404' }}
934+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-4vcpu-ubuntu-2404' }}
925935
timeout-minutes: 5
926936
outputs:
927937
groups_json: ${{ steps.groups.outputs.groups_json }}
@@ -950,7 +960,7 @@ jobs:
950960
if: inputs.docker_lanes != ''
951961
name: Docker E2E targeted lanes (${{ matrix.group.label }})
952962
continue-on-error: ${{ inputs.advisory }}
953-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
963+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
954964
timeout-minutes: 60
955965
strategy:
956966
fail-fast: false
@@ -1182,7 +1192,7 @@ jobs:
11821192
if: inputs.include_openwebui && !inputs.include_release_path_suites && inputs.docker_lanes == ''
11831193
name: Docker E2E (openwebui)
11841194
continue-on-error: ${{ inputs.advisory }}
1185-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
1195+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
11861196
timeout-minutes: 60
11871197
env:
11881198
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
@@ -1308,7 +1318,7 @@ jobs:
13081318
needs: validate_selected_ref
13091319
if: inputs.include_release_path_suites || inputs.include_openwebui || inputs.docker_lanes != ''
13101320
continue-on-error: ${{ inputs.advisory }}
1311-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
1321+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
13121322
timeout-minutes: ${{ inputs.release_test_profile == 'full' && 90 || 60 }}
13131323
permissions:
13141324
actions: read
@@ -1551,7 +1561,7 @@ jobs:
15511561
needs: validate_selected_ref
15521562
if: inputs.include_live_suites && (inputs.live_suite_filter == '' || startsWith(inputs.live_suite_filter, 'live-') || startsWith(inputs.live_suite_filter, 'docker-live-models'))
15531563
continue-on-error: ${{ inputs.advisory }}
1554-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
1564+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
15551565
timeout-minutes: 60
15561566
permissions:
15571567
contents: read
@@ -1624,7 +1634,7 @@ jobs:
16241634
needs: [validate_selected_ref, prepare_live_test_image]
16251635
if: inputs.include_live_suites && inputs.live_model_providers == '' && (inputs.live_suite_filter == '' || inputs.live_suite_filter == 'docker-live-models')
16261636
continue-on-error: ${{ inputs.advisory }}
1627-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
1637+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
16281638
timeout-minutes: 45
16291639
strategy:
16301640
fail-fast: false
@@ -1775,7 +1785,7 @@ jobs:
17751785
needs: [validate_selected_ref, prepare_live_test_image]
17761786
if: inputs.include_live_suites && inputs.live_model_providers != '' && (inputs.live_suite_filter == '' || inputs.live_suite_filter == 'docker-live-models')
17771787
continue-on-error: ${{ inputs.advisory }}
1778-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
1788+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
17791789
timeout-minutes: 45
17801790
env:
17811791
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
@@ -1949,7 +1959,7 @@ jobs:
19491959
needs: validate_selected_ref
19501960
if: inputs.include_live_suites && !inputs.live_models_only && (inputs.live_suite_filter == '' || (startsWith(inputs.live_suite_filter, 'native-live-') && !startsWith(inputs.live_suite_filter, 'native-live-extensions-media') && inputs.live_suite_filter != 'native-live-extensions-a-k'))
19511961
continue-on-error: ${{ inputs.advisory }}
1952-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
1962+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
19531963
timeout-minutes: ${{ matrix.timeout_minutes }}
19541964
strategy:
19551965
fail-fast: false
@@ -2251,6 +2261,7 @@ jobs:
22512261
env:
22522262
OPENCLAW_LIVE_COMMAND: ${{ matrix.command }}
22532263
OPENCLAW_LIVE_SUITE_ADVISORY: ${{ matrix.advisory }}
2264+
shell: bash
22542265
run: |
22552266
set +e
22562267
bash .release-harness/scripts/ci-live-command-retry.sh
@@ -2270,7 +2281,7 @@ jobs:
22702281
needs: [validate_selected_ref, prepare_live_test_image]
22712282
if: inputs.include_live_suites && !inputs.live_models_only && (inputs.live_suite_filter == '' || startsWith(inputs.live_suite_filter, 'live-'))
22722283
continue-on-error: ${{ inputs.advisory }}
2273-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
2284+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-32vcpu-ubuntu-2404' }}
22742285
timeout-minutes: ${{ matrix.timeout_minutes }}
22752286
strategy:
22762287
fail-fast: false
@@ -2469,6 +2480,7 @@ jobs:
24692480
env:
24702481
OPENCLAW_LIVE_COMMAND: ${{ matrix.command }}
24712482
OPENCLAW_LIVE_SUITE_ADVISORY: ${{ matrix.advisory }}
2483+
shell: bash
24722484
run: |
24732485
set +e
24742486
bash .release-harness/scripts/ci-live-command-retry.sh
@@ -2488,7 +2500,7 @@ jobs:
24882500
needs: validate_selected_ref
24892501
if: inputs.include_live_suites && !inputs.live_models_only && (inputs.live_suite_filter == '' || startsWith(inputs.live_suite_filter, 'native-live-extensions-media') || inputs.live_suite_filter == 'native-live-extensions-a-k')
24902502
continue-on-error: ${{ inputs.advisory }}
2491-
runs-on: ${{ github.event_name == 'workflow_call' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
2503+
runs-on: ${{ inputs.use_github_hosted_runners && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
24922504
container:
24932505
image: ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04
24942506
credentials:
@@ -2656,6 +2668,7 @@ jobs:
26562668
if: contains(matrix.profiles, inputs.release_test_profile) && (inputs.live_suite_filter == '' || inputs.live_suite_filter == matrix.suite_id || (inputs.live_suite_filter == 'native-live-extensions-media-video' && startsWith(matrix.suite_id, 'native-live-extensions-media-video-')))
26572669
env:
26582670
OPENCLAW_LIVE_SUITE_ADVISORY: ${{ matrix.advisory }}
2671+
shell: bash
26592672
run: |
26602673
set +e
26612674
${{ matrix.command }}

extensions/memory-core/src/tools.test.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { beforeEach, describe, expect, it, vi } from "vitest";
22
import {
3+
getMemorySearchManagerMockCalls,
34
getMemorySearchManagerMockConfigs,
45
getMemorySearchManagerMockParams,
56
resetMemoryToolMockState,
@@ -85,6 +86,81 @@ describe("memory_search unavailable payloads", () => {
8586
});
8687
});
8788

89+
it("re-resolves the manager once when a cached sqlite handle was closed", async () => {
90+
let searchCalls = 0;
91+
setMemorySearchImpl(async () => {
92+
searchCalls += 1;
93+
if (searchCalls === 1) {
94+
throw new Error("database is not open");
95+
}
96+
return [
97+
{
98+
path: "MEMORY.md",
99+
startLine: 1,
100+
endLine: 1,
101+
score: 0.9,
102+
snippet: "Thread-hidden codename: ORBIT-22.",
103+
source: "memory" as const,
104+
},
105+
];
106+
});
107+
108+
const tool = createMemorySearchToolOrThrow({
109+
config: {
110+
agents: { list: [{ id: "main", default: true }] },
111+
memory: { citations: "off" },
112+
},
113+
});
114+
const result = await tool.execute("closed-db", { query: "hidden thread codename" });
115+
116+
expect((result.details as { results?: Array<{ path: string }> }).results).toEqual([
117+
{
118+
corpus: "memory",
119+
path: "MEMORY.md",
120+
startLine: 1,
121+
endLine: 1,
122+
score: 0.9,
123+
snippet: "Thread-hidden codename: ORBIT-22.",
124+
source: "memory",
125+
},
126+
]);
127+
expect(searchCalls).toBe(2);
128+
expect(getMemorySearchManagerMockCalls()).toBe(2);
129+
});
130+
131+
it("forces a sync and retries once when the first search has zero hits", async () => {
132+
let searchCalls = 0;
133+
setMemorySearchImpl(async () => {
134+
searchCalls += 1;
135+
if (searchCalls === 1) {
136+
return [];
137+
}
138+
return [
139+
{
140+
path: "MEMORY.md",
141+
startLine: 1,
142+
endLine: 1,
143+
score: 0.9,
144+
snippet: "Thread-hidden codename: ORBIT-22.",
145+
source: "memory" as const,
146+
},
147+
];
148+
});
149+
150+
const tool = createMemorySearchToolOrThrow({
151+
config: {
152+
agents: { list: [{ id: "main", default: true }] },
153+
memory: { citations: "off" },
154+
},
155+
});
156+
const result = await tool.execute("zero-hit-retry", { query: "hidden thread codename" });
157+
158+
expect((result.details as { results?: Array<{ path: string }> }).results?.[0]?.path).toBe(
159+
"MEMORY.md",
160+
);
161+
expect(searchCalls).toBe(2);
162+
});
163+
88164
it("returns structured search debug metadata for qmd results", async () => {
89165
setMemoryBackend("qmd");
90166
setMemorySearchImpl(async (opts) => {

0 commit comments

Comments
 (0)