mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix(docker): package runtime workspace templates
This commit is contained in:
88
.github/workflows/docker-release.yml
vendored
88
.github/workflows/docker-release.yml
vendored
@@ -162,6 +162,50 @@ jobs:
|
||||
provenance: mode=max
|
||||
push: true
|
||||
|
||||
- name: Smoke test amd64 runtime workspace templates
|
||||
shell: bash
|
||||
env:
|
||||
IMAGE_REFS: ${{ steps.tags.outputs.value }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mapfile -t image_refs <<< "${IMAGE_REFS}"
|
||||
image_ref="${image_refs[0]}"
|
||||
if [[ -z "${image_ref}" ]]; then
|
||||
echo "::error::No amd64 image ref resolved for runtime template smoke"
|
||||
exit 1
|
||||
fi
|
||||
docker run --rm --entrypoint /bin/sh "${image_ref}" -lc '
|
||||
set -eu
|
||||
test -f /app/src/agents/templates/HEARTBEAT.md
|
||||
temp_root="$(mktemp -d)"
|
||||
trap "rm -rf \"${temp_root}\"" EXIT
|
||||
mkdir -p "${temp_root}/home" "${temp_root}/cwd"
|
||||
cd "${temp_root}/cwd"
|
||||
set +e
|
||||
HOME="${temp_root}/home" \
|
||||
USERPROFILE="${temp_root}/home" \
|
||||
OPENCLAW_HOME="${temp_root}/home" \
|
||||
OPENCLAW_NO_ONBOARD=1 \
|
||||
OPENCLAW_SUPPRESS_NOTES=1 \
|
||||
OPENCLAW_DISABLE_BUNDLED_PLUGINS=1 \
|
||||
OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK=1 \
|
||||
AWS_EC2_METADATA_DISABLED=true \
|
||||
AWS_SHARED_CREDENTIALS_FILE="${temp_root}/home/.aws/credentials" \
|
||||
AWS_CONFIG_FILE="${temp_root}/home/.aws/config" \
|
||||
node /app/openclaw.mjs agent --message "workspace bootstrap smoke" --session-id "workspace-bootstrap-smoke" --local --timeout 1 --json \
|
||||
>"${temp_root}/out.log" 2>&1
|
||||
status="$?"
|
||||
set -e
|
||||
if grep -F "Missing workspace template:" "${temp_root}/out.log"; then
|
||||
cat "${temp_root}/out.log"
|
||||
exit 1
|
||||
fi
|
||||
test -f "${temp_root}/home/.openclaw/workspace/HEARTBEAT.md"
|
||||
if [ "${status}" -ne 0 ]; then
|
||||
cat "${temp_root}/out.log"
|
||||
fi
|
||||
'
|
||||
|
||||
# Build arm64 image. Default and slim tags point to the same slim runtime.
|
||||
build-arm64:
|
||||
needs: [approve_manual_backfill]
|
||||
@@ -260,6 +304,50 @@ jobs:
|
||||
provenance: mode=max
|
||||
push: true
|
||||
|
||||
- name: Smoke test arm64 runtime workspace templates
|
||||
shell: bash
|
||||
env:
|
||||
IMAGE_REFS: ${{ steps.tags.outputs.value }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mapfile -t image_refs <<< "${IMAGE_REFS}"
|
||||
image_ref="${image_refs[0]}"
|
||||
if [[ -z "${image_ref}" ]]; then
|
||||
echo "::error::No arm64 image ref resolved for runtime template smoke"
|
||||
exit 1
|
||||
fi
|
||||
docker run --rm --entrypoint /bin/sh "${image_ref}" -lc '
|
||||
set -eu
|
||||
test -f /app/src/agents/templates/HEARTBEAT.md
|
||||
temp_root="$(mktemp -d)"
|
||||
trap "rm -rf \"${temp_root}\"" EXIT
|
||||
mkdir -p "${temp_root}/home" "${temp_root}/cwd"
|
||||
cd "${temp_root}/cwd"
|
||||
set +e
|
||||
HOME="${temp_root}/home" \
|
||||
USERPROFILE="${temp_root}/home" \
|
||||
OPENCLAW_HOME="${temp_root}/home" \
|
||||
OPENCLAW_NO_ONBOARD=1 \
|
||||
OPENCLAW_SUPPRESS_NOTES=1 \
|
||||
OPENCLAW_DISABLE_BUNDLED_PLUGINS=1 \
|
||||
OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK=1 \
|
||||
AWS_EC2_METADATA_DISABLED=true \
|
||||
AWS_SHARED_CREDENTIALS_FILE="${temp_root}/home/.aws/credentials" \
|
||||
AWS_CONFIG_FILE="${temp_root}/home/.aws/config" \
|
||||
node /app/openclaw.mjs agent --message "workspace bootstrap smoke" --session-id "workspace-bootstrap-smoke" --local --timeout 1 --json \
|
||||
>"${temp_root}/out.log" 2>&1
|
||||
status="$?"
|
||||
set -e
|
||||
if grep -F "Missing workspace template:" "${temp_root}/out.log"; then
|
||||
cat "${temp_root}/out.log"
|
||||
exit 1
|
||||
fi
|
||||
test -f "${temp_root}/home/.openclaw/workspace/HEARTBEAT.md"
|
||||
if [ "${status}" -ne 0 ]; then
|
||||
cat "${temp_root}/out.log"
|
||||
fi
|
||||
'
|
||||
|
||||
# Create multi-platform manifests
|
||||
create-manifest:
|
||||
needs: [approve_manual_backfill, build-amd64, build-arm64]
|
||||
|
||||
@@ -178,6 +178,7 @@ COPY --from=runtime-assets --chown=node:node /app/package.json .
|
||||
COPY --from=runtime-assets --chown=node:node /app/pnpm-workspace.yaml .
|
||||
COPY --from=runtime-assets --chown=node:node /app/patches ./patches
|
||||
COPY --from=runtime-assets --chown=node:node /app/openclaw.mjs .
|
||||
COPY --from=runtime-assets --chown=node:node /app/src/agents/templates ./src/agents/templates
|
||||
COPY --from=runtime-assets --chown=node:node /app/${OPENCLAW_BUNDLED_PLUGIN_DIR} ./${OPENCLAW_BUNDLED_PLUGIN_DIR}
|
||||
COPY --from=runtime-assets --chown=node:node /app/skills ./skills
|
||||
COPY --from=runtime-assets --chown=node:node /app/docs ./docs
|
||||
|
||||
@@ -246,6 +246,20 @@ describe("Dockerfile", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps runtime workspace templates in final images", async () => {
|
||||
const dockerfile = await readFile(dockerfilePath, "utf8");
|
||||
const runtimeStageIndex = dockerfile.lastIndexOf("FROM base-runtime");
|
||||
const templatesCopyIndex = dockerfile.indexOf(
|
||||
"COPY --from=runtime-assets --chown=node:node /app/src/agents/templates ./src/agents/templates",
|
||||
runtimeStageIndex,
|
||||
);
|
||||
const userIndex = dockerfile.indexOf("USER node", runtimeStageIndex);
|
||||
|
||||
expect(runtimeStageIndex).toBeGreaterThan(-1);
|
||||
expect(templatesCopyIndex).toBeGreaterThan(runtimeStageIndex);
|
||||
expect(templatesCopyIndex).toBeLessThan(userIndex);
|
||||
});
|
||||
|
||||
it("keeps package manager patch files in runtime images", async () => {
|
||||
const dockerfile = collapseDockerContinuations(await readFile(dockerfilePath, "utf8"));
|
||||
const pnpmWorkspace = YAML.parse(await readFile(pnpmWorkspacePath, "utf8")) as {
|
||||
@@ -277,6 +291,16 @@ describe("Dockerfile", () => {
|
||||
expect(workflow).not.toContain("OPENCLAW_EXTENSIONS=diagnostics-otel\n");
|
||||
});
|
||||
|
||||
it("smokes runtime workspace templates before Docker release manifests publish", async () => {
|
||||
const workflow = await readFile(dockerReleaseWorkflowPath, "utf8");
|
||||
|
||||
expect(workflow).toContain("Smoke test amd64 runtime workspace templates");
|
||||
expect(workflow).toContain("Smoke test arm64 runtime workspace templates");
|
||||
expect(workflow).toContain("test -f /app/src/agents/templates/HEARTBEAT.md");
|
||||
expect(workflow).toContain('grep -F "Missing workspace template:"');
|
||||
expect(workflow).toContain('test -f "${temp_root}/home/.openclaw/workspace/HEARTBEAT.md"');
|
||||
});
|
||||
|
||||
it("does not override bundled plugin discovery in runtime images", async () => {
|
||||
const dockerfile = collapseDockerContinuations(await readFile(dockerfilePath, "utf8"));
|
||||
expect(dockerfile).toContain(`ARG OPENCLAW_BUNDLED_PLUGIN_DIR=${BUNDLED_PLUGIN_ROOT_DIR}`);
|
||||
|
||||
Reference in New Issue
Block a user